Перехватчик Netfiler не вызывается
-
09-09-2019 - |
Вопрос
Я пишу модуль ядра, который регистрирует перехват с помощью 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 никогда не печатается.Я что-то упускаю?
Решение
Используемый здесь протокол отличается от номера IP-протокола, присвоенного IANA, для которого 8 соответствует EGP, а EGP устарел.
Поле протокола для sk_buff определено в , где 8 соответствует ETH_P_IP.Поскольку ваши данные всегда представляют собой IP-трафик, первая условная проверка всегда верна.Таким образом, вторая часть кода никогда не выполняется.
Другие советы
Пара мыслей:
- обработчик перехвата принимает (struct skbuff **), а не (struct skbuff *)
- исходя из вышеизложенного,
skb->protocol
не существует.Вы хотите либо(*skb)->protocol
или вам нужна следующая идиома:
struct sk_buff *sock_buf = *skb;
if(sock_buff->protocol)
- Если пакет является пакетом EGP, вам не следует ожидать вывода от второго printk, поскольку вы вернетесь раньше него.
Вам нужно изучить, как sk_buff
работает, поле протокола инициализируется функцией `eth_type_trans', которая принимает значения ETH_P_*.Все значения ETH_P_* определены в если_эфир.Вот некоторые из этих значений.
#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