1

使用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 指向(指针)(无符号字符)内存中的 TCP 标头
  2. 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);

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

  1. 假设数据包中指定的长度大于结构长度
  2. 在 (ethernet + ip + tcphdr) 结构的长度之后读取 N 个字节?
  3. 删除这些字节,现在读取有效负载。

正确的?读取随机有效负载的字节序列而不是实际数据让我很生气。

4

2 回答 2

2

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

于 2010-11-19T04:12:16.833 回答
1

The comment "// data length?" is incorrect and should be "// TCP header length in bytes". The if (hlen > sizeof(*tp)) stmt checks if there are any options and also handles the case where random bits are misinterpreted as a TCP header, since that can produce a TH_OFF()*4 less than the min size of the header. After subtracting sizeof(*tp) from hlen, it now contains the size of the TCP options in bytes. The code can then proceed to walk the options. At no point does it read "a random payload's byte sequence instead of actual data", or at least not given what I think you mean...

于 2010-11-19T05:25:05.197 回答