Getting TCP options (beyond tcphdr->doff) out of * char eth/ip/tcp packer representation
Playing around with http://www.tcpdump.org/sniffex.c to get packet options.
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 points to TCP header in (pointer) (unsigned char) memory
- data + struct ip + thdr->doff*4 points to end of TCP options = beginning of the data
Given the following structure,
typedef u_int tcp_seq;
struct sniff_tcp {
u_short th_sport; /* source por开发者_开发百科t */
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 */
};
Also there is a reference in TCPDump code:
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);
So, to read a part of packet, where options lie, it is needed to:
- Assume that length specified in packet is > than a structure length
- Read N bytes after (ethernet + ip + tcphdr) structure's length?
- Drop those bytes off, now read payload.
Correct? It simply boils me off to read a random payload's byte sequence instead of actual data.
The options lie between data + sizeof(struct ip) + sizeof(struct tcphdr)
and txt
. There may be no options, in which case these pointers will be equal.
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...
精彩评论