如何解决无法在 MacOS 中接收 GRE 数据包
我想在MacOS上实现PPTP客户端时,我电脑的PPTP服务器收不到GRE包中封装的LCP包,操作系统是Catalina 10.15.2。
这是我用 C 编写的代码。
int ppp_fd;
if ((ppp_fd = socket(AF_INET,SOCK_RAW,IPPROTO_GRE)) <= 0)
{
perror("[Error] Create a new socket failed");
return;
}
struct sockaddr_in recv;
recv.sin_addr.s_addr = htonl(INADDR_ANY);
recv.sin_port = 0;
recv.sin_family = AF_INET;
char buffer[BUFSIZ];
int ret;
int addr_len = sizeof(recv);
if((ret = recvfrom(ppp_fd,buffer,BUFSIZ,(struct sockaddr *)&recv,(socklen_t *)&addr_len)) < 0)
{
perror("[ERROR] Receive data failed");
return;
}
printf("ret: %d\n",ret);
Wireshark 可以正确捕获配置请求,但是代码似乎被阻塞并且什么也不打印。
解决方法
好吧,也许我们在MacOS中无法通过raw socket正常接收数据,但是Wireshark、tcpdump等软件可以捕获流量。因此,要解决上述问题,只需按照以下几个步骤操作即可。
- 使用 brew 等软件管理器安装 libpcap。
- 在源文件中包含头文件
#include<pcap/pcap.h>
。 - 举个简单的例子如下:
#include <stdio.h>
#include <pcap/pcap.h>
void get_packet_cb(u_char *arg,const struct pcap_pkthdr *pkthdr,const u_char *packet)
{
printf("Packet length: %d\n",pkthdr->len);
}
int main()
{
char err_msg[PCAP_ERRBUF_SIZE] = {0};
pcap_t *pcap_handler = pcap_open_live("vmnet8",65535,1,100,err_msg);
if(pcap_handler == NULL){
printf("[ERROR] %s\n",err_msg);
return (-1);
}
struct bpf_program filter;
if(pcap_compile(pcap_handler,&filter,"ip proto gre",0) == -1){
pcap_perror(pcap_handler,"[ERROR] Compile the expression of filter failed");
goto _close;
}
pcap_setfilter(pcap_handler,&filter);
int id = 0;
pcap_loop(pcap_handler,-1,get_packet_cb,NULL);
_close:pcap_close(pcap_handler);
return 0;
}
- 在终端中输入命令行
gcc source_name.c -lpcap -o output_name
进行编译和链接。
实际上,MacOS 中的许多协议无法正确接收,在我的实践中,至少 ICMP 数据报可以做到这一点。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。