UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
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
pcap_datalink
Сдвиги на 4, 14 и 24 байта объясняются на рис. 31.9 [128]. Сдвиг, равный 24 байтам, показанный для заголовков SLIP и PPP, применяется в BSD/OS 2.1.
Несмотря на то, что в названии DLT_EN10MB фигурирует обозначение «10МВ», этот тип канального уровня используется для сетей Ethernet, в которых скорость передачи данных равна 100 Мбит/с.
Наша функция
udp_check
В листинге 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
shaplen
pcap_open_live
len
caplen
len
45-46
Если мы посмотрим на библиотечную реализацию функции
pcap_next
pcap_
read
getmsg
recvfrom
Рис. 29.5. Организация вызовов функций для чтения из библиотеки захвата пакетов
Наша функция
udp_check
44-61
pcap_setfilter
Листинг 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))
45 err_quit("len = %d", len);
46 /* минимальная проверка заголовка IP */