Хочу разобраться с разработкой сетевых драйверов под Linux версии 2.6.x И сразу же столкнулся с проблемой... Чтоб скомпилировать модуль, нужны исходники линекса, с этим проблем не возникло. Затем начал писать модуль, и бац, dev_base не найден. ( она представляет точку входа в список зарегистрированных сетевых устройств ). Нет проблем, изучил netdevice.h и наткнулся на вот такую функцию static inline struct net_device *first_net_device (struct net *net) { return list_empty(&net->dev_base_head) ? NULL : net_device_entry(net->dev_base_head.next); } Как понял эта функция заменяет dev_base. ( так ли это??? ) в модуле пишу так Код (Text): struct net_device *current_device; // текущая сетевуха char *eth = "eth0"; // имя этой сетевухи my_init(struct net_device *current_device) { printk("Внутри my_init \n"); if ((current_device = kmalloc(sizeof(struct net_device), GFP_KERNEL)) == NULL ) printk("Ошибка выделения памяти kmalloc \n"); if( (current_device = first_net_device(net)) == NULL ) printk("НАШЛИ !!! \n"); else printk("НЕ НОШЛИ!! \n"); printk("current_device->name = %s \n", current_device->name); // Хочу увидеть что действительно найдено нужное устройство. printk("Перед return в my_init \n"); return 0; }; my_cleanup() // выгружаем наш модуль { printk("Внутри my_cleanup \n"); kfree(current_device); printk("Выход из my_cleanup \n"); }; module_init(my_init); module_exit(my_cleanup); При загрузке модуля в ядро выводится следующее localhost klogd: Внутри my_init localhost klogd: НАШЛИ !!! localhost klogd: current_device->name = <NULL> localhost klogd: Перед return в my_init localhost klogd: Внутри my_cleanup localhost klogd: Выход из my_cleanup Если заменить printk("current_device->name = %s \n", current_device->name); на printk("current_device->name = %s \n", *current_device->name); То вылезит вот это и нет возможности выгрузить модуль. Код (Text): Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: Oops: 0000 [#5] SMP Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: last sysfs file: /sys/devices/pci0000:00/0000:00:1e.0/0000:02:05.0/net/eth0/ifindex Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: Process insmod (pid: 22206, ti=d641a000 task=db2fc9e0 task.ti=d641a000) Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: Stack: Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: 7fffffff c062a6b0 c062a6b4 d641bdc0 c03c9c6d 000016d0 48f13c13 000016d0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: c180d500 c05eb500 01222000 d641bdc8 d641bda0 c03cb608 d641bdb4 c01bb560 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: Call Trace: Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c0103026>] ? do_one_initcall+0x26/0x1c0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c03c9c6d>] ? schedule_timeout+0xad/0xe0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c03cb608>] ? _spin_lock+0x8/0x10 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c01bb560>] ? add_partial+0x40/0x70 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c01bce62>] ? __slab_free+0x112/0x2f0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c03cb546>] ? _spin_lock_irq+0x16/0x20 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c03c8efb>] ? wait_for_common+0xbb/0x130 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c01bfe66>] ? percpu_free+0x46/0x50 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost last message repeated 3 times Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c0176f9c>] ? stop_machine_destroy+0x3c/0x40 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c0166c05>] ? load_module+0xa5/0x1c50 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<f85ba000>] ? cleanup_module+0x0/0x30 [index5] Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c0188384>] ? marker_update_probe_range+0x194/0x2a0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c0189536>] ? tracepoint_update_probe_range+0x76/0xa0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c018958f>] ? tracepoint_module_notify+0x2f/0x40 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c03ce27d>] ? notifier_call_chain+0x2d/0x70 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c015783d>] ? __blocking_notifier_call_chain+0x4d/0x60 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c015786a>] ? blocking_notifier_call_chain+0x1a/0x20 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c0168846>] ? sys_init_module+0x96/0x1d0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c01c01ca>] ? sys_close+0x7a/0xc0 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c010ac5b>] ? sysenter_do_call+0x12/0x2f Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: [<c03c0000>] ? quirk_usb_early_handoff+0x3c0/0x460 Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: Code: c7 04 24 f3 a0 5b f8 e8 0b ec e0 c7 ba d0 00 00 00 b8 2c b9 56 c0 e8 0f 38 c0 c7 85 c0 74 33 c7 04 24 0a a1 5b f8 e8 ec eb e0 c7 <0f> be 05 00 00 00 00 c7 04 24 1b a1 5b f8 89 44 24 04 e8 d5 eb Message from syslogd@localhost at Wed Jul 15 17:48:05 2009 ... localhost klogd: EIP: [<f85ba061>] init_module+0x31/0x68 [index5] SS:ESP 0068:d641bd48 Первый вопрос: почему не могу просмотреть имя сетевого устройств? Второй вопрос: что означает вывод консоли, при неверном доступе к памяти (тот что описал чуть выше ) ? как в нём разобраться?
Таки не нашли. Разименование нулевого указателя черевато. Чтобы стек трейс увидеть неплохо бы дебаг символы включить при компиляции.
agrischuk С first_net_device разобрался, теперь находит все сетевые адаптеры. А вот с отладкой беда. Никогда не отлаживал приложения работающие в ядре. ( вроде у меня есть литература по отладке ядра в GDB под DDD но там всего пара страниц..попробую разобраться ) Как включить дебаг символы при компиляции,чтобы увидеть стек трейс? Как выгружать модуль после ошибок с памятью??? ( insmod -f не помогает ) А то приходится каждые раз, что бы избежать перезагрузки переименовывать исходник модуля, редактировать Makefile и собственно изменять команду компиляции. ( хоть это и быстро...но очень надоедает )
agrischuk Я в предыдущем посте сделал ошибку..я имел ввиду, что выгрузить модуль через rmmod -f не получается.
И ещё один вопрос, когда пытаюсь вывести через printk, mtu сетевого устройства ( eth - это значение должно быть равно 1500). То пишу это printk( "net_device mtu = %u \n", &dev->mtu ); Выводится net_device mtu = 4136237260 cовсем не 1500 )) Как получить верные данные из &dev->mtu ? ( вывести на консоль )
Амперсент убери, это взятие адреса. Посмотри что выводит rmmod -v. Если есть возможность используй виртуальную машину, там откат идет быстро.
agrischuk Ок спасибо за совет. И у меня следующий вопрос) Касающийся фильтров. При insmod модуля консоль как бы зависает, тоесть начинаю грузить модуль в ядро, и окончание загрузки не происходит ( просто чёрная консколь остается..как будто комп чтото считает долго) при нажатии ctrl+c(d) "программа не прерывается" и всё также модуль не выгружается из ядра. По фильтрам у меня есть литература, и я достаточно хорошо её освоил. Но теория теорией, а на практике всё всегда по другому. Беру пример из интернета вот он Код (Text): #include <linux/kernel.h> #include <linux/module.h> #include <linux/netfilter_ipv4.h> #include <linux/netfilter.h> MODULE_LICENSE ("GPL v2"); MODULE_AUTHOR ("ill"); MODULE_DESCRIPTION ("Firewall"); /* * Объявление структур. Мы объявим 2-е структуры. * 1-я для входящих пакетов * 2-я для исходящих пакетов */ struct nf_hook_ops nf_incoming; struct nf_hook_ops nf_outgoing; int i=1; 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 *)) { /* Для примера, мы будем отбрасывать все пакеты */ return NF_DROP; } int init_module (void) { /* * Заполнение структур * Сначала, заполним структуру для входящих пакетов */ nf_incoming.hook=main_hook; nf_incoming.pf=PF_INET; nf_incoming.hooknum=NF_IP_PRE_ROUTING; nf_incoming.priority=NF_IP_PRI_FIRST; /* Теперь для исходящих */ nf_outgoing.hook=main_hook; nf_outgoing.pf=PF_INET; nf_outgoing.hooknum=NF_IP_POST_ROUTING; nf_outgoing.priority=NF_IP_PRI_FIRST; /* Вроде все, осталось только зарегистрировать наши функции */ nf_register_hook(&nf_incoming); nf_register_hook(&nf_outgoing); printk ("FireWall loaded\n"); return 0; } void cleanup_module (void) { /* Не забываем удалить наши вызовы :), а то конфуз может случиться */ nf_unregister_hook(&nf_incoming); nf_unregister_hook(&nf_outgoing); printk ("FireWall unload\n"); } В своём коде делаю всё по аналагоии..с кодом данным из интернета. Расхождение только в том, что в моей версии ядра, в исходниках структура struct nf_hook_ops выглядит так struct nf_hook_ops { struct list_head list; /* User fills in from here down. */ nf_hookfn *hook; struct module *owner; Добавлена новая структура. u_int8_t pf; unsigned int hooknum; /* Hooks are ordered in ascending priority. */ int priority; }; Хочу поинтересоваться, что это за структура такая...и где её определения находятся) Для пробы делаю такой код).. Код (Text): unsigned int ip_in_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) ) // функция перехватчик входящих ip пакетов, сробатывающая в NF_INET_PRE_ROUTING { return NF_DROP; } unsigned int ip_out_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) ) // функция перехватчик исходящих ip пакетов, сробатывающая в NF_INET_PRE_ROUTING { return NF_DROP; } my_init() { struct nf_hook_ops filter_ip_in_ops; // структура функции перехватчика входящих ip пакетов struct nf_hook_ops filter_ip_out_ops; // структура функции перехватчика исходящих ip пакетов struct module *owner; // ЧТО ЗА СТРУКТУРА??? //заполняем структуру перехватчика для входящих ip пакетов filter_ip_in_ops.hook = ip_in_hook; // ф-я перехватчик для входящих ip пакетов filter_ip_in_ops.owner = owner ; // struct module *owner; filter_ip_in_ops.pf = PF_INET; // семейство протоколов filter_ip_in_ops.hooknum = NF_INET_PRE_ROUTING ; // filter_ip_in_ops.priority = NF_IP_PRI_FIRST ; // приоретет обработки hook //заполняем структуру перехватчика для исходящих ip пакетов filter_ip_out_ops.hook = ip_out_hook; // ф-я перехватчик для исходящих ip пакетов filter_ip_out_ops.owner = owner ; // struct module *owner; filter_ip_out_ops.pf = PF_INET; // семейство протоколов filter_ip_out_ops.hooknum = NF_INET_PRE_ROUTING ; // filter_ip_out_ops.priority = NF_IP_PRI_FIRST ; // приоретет обработки hook return 0; }; my_cleanup(struct nf_hook_ops *filter_ip_in_ops, struct nf_hook_ops *filter_ip_out_ops) { nf_unregister_hook(&filter_ip_in_ops); //выгружаем перехватчик nf_unregister_hook(&filter_ip_out_ops); //выгружаем перехватчик }; module_init(my_init); module_exit(my_cleanup); Где ошибка? [root@localhost ~]# rmmod -v index rmmod index, wait=no ERROR: Removing 'index': Device or resource busy
чёрт, редактирования не вижу... в попыхах не дописал, что у меня в коде, перед return 0 в my_init() есть следующее nf_register_hook(&filter_ip_in_ops); // регестрируем перехватчик входящих ip пакетов nf_register_hook(&filter_ip_out_ops); // регестрируем перехватчик исходящих ip пакетов тоесть вот мой код Код (Text): unsigned int ip_in_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) ) // функция перехватчик входящих ip пакетов, сробатывающая в NF_INET_PRE_ROUTING { return NF_DROP; } unsigned int ip_out_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) ) // функция перехватчик исходящих ip пакетов, сробатывающая в NF_INET_PRE_ROUTING { return NF_DROP; } my_init() { struct nf_hook_ops filter_ip_in_ops; // структура функции перехватчика входящих ip пакетов struct nf_hook_ops filter_ip_out_ops; // структура функции перехватчика исходящих ip пакетов struct module *owner; // ЧТО ЗА СТРУКТУРА??? //заполняем структуру перехватчика для входящих ip пакетов filter_ip_in_ops.hook = ip_in_hook; // ф-я перехватчик для входящих ip пакетов filter_ip_in_ops.owner = owner ; // struct module *owner; filter_ip_in_ops.pf = PF_INET; // семейство протоколов filter_ip_in_ops.hooknum = NF_INET_PRE_ROUTING ; // filter_ip_in_ops.priority = NF_IP_PRI_FIRST ; // приоретет обработки hook //заполняем структуру перехватчика для исходящих ip пакетов filter_ip_out_ops.hook = ip_out_hook; // ф-я перехватчик для исходящих ip пакетов filter_ip_out_ops.owner = owner ; // struct module *owner; filter_ip_out_ops.pf = PF_INET; // семейство протоколов filter_ip_out_ops.hooknum = NF_INET_PRE_ROUTING ; // filter_ip_out_ops.priority = NF_IP_PRI_FIRST ; // приоретет обработки hook nf_register_hook(&filter_ip_in_ops); // регестрируем перехватчик входящих ip пакетов nf_register_hook(&filter_ip_out_ops); // регестрируем перехватчик исходящих ip пакетов return 0; }; my_cleanup(struct nf_hook_ops *filter_ip_in_ops, struct nf_hook_ops *filter_ip_out_ops) { nf_unregister_hook(&filter_ip_in_ops); //выгружаем перехватчик nf_unregister_hook(&filter_ip_out_ops); //выгружаем перехватчик }; module_init(my_init); module_exit(my_cleanup);
owner - владелец, просто поставь стандартное значение (уж погугли, будь добр). Насчет my_cleanup - кто тебе эти два параметра передает? ИМХО прототип у функции переменное количество или нет аргуметов.
А можно поинтересоваться, что за приложение вы пишите? Баги: filter_ip_in_ops и filter_ip_out_ops вы регистрируете два абсолютно одинаковых хука filter_ip_in_ops.hooknum = NF_INET_PRE_ROUTING ; filter_ip_out_ops.hooknum = NF_INET_PRE_ROUTING ; // Тут надо POST_ROUTING Структуры filter_ip_in_ops и filter_ip_out_ops локальные, распологаются в стеке функции init. В module_exit не передается никаких параметров и nf_unregister_hook вы делаете хрен знает для чего. Объявите переменные глобально.
bsnake Это даже не приложение, скорее просто стараюсь разобраться в сетевой архитектуре linux, по частям. =) Насчёт багов, это да....мои недочеты. Кстати, шикарно) пробовал вот этот код. Всё работает. Код (Text): unsigned int ip_in_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) ) // функция перехватчик входящих ip пакетов, сробатывающая в NF_INET_PRE_ROUTING { return NF_DROP; } struct nf_hook_ops filter_ip_in_ops; // структура функции перехватчика входящих ip пакетов my_init( ) { printk("Внутри my_init \n"); filter_ip_in_ops.hook = ip_in_hook; // ф-я перехватчик для входящих ip пакетов filter_ip_in_ops.owner = THIS_MODULE ; // УСТАНОВИТЬ УКАЗАТЕЛЬ НА МОДУЛЬ СОЗДАВШИЙ HOOK // struct module *owner; filter_ip_in_ops.pf = PF_INET; // семейство протаколов filter_ip_in_ops.hooknum = NF_INET_PRE_ROUTING ; // filter_ip_in_ops.priority = NF_IP_PRI_FIRST ; // приоретет обработки hook nf_register_hook(&filter_ip_in_ops); // регестрируем перехватчик входящих ip пакетов return 0; }; my_cleanup( ) // выгружаем наш модуль { printk("Внутри my_cleanup \n"); nf_unregister_hook(&filter_ip_in_ops); //выгружаем перехватчик printk("Конец \n"); }; module_init(my_init); module_exit(my_cleanup);
Поясните пожалуйста, почему вот на этом коде, система намертво виснет??? iphdr= skb->network_header; // получаем заголовок ip пакета эта строка находится в перехватчике ip пакетов. вот участок злополучного кода unsigned int ip_in_hook(unsigned int hooknum, struct sk_buff *skb, const struct net_device *in, const struct net_device *out, int (*okfn)(struct sk_buff *) ) // функция перехватчик входящих ip пакетов, срабатывающая в NF_INET_PRE_ROUTING { // заполняем структуру iphdr принятого пакета struct iphdr *iphdr; iphdr = kmalloc (sizeof (struct iphdr), GFP_KERNEL); iphdr= skb->network_header; // получаем заголовок ip пакета// Как тока доходим до сюда, каюк системе! kfree(iphdr); // сразу удаляем return NF_DROP; // это пример }
Код (Text): struct sk_buff { sk_buff_data_t network_header; ... #ifdef NET_SKBUFF_DATA_USES_OFFSET typedef unsigned int sk_buff_data_t; #else typedef unsigned char *sk_buff_data_t; #endif Может пока вам ещё рано лезть в ядро? Вам пока книжек по С\С++ почитать и документацию на ядро с исходниками, тогда 99% вопрос отпадут сразу.
bsnake Книжек по си перечитано уйма, ( да и доки почитываю ). В основном специализируюсь на ассемблере, но в ядре асм мало помогает. Так что не рано. Нужна практика, которой очень мало. Я не понимаю, как предо ставленый Вами код, может изменить моё мировоззрение на структуру кода. sk_buff_data_t - неизвестный для меня тип, в том плане, что я не знаю из скольких байтов он состоит, в моём понимании это указатель на заголовок ip пакета. А заголовок должен представляться структурой struct iphdr . Значит делаем указатель на ip заголовок struct iphdr *iphdr . В функцию передаём указатель на буфер сокета, получаем что sk_buff->network_header это первый байт указателя на ip заголовок. Значит можно присвоить адрес iphdr = skb->network_header и теперь iphdr указывает на нужный нам заголовок( представляемый структурой struct iphdr ). Это рассуждение конечно-же не верное.(ядро то почти моментально падает). Но хочется понять...что я ещё не понимаю))))... Что не понимаю в процессе работы этого кода?(или того, что делаю) И я к сожалению не понимаю. чем мне может помочь это? Код (Text): #ifdef NET_SKBUFF_DATA_USES_OFFSET typedef unsigned int sk_buff_data_t; #else typedef unsigned char *sk_buff_data_t; #endif Разъясните если не сложно.
Пока сайт весел, разобрался с проблемой. Но хотел бы пояснения) насчёт Код (Text): #ifdef NET_SKBUFF_DATA_USES_OFFSET typedef unsigned int sk_buff_data_t; #else typedef unsigned char *sk_buff_data_t; #endif На что влияет NET_SKBUFF_DATA_USES_OFFSET , где должна быть определена? И для совместимости с разными дистрибутивами , нужно код писать с учётом возможности *sk_buff_data_t и sk_buff_data_t Этож сколько #ifdef нужно будет написать..........
тебе эту структуру не надо юзать, насколько я помню ее пользуют макросы из skbuff.h, а тебе надо типа так {{{ iphdr = ip_hdr( skb ); }}} только хидер валиден если изначально было сделано skb_reset_network_header ( skb ); при условии что в момент вызова skb->data указывал именно на ip заголовок, а вообще чтоб поянть смотри исходники ядра, там все есть http://lxr.linux.no/linux+v2.6.22/net/ipv4/ip_input.c#L380
поясняю iphdr = kmalloc (sizeof (struct iphdr), GFP_KERNEL); выделяешь память iphdr= skb->network_header; устанавливаешь iphdr в середину сетевого пакета ( указатель на выделенную память теряется ) kfrree(iphdr); пытаешься грохнуть память в середине сетевого пакета, который система использует, вот тебе и мертво виснет...
Теперь никак не получается отправить буфер сокета в сетевой адаптер ((..вот код. С достаточно хорошими коментами. struct new_pkt // структура, которая будет записана в буфер сокета, для отправки в сетевой адаптер { struct iphdr iphdr; // ip заголовок, тут можно указать, ip назначения и тд struct udphdr udphdr; // заголовок транспортного уровня, тут можно будет указать порт принимающего чело char new_data[1024]; // данные } new_pkt; /* Вообще, в буфере сокета, данные должны располагаться так MAC header IP header UDP header UDP data Если не ошибаюсь, моя структура struct new_pkt должна соответствовать этим требованиям ( Mac header вроде должен быть добавлен уже сетевым адаптером..но я точно не знаю (((...поясните плиз ) */ struct new_pkt *new_pkt_ptr ; new_pkt_ptr = kmalloc( sizeof(struct new_pkt), GFP_ATOMIC ); // выделяем память для нового пакета ( то что надо передать сначала в sk_buff затем этот буфер сокета в сетевой адаптер ) // создание буфера сокета для отправки struct sk_buff *sk_buff_ptr; sk_buff_ptr = dev_alloc_skb(sizeof(struct new_pkt)); // выделяем память для буфера сокета sk_buff_ptr->protocol=htons(ETH_P_IP); // if_ether.h /* Internet Protocol packet */ memcpy(skb_put(sk_buff_ptr, sizeof(struct new_pkt)), new_pkt_ptr, sizeof(struct new_pkt));// skb_put дописывает данные в конец текущего пакета ( увеличивает указатель tail и skb->len) // это не обязательно, но желательно понять)..как выставить указатели на инет заголовки в sk_buff ( transport_header; network_header; mac_header (его пока не существует) указывающие на данные скопированной структуры в буфер данных сокета через skb_put тоесть чтоб, sk_buff_ptr->transport_header указывал на new_pkt_ptr->iphdr а new_pkt_ptr->transport_header на new_pkt_ptr->udphdr ( в буфере сокета) //sk_buff_ptr->network_header = sk_buff_ptr->data; ????? //sk_buff_ptr->transport_header = sk_buff_ptr->data+sizeof( struct iphdr ) ; ????? struct net_device *dev; // указатель на сетевое устройство dev = first_net_device(&init_net); // первое устройство net_device Как правило lo while ( (dev = next_net_device(dev)) !=NULL ) // пробуем отослать пакет, из каждого сетевого устройства { printk("Внутри while \n"); sk_buff_ptr->dev = dev ; dev_queue_xmit(sk_buff_ptr); // сетевое устройство указано параметром sk_buff_ptr->dev ..... при выполнении этой команды, система виснет)) намертво! } kfree_skb(sk_buff_ptr); kfree(new_pkt_ptr); Как отправить данные в сетевой адаптер? Где у меня ошибки??