Linux - статьи




Реализация сети в операционной - часть 11


Уровень IP Проверка ошибок Дефрагментация если необходимо Определение маршрута(форвардить или нет) Отсылка пакета по назначению(TCPUDPforwarding)

Получение пакета в UDP Проверка ошибок проверка сокета назначения пересылка пакета в очередь сокета пробуждения ждущего процесса

Получение TCP Проверка флагов и ошибок а также не был ли получен пакет ранее Определение сокета пересылка пакета в очередь сокета пробуждения ждущего процесса

Чтение из сокета(2) Пробуждение процесса Вызов соответствуюшей функции доставки(udp tcp) в буфер пользователя Возврат

IP forwarding

Рассмотрим подробнее процесс форвардинга пакетов

Сначада идет проверка TTL и уменьшение его на 1 Проверка пакета на наличие действительного маршрута если такого нет то отсылается соответствующее icmp cообщение копирование пакета в новый буфер и освобождение старого Установка нужных ip опций фрагменторование если необходимо отправка пакета на нужный девайс

DEVICE_rx() девайсно зависимая функция, пример drivers/net/de600.c здесь я попытаюсь перевести замечательные комментарии автора

Linux driver for the D-Link DE-600 Ethernet pocket adapter. * * Portions (C) Copyright 1993, 1994 by Bjorn Ekwall * The Author may be reached as bj0rn@blox.se

/* * Если у нас хороший пакет то забираем его из адаптера */ static void de600_rx_intr(struct net_device *dev) { struct sk_buff *skb; unsigned long flags; int i; int read_from; int size; register unsigned char *buffer;

save_flags(flags); cli();

/* Определяем размер пакета */ size = de600_read_byte(RX_LEN, dev); /* нижния байт */ size += (de600_read_byte(RX_LEN, dev) << 8); /* верхний байт */ size -= 4; /* Ignore trailing 4 CRC-bytes */

/* Сообщаем адаптеру куда ложить следующий пакет и получаем */

read_from = rx_page_adr(); next_rx_page(); de600_put_command(RX_ENABLE);

restore_flags(flags);

if ((size < 32) (size > 1535)) { printk("%s: Bogus packet size %d.\n", dev->name, size); if (size > 10000) adapter_init(dev); return; }

skb = dev_alloc_skb(size+2); if (skb == NULL) { printk("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, size); return; } /* Иначе*/




Содержание  Назад  Вперед