从NFQueue读取数据包时的零序号

时间:2015-11-17 06:43:50

标签: c++ linux sockets network-programming netfilter

我试图从使用C ++在NFQueue中排队的数据包中读取TCP序列号。但是当我打印出序列号时,我注意到偶尔会得到零作为序列号。我查看了Wireshark,但没有序列号为零。所有序列号都是有序的。

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <iomanip>
#include <netinet/in.h>
extern "C" {
#include <linux/netfilter.h>  /* Defines verdicts (NF_ACCEPT, etc) */
#include <libnetfilter_queue/libnetfilter_queue.h>
#include <linux/tcp.h>
#include <linux/ip.h>
}

using namespace std;

static int Callback(nfq_q_handle *myQueue, struct nfgenmsg *msg,
                nfq_data *pkt, void *cbData) {

    uint32_t id, tSeq;
    unsigned char *pktData;
    nfqnl_msg_packet_hdr *header;

    header = nfq_get_msg_packet_hdr(pkt);
    struct iphdr *iph = ((struct iphdr *) pktData);
    id = ntohl(header->packet_id);

    nfq_get_payload(pkt, &pktData);
    struct tcphdr *tcp = ((struct tcphdr *) (pktData + (iph->ihl << 2)));
    tSeq = ntohl(tcp->seq);

    printf("%u\n", tSeq);

}

int main(int argc, char **argv) {

    int fd, res;
    char buf[262124];
    struct nfq_handle *nfqHandle;
    struct nfq_q_handle *myQueue;
    struct nfnl_handle *netlinkHandle;

    nfqHandle = nfq_open();
    nfq_unbind_pf(nfqHandle, AF_INET);
    nfq_bind_pf(nfqHandle, AF_INET);

    myQueue = nfq_create_queue(nfqHandle,  0, &Callback, NULL);
    nfq_set_mode(myQueue, NFQNL_COPY_PACKET, 0xffff);

    netlinkHandle = nfq_nfnlh(nfqHandle);
    fd = nfnl_fd(netlinkHandle);

    while(true){
        res = recv(fd, buf, sizeof(buf), 0);
        nfq_handle_packet(nfqHandle, buf, res);
    }

    nfq_destroy_queue(myQueue);
    nfq_close(nfqHandle);
    return 0;
}

我需要为其他用途检索正确的序列号。我真的想知道零序的背后原因。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我刚刚在回调函数中切换了两个语句的顺序。

static int Callback(nfq_q_handle *myQueue, struct nfgenmsg *msg,
                nfq_data *pkt, void *cbData) {

    uint32_t id, tSeq;
    unsigned char *pktData = NULL;
    nfqnl_msg_packet_hdr *header;

    header = nfq_get_msg_packet_hdr(pkt);
    nfq_get_payload(pkt, &pktData);
    struct iphdr *iph = ((struct iphdr *) pktData);

    id = ntohl(header->packet_id);
    struct tcphdr *tcp = ((struct tcphdr *) (pktData + (iph->ihl << 2)));
    tSeq = ntohl(tcp->seq);

    printf("%u\n", tSeq);

}

iph的值来自pktData,但您在初始化pktData之前已将iph分配给pktData,这可能是您的程序获取序列号的原因我在我的机器上测试过。如果它不适合您,请告诉我。