从*char eth/ip/TCP封隔器表示中获取TCP选项(超出tcphdr->;doff)

从*char eth/ip/TCP封隔器表示中获取TCP选项(超出tcphdr->;doff),tcp,libpcap,Tcp,Libpcap,使用来获取数据包选项 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 tcphd

使用来获取数据包选项

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.
}
  • data+struct ip指向(指针)(无符号字符)内存中的TCP头
  • data+struct ip+thdr->doff*4点到TCP结束选项=数据开始
  • 鉴于以下结构

    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);
    
    因此,要读取数据包的一部分(选项所在),需要:

  • 假设数据包中指定的长度大于结构长度
  • 在(以太网+ip+tcphdr)结构的长度之后读取N个字节
  • 放下那些字节,现在读取有效负载

  • 对吗?读取随机有效负载的字节序列而不是实际数据简直让我恼火。

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

    注释“//data length?”不正确,应为“//TCP头长度(字节)”。if(hlen>sizeof(*tp))stmt检查是否有任何选项,并处理随机位被误解为TCP头的情况,因为这会产生小于头的最小大小的TH_OFF()*4。从hlen中减去sizeof(*tp)后,它现在包含TCP选项的大小(以字节为单位)。然后,代码可以继续遍历选项。它在任何时候都不会读取“随机负载的字节序列而不是实际数据”,或者至少没有给出我认为你的意思