我的目标是编写一个LKM(Linux内核模块),它拦截所有TCP数据包,查找tcp_sock结构,并根据某些条件,从tcp_sock结构中记录一些信息(例如:tcpsock-> snd_una)。
这就是我想要实现的目的:我在ubunutu上使用netfilter拦截(下面的代码),但有没有办法访问tcp_sock结构(在代码中查找注意)? / p>
我并不特别关注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;
}
答案 0 :(得分:0)
我能够通过查找inet哈希表(下面的代码片段)来实现它。我是这个例子中的服务器。确保在3次握手完成后进行查找。
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);