views:

130

answers:

1

Hello, I am writing a kernel module which registers a hook with netfilter. The handler is not being called if I ssh/telnet into the machine where the module is loaded.

struct nf_hook_ops my_hook_ops;
my_hook_ops.hook = hook_handler;
my_hook_ops.pf = PF_INET;
my_hook_ops.hooknum = NF_INET_PRE_ROUTING;
my_hook_ops.priority =  NF_IP_PRI_FIRST;
nf_register_hook(&my_hook_ops);

The handler function:

unsigned int hook_handler(unsigned int hooknum,
             struct sk_buff *skb,
             const struct net_device *in,
             const struct net_device *out,
             int (*okfn)(struct sk_buff *))
{


    if(!skb)
     return NF_ACCEPT;

    struct iphdr* ip_header;
    struct tcphdr* tcp_header;
    union  ip_address ipaddr;

    printk(KERN_INFO "Entered handler\n");

    if(skb->protocol == 8)
     return NF_ACCEPT;

    // Log the received packet
    ip_header  = ip_hdr(skb);
    tcp_header = tcp_hdr(skb);
    ipaddr.saddr = ip_header->saddr;
    printk(KERN_INFO "Received packet:\nIP Address: %u.%u.%u.%u\nProtocol: %d\nSource port: %d\nDestination port: %d\n",
      ipaddr.a[0],ipaddr.a[1],ipaddr.a[2],ipaddr.a[3],
      skb->protocol,
      tcp_header->source,
      tcp_header->dest);

    return NF_ACCEPT;
}

The hook is being called for protocol 8 (Exterior Gateway Protocol). The second printk never gets printed. Am I missing anything?

+1  A: 

A couple of thoughts:

  • a hook handler takes a (struct skbuff **), not a (struct skbuff *)
  • following on from the above, skb->protocol doesn't exist. You want either (*skb)->protocol or you want the following idiom:
struct sk_buff *sock_buf =  *skb;
if(sock_buff->protocol)
  • If the packet is an EGP packet, you should not be expecting output from the second printk, because you return before it.
Stobor
I am using kernel 2.6.27-11 and the netfilter.h has the following declaration for the function.typedef unsigned int nf_hookfn(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *));
Rohit
I understand that it won't print the second line if its EGP. But should it print when a telnet/ssh/mysql/http connection is opened? Right now I get nothing but EGP packets. I am trying to invoke it from a different machine to avoid any shared memory optimizations too.
Rohit
Ah - that changed in 2.6.24. I'll have a play with the newer kernel and check.
Stobor