Читаем Linux: Полное руководство полностью

Прежде чем перейти к рассмотрению функций ICMP, разберемся, как же ICMP-пакеты принимаются операционной системой. Собственно, ICMP-пакет принимается операционной системой Linux так же, как и любой другой пакет. Драйвер сетевой платы (или другого сетевого устройства) собирает полный пакет данных, затем он строит структуру sk_buff.

Листинг 27.1. Структура sk_buff

struct sk_buff {

 /* Эти два члена должны быть первыми */

 struct sk_buff* next; /* Следующий буфер в списке*/

 struct sk_buff* prev;/* Предыдущий буфер в списке*/

 struct sk_buff_head * list; /* "Голова" списка */

 struct sock *sk; /* Сокет */

 struct timeval stamp; /* Время прибытия пакета */

 struct net_device *dev; /* Сетевое устройство */

 /* Заголовок транспортного уровня */

 union {

  struct tcphdr *th;

  struct udphdr *uh;

  struct icmphdr *icmph;

  struct igmphdr* igmph;

  struct iphdr *ipiph;

  struct spxhdr *spxh;

  unsigned char *raw;

 } h;

 /* Заголовок сетевого уровня */

 union {

  struct iphdr *iph;

  struct ipv6hdr* ipv6h;

  struct arphdr *arph;

  struct ipxhdr *ipxh;

  unsigned char *raw;

 } nh;

 union {

  struct ethhdr *ethernet;

  unsigned char *raw;

 } mac;

 struct dst_entry *dst;

 char cb[48];

 unsigned int len; /* Длина данных */

 unsigned int data_len;

 unsigned int csum; /* Контрольная сумма */

 unsigned char __unused, /* He используется */

               cloned, /* Заголовок должен клонироваться */

               pkt_type, /* Класс пакета */

               ip_summed; /* контрольная сумма IP */

 __u32 priority; /* Приоритет пакета */

 atomic_t users; /* Счетчик пользователей — см.

                    datagram.c, tcp.c */

 unsigned short protocol; /* Протокол пакета */

 unsigned short security; /* Уровень безопасности */

 unsigned int truesize; /* Размер буфера */

 unsigned char *head; /* Заголовок буфера */

 unsigned char *data; /* Указатель заголовка данных */

 unsigned char *tail; /* Указатель "хвоста" */

 unsigned char *end; /* Конечный указатель */

 void (*destructor)(struct sk_buff*);

#ifdef CONFIG_NETFILTER

 unsigned long nfmark;

 /* Cache info */

 __u32 nfcache;

 /* Ассоциированное соединение */

 struct nf_ct_info *nfct;

#ifdef CONFIG_NETFILTER_DEBUG

 unsigned int nf_debug;

#endif

#endif /* CONFIG_NETFILTER*/

#if defined(CONFIG_HIPPI)

 union {

  __u32 ifield;

 } private;

#endif

#ifdef CONFIG_WET_SCHED

 __u32 tc_index; /* Индекс контроля трафика */

#endif

};

Данная структура описана в файле /usr/src/linux/include/linux/skbuff.h. После формирования структуры sk_buff она передается драйвером функции netif_rx.

int netif_rx(struct sk_buff *skb);

Функция netif_rx() описана в файле /usr/src/linux/net/core/dev.c. Она получает пакет от драйвера сетевого устройства и ставит его в очередь (очередь называется backlog) протокола высшего уровня. Функция возвращает следующие значения:

♦ NET_RX_SUCCESS — пакет удачно поставлен в очередь;

♦ NET_RX_CN_LOW — имеется небольшая «пробка» при постановке пакета в очередь, но скоро она «рассосется»;

♦ NET_RX_CN_MOD — «пробка» чуть больше — средней «длины»;

♦ NET_RX_CN_HIGH — очень большая «пробка»;

♦ NET_RX_DROP — пакет был удален.

Если в очереди backlog находятся более 300 пакетов, новый пакет будет удален без какого-либо предупреждения.

Перейти на страницу:

Все книги серии Полное руководство

Похожие книги