c - What is the correct offset for casting to iphdr and tcphdr? -


here's strange behavior of recv(). i'm using libnetfilter_queue library , iptablesin order store incoming packets 3 different queues, depending on source port (i check condition iptables rules written below).

basically, packets payload contains letter e. here's code (for brevity, omitted controls on errors).

/* bunch of #include <whatineed.h> */  int main() {     pthread_t threads[3];     pthread_create(&threads[0], null, queuethread, (void *)0);     pthread_create(&threads[1], null, queuethread, (void *)1);     pthread_create(&threads[2], null, queuethread, (void *)2);     pthread_exit(null);     return 0; } 

the function executed each thread:

void *queuethread(void *queuenum) {     int fd, rv;     int queue_num = (int)queuenum;     struct nfq_handle *h = null;     struct nfq_q_handle *qh = null;     char buf[8192] __attribute__ ((aligned));      /* queue handling setup */     h = nfq_open();     nfq_unbind_pf(h, af_inet);     nfq_bind_pf(h, af_inet);     qh = nfq_create_queue(h, queue_num, &packethandler, null);     nfq_set_queue_maxlen(qh, 10000);     nfq_set_mode(qh, nfqnl_copy_packet, 0xffff);     memset(buf, '\0', sizeof(buf));     /* tried increase socket buffer size, nothing changes  */     nfnl_rcvbufsiz(nfq_nfnlh(h), 10000 * 1500);     fd = nfq_fd(h);     while ((rv = recv(fd, buf, sizeof(buf), 0)) > 0))  {         printf("queuethread: read %d bytes file descriptor %d\n", rv, fd);         nfq_handle_packet(h, buf, rv);     }     nfq_destroy_queue(qh);     nfq_close(h);     pthread_exit(null); } 

the callback function called on each packet queuethread:

int packethandler(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,     struct nfq_data *nfa, void *data) {         struct nfqnl_msg_packet_hdr *ph = null;         unsigned char *nf_packet = null;         int pkt_size = 0;         ph = nfq_get_msg_packet_hdr(nfa);         int id = ntohl(ph -> packet_id);         pkt_size = nfq_get_payload(nfa, &nf_packet);         printf("packethandler: pkt %d byte, says: %s\n", pkt_size, nf_packet);         /* let's check, e.g., protocol */         struct iphdr *iph = (struct iphdr *) (nf_packet + sizeof(struct ethhdr));         printf("packethandler: pkt protocol %d\n", iph->protocol);         return nfq_set_verdict(qh, id, nf_accept, 0, null); } 

after setting following rules on iptables:

sudo iptables -i input -p tcp --sport 25 -j nfqueue --queue-num 0 sudo iptables -i input -p tcp --sport 80 -j nfqueue --queue-num 1 sudo iptables -i input -p udp --sport 5060 -j nfqueue --queue-num 2 sudo iptables -i input -p tcp --sport 5060 -j nfqueue --queue-num 2 

opening new tab on browser , loading page (so, getting packets coming port 80), here's output:

queuethread: read 148 bytes file descriptor 4 packethandler: pkt 60 byte, says: e  packethandler: pkt protocol 35 queuethread: read 148 bytes file descriptor 4 packethandler: pkt 60 byte, says: e  packethandler: pkt protocol 35 queuethread: read 148 bytes file descriptor 4 packethandler: pkt 60 byte, says: e  packethandler: pkt protocol 35 

i tried nping sending myself, in terminal, packets coming port 25 , port 5060, result same: strange protocol number , letter e. can't cast payload tcphdr or udphdr struct , data need, since don't know got queuethread() , pass packethandler().

apparently, mistake adding sizeof(struct ethhdr) payload in order arrive ip header of packet: that's why got weird protocol , port numbers, in offset not supposed be. still got e nevermind, can read success protocol , port numbers; sorry distraction.

here's found out this: how nfq_get_payload structure return data?


Comments