Назначение и источник PCAP одинаковы

У меня небольшие проблемы с libpcap. я использую pcap_loop() с этим обратным вызовом:

void pcap_callback(u_char *useless, const struct pcap_pkthdr *pcap_header, const u_char *packet) {
struct ether_header *head = (struct ether_header *)packet;
struct ip *ip = (struct ip *)(packet + sizeof(struct ether_header));

u_short eth_type = ntohs(head->ether_type);
const char *s_ipad = inet_ntoa(ip->ip_src);
const char *d_ipad = inet_ntoa(ip->ip_dst);
const char *s_host = ether_ntoa((struct ether_addr *)head->ether_shost);
const char *d_host = ether_ntoa((struct ether_addr *)head->ether_dhost);

if (eth_type == ETHERTYPE_IP || eth_type == ETHERTYPE_IPV6) {
NSLog(@"\nPACKET\ns IP  : %s\ns MAC: %s\n\nd IP  : %s\nd MAC: %s\n\n", s_ipad, s_host, d_ipad, d_host);
}
}

На консоли я получаю пакеты, назначение и источник которых точно совпадают. Таким образом, IP и MAC-адреса не отличаются. Используя фильтры, я мог выяснить, что все пакеты имеют адреса назначения.

Вот код, который я использую для запуска pcap:

void sniff() {
pcap_t *handle;
char *device;
char errbuf[PCAP_ERRBUF_SIZE];

char *net;
char *mask;
bpf_u_int32 netp;
bpf_u_int32 maskp;
struct in_addr addr;

device = "en1";

pcap_lookupnet(device, &netp, &maskp, errbuff);

addr.s_addr = netp;
net = inet_ntoa(addr);
NSLog(@"ROUTER: %s", net);

addr.s_addr = maskp;
mask = inet_ntoa(addr);
NSLog(@"SNMASK: %s", mask);

handle = pcap_open_live(device, BUFSIZ, 0, 10, errbuf);

struct bpf_program filterProgram;
pcap_compile(handle, &filterProgram, "src 10.0.10.40 or dst 10.0.10.40", 1, maskp);
pcap_setfilter(handle, &filterProgram);

pcap_loop(handle, 100, pcap_callback, NULL);
pcap_close(handle);
}

3

Решение

От ‘man inet_ntoa’:
Функция inet_ntoa () преобразует адрес хоста в Интернете, заданный в порядке сетевых байтов, в строку в десятичном формате с точками IPv4. Строка возвращается в статически выделенном буфере, который последующие вызовы будут перезаписывать.

Поэтому вы должны скопировать s_ipad и s_host перед повторным вызовом inet_ntoa и ether_ntoa. Что-то вроде этого:

const char *aux = inet_ntoa(ip->ip_src);
const char *s_ipad = strcpy(new char[strlen(aux)+1], aux);
aux = inet_ntoa(ip->ip_dst);
const char *d_ipad = strcpy(new char[strlen(aux)+1], aux);
aux = ether_ntoa((struct ether_addr *)head->ether_shost);
const char *s_host = strcpy(new char[strlen(aux)+1], aux);
aux = ether_ntoa((struct ether_addr *)head->ether_dhost);
const char *d_host = strcpy(new char[strlen(aux)+1], aux);
//do whatever...
delete[] s_ipad; delete[] d_ipad;delete[] s_host; delete[] d_host;
6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]