本文介绍了使用的setsockopt()系统与设备绑定原始套接字是不是在Fedora Core 6个工作(2.6.18-1.2798.fc6)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
请任何一个能帮助解决这一问题。请
在下面的示例code,我们与绑定的eth0生袜子。但在运行该程序
原料袜子recvfrom的接收距离为eth0和放包; eth1的同一台机器(xx_86)上。
这是我不清楚为什么,可以帮助人们在这个问题上。
我希望setsockopt的工作不正常
操作系统:Fedora的核心6(2.6.18-1.2798.fc6)
SAMPE code:
的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&errno.h中GT;
#包括LT&;&unistd.h中GT;
#包括LT&; SYS / socket.h中>
#包括LT&; netinet / in.h中>
#包括LT&; Linux的/ if_ether.h>
#包括LT&;净/ if.h中>
#包括LT&; Linux的/ filter.h>
#包括LT&; SYS / ioctl.h>
#包括LT&;&string.h中GT;
#包括LT&; ARPA / inet.h>INT主(INT ARGC,字符** argv的){
INT袜子,我;
无符号字符缓冲区[2048];
unsigned char型tbuff [2048];
无符号字符* iphead,* ethhead,* PHEAD;
结构的ifreq ethreq;//注意:使用TCPDUMP来构建滤波器阵列。
//设置过滤器来嗅探端口仅443
// $ sudo的tcpdump的-dd端口443//为原料的eth0 recvfrom的如果((袜子=插座(PF_PACKET,SOCK_RAW,htons(ETH_P_IP)))== -1){
PERROR(插座);
出口(1);
}
//设置网卡promiscuos
函数strncpy(ethreq.ifr_name,eth0的,IFNAMSIZ);
如果(的ioctl(袜子,SIOCGIFFLAGS,&安培; ethreq)== -1){
PERROR(的ioctl);
关闭(袜子);
出口(1);
}
ethreq.ifr_flags | = IFF_PROMISC;
如果(的ioctl(袜子,SIOCSIFFLAGS,&安培; ethreq)== -1){
PERROR(的ioctl);
关闭(袜子);
出口(1);
}//绑定为eth0袜子 结构的ifreq接口;
memset的(安培;接口,0,sizeof的(接口));
函数strncpy(Interface.ifr_ifrn.ifrn_name,eth0的,IFNAMSIZ);
如果(setsockopt的(袜子,SOL_SOCKET,SO_BINDTODEVICE,&安培;接口方面,的sizeof(接口))小于0){接近(袜子); }
//打开SENDTO RAW套接 INT S =插座(PF_INET,SOCK_RAW,IPPROTO_RAW); 结构SOCKADDR_IN罪。
memset的(安培;罪,0,sizeof的(罪));
sin.sin_family = AF_INET;
sin.sin_port = htons(0);
sin.sin_addr.s_addr = inet_addr(10.3.161.104); //通知籽粒不填IP和传输首 诠释1 = 1;
const int的* VAL =安培;之一;
如果(setsockopt的(S,IPPROTO_IP,IP_HDRINCL,缬氨酸,的sizeof(一个))小于0)
的printf(警告:不能设置HDRINCL \\ n!); //绑定eth0的袜子描述 结构的ifreq接口1;
memset的(安培;接口1,0,sizeof的(接口1));
函数strncpy(Interface1.ifr_ifrn.ifrn_name,eth0的,IFNAMSIZ);
如果(setsockopt的(S,SOL_SOCKET,SO_BINDTODEVICE,&放大器;接口1,sizeof的(接口1))≤; 0){关闭(多个); }
而(1){
的printf(---------------------- \\ n);
I = recvfrom的(袜子,缓冲器,的sizeof(缓冲液),0,NULL,NULL);
的printf(%d字节读\\ N,I); //检查头大小:以太网= 14,IP = 20,TCP = 8(总和= 42)
如果(ⅰ&下; 42){
PERROR(recvfrom的());
的printf(不完整的数据包(错误为%d)\\ n,错误号);
关闭(袜子);
出口(0);
} PHEAD =缓冲区+ 14; //(跳过以太网帧头)
的memcpy(tbuff,PHEAD,I-14);
iphead = tbuff;
如果(* iphead ==×45){
INT ptrindex = iphead [9];
开关(ptrindex){ 情况1:
的printf(运输通讯协定是:ICMP \\ n);
打破;
案例2:
的printf(运输protol是:IGMP \\ n);
打破;
情况6:
的printf(传输协议是:TCP \\ n);
打破;
案例17:
的printf(传输协议是:UDP \\ n);
打破;
案例103:
的printf(传输协议是:PIM \\ n);
打破;
默认:
的printf(传输协议为:%d个\\ N,iphead [9]);
}
//的printf(%d个,* ptrindex);
//的printf(\\ n传输协议是:%U \\ N,iphead [9]);
的printf(源地址:%D%D,端口:%d个\\ N,
iphead [12],iphead [13],iphead [14],iphead [15],(iphead [20]&下;&下; 8)+ iphead [21]);
的printf(目的地地址:。。%D%D,端口数:%d \\ n,
iphead [16],iphead [17],iphead [18],iphead [19],(iphead [22]&下;&下; 8)+ iphead [23]);
如果(SENDTO(S,tbuff,I-14,0,(结构sockaddr *)及罪的sizeof(罪))小于0)
的printf(错误。\\ n); 其他{printf的(\\ n该接收的数据包被发送\\ n);} memset的(缓冲液,0,sizeof的(缓冲液));
memset的(tbuff,0,sizeof的(tbuff)); }
其他{printf的(非IP收到了);} }
关闭(袜子);
}
解决方案
在Linux手册页(http://linux.die.net/man/7/socket):
So, try the bind instead.
这篇关于使用的setsockopt()系统与设备绑定原始套接字是不是在Fedora Core 6个工作(2.6.18-1.2798.fc6)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!