从* char eth / ip / tcp packer表示中获取TCP选项(超出tcphdr-> doff)

时间:2010-11-19 01:51:10

标签: tcp libpcap

使用http://www.tcpdump.org/sniffex.c来获取数据包选项。

void payload (char *data) { // data contains full copied packet source without ethernet header.
 char *ptr = NULL;
 //ptr = data;
 //struct ip *pip = (struct ip *) ptr;

 ptr = data + sizeof(struct ip);
 struct tcphdr *thdr = (struct tcphdr *) ptr;

 ptr = data + sizeof(struct ip) + (thdr->doff*4);
 char *txt = (char *) ptr;
 // *txt can be fprint/cout'ed, returned OK.
}
  1. data + struct ip指向(指针)(unsigned char)内存中的TCP标头
  2. data + struct ip + thdr-> doff * 4点到TCP选项的结尾=数据的开头
  3. 鉴于以下结构,

    typedef u_int tcp_seq;
    
    struct sniff_tcp {
            u_short th_sport;               /* source port */
            u_short th_dport;               /* destination port */
            tcp_seq th_seq;                 /* sequence number */
            tcp_seq th_ack;                 /* acknowledgement number */
            u_char  th_offx2;               /* data offset, rsvd */
    #define TH_OFF(th)      (((th)->th_offx2 & 0xf0) >> 4)
            u_char  th_flags;
            #define TH_FIN  0x01
            #define TH_SYN  0x02
            #define TH_RST  0x04
            #define TH_PUSH 0x08
            #define TH_ACK  0x10
            #define TH_URG  0x20
            #define TH_ECE  0x40
            #define TH_CWR  0x80
            #define TH_FLAGS        (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)
            u_short th_win;                 /* window */
            u_short th_sum;                 /* checksum */
            u_short th_urp;                 /* urgent pointer */
    };
    

    TCPDump代码中也有一个引用:

     tp = (struct tcphdr *)bp; // packet header.
      hlen = TH_OFF(tp) * 4;    // data length?
    
      if (hlen > sizeof(*tp)) {
                     register const u_char *cp;
                     register u_int i, opt, datalen;
                     register u_int len;
                     hlen -= sizeof(*tp);
    

    因此,要读取选项所在的数据包的一部分,需要:

    1. 假设数据包中指定的长度是>比结构长度
    2. 在(ethernet + ip + tcphdr)结构的长度之后读取N个字节?
    3. 删除这些字节,现在读取有效负载。
    4. 正确?它只是简单地让我读取随机有效载荷的字节序列而不是实际数据。

2 个答案:

答案 0 :(得分:2)

选项位于data + sizeof(struct ip) + sizeof(struct tcphdr)txt之间。可能没有选项,在这种情况下这些指针将是相同的。

答案 1 :(得分:1)

评论“//数据长度?”是不正确的,应该是“// TCP标头长度,以字节为单位”。 if(hlen> sizeof(* tp))stmt检查是否有任何选项,并且还处理随机位被错误解释为TCP头的情况,因为这可以产生小于最小值的TH_OFF()* 4标题。从hlen中减去sizeof(* tp)之后,它现在包含TCP选项的大小(以字节为单位)。然后代码可以继续执行选项。它从来没有读过“随机有效载荷的字节序列而不是实际数据”,或者至少没有给出我认为你的意思......