Крюк Netfiler не вызывается - PullRequest
       12

Крюк Netfiler не вызывается

1 голос
/ 27 февраля 2009

Я пишу модуль ядра, который регистрирует ловушку с помощью 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 (протокол внешнего шлюза). Второй принт никогда не печатается. Я что-то упустил?

Ответы [ 3 ]

3 голосов
/ 06 октября 2011

Используемый здесь протокол отличается от номера протокола IP, назначенного IANA, для которого 8 относится к EGP, а EGP устарел.

Определено поле протокола для sk_buff, для которого 8 - для ETH_P_IP. Поскольку ваши данные всегда являются IP-трафиком, первая условная проверка всегда верна. Поэтому вторая часть кода никогда не будет выполнена.

1 голос
/ 27 февраля 2009

Пара мыслей:

  • обработчик хука принимает (struct skbuff **), а не (struct skbuff *)
  • Исходя из вышеизложенного, skb->protocol не существует. Вы хотите либо (*skb)->protocol, либо следующую фразу:
struct sk_buff *sock_buf =  *skb;
if(sock_buff->protocol)
  • Если пакет является пакетом EGP, вы не должны ожидать вывода от второго printk, потому что вы возвращаетесь перед ним.
0 голосов
/ 06 марта 2013

Вам нужно изучить, как работает 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

...