我编写了一个 Sniffer, 能捕获 IP 包了. 可是我觉得 IP 包的大小好像有点不对劲,
怀疑是我的 IP 头结构定义有问题.有的人好像这样定义的
typedef struct _IPHEADER {
        unsigned char  header_len:4;
        unsigned char  version:4;   
        unsigned char  tos;            // type of service
        unsigned short total_len;      // length of the packet
        unsigned short ident;          // unique identifier
        unsigned short flags;          
        unsigned char  ttl;            
        unsigned char  proto;          // protocol ( IP , TCP, UDP etc)
        unsigned short checksum;       
        unsigned int   sourceIP;
        unsigned int   destIP;}IPHEADER;但我觉得不对,
unsigned char  header_len:4;        unsigned char  version:4; 这两个字段应该共用一个字节才对啊. 高4位版本号,低4位是头部长度(以 32 位为单位).于是我这样定义IP头typedef struct ip_hdr
{
    unsigned char ip_verlen; // 4-bit 版本号
                             // 4-bit 首部长度 (in 32-bit words)
    unsigned char ip_tos; // IP 服务类型
    unsigned short ip_totallength; // 总长度(字节数)
    //第一个32位
    unsigned short ip_id; // 标识
    unsigned short ip_offset; //3位标志,13位分片偏移,
    
    //第二个32位
    unsigned char ip_ttl; // 生存时间
    unsigned char ip_protocol; // 上层协议
    unsigned short ip_checksum; // 首部检验和
    //第三个32位
    unsigned int ip_srcaddr; // 源IP地址
    //第四个32位
    unsigned int ip_destaddr; // 目的IP地址
    //第五个32位

   } ipHead;unsigned char ip_verlen;前两个字段共用一个字节(移位可做到).可我觉得 我读出的IP包的总长度好像比一般的大了许多,大概最小的都是 8192 字节
而其它的任何字段的值都是正确的
这是为什么. 
第一个回答对的,200分全给他!

解决方案 »

  1.   

    同意改成单字节对齐:
    #pragma pack(1)
      

  2.   

    参考一下这篇文章
    http://www.hacker.com.cn/article/list.asp?id=3025
      

  3.   

    单字节,project->setting里面改
      

  4.   

    #pragma pack(1)
    这个写在什么地方?单字节,project->setting 在哪里啊?能否解释一下,
    我太衰了, 真不想浪费各位时间.
      

  5.   

    打开工程,菜单上有Project一下选择setting...
    在stdafx.h里加#pragma pack(1)//
      

  6.   

    字节对齐问题,在结构体声明的同时添加,方法有二:1 stdafx.h中加入#pragma pack(1),这样做的缺点是所有的结构体全部都用单字节对齐,影响程序执行效率;2 在定义的同时制定,参考下面代码
    #pragma pack(1)
    typedef struct _tagDATA
    {
     DWORD dwData;
     DWORD dwParam;
     BYTE  bInfo[1];
    }DATA, *LPDATA;
    #pragma pack()
    注意:前后两个pragma pack缺一不可,看清楚它们的差异!
      

  7.   

    如果你的比人家标准的要小,就#pragma pack(1)的值设置的小一点,否则就设置的大一点,比如32。还有,如果你的对齐方式如果设置的小了,比如是4,那你还要注意你声名结构体成员变量的顺序,
    BOOL b1;
    int  n1;
    BOOL b2;

    BOOL b1;
    BOOL b2;
    int  n1;
    占的字节是不一样的,前面的比后面的要大
      

  8.   

    还是不行!已经改成字节对齐, 可我的程序报告最小的一个包的长度仍然很大, 8192 字节啊.
    我觉得网络上的包不会都这么大的, 我的包大部分都 10240 或者 56235 字节那么大.
    我想我的ipHead结构定义的是没有问题的.
      

  9.   

    CString theTmp="";
    BYTE RecvBuf[65535];recv(theSocket, (char *)RecvBuf, 65535, 0);
    ipHead *ip=(ipHead *)(RecvBuf);
    theTmp.Format("%d",ip->ip_totallength);
    pCListCtrl->SetItemText(i,3,theTmp);有什么问题呢?
      

  10.   

    包的总长度可以由下面定义的这个结构中的一个变量 unsigned short ip_totallength 来确定.
    typedef struct ip_hdr
    {
        unsigned char ip_verlen; // 4-bit 版本号
                                 // 4-bit 首部长度 (in 32-bit words)
        unsigned char ip_tos; // IP 服务类型
        unsigned short ip_totallength; // 总长度(字节数)
        //第一个32位
        unsigned short ip_id; // 标识
        unsigned short ip_offset; //3位标志,13位分片偏移,
        
        //第二个32位
        unsigned char ip_ttl; // 生存时间
        unsigned char ip_protocol; // 上层协议
        unsigned short ip_checksum; // 首部检验和
        //第三个32位
        unsigned int ip_srcaddr; // 源IP地址
        //第四个32位
        unsigned int ip_destaddr; // 目的IP地址
        //第五个32位

       } ipHead;
      

  11.   

    还有不对劲的地方, 我随便访问几个网站,那么应该使用 TCP 协议,
    对方端口应该是 80 才对, 可我的程序总显示端口是 20480
    访问好多网站都一样。
    大家觉得是什么问题啊?
    TCP头的其它字段值是对的。
      

  12.   

    80 = 0x50;
    20480 = 0x50 00;要么 就是 偏了 一个字节。
    要么 就是 字节顺序 问题 0x0050 变成了 0x5000;我想 字节顺序的可能性比较大, 看看通常的socket程序就知道了:
    ...
    struct sockaddr_in local;
    ...
    local.port = htons(0x50); 
    ...在这里使用的是端口0x50, 但是local.port 的值 显然不是 0x50了。
    要变回来,就得对原始网络数值再来一次 ntohs。
    理论上来讲:
    htons(0x50) = 0x5000;
    ntohs(0x5000) = 0x50;即楼主所看到的
    80 <===> 20480;