LINUX.ORG.RU

формат DNS пакета


0

0

Пишу небольшую программу, которая будет стоять на LINUX маршрутизаторе, слушать проходящий трафик и вылавливать из него ответы DNS серверов. Из этих ответов будет выделять host = ip. Сразу же столкнулся с проблемой - в пакете, передаваемом в мою функцию из libpcap не могу найти начало ответа DNS сервера, пытаюсь сделать так:

void parse_dns (char *packet, int caplen){

u_char *data;
int datalen;

ns_msg handle;

data = (packet + LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H);
datalen = caplen - (LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H);

printf("%i\n",datalen);

if(ns_initparse(data, datalen, &handle) == -1 ){
fprintf(stderr, "ns_initparse: %s\n", strerror(errno));
}

}

естественно нифига не работает, при ловле пакета появляется ошибка
ns_initparse: Message too long

подскажите, что я делаю не так?

На всякий случай, вся программа:

#include <stdio.h>
#include <pcap.h>
#include <arpa/nameser.h>
#include <resolv.h>
#include <netinet/in.h>
#include <libnet.h>
#include <sys/types.h>
#include <netdb.h>
#include <errno.h>

extern int errno;

char *pcap_dev;
char pcap_filter_app[] = "udp and port 53";
struct bpf_program pcap_filter;
char pcap_errbuf[PCAP_ERRBUF_SIZE];
pcap_t *pcap_handle;
char *pcap_packet;
struct pcap_pkthdr pcap_header;

void parse_dns (char *packet, int caplen){
u_char *data;
int datalen;

ns_msg handle;

data = (packet + LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H);
datalen = caplen - (LIBNET_ETH_H + LIBNET_IP_H + LIBNET_UDP_H + LIBNET_DNS_H);

printf("%i\n",datalen);

if(ns_initparse(data, datalen, &handle) == -1 ){
fprintf(stderr, "ns_initparse: %s\n", strerror(errno));
}

}

int main(int argc,char *argv[]){
pcap_dev = argv[1];
printf("Device: %s\n",pcap_dev);

pcap_handle=pcap_open_live(pcap_dev,BUFSIZ,0,0,pcap_errbuf);
pcap_compile(pcap_handle,&pcap_filter,pcap_filter_app,0,-1);

pcap_setfilter(pcap_handle,&pcap_filter);

for(;{
pcap_packet=(u_char *)pcap_next(pcap_handle,&pcap_header);

if (pcap_packet == NULL) continue;
parse_dns(pcap_packet, (int)pcap_header.caplen);
}

pcap_close(pcap_handle);
return(0);
}

компилирую так:
gcc -static -oaxfr dns-acctd.c -o dns-acctd.o -lpcap -lresolv

anonymous
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.