I have a tpacket3_hdr *ppd
pointer object. I know how to extract iphdr and tcphdr but what if I need the body part of a packet. I am trying like this
struct iphdr *ip = (struct iphdr *) ((uint8_t *) eth + ETH_HLEN);
struct tcphdr *tcp=(struct tcp *)((uint8_t *)ip+sizeof(struct iphdr));
char *payload_body=(char *)(tcp+sizeof(struct tcphdr));
printf("%s\n",payload_body);//Printing wrong Not containing what I am checking by simply downloading html
I dont think its the right way of doing this. Full code from Rx Ring from MMAP is given here https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/net/psock_tpacket.c
[Adapted from Cormen and Stevens, 10.4 TCP Segment Format]
/* The offset of the payload data (in 32bit words))
** is tucked into the upper 4 bits of an unsigned character.
** Typically (0x5x & 0xf0) >>2 := 0x20
*/
#define TCP_HLEN(p) (((p)->tcp_offset & 0xf0) >> 2)
char *payload_body=(char *)((uint8_t *)tcp + TCP_HLEN(tcp)) ;
The ip struct has a similar length field in its ip_verlen
field(version:=4 bits , lengh_in_words:= 4 bits).
For IP the corresponding calculation would be:
#define IPMHLEN 20 /* minimum IP header length (in bytes) */
#define IP_HLEN(pip) (((pip)->ip_verlen & 0xf) <<2)
So that is the offset (in bytes) where the TCP header would start. The space between offsets IPMHLEN
and IPHLEN(pip)
(if any) is occupied by IP-options.
RFCs:
This is the layout of a raw segment, as it travels on the net. I am assuming that your file stores this format as-is.
[I would not use sizeof
in any offset/size calculation, since the in-memory structures could contain padding and alignment.]