
我试图在同一台机器上使用我自己的自定义协议ID在PF_SOCKET上发送和接收types为SOCK_RAW数据包。 这是我的发件人和收件人示例代码 –
sender.c
#include<sys/socket.h> #include<linux/if_packet.h> #include<linux/if_ether.h> #include<linux/if_arp.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #define CUSTOM_PROTO 0xB588 int main () { int sockfd = -1; struct sockaddr_ll dest_addr = {0},src_addr={0}; char *buffer = NulL; struct ethhdr *eh; sockfd = socket(PF_PACKET,SOCK_RAW,htons(CUSTOM_PROTO) ); if ( sockfd == -1 ) { perror("socket"); return -1; } buffer = malloc(1518); eh = (struct ethhdr *)buffer; dest_addr.sll_ifindex = if_nametoindex("eth0"); dest_addr.sll_addr[0] = 0x0; dest_addr.sll_addr[1] = 0xc; dest_addr.sll_addr[2] = 0x29; dest_addr.sll_addr[3] = 0x49; dest_addr.sll_addr[4] = 0x3f; dest_addr.sll_addr[5] = 0x5b; dest_addr.sll_addr[6] = 0x0; dest_addr.sll_addr[7] = 0x0; //other host MAC address unsigned char dest_mac[6] = {0x0,0xc,0x29,0x49,0x3f,0x5b}; /*set the frame header*/ memcpy((voID*)buffer,(voID*)dest_mac,ETH_ALEN); memcpy((voID*)(buffer+ETH_ALEN),ETH_ALEN); eh->h_proto = htons(PAVAN_PROTO); memcpy((voID*)(buffer+ETH_ALEN+ETH_ALEN + 2),"Pavan",6 ); int send = sendto(sockfd,buffer,1514,(struct sockaddr*)&dest_addr,sizeof(dest_addr) ); if ( send == -1 ) { perror("sendto"); return -1; } return 0; }
receiver.c
#include<sys/socket.h> #include<linux/if_packet.h> #include<linux/if_ether.h> #include<linux/if_arp.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #define CUSTOM_PROTO 0xB588 int main () { int sockfd = -1; struct sockaddr_ll dest_addr = {0},src_addr={0}; char *recvbuf = malloc(1514); sockfd = socket(PF_PACKET,htons(CUSTOM_PROTO) ); if ( sockfd == -1 ) { perror("socket"); return -1; } int len = recvfrom(sockfd,recvbuf,NulL,NulL); printf("I received: n"); return 0; }
发件人和收件人都在Ubuntu VirtualBox上运行。 问题是接收机挂在recvfrom 。 但是在receiver.c ,如果我把htons(CUSTOM_PROTO) htons(ETH_P_ALL) ,接收器工作的很好。
使用非pipe理员帐户的windows pgm套接字访问错误
TCP堆栈是否在现有连接上发送未经请求的RST?
linux套接字内核缓冲区是否交换到磁盘?
接收到FIN数据包时,套接字接收stream是否closures?
find一个linux套接字的原始拥有过程
为什么内核没有将自定义协议ID的数据包传递给我的自定义协议ID套接字?
我在GDB中valIDation过,当我用htons(ETH_P_ALL)接收数据包htons(ETH_P_ALL)
更新:如果我select本地回环lo和MAC地址00:00:00:00:00:00 ,而不是eth0接口和它的相应MAC地址, CUSTOM_PROTO就可以正常工作!
更新2如果发件人和收件人在不同的机器上, CUSTOM_PROTO可以正常工作。 这个发现和prev更新让我怀疑在eth0上发送的数据包没有被同一台机器接收到。 但是ETH_P_ALL在同一台机器上工作的事实驳斥了我的怀疑。
如何在linux中使用gethostbyname_r
linux和windows套接字编程中的INADDR_ANY之间的区别
将Java Socket绑定到每个环回地址
linux *** 作系统。 Sol_NETlink没有定义
winsock:使用本地主机(127.0.0.1)时连接失败,错误10049
ETH_P_ALL与任何其他协议
协议ETH_P_ALL具有捕获传出数据包的特殊作用。
使用任何不等于ETH_P_ALL协议的接收器套接字接收来自设备驱动程序的协议数据包。
带有协议ETH_P_ALL套接字在将传出数据包发送到设备驱动程序和从设备驱动程序接收的所有传入数据包之前接收所有数据包。
环回设备vs以太网设备
发送到回环设备的数据包从该设备出去,然后从设备接收到相同的数据包作为传入。 因此,当CUSTOM_PROTO与回送一起使用时,套接字将捕获具有自定义协议的数据包作为传入。
请注意,如果ETH_P_ALL与回送设备一起使用,则每个数据包都会被接收两次。 一旦被捕获为传出,并且第二次被传入。
在eth0的情况下,数据包从设备传输。 所以,这样的数据包到设备驱动程序,然后可以在物理以太网端口的另一侧看到它们。 例如,使用VirtualBox“Host-only”网络适配器,这些数据包可以被主机系统中的一些嗅探器捕获。
但是,传输到物理端口(或其仿真)的数据包不会重定向到该端口。 所以,他们没有收到来自设备的传入。 这就是为什么这样的数据包只能通过ETH_P_ALL在传出方向捕获,而在传入方向上不能被CUSTOM_PROTO ETH_P_ALL 。
从技术上讲,应该可以准备特殊设置来做外部数据包回送(来自设备端口的数据包应该被发送回该端口)。 在这种情况下,行为应该类似于回送设备。
内核实现
查看内核文件net/core/dev.c 有两个不同的列表:
struct List_head ptype_base[PTYPE_HASH_SIZE] __read_mostly; struct List_head ptype_all __read_mostly; /* Taps */
列表ptype_all用于协议ETH_P_ALL套接口处理程序。 列表ptype_base用于具有正常协议的处理程序。
从dev_hard_start_xmit()调用的dev_hard_start_xmit()有一个传出包的挂钩:
if (!List_empty(&ptype_all)) dev_queue_xmit_nit(skb,dev);
对于传出数据包, dev_queue_xmit_nit()函数dev_queue_xmit_nit()来处理每个ETH_P_ALL每个项目的ptype_all 。 最后,带有协议ETH_P_ALL的类型为AF_SOCKET的套接字捕获该输出分组。
所以,观察到的行为与任何自定义协议都没有关系。 ETH_P_IP可以观察到相同的行为。 在这种情况下,接收方能够捕获所有传入的IP数据包,但是它不能捕获sender.c从"eth0"发送到"eth0"设备的MAC地址的IP数据包。
它也可以被tcpdump看到。 如果使用只捕获传入数据包的选项调用tcpdump (不同版本的tcpdump使用不同的命令行参数来启用此类过滤),则不捕获发送方发送的数据包。
在同一台机器上需要通过协议ID区分数据包的初始任务可以使用ETH_P_ALL来解决。 接收机应该捕获所有数据包并检查协议,例如:
while (1) { int len = recvfrom(sockfd,NulL); if (ntohs(*(uint16_t*)(recvbuf + ETH_ALEN + ETH_ALEN)) == CUSTOM_PROTO) { printf("I received: n"); break; } }
有用的参考“kernel_flow”与一个很好的图http://img.zgserver.com/c/Network_data_flow_through_kernel.png
它基于2.6.20内核,但在现代内核中, ETH_P_ALL以相同的方式处理。
总结以上是内存溢出为你收集整理的数据包套接字未接收自定义协议ID的数据全部内容,希望文章能够帮你解决数据包套接字未接收自定义协议ID的数据所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)