Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C中Mac OS X上带libpcap的嗅探器_C_Pcap_Packet Sniffers - Fatal编程技术网

C中Mac OS X上带libpcap的嗅探器

C中Mac OS X上带libpcap的嗅探器,c,pcap,packet-sniffers,C,Pcap,Packet Sniffers,我试图创建自己的嗅探器(只是为了好玩),我在Mac上工作。 我正在使用libpcap,这是一个非常好的嗅探库。所以,我使用了这个简单的嗅探器,它嗅探5个数据包:(它是用C编写的) #包括 #包括“hacking.h” 无效pcap_致命(常量字符*输入失败,常量字符*错误){ printf(“在%s中出现致命错误:%s\n”,在中失败,errbuf); 出口(1); } int main(){ 结构pcap_pkthdr头; const u_char*数据包; 字符errbuf[PCAP_err

我试图创建自己的嗅探器(只是为了好玩),我在Mac上工作。 我正在使用libpcap,这是一个非常好的嗅探库。所以,我使用了这个简单的嗅探器,它嗅探5个数据包:(它是用C编写的)

#包括
#包括“hacking.h”
无效pcap_致命(常量字符*输入失败,常量字符*错误){
printf(“在%s中出现致命错误:%s\n”,在中失败,errbuf);
出口(1);
}
int main(){
结构pcap_pkthdr头;
const u_char*数据包;
字符errbuf[PCAP_errbuf_SIZE];
字符*设备;
pcap_t*pcap_手柄;
int i;
设备=pcap_lookupdev(errbuf);
如果(设备==NULL)
pcap_致命(“pcap_lookupdev”,errbuf);
printf(“在设备%s上嗅探”,设备);
pcap_handle=pcap_open_live(设备,4096,1,0,errbuf);
if(pcap_handle==NULL)
pcap_致命(“pcap_开放_活动”,errbuf);
对于(i=0;i<5;i++){
packet=pcap\u next(pcap\u句柄和报头);
printf(“获取了%d字节的数据包,\n”,header.len);
转储(数据包,报头.len);
}
pcap_关闭(pcap_手柄);
}
如果你想知道的话,是的,我从一本书(黑客:剥削的艺术)中拿了它,并做了一些修改。问题是,如果我在Linux上运行它,它工作得很好,没有问题。但是如果我在Mac上运行它,它就不能工作,也不能捕获任何数据包


你们中有人能帮忙吗?提前谢谢

除了Petesh:有关详细信息,请查看手册页(“终端中的man pcap”)

它说:

在BSD下(包括Mac OS X):

如果您收到“pcap_lookupdev中的致命错误”错误消息,那么问题是Sascha所说的-您没有捕获数据包的权限。如果您收到该消息,请尝试使用
sudo
运行该程序,或者尝试更改/dev/bpf*设备的所有权(您需要使用
sudo
)。但是,您说的是“它在‘en0’上嗅探”,所以您可能是说因为它正在打印“在设备en0上嗅探”,在这种情况下,
pcap\u lookupdev()
不会失败

如果您遇到“pcap\u open\u live中的致命错误”,这也可能是权限问题,但您几乎肯定不会因为那里的权限而出现错误,因为
pcap\u lookupdev()
可能已经失败


如果您没有收到“致命错误”错误消息,那么正如Petesh所指出的,问题可能是您指定了0作为超时。如果将0指定为超时,
pcap\u loop()
pcap\u dispatch()
pcap\u next()
pcap\u next\u ex()
可以在向应用程序提供数据包之前无限期等待;在某些平台上,如Linux和Solaris,它不会无限期等待,但在其他平台上,如*BSD和OS X,它可能无限期等待。尝试1000次超时,即1秒;例如,tcpdump就是这样做的。

我在10.8.4中测试了代码,并将param改为_ms(读取超时)为一些非零值,然后开始接收数据包

谢谢你的基本代码。这节省了我的时间

问候,,
Anand Choubey

它是否打印任何错误消息?你确定你在正确的网络设备上收听吗?是的,我确定。它在“en0”上进行嗅探,en0是正确的设备。您无权访问/dev/bpf*,它是Mac OS X上的嗅探设备。在sudo下运行它,它可能会对您起作用。另一个问题是,pcap_open_live有一个备份缓冲区,在缓冲区填满之前,
pcap_next
可能不会返回。在读取时,您应该使用非零超时(例如1000),并检查是否返回了数据包。我的程序在某些Mac上看到了相同的奇怪行为(它也使用pcap_setfilter,从sudo开始)。在两台Mac电脑上,我的程序运行良好,在另外两台(也是最新的操作系统,也安装了所有更新)上,我没有收到任何数据包。相同的代码,不同的行为。更奇怪的是:如果我并行运行tcpdump,那么tcdump转储数据包,我的程序开始接收数据包。你应该添加一个关于“读取超时”的注释——他可能也遇到了这个问题。事实上,如果你在回答他的问题(你的评论是这样做的),你应该添加这个注释,你应该在回答中这样做,而不是在评论中。
#include <pcap.h>
#include "hacking.h"

void pcap_fatal(const char *failed_in, const char *errbuf) {
     printf("Fatal Error in %s: %s\n", failed_in, errbuf);
     exit(1);
}

int main() {
    struct pcap_pkthdr header;
    const u_char *packet;
    char errbuf[PCAP_ERRBUF_SIZE];
    char *device;
    pcap_t *pcap_handle;
    int i;

device = pcap_lookupdev(errbuf);
if(device == NULL)
    pcap_fatal("pcap_lookupdev", errbuf);

printf("Sniffing on device %s\n", device);

pcap_handle = pcap_open_live(device, 4096, 1, 0, errbuf);
if(pcap_handle == NULL)
    pcap_fatal("pcap_open_live", errbuf);

for(i=0; i < 5; i++) {
    packet = pcap_next(pcap_handle, &header);
    printf("Got a %d byte packet\n", header.len);
    dump(packet, header.len);
}

pcap_close(pcap_handle);

}
          You must have read access to /dev/bpf* on systems that don't have a cloning
          BPF device, or to /dev/bpf on systems that do.  On BSDs with a devfs  (this
          includes  Mac OS X), this might involve more than just having somebody with
          super-user access setting the ownership or permissions on the BPF devices -
          it  might  involve  configuring  devfs  to set the ownership or permissions
          every time the system is booted, if the system even supports  that;  if  it
          doesn't  support  that,  you might have to find some other way to make that
          happen at boot time.