Чтение онлайн

на главную

Жанры

UNIX: разработка сетевых приложений
Шрифт:

7 struct udpiphdr*

8 udp_read(void)

9 {

10 int len;

11 char *ptr;

12 struct ether_header *eptr;

13 for (;;) {

14 ptr = next_pcap(&len);

15 switch (datalink) {

16 case DLT_NULL: /* заголовок обратной петли = 4 байта */

17 return (udp_check(ptr + 4, len — 4));

18 case DLT_EN10MB:

19 eptr = (struct ether_header*)ptr;

20 if (ntohs(eptr->ether_type) != ETHERTYPE_IP)

21 err_quit("Ethernet type not IP", ntohs(eptr->ether_type));

22 return (udp_check(ptr + 14, len — 14));

23 case DLT_SLIP: /*
заголовок SLIP = 24 байта */

24 return (udp_check(ptr + 24, len — 24));

25 case DLT_PPP: /* заголовок PPP = 24 байта */

26 return (udp_check(ptr + 24, len — 24));

27 default:

28 err_quit("unsupported datalink (%d)", datalink);

29 }

30 }

31 }

14-29
Наша функция
next_pcap
(см. листинг 29.12) возвращает следующий пакет из устройства захвата пакетов. Поскольку заголовки канального уровня различаются в зависимости от фактического типа устройства, мы применяем ветвление в зависимости от значения, возвращаемого функцией
pcap_datalink
.

ПРИМЕЧАНИЕ

Сдвиги на 4, 14 и 24 байта объясняются на рис. 31.9 [128]. Сдвиг, равный 24 байтам, показанный для заголовков SLIP и PPP, применяется в BSD/OS 2.1.

Несмотря на то, что в названии DLT_EN10MB фигурирует обозначение «10МВ», этот тип канального уровня используется для сетей Ethernet, в которых скорость передачи данных равна 100 Мбит/с.

Наша функция

udp_check
(см. листинг 29.13) исследует пакет и проверяет поля в заголовках IP и UDP.

В листинге 29.12 показана функция

next_pcap
, возвращающая следующий пакет из устройства захвата пакетов.

Листинг 29.12. Функция next_pcap: возвращает следующий пакет

//udpcksum/pcap.c

38 char*

39 next_pcap(int *len)

40 {

41 char *ptr;

42 struct pcap_pkthdr hdr;

43 /* продолжаем следить, пока пакет не будет готов */

44 while ((ptr = (char*)pcap_next(pd, &hdr)) == NULL);

45 *len = hdr.caplen; /* длина захваченного пакета */

46 return (ptr);

47 }

43-44
Мы вызываем библиотечную функцию
pcap_next
, возвращающую следующий пакет. Указатель на пакет является возвращаемым значением данной функции, а второй аргумент указывает на структуру
pcap_pkthdr
, которая тоже возвращается заполненной:

struct pcap_pkthdr {

struct timeval ts; /*
временная метка */

bpf_u_int32 caplen; /* длина захваченного фрагмента */

bpf_u_int32 len; /* полная длина пакета, находящегося в канале */

};

Временная отметка относится к тому моменту, когда пакет был считан устройством захвата пакетов, в противоположность моменту фактической передачи пакета процессу, которая может произойти чуть позже. Переменная

caplen
содержит длину захваченных данных (вспомним, что в листинге 29.2 нашей переменной
shaplen
было присвоено значение 200 и она являлась вторым аргументом функции
pcap_open_live
в листинге 29.5). Назначение устройства захвата пакетов состоит в захвате заголовков, а не всего содержимого каждого пакета. Переменная
len
— это полная длина пакета, находящегося в канале. Значение
caplen
будет всегда меньше или равно значению
len
.

45-46
Перехваченная часть пакета возвращается через указатель (аргумент функции), и возвращаемым значением функции является указатель на пакет. Следует помнить, что указатель на пакет указывает фактически на заголовок канального уровня, который представляет собой 14-байтовый заголовок Ethernet в случае кадра Ethernet или 4-байтовый псевдоканальный (pseudo-link) заголовок в случае закольцовки на себя.

Если мы посмотрим на библиотечную реализацию функции

pcap_next
, мы увидим, что между различными функциями существует некоторое «разделение труда», схематически изображенное на рис. 29.5. Наше приложение вызывает функции
pcap_
, среди которых есть как зависящие, так и не зависящие от устройства захвата пакетов. Например, мы показываем, что реализация BPF вызывает функцию
read
, в то время как реализация DLPI вызывает функцию
getmsg
, а реализация Linux вызывает
recvfrom
.

Рис. 29.5. Организация вызовов функций для чтения из библиотеки захвата пакетов

Наша функция

udp_check
проверяет различные поля в заголовках IP и UDP. Она показана в листинге 29.13. Эту проверку необходимо выполнить, так как при получении пакета от устройства захвата пакетов уровень IP не замечает этого пакета. Для символьного сокета это не так.

44-61
Длина пакета должна включать хотя бы заголовки IP и UDP. Версия IP проверяется вместе с длиной и контрольной суммой заголовка IP. Если поле протокола указывает на дейтаграмму UDP, функция возвращает указатель на объединенный заголовок IP/UDP. В противном случае программа завершается, так как фильтр захвата пакетов, заданный при вызове функции
pcap_setfilter
в листинге 29.5, не должен возвращать пакеты никакого другого типа.

Листинг 29.13. Функция udp_check: проверка полей в заголовках IP и UDP

//udpcksum/udpread.c

38 struct udpiphdr*

39 udp_check(char *ptr, int len)

40 {

41 int hlen;

42 struct ip *ip;

43 struct udpiphdr *ui;

44 if (len < sizeof(struct ip) + sizeof(struct udphdr))

Поделиться:
Популярные книги

Идущий в тени 4

Амврелий Марк
4. Идущий в тени
Фантастика:
боевая фантастика
6.58
рейтинг книги
Идущий в тени 4

Дракон с подарком

Суббота Светлана
3. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
6.62
рейтинг книги
Дракон с подарком

Я снова не князь! Книга XVII

Дрейк Сириус
17. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я снова не князь! Книга XVII

Метка драконов. Княжеский отбор

Максименко Анастасия
Фантастика:
фэнтези
5.50
рейтинг книги
Метка драконов. Княжеский отбор

Авиатор: назад в СССР 11

Дорин Михаил
11. Покоряя небо
Фантастика:
альтернативная история
5.00
рейтинг книги
Авиатор: назад в СССР 11

На границе империй. Том 7. Часть 5

INDIGO
11. Фортуна дама переменчивая
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
5.00
рейтинг книги
На границе империй. Том 7. Часть 5

Темный охотник 6

Розальев Андрей
6. КО: Темный охотник
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный охотник 6

Корпулентные достоинства, или Знатный переполох. Дилогия

Цвик Катерина Александровна
Фантастика:
юмористическая фантастика
7.53
рейтинг книги
Корпулентные достоинства, или Знатный переполох. Дилогия

Все еще не Герой!. Том 2

Довыдовский Кирилл Сергеевич
2. Путешествие Героя
Фантастика:
боевая фантастика
юмористическое фэнтези
городское фэнтези
рпг
5.00
рейтинг книги
Все еще не Герой!. Том 2

Довлатов. Сонный лекарь 3

Голд Джон
3. Не вывожу
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Довлатов. Сонный лекарь 3

Попаданка в деле, или Ваш любимый доктор - 2

Марей Соня
2. Попаданка в деле, или Ваш любимый доктор
Любовные романы:
любовно-фантастические романы
7.43
рейтинг книги
Попаданка в деле, или Ваш любимый доктор - 2

Возмездие

Злобин Михаил
4. О чем молчат могилы
Фантастика:
фэнтези
7.47
рейтинг книги
Возмездие

Ваше Сиятельство 8

Моури Эрли
8. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 8

Чемпион

Демиров Леонид
3. Мания крафта
Фантастика:
фэнтези
рпг
5.38
рейтинг книги
Чемпион