Библиотека сайта 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, как это происходит для других сетевых интерфейсов.
| Предыдущий раздел: | Оглавление | Следующий раздел: |
| Протокол сетевого уровня | Внутренние механизмы ядра |
