UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Листинг 29.8. Функция send_dns_query: отправка запроса UDP на сервер DNS
//udpcksum/senddnsquery-raw.c
6 void
7 send_dns_query(void)
8 {
9 size_t nbytes;
10 char *buf, *ptr;
11 buf = Malloc(sizeof(struct udpiphdr) + 100);
12 ptr = buf + sizeof(struct udpiphdr); /* место для заголовков IP и UDP */
13 *((uint16_t*)ptr) = htons(1234); /* идентификатор */
14 ptr += 2;
15 *((uint16_t*)ptr) = htons(0x0100); /* флаги */
16 ptr += 2;
17 *((uint16_t*)ptr) = htons(1); /* количество запросов */
18 ptr += 2;
19 *((uint16_t*)ptr) = 0; /* количество записей в ответе */
20 ptr += 2;
21 *((uint16_t*)ptr) = 0; /* количество авторитетных записей */
22 ptr += 2;
23 *((uint16_t*)ptr) = 0; /* количество дополнительных записей */
24 ptr += 2;
25 memcpy(ptr, " 01a 14root-servers 03net 00", 20);
26 ptr += 20;
27 *((uint16_t*)ptr) = htons(1); /* тип запроса = А */
28 ptr += 2;
29 *((uint16_t*)ptr) = htons(1); /* класс запроса = 1 (IP-адрес) */
30 ptr += 2;
31 nbytes = (ptr - buf) - sizeof(struct udpiphdr);
32 udp_write(buf, mbytes),
33 if (verbose)
35 printf("sent: %d bytes of datan", nbytes);
36 }
11-12
buf
ptr
13-24
25-30
a.root-servers.net
a
root-servers
net
31-32
udp_write
В листинге 29.9 показана функция
open_output
Листинг 29.9. Функция open_output: подготовка символьного сокета
2 int rawfd; /* символьный сокет */
3 void
4 open_output(void)
5 {
6 int on=1;
7 /*
8 * Для отправки IP-дейтаграмм нужен символьный сокет
9 * Для его создания нужны права привилегированного пользователя.
10 * Кроме того, необходимо указать параметр сокета IP_HDRINCL.
11 */
12 rawfd = Socket(dest->sa_family, SOCK_RAW, 0);
13 Setsockopt(rawfd, IPPROTO_IP, IP_HDRINCL, &on., sizeof(on));
14 }
2
7-13
IP_HDRINCL
В листинге 29.10 показана наша функция
udp_write
Листинг 29.10. Функция udp_write: формирование заголовков UDP и IP и запись дейтаграммы IP в символьный сокет
//udpcksum/udpwrite.c
19 void
20 udp_write(char *buf, int userlen)
21 {
22 struct udpiphdr *ui;
23 struct ip *ip;
24 /* заполнение заголовка и вычисление контрольной суммы */
25 ip = (struct ip*)buf;
26 ui = (struct udpiphdr*)buf;
27 bzero(ui, sizeof(*ui));
28 /* добавляем 8 к длине псевдозаголовка */
29 ui->ui_len = htons((uint16_t)(sizeof(struct udphdr) + userlen));
30 /* добавление 28 к длине IP-дейтаграммы */
31 userlen += sizeof(struct udpiphdr);
32 ui->ui_pr = IPPROTO_UDP;