如何在混杂模式下打开原始UDP套接字?

如何在混杂模式下打开原始UDP套接字?,udp,c,linux,sockets,network-programming,raw-sockets,Udp,C,Linux,Sockets,Network Programming,Raw Sockets,我正试图打开一个原始套接字来处理流量。我需要它是混乱的。我看了很多资料,但我完全糊涂了。 这是我的密码: char interface_name[12]; strcpy(interface_name, "eth1"); sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); if ( sd == -1 ) { perror("error in opening socket."); return; } if ( setsockopt(sd, SO

我正试图打开一个原始套接字来处理流量。我需要它是混乱的。我看了很多资料,但我完全糊涂了。 这是我的密码:

char interface_name[12];
strcpy(interface_name, "eth1");
sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
if ( sd == -1 ) {
    perror("error in opening socket.");
    return;
}

if ( setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, interface_name, strlen(interface_name)) == -1 )
{
    perror("error in binding sd.");
    return;
}
int one = 1;
if ( setsockopt (sd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0)
{
    perror("error in setting HDRINCL.");
    return;
}
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, interface_name);
if (ioctl(sd, SIOCGIFINDEX, &ifr) < 0) {
    perror("ioctl(SIOCGIFINDEX) failed");
    return;
}
int interface_index = ifr.ifr_ifindex;
ifr.ifr_flags |= IFF_PROMISC;
if( ioctl(sd, SIOCSIFFLAGS, &ifr) != 0 )
{
    perror("ioctl for IFF_PROMISC failed.");
    return;
}
struct packet_mreq mr;
memset(&mr, 0, sizeof(mr));
mr.mr_ifindex = interface_index;
mr.mr_type = PACKET_MR_PROMISC;

if (setsockopt(sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) < 0) {
    perror("setsockopt(PACKET_MR_PROMISC) failed");
    return 1;
}
char接口_名称[12];
strcpy(接口名称“eth1”);
sd=插座(AF_INET、SOCK_RAW、IPPROTO_UDP);
如果(sd==-1){
perror(“打开套接字时出错”);
回来
}
if(setsockopt(sd,SOL_SOCKET,SO_BINDTODEVICE,interface_name,strlen(interface_name))=-1)
{
perror(“绑定sd时出错”);
回来
}
int-one=1;
如果(设置锁定选项(sd、IPPROTO_IP、IP_HDRINCL和一个,大小(一个))<0)
{
perror(“设置HDRINCL时出错”);
回来
}
结构ifreq-ifr;
memset(&ifr,0,sizeof(ifr));
strcpy(ifr.ifr\u名称、接口\u名称);
如果(ioctl(sd、SIOCGIFINDEX和ifr)<0){
perror(“ioctl(SIOCGIFINDEX)失败”);
回来
}
int接口索引=ifr.ifr\U ifindex;
ifr.ifr_flags |=IFF_混杂;
如果(ioctl(sd、SIOCSIFFLAGS和ifr)!=0)
{
perror(“IFF_PROMISC的ioctl失败”);
回来
}
结构包_mreqmr;
memset(&mr,0,sizeof(mr));
mr.mr_iIndex=界面指数;
mr.mr\u type=包\u mr\u PROMISC;
if(setsockopt(sd、SOL_数据包、数据包添加_成员资格和mr、sizeof(mr))<0){
perror(“SetStockopt(数据包\u MR\u PROMISC)失败”);
返回1;
}
最后的
setsockopt()
失败,错误消息为“协议不可用”。

原因可能是什么?有什么建议吗?

这是因为您使用的是只用于套接字的
SOL\u数据包。对于原始
INET
sockets,您不需要该选项。

现在我记得,该部分是从AF_数据包示例中采用的。好啊那么,我如何才能将AF_INET插座设置为混乱模式呢?@Ramazan,但你真的将其设置为插座吗?你不在一个接口上设置它吗(你已经这样做了)?我在没有最后一个setsockopt的情况下尝试过,但这次我无法接收数据包。但是,如果我将套接字更改为数据包套接字,并保留最后的setsockopt,则可以接收数据包。我必须使用数据包插座吗?