gpt4 book ai didi

c - libpcap 数据包嗅探 流量分析

转载 作者:行者123 更新时间:2023-11-30 17:18:24 24 4
gpt4 key购买 nike

我在 C++ 上使用 libpcap 制作了一个数据包嗅探器。我正在使用 pcap_loop 并调用一个环回函数,目前我还没有考虑太多。这是我的代码。

int PacketSniff(int *count)
{
int ifnum;
int NumOfDevs=0;
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 ip;
bpf_u_int32 netmask;
struct in_addr ip_addr , netmask_addr;
pcap_if_t *devs , *d;
pcap_t *handler;
char packet_filter[] = "ip";
struct bpf_program fcode;


/* Find all interface devices */
pcap_findalldevs(&devs, errbuf);

for(d=devs; d; d=d->next)
{
printf("%d. %s", ++NumOfDevs, d->name);
if (d->description)
{
printf(" (%s)\n", d->description);
}
else
{
printf(" (No description available)\n");
}
}
if(NumOfDevs==0)
{
printf("\nNo interfaces found!\n");
return (-1);
}


/* Prompt User to select interface */
printf("Enter the interface number (1-%d):\n",NumOfDevs);
scanf("%d",&ifnum);

if(ifnum < 1 || ifnum > NumOfDevs)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(devs);
return (-1);
}


/* Jump to the selected adapter/interface */
for(d=devs; ifnum>1 ;d=d->next, ifnum--);

/* Open the selected adapter/interface */
handler = pcap_open_live(d->name, 65535, 0, 2000, errbuf);

if ((handler = pcap_open_live(d->name, 65535, 0, 2000, errbuf)) == NULL)
{
fprintf(stderr, "Couldn't open device %s: %s\n", d->name, errbuf);
return(-1);
}




if (pcap_datalink(handler) != DLT_EN10MB )
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
pcap_freealldevs(devs);
return -1;

}

/* This means that we set the datalink layer header size at 14 */
int linkhdrlen = 14;


if (pcap_lookupnet(d->name, &ip, &netmask, errbuf) <0 )
{
fprintf(stderr, "Can't get netmask for device %s\n", d->name);
netmask = 0;
ip = 0;
}


/* Compile the filter */
if (pcap_compile(handler, &fcode, packet_filter, 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax. Error: %s\n", errbuf);
pcap_freealldevs(devs);
return -1;
}

/* Set the filter */
if (pcap_setfilter(handler, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter. Error: %s\n", errbuf);
pcap_freealldevs(devs);
return -1;
}


printf("\nListening for packets on interface <%s>...\n", d->name);

/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(devs);

pcap_loop(handler, 0, my_callback, NULL);}

my_callback 是这样的:

void my_callback(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_ptr){

struct tm ltime;
char timestr[16];
struct ip_header *iphdr;
struct tcp_header *tcphdr;
time_t local_tv_sec;




/* Convert the timestamp to readable format */

local_tv_sec = header->ts.tv_sec;
localtime_r(&local_tv_sec , &ltime);
strftime( timestr, sizeof timestr, "%H:%M:%S", &ltime);

/* Print timestamp and length of the packet */
printf("Time >> %s.%.6d \nPacket Length:%d \n\n", timestr, header->ts.tv_usec, header->len);

/* Retireve the position of the ip header http://www.tcpdump.org/pcap.html */
iphdr = (ip_header *) (pkt_ptr +14);




// Advance to the transport layer header then parse and display
// the fields based on the type of hearder: tcp, udp or icmp.

pkt_ptr += 4*iphdr->ver_ihl ;
tcphdr = (tcp_header *)(pkt_ptr + 14);
/* print ip addresses and tcp ports */
printf("%d.%d.%d.%d : %d ---> %d.%d.%d.%d : %d\n\n",
iphdr->saddr.byte1,
iphdr->saddr.byte2,
iphdr->saddr.byte3,
iphdr->saddr.byte4,
tcphdr->src_port,
iphdr->daddr.byte1,
iphdr->daddr.byte2,
iphdr->daddr.byte3,
iphdr->daddr.byte4,
tcphdr->dst_port);}

现在我可以嗅探数据包并打印各种内容。但我的目标是在嗅探数据包时从数据包中提取统计信息(例如 numOfpackets 、 numOfTCPpackets 、 numOfIncomingPAcket 、 numOfOutgoingPackets 、数据包大小方差、时间间隔方差)。但我希望这可以在 1000 毫秒的时间窗口内完成。

例如:每 1000 毫秒我想要一个输出文件..

TCPPackets 数量 = ....

numof = ....

.

.

.

我的问题是:我怎样才能合并这些时间窗口?如何在不过多干扰嗅探速度的情况下提取所需的统计数据?

非常感谢!

最佳答案

使用 pcap_next() 而不是 pcap_loop() 来获取数据包,并使用 pcap_set_timeout() 将超时设置为一个较小的值,例如 10 毫秒,以防止 pcap_next() 永远阻塞,以便您的代码将统计信息写入文件获得逃跑的机会。您需要在循环中调用 pcap_next() 并在 pcap_next() 调用后添加如下代码:

if (cur_time64() - last_time64 >= stat_time64)
{
last_time64 += stat_time64;
print_statistics_to_file();
}

...其中 cur_time64() 以 64 位整数形式返回自纪元以来的当前时间(以微秒为单位)(如果您使用类 Unix 操作系统,则可以使用 gettimeofday() 来实现 cur_time64())。在您的示例中,stat_time64 将为 1 秒,即 1000*1000。

然后,继续处理数据包。检查pcap_next()的返回值是否返回数据包:如果没有,则继续循环;如果是,则处理该数据包。

为了在不过多干扰嗅探速度的情况下进行检查,您唯一的选择是尽可能高效地编写代码。仅处理那些您绝对需要处理的 header 字段,即您可以避免检查 IP 和 TCP header 的校验和。

关于c - libpcap 数据包嗅探 流量分析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29186088/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com