Библиотека сайта rus-linux.net
Цилюрик О.И. Модули ядра Linux | ||
Назад | Внешние интерфейсы модуля | Вперед |
Протокол транспортного уровня
На этом уровне обеспечивается обработка таких протоколов, как: UDP, TCP, SCTP... Протоколы транспортного уровня (протоколы IP) описаны в <linux/in.h>:
/* Standard well-defined IP protocols. */ enum { IPPROTO_IP = 0, /* Dummy protocol for TCP */ IPPROTO_ICMP = 1, /* Internet Control Message Protocol */ IPPROTO_IGMP = 2, /* Internet Group Management Protocol */ ... IPPROTO_TCP = 6, /* Transmission Control Protocol */ ... IPPROTO_UDP = 17, /* User Datagram Protocol */ ... IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */ ... IPPROTO_RAW = 255, /* Raw IP packets */ }
Для установки обработчика протоколов транспортного уровня существует API <net/protocol.h> :
struct net_protocol { // This is used to register protocols int (*handler)( struct sk_buff *skb ); void (*err_handler)( struct sk_buff *skb, u32 info ); int (*gso_send_check)( struct sk_buff *skb ); struct sk_buff *(*gso_segment)( struct sk_buff *skb, int features ); struct sk_buff **(*gro_receive)( struct sk_buff **head, struct sk_buff *skb ); int (*gro_complete)( struct sk_buff *skb ); unsigned int no_policy:1, netns_ok:1; }; int inet_add_protocol( const struct net_protocol *prot, unsigned char num ); int inet_del_protocol( const struct net_protocol *prot, unsigned char num );
- где 2-й параметр вызова функций как раз и есть константа из числа IPPROTO_*.
Пример модуля, устанавливающего протокол:
trn_proto.c :
#include <linux/module.h> #include <linux/init.h> #include <net/protocol.h> int test_proto_rcv( struct sk_buff *skb ) { printk( KERN_INFO "Packet received with length: %u\n", skb->len ); return skb->len; }; static struct net_protocol test_proto = { .handler = test_proto_rcv, .err_handler = 0, .no_policy = 0, }; //#define PROTO IPPROTO_ICMP //#define PROTO IPPROTO_TCP #define PROTO IPPROTO_RAW static int __init my_init( void ) { if( inet_add_protocol( &test_proto, PROTO ) < 0 ) { printk( KERN_INFO "proto init: can't add protocol\n"); return -EAGAIN; }; printk( KERN_INFO "proto module loaded\n" ); return 0; } static void __exit my_exit( void ) { inet_del_protocol( &test_proto, PROTO ); printk( KERN_INFO "proto module unloaded\n" ); } module_init( my_init ); module_exit( my_exit ); MODULE_AUTHOR( "Oleg Tsiliuric" ); MODULE_LICENSE( "GPL v2" );
$ sudo insmod trn_proto.ko
$ lsmod | head -n2
Module Size Used by trn_proto 780 0
$ dmesg | tail -n2
proto init: can't add protocol proto module loaded
$ cat /proc/modules | grep proto
trn_proto 780 0 - Live 0xf9a26000
$ ls -R /sys/module/trn_proto
/sys/module/trn_proto: holders initstate notes refcnt sections srcversion ...
Статистики
Для накопления статистики работы сетевого интерфейса описана структура (весьма большая, определена в <linux/netdevice.h>, показано только начало структуры) :
struct net_device_stats { unsigned long rx_packets; /* total packets received */ unsigned long tx_packets; /* total packets transmitted */ unsigned long rx_bytes; /* total bytes received */ unsigned long tx_bytes; /* total bytes transmitted */ unsigned long rx_errors; /* bad packets received */ unsigned long tx_errors; /* packet transmit problems */ ... }
Такая структура должна заполняться кодом модуля статистическими данными проходящих пакетов. Это делается, если вы хотите получать статистики сетевого интерфейса пользователем через интерфейс файловой системы /proc, как это происходит для других сетевых интерфейсов.
Предыдущий раздел: | Оглавление | Следующий раздел: |
Протокол сетевого уровня | Внутренние механизмы ядра |