Reputation: 1720
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?
Upvotes: 1
Views: 1339
Reputation: 1089
You need to study how sk_buff
works, the protocol field initialized by the function `eth_type_trans' which takes on ETH_P_* values. All ETH_P_* values are defined in if_ether. Here are some of these values.
#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */
#define ETH_P_PUP 0x0200 /* Xerox PUP packet */
#define ETH_P_PUPAT 0x0201 /* Xerox PUP Addr Trans packet */
#define ETH_P_IP 0x0800 /* Internet Protocol packet */
You clearly see that 0x08 is defined for Internet Protocol packet
. And your code clearly return in case of 8 (which is IP
packet)
if(skb->protocol == 8)
return NF_ACCEPT;
Your ssh/telnet
clearly IP packet(s) and rejected by above code. Please use proper protocol defined values defined in if_ethr
Upvotes: 0
Reputation: 738
The protocol used here is different from the IP protocol number as assigned by IANA, for which 8 is for EGP and EGP has been outdated.
The protocol field for sk_buff is defined in , for which 8 is for ETH_P_IP. As your data is allways IP traffic,the first conditional check is always true. So the second part of code never get executed.
Upvotes: 3
Reputation: 45132
A couple of thoughts:
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)
Upvotes: 1