title: Getting TCP options (beyond tcphdr->doff) out of * char eth/ip/tcp packer representation
body: <p>Playing around with <a href="http://www.tcpdump.org/sniffex.c" rel="nofollow">http://www.tcpdump.org/sniffex.c</a> to get packet options.</p>
  
  <pre><code>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-&gt;doff*4);
   char *txt = (char *) ptr;
   // *txt can be fprint/cout'ed, returned OK.
  }
  </code></pre>
  
  <ol>
  <li>data + struct ip points to TCP header in (pointer) (unsigned char) memory</li>
  <li>data + struct ip + thdr->doff*4 points to end of TCP options = beginning of the data</li>
  </ol>
  
  <p>Given the following structure,</p>
  
  <pre><code>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)-&gt;th_offx2 &amp; 0xf0) &gt;&gt; 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 */
  };
  </code></pre>
  
  <p>Also there is a reference in TCPDump code:</p>
  
  <pre><code> tp = (struct tcphdr *)bp; // packet header.
    hlen = TH_OFF(tp) * 4;    // data length?
  
    if (hlen &gt; sizeof(*tp)) {
                   register const u_char *cp;
                   register u_int i, opt, datalen;
                   register u_int len;
                   hlen -= sizeof(*tp);
  </code></pre>
  
  <p>So, to read a part of packet, where options lie, it is needed to:</p>
  
  <ol>
  <li>Assume that length specified in packet is > than a structure length</li>
  <li>Read N bytes after (ethernet  + ip  + tcphdr) structure's length?</li>
  <li>Drop those bytes off, now read payload.</li>
  </ol>
  
  <p>Correct? It simply boils me off to read a random payload's byte sequence instead of actual data.</p>