>>IP пакет должен быть сформирован верно (адреса, флаги, контрольная сумма).
>>
>>Вот такой запуск tcpdump поможет в более подробном анализе Ethernet кадров:
>>tcpdump -XX -v -n -s 256 -i <ifname>
>
>tcpdump ничего не показывает, пробовал даже через ip_send послать ip пакет
>
>ip_t *ip;
>
>if ((ip = ip_open()) == NULL)
>printf("error");
>
>if((ip_send(ip,iph, size_ip)) != size_ip)
>printf("error 2");
>
>ip_close(ip); Для примера привожу куски реально работающего кода, при передаче tcpdump все показывает.
Попробуй запускать tcpdump на приемной стороне, а так же смотреть на светодиоды активности сети на интерфейсах (коммутаторе). В качестве примера формирования пакетов различных протоколов смотри исходники tcpdump (функции разборки пакетов), там довольно все понятно, в каком поле пакета что должно лежать. Плюс соответствующие RFC по форматам пакетов.
------- открытие интерфейса -------
if((m_eth= eth_open(m_ifname)) == NULL)
{
VLOG(fm_log, 1, "Ошибка eth_open('%s'), errno: %d (%s)", m_ifname, errno, strerror(errno));
return(-1);
}
--------------
-------- метод передачи кадра через интерфейс ------
frame.set_mac_addr(m_mac);
return( eth_send(m_eth, frame.get_raw(), frame.get_size()));
}
--------------
------- часть метода формирования кадра UDP пакета -------
union // буфер кадра
{
...
struct // UDP пакет (RFC 768)
{
struct ether_header hdr;
struct ip ip;
struct udphdr udp;
uint8_t data[1];
} __packed udp;
...
uint8_t raw[ETHER_MAX_LEN - ETHER_CRC_LEN]; // сырой Ethernet кадр (без контрольной суммы)
} m_frame;
// формирование кадра
struct pseudo_udp_hdr {
in_addr_t src;
in_addr_t dst;
uint8_t zero;
uint8_t proto;
uint16_t length;
} __packed *pseudo;
// зануление заголовков
memset(m_frame.raw, 0, sizeof(m_frame.udp));
// UDP заголовок + данные
m_frame.udp.udp.uh_sport = htons(sport);
m_frame.udp.udp.uh_dport = htons(dport);
m_frame.udp.udp.uh_ulen = htons(sizeof(m_frame.udp.udp) + data_size);
if(data_size)
memcpy( m_frame.udp.data, data, data_size);
// псевдозаголовок для контрольной суммы (заполняется на месте IP заголовка перед UDP пакетом)
pseudo = (struct pseudo_udp_hdr *) ( (uint8_t *)(&m_frame.udp.udp) - sizeof(*pseudo)) ;
pseudo->src = src.s_addr;
pseudo->dst = dst.s_addr;
pseudo->proto = IPPROTO_UDP;
pseudo->length = htons(sizeof(m_frame.udp.udp) + data_size);
m_frame.udp.udp.uh_sum = ip_checksum((uint8_t *)pseudo, sizeof(*pseudo) + sizeof(m_frame.udp.udp) + data_size);
// IP заголовок
memset(pseudo, 0, sizeof(*pseudo));
m_frame.udp.ip.ip_v = IPVERSION;
m_frame.udp.ip.ip_hl = 5; // 20/4
m_frame.udp.ip.ip_len = htons(sizeof(m_frame.udp.ip) + sizeof(m_frame.udp.udp) + data_size);
m_frame.udp.ip.ip_id = htons(get_number());
m_frame.udp.ip.ip_ttl = 255;
m_frame.udp.ip.ip_p = IPPROTO_UDP;
m_frame.udp.ip.ip_src.s_addr = src.s_addr;
m_frame.udp.ip.ip_dst.s_addr= dst.s_addr;
m_frame.udp.ip.ip_sum = ip_checksum((uint8_t *) &m_frame.udp.ip, sizeof(m_frame.udp.ip));
m_size = sizeof(m_frame.udp.hdr) + sizeof(m_frame.udp.ip) + sizeof(m_frame.udp.udp) + data_size;
// заполенение Ether заголовка
m_frame.udp.hdr.ether_type= htons(ETHERTYPE_IP);
--------------