|
|
  |
Ethernet на ПЛИС, PHY+MAC+UDP/IP |
|
|
|
Jun 22 2015, 11:41
|
Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 21-01-15
Пользователь №: 84 716

|
Цитата(mobidev @ Jun 22 2015, 14:31)  QM question это как я понимаю пытается отрабатывать upnp, но Ваша проблема иная, пк и железка хотят поиметь IP, посему и засыпают arp-запросы. Как собираетесь общаться с пк, если оно хочет ip, а ip никто не согласовал! Ага, значит без arp не обойтись. Есть ли дока подробная? Буду разбераться куда его в ethernet frame вставлять и вообще что с ним делать
|
|
|
|
|
Jun 22 2015, 12:03
|
Местный
  
Группа: Свой
Сообщений: 202
Регистрация: 22-06-08
Из: Краснодарский край
Пользователь №: 38 488

|
Цитата(NSergeevich @ Jun 22 2015, 15:41)  Ага, значит без arp не обойтись. Есть ли дока подробная? Буду разбераться куда его в ethernet frame вставлять и вообще что с ним делать Если нужна подробная дока именно по ARP, то наверно правильнее читать соответствующий RFC. Например, начать с RFC 826 https://tools.ietf.org/html/rfc826P.S. а вообще наверняка есть готовые решения.
|
|
|
|
|
Jun 22 2015, 12:41
|
Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 21-01-15
Пользователь №: 84 716

|
Цитата(doom13 @ Jun 22 2015, 15:27)  Руками IP-адрес пропишите и если не появятся пакеты в Wireshark, то ищите проблему на плате (в проекте). Я бы и прописал руками, вот только куда? Я так понимаю если в ethernet frame добавлять arp то и будет куда прописать ip.
Сообщение отредактировал NSergeevich - Jun 22 2015, 12:41
|
|
|
|
|
Jun 22 2015, 12:53
|
Группа: Участник
Сообщений: 13
Регистрация: 16-06-15
Пользователь №: 87 174

|
Цитата(NSergeevich @ Jun 22 2015, 11:50)  C этим модом тоже самое Sergeevich, скачайте прогу PackETH. Там сможите потренироваться с этими пакетами. Можно создавать UDP, ARP или свои собственные. Я долго парился, высчитывал. А с ней все пошло как по маслу. Там же можно и проверяться, правильно ли посчитали UDP Checksumme или Frame Check (CRC32). http://packeth.sourceforge.net/packeth/Home.html И да еще один важный момент: Попробуйте поменять местами 5D <-> D5 в Preable. У меня работает вот этот вариант : 55 55 55 55 55 55 55 D5
|
|
|
|
|
Jun 22 2015, 12:54
|
Знающий
   
Группа: Свой
Сообщений: 555
Регистрация: 14-10-09
Пользователь №: 52 939

|
Код /// size 14 bytes logic [7:0] ether_hdr_da[5:0]; // destination MAC address logic [7:0] ether_hdr_sa[5:0]; // source MAC address logic [7:0] ether_hdr_type_code[1:0]; // type code - 0x0800 is IP
/// size 20 bytes
logic [7:0] ip_hdr_ver_hlen; // version - 4 bits; IP hdr len - 4 bits // IPv4 with 20 byte header 0x45 logic [7:0] ip_hdr_tos; // Type of service logic [7:0] ip_hdr_tlen[1:0]; // Size of datagram (header + data) logic [7:0] ip_hdr_id[1:0]; // together with sa, uniequly identifies pkt logic [7:0] ip_hdr_frag_off[1:0]; // flags - 3 bits; fragment offset - 13 bits logic [7:0] ip_hdr_ttl; // time to live logic [7:0] ip_hdr_proto; // protocol UDP_PROTO 0x11 logic [7:0] ip_hdr_csum[1:0]; // header checksum logic [7:0] ip_hdr_sa[3:0]; // IP source address logic [7:0] ip_hdr_da[3:0]; // IP dest address /// size 8 bytes
logic [7:0] udp_hdr_sp[1:0]; // Source port logic [7:0] udp_hdr_dp[1:0]; // Destination port logic [7:0] udp_hdr_len[1:0]; // length of packet logic [7:0] udp_hdr_csum[1:0]; // checksum Код always_comb begin case (cnt_words_tx) 0: aso_out0_data = { ether_hdr_da[5], ether_hdr_da[4], ether_hdr_da[3], ether_hdr_da[2] }; 1: aso_out0_data = { ether_hdr_da[1], ether_hdr_da[0], ether_hdr_sa[5], ether_hdr_sa[4] }; 2: aso_out0_data = { ether_hdr_sa[3], ether_hdr_sa[2], ether_hdr_sa[1], ether_hdr_sa[0] }; 3: aso_out0_data = { ether_hdr_type_code[1], ether_hdr_type_code[0], ip_hdr_ver_hlen, ip_hdr_tos }; 4: aso_out0_data = { ip_hdr_tlen[1], ip_hdr_tlen[0], ip_hdr_id[1], ip_hdr_id[0] }; 5: aso_out0_data = { ip_hdr_frag_off[1], ip_hdr_frag_off[0], ip_hdr_ttl, ip_hdr_proto }; 6: aso_out0_data = { ip_hdr_csum[1], ip_hdr_csum[0], ip_hdr_sa[3], ip_hdr_sa[2] }; 7: aso_out0_data = { ip_hdr_sa[1], ip_hdr_sa[0], ip_hdr_da[3], ip_hdr_da[2] }; 8: aso_out0_data = { ip_hdr_da[1], ip_hdr_da[0], udp_hdr_sp[1], udp_hdr_sp[0] }; 9: aso_out0_data = { udp_hdr_dp[1], udp_hdr_dp[0], udp_hdr_len[1], udp_hdr_len[0] }; 10: aso_out0_data = { udp_hdr_csum[1], udp_hdr_csum[0], aso_out0_data_tx[31:16]}; default: aso_out0_data = aso_out0_data_tx; endcase end
|
|
|
|
|
Jun 22 2015, 13:26
|
Местный
  
Группа: Свой
Сообщений: 202
Регистрация: 22-06-08
Из: Краснодарский край
Пользователь №: 38 488

|
Цитата(HFSE @ Jun 22 2015, 16:53)  правильно ли посчитали UDP Checksumme Сделаю небольшую подсказку, протоколом UDP предусматривается один из вариантов обмена без обязательного подсчёта контрольной суммы заголовка udp-пакета, но только его! Но это отступление от темы Mac+ip.
|
|
|
|
|
Jun 22 2015, 15:02
|
Частый гость
 
Группа: Участник
Сообщений: 102
Регистрация: 21-01-15
Пользователь №: 84 716

|
Цитата(HFSE @ Jun 22 2015, 15:53)  Sergeevich, скачайте прогу PackETH. Там сможите потренироваться с этими пакетами. Можно создавать UDP, ARP или свои собственные. Я долго парился, высчитывал. А с ней все пошло как по маслу. Там же можно и проверяться, правильно ли посчитали UDP Checksumme или Frame Check (CRC32). http://packeth.sourceforge.net/packeth/Home.html И да еще один важный момент: Попробуйте поменять местами 5D <-> D5 в Preable. У меня работает вот этот вариант : 55 55 55 55 55 55 55 D5 У меня преамбулу добавляет сама корка мака gosu-art, мне это уже понятно. Теперь не понятно какими данными заполнять : Код logic [7:0] ip_hdr_ver_hlen; // version - 4 bits; IP hdr len - 4 bits // IPv4 with 20 byte header 0x45 logic [7:0] ip_hdr_tos; // Type of service logic [7:0] ip_hdr_tlen[1:0]; // Size of datagram (header + data) logic [7:0] ip_hdr_id[1:0]; // together with sa, uniequly identifies pkt logic [7:0] ip_hdr_frag_off[1:0]; // flags - 3 bits; fragment offset - 13 bits logic [7:0] ip_hdr_ttl; // time to live logic [7:0] ip_hdr_proto; // protocol UDP_PROTO 0x11 logic [7:0] ip_hdr_csum[1:0]; // header checksum откуда они берутся, в частности вот этот длинный header, как считать checksum и тд И вообще может быть есть у xilinx-а готовые корки на ip/udp, чтобы делали все сами, а я только дату пихал?
|
|
|
|
|
Jun 22 2015, 18:39
|
Знающий
   
Группа: Свой
Сообщений: 555
Регистрация: 14-10-09
Пользователь №: 52 939

|
Основные параметры Код localparam SIZE_ETHER_HDR = 14; localparam SIZE_IP_HDR = 20; localparam SIZE_UDP_HDR = 8;
localparam UDP_PROTO = 8'h11; localparam ETH_TYPE = 16'h0800; localparam IP_VER = 8'h45; localparam IP_TTL = 8'hFF;
assign {ip_hdr_ver_hlen} = IP_VER; assign {ether_hdr_type_code[1],ether_hdr_type_code[0]} = ETH_TYPE; assign ip_hdr_proto = UDP_PROTO; assign ip_hdr_ttl = IP_TTL; Расчет чек суммы для IP и UDP Код module udp_check_summ ( input iclk, input [15:0] packet_in, output [15:0] check_summ_out, input data_valid, input sop );
logic [15:0] accum_rg; logic [16:0] carry_check; logic carry_16; assign carry_check = accum_rg + packet_in; assign check_summ_out = 16'hFFFF - accum_rg; /// always_ff @ (posedge iclk) begin // if (sop && data_valid) // accum_rg <= packet_in; // else if (sop && !data_valid) if (sop) accum_rg <= '0; else begin if(data_valid) begin accum_rg <= accum_rg + packet_in + carry_check[16]; end end end
endmodule Далее просто заполнить поля вашими значениями Код if(avs_s0_write && avs_s0_chipselect) begin unique case(avs_s0_address) `ADDR_ETHER_DEST_MAC_0 : ether_hdr_da[0] <= avs_s0_writedata[7:0]; `ADDR_ETHER_DEST_MAC_1 : ether_hdr_da[1] <= avs_s0_writedata[7:0]; `ADDR_ETHER_DEST_MAC_2 : ether_hdr_da[2] <= avs_s0_writedata[7:0]; `ADDR_ETHER_DEST_MAC_3 : ether_hdr_da[3] <= avs_s0_writedata[7:0]; `ADDR_ETHER_DEST_MAC_4 : ether_hdr_da[4] <= avs_s0_writedata[7:0]; `ADDR_ETHER_DEST_MAC_5 : ether_hdr_da[5] <= avs_s0_writedata[7:0]; `ADDR_ETHER_SOURCE_MAC_0 : ether_hdr_sa[0] <= avs_s0_writedata[7:0]; `ADDR_ETHER_SOURCE_MAC_1 : ether_hdr_sa[1] <= avs_s0_writedata[7:0]; `ADDR_ETHER_SOURCE_MAC_2 : ether_hdr_sa[2] <= avs_s0_writedata[7:0]; `ADDR_ETHER_SOURCE_MAC_3 : ether_hdr_sa[3] <= avs_s0_writedata[7:0]; `ADDR_ETHER_SOURCE_MAC_4 : ether_hdr_sa[4] <= avs_s0_writedata[7:0]; `ADDR_ETHER_SOURCE_MAC_5 : ether_hdr_sa[5] <= avs_s0_writedata[7:0]; /// `ADDR_IP_TOS : {ip_hdr_tos[1], ip_hdr_tos[0]} <= avs_s0_writedata[15:0]; //`ADDR_IP_TLEN : {ip_hdr_tlen[1],ip_hdr_tlen[0]} <= avs_s0_writedata[15:0]; `ADDR_IP_ID : {ip_hdr_id[1],ip_hdr_id[0]} <= avs_s0_writedata[15:0]; `ADDR_IP_FRAG_OFF_ : {ip_hdr_frag_off[1],ip_hdr_frag_off[0]} <= avs_s0_writedata[15:0]; `ADDR_IP_SOURCE_ADDRESS : {ip_hdr_sa[3],ip_hdr_sa[2],ip_hdr_sa[1],ip_hdr_sa[0]} <= avs_s0_writedata; `ADDR_IP_DEST_ADDRESS : {ip_hdr_da[3],ip_hdr_da[2],ip_hdr_da[1],ip_hdr_da[0]} <= avs_s0_writedata; /// `ADDR_UDP_SOURCE_PORT : {udp_hdr_sp[1],udp_hdr_sp[0]} <= avs_s0_writedata[15:0]; `ADDR_UDP_DEST_PORT : {udp_hdr_dp[1],udp_hdr_dp[0]} <= avs_s0_writedata[15:0]; endcase end UPD: Структура для IP чек суммы Код always_comb begin case (cnt_check_words) 0: next_check_ipv4_word = {ip_hdr_ver_hlen, ip_hdr_tos}; 1: next_check_ipv4_word = {ip_hdr_tlen[1],ip_hdr_tlen[0]}; 2: next_check_ipv4_word = {ip_hdr_id[1],ip_hdr_id[0]}; 3: next_check_ipv4_word = {ip_hdr_frag_off[1],ip_hdr_frag_off[0]}; 4: next_check_ipv4_word = {ip_hdr_ttl,ip_hdr_proto}; 5: next_check_ipv4_word = {ip_hdr_sa[3],ip_hdr_sa[2]}; 6: next_check_ipv4_word = {ip_hdr_sa[1],ip_hdr_sa[0]}; 7: next_check_ipv4_word = {ip_hdr_da[3],ip_hdr_da[2]}; 8: next_check_ipv4_word = {ip_hdr_da[1],ip_hdr_da[0]}; default: next_check_ipv4_word = '0; endcase end Структура для UDP чек суммы (если не хотите возиться с ней то можно занулить) Код case (cnt_check_words) //udp pseudo header 0: next_check_udp_word = {ip_hdr_sa[3],ip_hdr_sa[2]}; 1: next_check_udp_word = {ip_hdr_sa[1],ip_hdr_sa[0]}; 2: next_check_udp_word = {ip_hdr_da[3],ip_hdr_da[2]}; 3: next_check_udp_word = {ip_hdr_da[1],ip_hdr_da[0]}; 4: next_check_udp_word = {16'h00,ip_hdr_proto}; 5: next_check_udp_word = {udp_hdr_len[1],udp_hdr_len[0]}; //udp header 6: next_check_udp_word = {udp_hdr_sp[1],udp_hdr_sp[0]}; 7: next_check_udp_word = {udp_hdr_dp[1],udp_hdr_dp[0]}; 8: next_check_udp_word = {udp_hdr_len[1],udp_hdr_len[0]}; default: next_check_udp_word = данные;
|
|
|
|
|
Jun 22 2015, 19:03
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(NSergeevich @ Jun 22 2015, 19:00)  подкиньте ресурс, где можно былобы почитать о всех этих хеадерах и чексуммах На Википедии можно почитать: Ethernet, IP и UDP. Вообще, при отправке пакета Ethernet, чтобы Wireshark его видел, достаточно подать на MAC пакет состоящий из DST MAC, SRC MAC, тип пакета (08 00) и произвольные данные (минимум 46 байт, если меньше MAC добивает нулями недостающие). Далее MAC дополнияет всё это преамбулой, SFD и CFS и выдаёт на PHY. Т.е. если эти условия выполнены, то никакие арпы и т.д. не нужны, Вы увидите свой пакет в Wireshark. Если нет - ищите проблему где-то в проекте/железе: 1) Включен ли передатчик MAC-контроллера? 2) Выдаёт ли MAC данные на PHY? 3) Какой интерфейс MAC-PHY используется в системе? 4) Правильно ли настроен PHY? 5) и т.д. Да, какую FPGA используете? Есть стандартные генераторы Ethernet трафика, можно попробовать загрузить сеть данными генератора. Чтобы проверить соединение PC-PHY, можно включить PHY в режим Line Loopback и побросать пакеты с компа на плату.
|
|
|
|
|
Jun 22 2015, 19:23
|
Знающий
   
Группа: Свой
Сообщений: 555
Регистрация: 14-10-09
Пользователь №: 52 939

|
Цитата(doom13 @ Jun 22 2015, 22:03)  Вообще, при отправке пакета Ethernet, чтобы Wireshark его видел, достаточно подать на MAC пакет состоящий из DST MAC, SRC MAC, тип пакета (08 00) Не факт. На старой машине + ХР - да, видел что все принимается в том числе и RAW без всяких ARP Как только обновил комп + win8. то пакеты начинают приниматься только после того как откроешь socket на определенный IP. После вызова ф-ции в VisualStudio посылается ARP запрос.
|
|
|
|
|
Jun 22 2015, 20:02
|
Профессионал
    
Группа: Свой
Сообщений: 1 404
Регистрация: 11-03-11
Из: Минск, Беларусь
Пользователь №: 63 539

|
Цитата(gosu-art @ Jun 22 2015, 22:23)  Не факт. На старой машине + ХР - да, видел что все принимается в том числе и RAW без всяких ARP Как только обновил комп + win8. то пакеты начинают приниматься только после того как откроешь socket на определенный IP. После вызова ф-ции в VisualStudio посылается ARP запрос. На новой машине + Win 7 это так (Wireshark всё видит), а с Win 8 не работал. Но что-то мне кажется, что Wireshark или любой другой сниффер будет видеть пакеты и без открытия сокета (на Win7 работает именно так). А на основании данных ARP заполняется ARP-таблица, настраивается фильтр MAC-контроллера на фильтрацию ненужного трафика и пропуск заданных MAC-адресов. Задача сниффера - мониторить весь трафик в сети, так что он должен видеть все пакеты (исключение только те, что перенаправляются сетевым коммутатором сразу на другой/нужный ПК). Ну а уж если и стоит галка promiscuous mode, то точно должен принимать все пакеты (возможно только если мак-адрес все нули задать, только тогда работать не будет). ARP запрос после вызова Вашей функции отправляется для определения MAC-адреса удалённого устройства, т.е. чтобы знать какой MAC-адрес забивать в отправляемый пакет для соответствующего IP. (IP Вы знаете, MAC определяет система с помощью ARP запроса).
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|