Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > отправка ICMP-сообщения / WinPcap


Автор: keepergf 21.5.2013, 18:28
Доброго времени суток! 

есть проблемочка: нужно заполнить поле данных в отправляемом icmp-сообщении с типом=3 и кодом=0 (впрочем код не важен). подскажите чем и как можно заполнить это поле? (язык c++)


Код

typedef struct ethernet_header
{
    UCHAR dest[6];
    UCHAR source[6];
    USHORT type;
}   ETHER_HDR , *PETHER_HDR , FAR * LPETHER_HDR , ETHERHeader;
 
typedef struct ip_hdr
{
    unsigned char ip_header_len:4; 
    unsigned char ip_version :4;
    unsigned char ip_tos; 
    unsigned short ip_total_length;
    unsigned short ip_id;
 
    unsigned char ip_frag_offset :5;
 
    unsigned char ip_more_fragment :1;
    unsigned char ip_dont_fragment :1;
    unsigned char ip_reserved_zero :1;
 
    unsigned char ip_frag_offset1; 
 
    unsigned char ip_ttl; 
    unsigned char ip_protocol; 
    unsigned short ip_checksum; 
    unsigned int ip_srcaddr; 
    unsigned int ip_destaddr; 
} IPV4_HDR;
 
typedef struct icmp_hdr
{
    BYTE type; 
    BYTE code; 
    USHORT checksum;
    USHORT id;
    USHORT seq;
} ICMP_HDR;



    int SizeData = DefDataType(type);
    int sizePack = sizeof(ETHER_HDR) + sizeof(IPV4_HDR) + sizeof(ICMP_HDR)+ SizeData;
    u_char *packet = new u_char[sizePack];
    ETHER_HDR *ethr= (ETHER_HDR *)packet;
    IPV4_HDR *ip_hdr = (IPV4_HDR *)(packet + sizeof(ETHER_HDR));
    ICMP_HDR *icmp_hdr = (ICMP_HDR *)(packet + sizeof(IPV4_HDR) + sizeof(ETHER_HDR));
    memset(packet, 0, sizePack);

        /*set mac source*/
            ethr->source[k] = ethhdr->dest[k];

        /*set mac destination*/
            ethr->dest[k] = ethhdr->source[k];

        ethr->type = htons(0x0800);

    ip_hdr->ip_header_len = 5;
    ip_hdr->ip_version = 4;
    ip_hdr->ip_tos = 0;
    ip_hdr->ip_total_length = ntohs(28 + (u_short)SizeData); 
    ip_hdr->ip_id = GetCurrentProcessId() + seqid;
    ip_hdr->ip_frag_offset = 0;
    ip_hdr->ip_ttl = 128;
    ip_hdr->ip_protocol = 1;

        /* set IP address destination*/
        ip_hdr->ip_destaddr = iphdr->ip_srcaddr;

        /*set IP address source*/
        ip_hdr->ip_srcaddr = iphdr->ip_destaddr;

    ip_hdr->ip_checksum = in_cksum((unsigned short *)ip_hdr, sizeof(IPV4_HDR));

    /* set ICMP type and code*/
    icmp_hdr->type = type;
    icmp_hdr->code = code;

    icmp_hdr->id = icmphdr->id;
    icmp_hdr->seq = icmphdr->seq;
    seqid += 0x0100;//++

    UCHAR *data = (UCHAR *)(packet + sizeof(IPV4_HDR) + sizeof(ETHER_HDR) + sizeof(ICMP_HDR));

         //вот тут надо как-то заполнить data. (тип 3. код 0. и wireshark или ping корректно воспринимали этот ответ)
        
    icmp_hdr->checksum = in_cksum((unsigned short*)(packet+ sizeof(IPV4_HDR) + sizeof(ETHER_HDR)), sizeof(ICMP_HDR) +            
                                                                                 DefDataType(type));

    pcap_sendpacket(fp, packet, sizePack);

Автор: feodorv 21.5.2013, 21:37
Цитата(keepergf @  21.5.2013,  19:28 Найти цитируемый пост)
нужно заполнить поле данных в отправляемом icmp-сообщении с типом=3

Это поле должно включать в себя:
  • ip заголовок (включая все опции) датаграммы, на которую сгенерирована ошибка
  • первые 8 байт ip датаграммы, которые следуют непосредственно за ip заголовком
http://www.networksorcery.com/enp/protocol/icmp/msg3.htm.

Цитата(keepergf @  21.5.2013,  19:28 Найти цитируемый пост)
    icmp_hdr->id = icmphdr->id;
    icmp_hdr->seq = icmphdr->seq;

Вот это я не понял. Это взято, на вид, с http://www.networksorcery.com/enp/protocol/icmp/msg0.htm...

Автор: keepergf 22.5.2013, 23:27
Цитата(feodorv @  21.5.2013,  21:37 Найти цитируемый пост)
Цитата(keepergf @  21.5.2013,  19:28 )
    icmp_hdr->id = icmphdr->id;
    icmp_hdr->seq = icmphdr->seq;

Вот это я не понял. Это взято, на вид, с ICMP type 0... 


Да, это для типа = 0, заполняется из входящего ICMP-запроса.

Код

u_char *pkt_data;
ethhdr = (ETHER_HDR *)pkt_data;
iphdr = (IPV4_HDR *)(pkt_data + sizeof(ETHER_HDR));
icmphdr = (ICMP_HDR *)(pkt_data + sizeof(IPV4_HDR) + sizeof(ETHER_HDR));

icmphdr отсюда.

Заработало! Спасибо за помощь!!! =)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)