1

我正在编写一个内核模块,它使用 netfilter 注册一个钩子。如果我 ssh/telnet 进入加载模块的机器,则不会调用处理程序。

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);

处理函数:

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;
}

正在为协议 8(外部网关协议)调用钩子。第二个 printk 永远不会被打印。我错过了什么吗?

4

3 回答 3

3

这里使用的协议与 IANA 分配的 IP 协议号不同,其中 8 用于 EGP,EGP 已过时。

sk_buff 的协议字段在 中定义,其中 8 用于 ETH_P_IP。由于您的数据始终是 IP 流量,因此第一个条件检查始终为真。所以代码的第二部分永远不会被执行。

于 2011-10-06T12:20:44.767 回答
1

几个想法:

  • 钩子处理程序采用 (struct skbuff **),而不是 (struct skbuff *)
  • 从上面继续,skb->protocol不存在。您想要(*skb)->protocol或想要以下成语:
struct sk_buff *sock_buf =  *skb;
if(sock_buff->protocol)
  • 如果数据包是 EGP 数据包,您不应该期待第二个 printk 的输出,因为您在它之前返回。
于 2009-02-27T04:59:53.710 回答
0

您需要研究如何sk_buff工作,由函数 `eth_type_trans' 初始化的协议字段,该函数采用 ETH_P_* 值。所有 ETH_P_* 值都在if_ether中定义。以下是其中一些值。

#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     */

您清楚地看到 0x08 是为Internet Protocol packet. 并且您的代码在 8 的情况下清楚地返回(这是IP数据包)

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

您的ssh/telnet明确 IP 数据包并被上述代码拒绝。请使用if_ethr中定义的正确协议定义值

于 2013-03-06T18:04:28.963 回答