|
С/C++ - Самопальный снифер под Linux kas1e Xakep, номер #050, стр. 050-082-3 { unsigned int ip_length:4; // длина идет раньше из-за того, что на x86 unsigned int ip_version:4; // порядок следования байт - little endian unsigned char ip_tos; unsigned short ip_total_length; unsigned short ip_id; unsigned short ip_flags; unsigned char ip_ttl; unsigned char ip_protocol; unsigned short ip_chsum; unsigned int ip_source; // вот это добавили уже сами unsigned int ip_dest; // чтобы проще было }; Типы int, char, short мы уже выбираем сами в зависимости от длины поля. Далее, имея вот такую структуру, мы сможем легко адресоваться по буферу, используя данные поля. Соответственно и ARP-пакет описывается точно так же: struct my_arp /* смещение описание */ { unsigned short arp_hardware_type; /* 2b 0001 = Ethernet */ unsigned short arp_protocol; /* 2b 0800 = IPv4 */ unsigned char arp_mac_len; /* 1b 06 = 6 байт */ unsigned char arp_ip_len; /* 1b 04 = 4 байта */ unsigned short arp_opcode; /* 2b 0001/2 = запрос/ответ */ unsigned char arp_mac_source[6]; /* 6b mac источника */ unsigned char arp_ip_source[6]; /* 6b ip источника */ unsigned char arp_mac_dest[6]; /* 6b mac назначения */ unsigned char arp_ip_dest[6]; /* 6b ip назначения */ }; Для более полного представления смотри соответствующие RFC (в блок-врезке) и заголовочные файлы linux'a. Вот таким образом ты можешь наполнять какой-нибудь файл различными структурами, а потом просто подключать его в главную программу. Получается довольно удобно. Так же можно поступать и с функциями, но так как наши программки довольно маленькие, нам это не понадобится. Анализатор пакетов Эта программка делает простые вещи. При запуске она начинает читать всю информацию, проходящую через сетевую карту, и выводить на экран информацию об ethernet/ip/arp-пакетах. В общем-то, для своего размера (2-3 килобайта) это очень приятный сниферок. Если у тебя сегмент с пассивным хабом, то можно перевести ifconfig'ом карточку в promisc режим и ужаснуться огромнейшему количеству пакетов :). Сначала мы опишем все переменные, которые нам пригодятся в анализаторе: int sock; // Дескриптор на открытый сокет unsigned char buffer[65555]; // Буфер сделаем побольше struct my_ip *ip; // Вот наши struct my_arp *arp; // структурки struct in_addr need; // А это необходимо для inet_ntoa макроса После этого поднимаем наш супер-сокет: sock = socket(PF_PACKET,SOCK_PACKET,htons(ETH_P_ALL)); И далее в цикле начинаем читать данные с сокета и парсить в понятном формате на экран: while(1) { recvfrom(sock,buffer,sizeof buffer,0,0,0); // прочитали в буфер /* Теперь мы парсим, как нам будет угодно. Например, для вывода типа в ARP-па- кете мы показываем, где у нас в буфере ARP-пакет, и какое поле в структуре |