- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于我为 OSX 构建的一个小工具,我想捕获从某个以太网 Controller 发送和接收的数据包的长度。
当我获取以太网卡时,我还会得到额外的信息,例如最大数据包大小、链接速度等。
当我启动(我所说的)“trafficMonitor”时,我会这样启动它:
static void initializeTrafficMonitor(const char* interfaceName, int packetSize) {
char errbuf[PCAP_ERRBUF_SIZE];
pcap_t* sessionHandle = pcap_open_live(interfaceName, packetSize, 1, 100, errbuf);
if (sessionHandle == NULL)
{
printf("Error opening session for device %s: %s\n", interfaceName, errbuf);
return;
}
pcap_loop(sessionHandle, -1, packetReceived, NULL);
}
提供的 interfaceName
是接口(interface)的 BSD 名称,例如 en0
。 packetSize
变量是一个整数,我在其中提供了该以太网适配器的最大数据包大小(这在当时看来是合乎逻辑的)。例如,我的 WiFi 适配器的数据包大小是 1538
。
我的回调方法称为 packetReceived
,如下所示:
void packetReceived(u_char* args, const struct pcap_pkthdr* header, const u_char* packet) {
struct pcap_work_item* item = malloc(sizeof(struct pcap_pkthdr) + header->caplen);
item->header = *header;
memcpy(item->data, packet, header->caplen);
threadpool_add(threadPool, handlePacket, item, 0);
}
我将数据包的所有属性填充到一个新结构中,并启动一个工作线程来分析数据包并处理结果。这是为了不让 pcap 等待,并试图解决这个在添加这个工作线程方法之前已经存在的问题。
handlePacket
方法是这样的:
void handlePacket(void* args) {
const struct pcap_work_item* workItem = args;
const struct sniff_ethernet* ethernet = (struct sniff_ethernet*)(workItem->data);
u_int size_ip;
const struct sniff_ip* ip = (struct sniff_ip*)(workItem->data + SIZE_ETHERNET);
size_ip = IP_HL(ip) * 4;
if (size_ip < 20) {
return;
}
const u_int16_t type = ether_packet(&workItem->header, workItem->data);
switch (ntohs(type)) {
case ETHERTYPE_IP: {
char sourceIP[INET_ADDRSTRLEN];
char destIP[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &ip->ip_src, sourceIP, sizeof(sourceIP));
inet_ntop(AF_INET, &ip->ip_dst, destIP, sizeof(destIP));
[refToSelf registerPacketTransferFromSource:sourceIP destinationIP:destIP packetLength:workItem->header.caplen packetType:ethernet->ether_type];
break;
}
case ETHERTYPE_IPV6: {
// handle v6
char sourceIP[INET6_ADDRSTRLEN];
char destIP[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &ip->ip_src, sourceIP, sizeof(sourceIP));
inet_ntop(AF_INET6, &ip->ip_dst, destIP, sizeof(destIP));
[refToSelf registerPacketTransferFromSource:sourceIP destinationIP:destIP packetLength:workItem->header.caplen packetType:ethernet->ether_type];
break;
}
}
}
根据以太网数据包的类型,我尝试确定它是使用 IPv4 还是 IPv6 地址发送的数据包。确定后,我将一些详细信息发送到 objectiveC 方法(源 IP 地址、目标 IP 地址和数据包长度)。
我将数据包转换为 tcpdump 网站 (http://www.tcpdump.org/pcap.html) 上解释的结构。
问题是 pcap 似乎跟不上接收/发送的数据包。要么我没有嗅探所有数据包,要么数据包长度错误。
有没有人指出我需要调整我的代码以使 pcap 捕获所有代码或我遇到某种问题的地方。
这些方法是从我的 objectiveC 应用程序调用的,refToSelf
是对 objC 类的引用。
编辑:我在后台线程中调用 initializeTrafficMonitor,因为 pcap_loop 正在阻塞。
最佳答案
这是在哪个版本的 OS X 上?在 Lion 之前的版本中,libpcap 在使用 BPF 的系统(例如 OS X)上的默认缓冲区大小为 32K 字节; 1992 called, they want their 4MB workstations and 10Mb Ethernets back .在 Lion 中,Apple 将 libpcap 更新为 1.1.1 版本;在 libpcap 1.1.0 中,默认的 BPF 缓冲区大小增加到 512MB(即使不是所有具有 BPF 的系统,也是大多数系统的最大值)。
如果这是 Snow Leopard,请尝试切换到新的 pcap_create()
/pcap_activate()
API,并使用 pcap_set_buffer_size()
来将缓冲区大小设置为 512MB。如果这是 Lion 或更高版本,那不会有什么不同。
如果您的程序无法跟上平均数据包速率,那将无济于事,但如果有临时,它至少意味着更少的数据包丢弃> 爆发超过平均水平。
如果您的程序跟不上平均数据包速率,那么,如果您只想要数据包的 IP 地址,请尝试设置快照长度(您称之为“packetSize”` ) 设置为一个足够大的值,以便仅捕获以太网 header 和 IPv4 和 IPv6 的 IP 地址。对于 IPv4,34 个字节就足够了(libpcap 或 BPF 可能会将其四舍五入到更大的值),因为这是 14 个字节的以太网 header + 20 个字节的 IPv4 header ,没有选项。对于 IPv6,它是 54 个字节,对于 14 个字节的以太网 header 和 40 个字节的 IPv6 header 。所以使用 54 的 packetSize 值。
请注意,在这种情况下,您应该使用 struct pcap_pkthdr 的
,计算数据包长度。 len
字段,不是 caplen
字段caplen
是捕获的数据量,不会大于指定的快照长度; len
是“线上”的长度。
此外,您可能想尝试在同一个线程中运行 pcap_loop() 和所有处理,并避免为数据包数据分配缓冲区并复制它,以查看那是否加快了处理速度向上。如果您必须在单独的线程中执行它们,请确保在完成后释放数据包数据。
关于c++ - 用pcap抓图跟不上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12234533/
我有一个下拉菜单,我希望在下拉菜单打开和关闭时显示按比例缩小的动画。我有一个 CODEPEN here带有供您试验的代码。 我将它减慢到 10 秒的动画(显然不是最终速度)只是为了让你明白我的意思。这
我是一名优秀的程序员,十分优秀!