UNIX: разработка сетевых приложений
Шрифт:
На рис. 29.4 приведены функции, используемые в нашей программе.
Рис. 29.4. Функции, которые используются в программе udpcksum
В листинге 29.1 [1] показан заголовочный файл
udpcksum.h
, в который включен наш базовый заголовочный файл unp.h
, а также различные системные заголовки, необходимые для получения доступа к определениям структур для заголовков пакетов IP и UDP. Листинг 29.1. Заголовочный
1
Все исходные коды программ, опубликованные в этой книге, вы можете найти по адресу http://www.piter.com.
//udpcksum/udpcksum.h
1 #include "unp.h"
2 #include <pcap.h>
3 #include <netinet/in_systm.h> /* необходим для ip.h */
4 #include <netinet/in.h>
5 #include <netinet/ip.h>
6 #include <netinet/ip_var.h>
7 #include <netinet/udp.h>
8 #include <netinet/udp_var.h>
9 #include <net/if.h>
10 #include <netinet/if_ether.h>
11 #define TTL_OUT 64 /* исходящее TTL */
12 /* объявление глобальных переменных */
13 extern struct sockaddr *dest, *local;
14 extern socklen_t destlen, locallen;
15 extern int datalink;
16 extern char *device;
17 extern pcap_t *pd;
18 extern int rawfd;
19 extern int snaplen;
20 extern int verbose;
21 extern int zerosum;
22 /* прототипы функций */
23 void cleanup(int);
24 char *next_pcap(int*);
25 void open_output(void);
26 void open_pcap(void);
27 void send_dns_query(void);
28 void test_udp(void);
29 void udp_write(char*, int);
30 struct udpiphdr *udp_read(void);
3-10
Для работы с полями заголовков IP и UDP требуются дополнительные заголовочные файлы Интернета.
11-30
Мы определяем некоторые глобальные переменные и прототипы для своих собственных функций, которые вскоре покажем. Первая часть функции
main
показана в листинге 29.2. Листинг 29.2. Функция main: определения
//udpcksum/main.c
1 #include "udpcksum.h"
2 /* определение глобальных переменных */
3 struct sockaddr *dest, *local;
4 struct sockaddr_in locallookup;
5 socklen_t destlen, locallen;
6 int datalink; /*
из pcap_datalink, файл <net/bpf.h> */
7 char *device; /* устройство pcap */
8 pcap_t *pd; /* указатель на структуру захваченных пакетов */
9 int rawfd; /* символьный сокет */
10 int snaplen = 200; /* объем захваченных данных */
11 int verbose;
12 int zerosum; /* отправка UDP-запроса без контрольной суммы */
13 static void usage(const char*);
14 int
15 main(int argc, char *argv[])
16 {
17 int c, lopt=0;
18 char *ptr, localname[1024], *localport;
19 struct addrinfo *aip;
В следующей части функции
main
, представленной в листинге 29.3, обрабатываются аргументы командной строки. Листинг 29.3. Функция main: обработка аргументов командной строки
//udpcksum/main.c
20 opterr = 0; /* отключаем запись сообщений getopt в stderr */
21 while ((с = getopt(argc, argv, "0i:l:v")) != -1) {
22 switch (с) {
23 case '0':
24 zerosum = 1;
25 break;
26 case 'i';
27 device = optarg; /* устройство pcap */
28 break;
29 case 'l'; /* локальный IP адрес и номер порта; a.b.c.d.p */
30 if ((ptr = strrchr(optarg, '.')) == NULL)
31 usage("invalid -l option");
32 *ptr++ = 0; /* нуль заменяет последнюю точку. */
33 local port = ptr; /* имя сервиса или номер порта */
34 strncpy(localname, optarg, sizeof(localname));
35 lopt = 1;
36 break;
37 case 'v':
38 verbose = 1;
39 break;
40 case '?':
41 usage("unrecognized option");
42 }
43 }
Обработка аргументов командной строки
20-25
Мы вызываем функцию getopt
для обработки аргументов командной строки. С помощью параметра – 0
мы посылаем запросы UDP без контрольной суммы UDP, чтобы выяснить, обрабатываются ли эти дейтаграммы сервером иначе, чем дейтаграммы с контрольной суммой.
Поделиться с друзьями: