Sockets LKM从数据包中查找tcp_sock

Sockets LKM从数据包中查找tcp_sock,sockets,tcp,linux-kernel,kernel-module,netfilter,Sockets,Tcp,Linux Kernel,Kernel Module,Netfilter,我的目标是编写一个LKM Linux内核模块,它截取所有TCP数据包,查找TCP_sock结构,并根据某些条件记录TCP_sock结构中的一些信息,例如:tcpsock->snd_una 这就是我试图实现这一点的方式:我在下面的ubunutu代码上使用netfilter进行拦截,但是有没有办法访问tcp_sock结构,在代码中查找注释 我对netfilter并不挑剔。请建议是否有任何其他方式来编写LKM来实现这一点。它必须是一个LKM unsigned int ip_packets_hook_f

我的目标是编写一个LKM Linux内核模块,它截取所有TCP数据包,查找TCP_sock结构,并根据某些条件记录TCP_sock结构中的一些信息,例如:tcpsock->snd_una

这就是我试图实现这一点的方式:我在下面的ubunutu代码上使用netfilter进行拦截,但是有没有办法访问tcp_sock结构,在代码中查找注释

我对netfilter并不挑剔。请建议是否有任何其他方式来编写LKM来实现这一点。它必须是一个LKM

unsigned int ip_packets_hook_func(unsigned int hooknum, 
            struct sk_buff *skb, 
            const struct net_device *in, 
            const struct net_device *out, 
            int (*okfn)(struct sk_buff *)) 
{
    struct iphdr *ipp = (struct iphdr *)skb_network_header(skb);
    struct tcphdr *tcp_hdr;
    struct tcp_sock *tcpsock;

    if (!skb) {
      return NF_ACCEPT;
    }

    if (ipp->protocol == IPPROTO_TCP ) { // Incomming packet is TCP
        tcp_hdr = (struct tcphdr *) ((__u32 *)ipp + ipp->ihl);
        tcpsock = (struct tcp_sock *) skb->sk;

        if(ntohs(tcp_hdr->dest) != INTERESTED_PORT) {
            return NF_ACCEPT;
        }

        printk("TCP ports: source: %d, dest: %d \n", ntohs(tcp_hdr->source),
                       ntohs(tcp_hdr->dest));

        if(tcp_hdr->syn || tcp_hdr->fin || tcp_hdr->rst) {
               printk("Flag: %s %s %s\n", tcp_hdr->syn? "SYN" : "",
                                          tcp_hdr->fin? "FIN" : "",
                                          tcp_hdr->rst? "RST" : "");
               return NF_ACCEPT;
        }

        // **NOTE**
        // skb->sk is NULL at this point. 
        // Get tcp_sock for this connection.
    } else {
        printk("Its not TCP\n");
    }

    return NF_ACCEPT;
}

我可以通过查找下面的inet哈希表代码片段来实现它。我是本例中的服务器。确保三方握手完成后进行查找

const struct iphdr *iph;
const struct tcphdr *th;
struct sock *sk = NULL;
struct tcp_sock *tp;

.
.
.
.

sk = __inet_lookup_established(dev_net(skb->dev), &tcp_hashinfo,
                                   iph->saddr, th->source,
                                   iph->daddr, ntohs(th->dest),
                                   skb->skb_iif);

// Sanity checks here.

tp = tcp_sk(sk);