Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Сети > Извлечение данных из ip-датаграмм


Автор: daff 16.5.2009, 23:48
Доброго времени суток!!!
Необходимо написать снифер пакетов и далее анализатор - пакеты у меня ловятся и из них вычленяется заголовок ip, а  проблемма состоит в том , что я не могу извлечь непосредственно данные!

Код


struct IPHeader
{
        UCHAR iph_verlen; 
        UCHAR iph_tos; 
        USHORT iph_length;
        USHORT iph_id; 
        USHORT iph_offset;
        UCHAR iph_ttl; 
        UCHAR iph_protocol;
        USHORT iph_xsum; 
        ULONG iph_src;
        ULONG iph_dest; 
};

struct UDPHeader
{
        USHORT source;
        USHORT dest;
        USHORT len;
        USHORT check;
};


struct TCPHeader
{
    unsigned short sport;
    unsigned short dport;
    unsigned int snumber;
    unsigned int anumber;
    unsigned int __rsvd1 : 4;
    unsigned int length : 4;
    unsigned char flags;
    unsigned short wsize;
    unsigned short csum;
    unsigned short uptr;
};

              typedef struct
              {
                     IPHeader IPHdr;
                      UDPHeader UDPHdr;
              }ip_udp_dg;

              typedef struct
              { 
                       IPHeader IPHdr;
                       TCPHeader  TCPHdr;
              }ip_tcp_dg;

               ip_udp_dg* *hdr_u;
               ip_tcp_dg* *hdr_t;

                char btBuffer[65536];


                if (recv(Form1->s, btBuffer, sizeof(btBuffer), 0) >= sizeof(IPHeader))
                {
                        hdr = (ip_udp_dg*)btBuffer;              //для UDP
                        hdr = (hdr = (ip_udp_dg*)btBuffer;   //для TCP

                       //прочие действия
  
                 }


пытаюсь достать данные следующим образом - &btBuffer[sizeof(IPHeader) * 2]) - для UDP пакетов что-то вроде доста>тся, а вот для TCP ничего нет!!!!

Автор: MAKCim 17.5.2009, 09:51
во-первых, все структуры должны быть упакованными

для TCP
Код

ip_tcp_dg *hdr = (ip_tcp_dg*)btBuffer;
void *ptr = (char*)hdr + ((hdr->IPHdr.iph_verlen & 0xf) << 2) + (hdr->TCPHdr.length << 2);

Автор: daff 17.5.2009, 17:47
А для чего требуется упаковка?

И как после упаковки достать данные?

Автор: MAKCim 18.5.2009, 21:24
Цитата(daff @  17.5.2009,  17:47 Найти цитируемый пост)
А для чего требуется упаковка?

чтобы избежать проблемы увеличения размера структуры из-за выравнивания
кроме того, вместо int, short и т. д нужно использовать фиксированные типы int16, int32 и т. д

Цитата(daff @  17.5.2009,  17:47 Найти цитируемый пост)
И как после упаковки достать данные?

точно так же

кроссплатформенный пример упаковки
Код

#pragma pack(push, 1)
struct packed
{
    short a;
    char b;
    int c;
    long d;
    short e;
};
#pragma pack(pop)

Автор: REZiaMIX 20.5.2009, 18:19
Значит так , в хеадере есть поле - длина пакета. Сами данные идут после хеадера. Т.е. смысл таков:
Код

char * header;
header = .... ;
size_t len = ((header_struct*)header)->len;
char * data = header+len;

(думаю суть понятна)
Соответственно структура должна быть с правильным выравниванием.
Иногда надо не забывать об обратном порядке байт =)

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