C – Linux – 内核模块 – TCP头

我正在尝试创建linux内核模块,它将检查传入的数据包.目前,我正在提取数据包的TCP标头并读取源和目标端口 – >但是我得到的值不正确.我有钩功能:

unsigned int 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 *hdr;
    /* Using this to filter data from another machine */
    unsigned long ok_ip = 2396891328;

    /* Some problem, empty network packet. Stop it now. */
    if (!skb)
        return NF_ACCEPT;

    /* Just to track only packets coming from 1 IP */
    if (ipp->saddr != ok_ip)
        return NF_ACCEPT;

    /* Incomming packet is TCP */
    if (ipp->protocol == IPPROTO_TCP) {
        hdr = (struct tcphdr *) skb_transport_header(skb);
        printk(" TCP ports: source: %d, dest: %d .\n", ntohs(hdr->source), 
                                                       ntohs(hdr->dest));
    }
}

现在,当我尝试telnet端口21(我没有收听):

[ 4252.961912]  TCP ports: source: 17664, dest: 52 .
[ 4253.453978]  TCP ports: source: 17664, dest: 52 .
[ 4253.953204]  TCP ports: source: 17664, dest: 48 .

当我telnet端口22 – SSH deamon在那里听:

[ 4299.239940]  TCP ports: source: 17664, dest: 52 .
[ 4299.240527]  TCP ports: source: 17664, dest: 40 .
[ 4299.552566]  TCP ports: source: 17664, dest: 40 .

从输出可见我得到了非常奇怪的结果,任何人都知道问题来自哪里?当我编译模块时,我没有错误/警告.内核版本(标题):3.7.10.不使用SELinux或类似的.

最佳答案
我遇到了为网络类编写小型防火墙的同样问题,我刚刚发现了我遇到的问题.我正在强制转换tcp标头.尝试转换为tcp然后访问端口.

这是它的代码片段

struct iphdr *ip_header;       // ip header struct
struct tcphdr *tcp_header;     // tcp header struct
struct udphdr *udp_header;     // udp header struct
struct sk_buff *sock_buff;

unsigned int sport ,
             dport;


sock_buff = skb;

if (!sock_buff)
    return NF_ACCEPT;

ip_header = (struct iphdr *)skb_network_header(sock_buff);
if (!ip_header)
    return NF_ACCEPT;


//if TCP PACKET
if(ip_header->protocol==IPPROTO_TCP)
{
    //tcp_header = (struct tcphdr *)skb_transport_header(sock_buff); //doing the cast this way gave me the same problem

    tcp_header= (struct tcphdr *)((__u32 *)ip_header+ ip_header->ihl); //this fixed the problem

    sport = htons((unsigned short int) tcp_header->source); //sport now has the source port
    dport = htons((unsigned short int) tcp_header->dest);   //dport now has the dest port
}

转载注明原文:C – Linux – 内核模块 – TCP头 - 代码日志