strcmp внутри модуля ядра сбой

Я пытаюсь обнаружить исходящие пакеты в моем модуле ядра (Netfilter). Для этого я использую функцию strcmp. Ядро всегда вылетает после загрузки моего модуля ядра с помощью функции strcmp. Я попытался удалить функцию strcmp - загрузилась без проблем. Надеюсь, проблема связана со всеми строковыми функциями, я также пробовал strstr () - моя система разбилась

Логика, лежащая в основе этого: входящий пакет будет иметь eth [0-9] +, назначенный «in-> name», и «out-> name» будет и наоборот для исходящего пакета.

Есть какие-нибудь сведения об обнаружении исходящего пакета? Я знал, что другой вариант - использовать output_hook вместо prerouting и postrouting hook. Но здесь я хочу по-разному искажать как входящий, так и исходящий пакет. Используемая мной версия ядра не поддерживает строковые функции внутри модулей?

$ uname -a
Linux vmdsk01 2.6.32-21-generic #32-Ubuntu SMP Fri Apr 16 08:09:38 UTC 2010 x86_64 GNU/Linux

Включить часть

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>

#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>

#include <linux/skbuff.h>
#include <linux/inet.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <net/ip.h>

#include <linux/string.h>

Главный крюк

31 unsigned int main_hook(unsigned int hooknum,  
32                   struct sk_buff *skb,
33                   const struct net_device *in,
34                   const struct net_device *out,
35                   int (*okfn)(struct sk_buff*))
36 {
37     if( strcmp(out->name, "<NULL>") == NULL ) // Outgoing packet must not have <NULL>
38     {
39         printk( KERN_INFO "OUTGOING PACKET");
40     }
41     ....

Я также попытался заменить строку 37 следующей, моя система зависает

37     if( strstr(out->name, "eth") != NULL ) // Outgoing packet must have eth[0-9]+ 

person Gopi    schedule 19.05.2014    source источник
comment
Есть ли у вас сообщения о сбоях? Дампы ядра? Следы стека? Журналы?   -  person Alexander Dzyoba    schedule 19.05.2014


Ответы (2)


У вас может быть указатель NULL в указателе структуры out. Вы можете добавить несколько проверок работоспособности в main_hook, например:

unsigned int main_hook(unsigned int hooknum,  
                   struct sk_buff *skb,
                   const struct net_device *in,
                   const struct net_device *out,
                   int (*okfn)(struct sk_buff*))
 {
     if (!out)
         return -EINVAL;

     if( strncmp(out->name, "<NULL>", IFNAMSIZ) == 0 ) // Outgoing packet must not have <NULL>
     {
         printk( KERN_INFO "OUTGOING PACKET");
     }
     ....

Поэтому я добавил проверку указателя out и использовал strncmp вместо strcmp, где IFNAMSIZ - это размер out->name, как определено в include / linux / netdevice.h. Кроме того, str(n)cmp не возвращает NULL, а возвращает 0.

Проверьте его и предоставьте сообщения о сбоях.

person Alexander Dzyoba    schedule 19.05.2014
comment
Спасибо, попробовал ваш исходник - ядро ​​не вылетает :), но все пакеты теряются. Мне не удалось открыть какой-либо сервис (http, ftp, ssh и т. Д.) Через этот компьютер. - person Gopi; 20.05.2014
comment
Конечно, ваши пакеты потеряны, вы возвращаете -EINVAL, потому что ваш указатель out равен NULL. Я не могу сказать вам, нормально ли это, потому что я не знаю вашего кода. Подумайте сами и вернитесь с вопросами о ловушках netfilter и о том, почему ядро ​​дает вам NULL out указатель. На этот вопрос вы должны принять ответ и двигаться дальше. - person Alexander Dzyoba; 20.05.2014
comment
Спасибо, я понял, что указатель out не всегда равен NULL, всякий раз, когда пакет обнаруживается фреймворком Netfilter, доступен указатель out. Ваш ответ дал мне ключ к разгадке :) - person Gopi; 20.05.2014

Я понял проблему, функция перехвата - это последовательность итераций, например, while (1) проверка пакета. Итерация может получить или не получить пакет. Если итерация получила пакет, структура out была бы доступна, и ее члены могли бы быть доступны; Я совершил ошибку, пытаясь получить доступ к члену без проверки доступности структуры.

Следующий код исправил цель и работал нормально.

if(out)
{
    if( strcmp(out->name, "<NULL>") ) // Outgoing packet must not have <NULL>
    {
        printk( KERN_INFO "Outgoing Packet");
    }
}
person Gopi    schedule 20.05.2014