Sockets 无法接收我刚刚发送的原始以太网帧数据包
我在本网站上引用了C代码: 下面是一张图片来解释: 我将其分为两部分进行编辑,一部分用于ethertype(将0x0800更改为自定义协议0x1234) 另一部分是删除用于IP报头处理的代码(因为原始代码基于IP,但我需要一个原始以太网帧) 我使用wireshark检测数据包,我可以接收我发送的数据包(在图像的左侧),我可以看到send.out正在发送数据包(图像的右下角)。但是recv.out无法接收数据包!?(图像右上角) 但是,如果我使用0x0800作为协议,recv.out可以从外部接收数据包,但仍然无法接收我发送的数据包 设置插座有错误吗 这是我的密码: 发送Sockets 无法接收我刚刚发送的原始以太网帧数据包,sockets,frame,ethernet,Sockets,Frame,Ethernet,我在本网站上引用了C代码: 下面是一张图片来解释: 我将其分为两部分进行编辑,一部分用于ethertype(将0x0800更改为自定义协议0x1234) 另一部分是删除用于IP报头处理的代码(因为原始代码基于IP,但我需要一个原始以太网帧) 我使用wireshark检测数据包,我可以接收我发送的数据包(在图像的左侧),我可以看到send.out正在发送数据包(图像的右下角)。但是recv.out无法接收数据包!?(图像右上角) 但是,如果我使用0x0800作为协议,recv.out可以从外部接
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#define MY_DEST_MAC0 0xbc
#define MY_DEST_MAC1 0xee
#define MY_DEST_MAC2 0x7b
#define MY_DEST_MAC3 0x75
#define MY_DEST_MAC4 0x56
#define MY_DEST_MAC5 0x2a
#define DEFAULT_IF "eth0"
#define BUF_SIZ 1024
int main(int argc, char *argv[])
{
int sockfd;
struct ifreq if_idx;
struct ifreq if_mac;
int tx_len = 0;
char sendbuf[BUF_SIZ];
struct ether_header *eh = (struct ether_header *) sendbuf; /*structure*/
struct iphdr *iph = (struct iphdr *) (sendbuf + sizeof(struct ether_header));
struct sockaddr_ll socket_address;
char ifName[IFNAMSIZ];
unsigned short proto = 0x1234;
/* Get interface name *//*eth0*/
if (argc > 1)
strcpy(ifName, argv[1]);
else
strcpy(ifName, DEFAULT_IF);
/* Open RAW socket to send on *//*IPv4*/
if ((sockfd = socket(AF_PACKET, SOCK_RAW, htons(proto))) == -1) {
perror("socket");
}
/* Get the index of the interface to send on *//*0*/
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)/*save INDEX info into if_idx*/
perror("SIOCGIFINDEX");
/* Get the MAC address of the interface to send on *//*local*//*save MAC info into if_mac*/
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror("SIOCGIFHWADDR");
/* Construct the Ethernet header */
memset(sendbuf, 0, BUF_SIZ);
/* Ethernet header */
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = MY_DEST_MAC0;
eh->ether_dhost[1] = MY_DEST_MAC1;
eh->ether_dhost[2] = MY_DEST_MAC2;
eh->ether_dhost[3] = MY_DEST_MAC3;
eh->ether_dhost[4] = MY_DEST_MAC4;
eh->ether_dhost[5] = MY_DEST_MAC5;
/* Ethertype field */
eh->ether_type = htons(proto);
tx_len += sizeof(struct ether_header);
/* Packet data */
sendbuf[tx_len++] = "h";
sendbuf[tx_len++] = "e";
sendbuf[tx_len++] = "l";
sendbuf[tx_len++] = "l";
sendbuf[tx_len++] = "o";
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_addr[0] = MY_DEST_MAC0;
socket_address.sll_addr[1] = MY_DEST_MAC1;
socket_address.sll_addr[2] = MY_DEST_MAC2;
socket_address.sll_addr[3] = MY_DEST_MAC3;
socket_address.sll_addr[4] = MY_DEST_MAC4;
socket_address.sll_addr[5] = MY_DEST_MAC5;
/* Send packet */
int cnt=0;
while(cnt<5){
if (sendto(sockfd, sendbuf, tx_len, 0, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) < 0)
printf("Send failed\n");
else
printf("success!\n");
cnt++;
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义我的目标MAC0 0xbc
#定义我的目标MAC1 0xee
#定义我的目标MAC2 0x7b
#定义我的目标MAC3 0x75
#定义我的目标MAC4 0x56
#定义我的目标MAC5 0x2a
#如果“eth0”,则定义默认值
#定义基本尺寸1024
int main(int argc,char*argv[])
{
int-sockfd;
结构ifreq if_idx;
结构ifreq if_mac;
int tx_len=0;
char sendbuf[BUF_SIZ];
结构以太标头*eh=(结构以太标头*)sendbuf;/*结构*/
结构iphdr*iph=(结构iphdr*)(sendbuf+sizeof(结构ether_头));
结构sockaddr\u ll套接字地址;
字符ifName[IFNAMSIZ];
无符号短proto=0x1234;
/*获取接口名称*/*eth0*/
如果(argc>1)
strcpy(ifName,argv[1]);
其他的
strcpy(ifName,默认值\u IF);
/*打开原始套接字以在*/*IPv4上发送*/
if((sockfd=socket(AF_数据包,SOCK_原始,htons(proto)))=-1){
佩罗(“插座”);
}
/*获取要在*/*0上发送的接口的索引*/
memset(&if_idx,0,sizeof(struct ifreq));
strncpy(如果为idx.ifr\U名称、ifName、IFNAMSIZ-1);
if(ioctl(sockfd、SIOCGIFINDEX和if_idx)<0)/*将索引信息保存到if_idx中*/
perror(“SIOCGIFINDEX”);
/*获取要在*/*本地*//*上发送的接口的MAC地址将MAC信息保存到if\U MAC中*/
memset(&if_mac,0,sizeof(struct ifreq));
strncpy(如果mac.ifr\U名称、ifName、IFNAMSIZ-1);
if(ioctl(sockfd、SIOCGIFHWADDR和if_mac)<0)
perror(“SIOCGIFHWADDR”);
/*构造以太网报头*/
memset(sendbuf,0,BUF_SIZ);
/*以太网报头*/
eh->ether_shost[0]=((uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[0];
eh->ether_shost[1]=(uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[1];
eh->ether_shost[2]=(uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[2];
eh->ether_shost[3]=(uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[3];
eh->ether_shost[4]=((uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[4];
eh->ether_shost[5]=((uint8_t*)和if_mac.ifr_hwaddr.sa_数据)[5];
eh->ether\u dhost[0]=我的目的地0;
eh->ether\u dhost[1]=我的目的地1;
eh->ether\u dhost[2]=我的目的地2;
eh->ether\u dhost[3]=我的目的地3;
eh->ether\u dhost[4]=我的目的地4;
eh->ether\u dhost[5]=我的目的地5;
/*醚型场*/
eh->乙醚类型=htons(原型);
tx_len+=sizeof(结构以太网头);
/*分组数据*/
sendbuf[tx_len++]=“h”;
sendbuf[tx_len++]=“e”;
sendbuf[tx_len++]=“l”;
sendbuf[tx_len++]=“l”;
sendbuf[tx_len++]=“o”;
/*网络设备的索引*/
socket\u address.sll\u ifindex=if\u idx.ifr\u ifindex;
/*地址长度*/
socket_address.sll_halen=ETH_ALEN;
/*目的地MAC*/
socket\u address.sll\u addr[0]=MY\u DEST\u MAC0;
socket\u address.sll\u addr[1]=我的目的地MAC1;
socket\u address.sll\u addr[2]=MY\u DEST\u MAC2;
socket\u address.sll\u addr[3]=MY\u DEST\u MAC3;
socket\u address.sll\u addr[4]=我的目的地MAC4;
socket\u address.sll\u addr[5]=我的目的地MAC5;
/*发送数据包*/
int-cnt=0;
while(cnt1)
strcpy(ifName,argv[1]);
其他的
strcpy(ifName,默认值\u IF);
/*标题结构*/
结构以太单元头*eh=(结构以太单元头*)buf;
/*打开PF_数据包套接字,侦听EtherType ETHER_TYPE*/*0x1234*/
if((sockfd=socket(PF_数据包,SOCK_原始,htons(以太类型)))=-1){
perror(“侦听器:套接字”);
返回-1;
}
/*将接口设置为混杂模式-我们是否每次都需要这样做?*/*将ifname转换为ifr_name*/
strncpy(ifopts.ifr_名称、ifName、IFNAMSIZ-1);
ioctl(sockfd、SIOCGIFFLAGS和ifopts);/*设置混杂模式*/
ifopts.ifr_flags |=IFF_PROMISC;
ioctl(sockfd、SIOCSIFFLAGS和ifopts);
/*允许重新使用插座-以防连接过早关闭*/
if(setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&sockopt,sizeof sockopt)=-1){
perror(“setsockopt”);
关闭(sockfd);
退出(退出失败);
}
/*绑定到设备*/
if(setsockopt(sockfd、SOL_SOCKET、SO_BINDTODEVICE、ifName、IFNAMSIZ-1)=-1){
perror(“SO_BINDTODEVICE”);
关闭(sockfd);
退出(退出失败);
}
重复:printf(“侦听器:正在等待接收来自…\n”);
numbytes=recvfrom(sockfd,buf,buf_SIZ,0,NULL,NULL);
printf(“侦听器:获取数据包%lu字节\n”,numbytes);
/*检查一下这个包是给我的*/
如果(eh->ether\u dhost[0]==DEST\u MAC0&&
eh->乙醚成本[1]==DEST\u MAC1&&
eh->乙醚成本[2]==DEST\u MAC2&&
eh->乙醚成本[3]==DEST\u MAC3&&
eh->乙醚成本[4]==DEST\u MAC4&&
eh->乙醚成本[5]==DEST\u MAC5){
printf(“正确的目标MAC地址\n”);
}否则{
printf(“错误的目标MAC:%x:%x:%x:%x:%x:%x:%x\n”,
eh->乙醚成本[0],
eh->乙醚成本[1],
eh->乙醚成本[2],
eh->乙醚成本[3],
eh->乙醚成本[4],
eh->ether_dhost[5]);
ret=-1;
去做;
}
/*打印包*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <linux/ip.h>
#include <linux/udp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/ether.h>
#define DEST_MAC0 0xbc
#define DEST_MAC1 0xee
#define DEST_MAC2 0x7b
#define DEST_MAC3 0x75
#define DEST_MAC4 0x56
#define DEST_MAC5 0x2a
#define ETHER_TYPE 0x1234
#define DEFAULT_IF "eth0"
#define BUF_SIZ 1024
int main(int argc, char *argv[])
{
char sender[INET6_ADDRSTRLEN];
int sockfd, ret, i;
int sockopt;
ssize_t numbytes;
struct ifreq ifopts; /* set promiscuous mode */
struct sockaddr_storage their_addr;
uint8_t buf[BUF_SIZ];
char ifName[IFNAMSIZ];
/* Get interface name *//*eth0*/
if (argc > 1)
strcpy(ifName, argv[1]);
else
strcpy(ifName, DEFAULT_IF);
/* Header structures */
struct ether_header *eh = (struct ether_header *) buf;
/* Open PF_PACKET socket, listening for EtherType ETHER_TYPE *//*0x1234*/
if ((sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETHER_TYPE))) == -1) {
perror("listener: socket");
return -1;
}
/* Set interface to promiscuous mode - do we need to do this every time? *//*cpy ifname into ifr_name*/
strncpy(ifopts.ifr_name, ifName, IFNAMSIZ-1);
ioctl(sockfd, SIOCGIFFLAGS, &ifopts); /*set promisc mode*/
ifopts.ifr_flags |= IFF_PROMISC;
ioctl(sockfd, SIOCSIFFLAGS, &ifopts);
/* Allow the socket to be reused - incase connection is closed prematurely */
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof sockopt) == -1) {
perror("setsockopt");
close(sockfd);
exit(EXIT_FAILURE);
}
/* Bind to device */
if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE, ifName, IFNAMSIZ-1) == -1) {
perror("SO_BINDTODEVICE");
close(sockfd);
exit(EXIT_FAILURE);
}
repeat: printf("listener: Waiting to recvfrom...\n");
numbytes = recvfrom(sockfd, buf, BUF_SIZ, 0, NULL, NULL);
printf("listener: got packet %lu bytes\n", numbytes);
/* Check the packet is for me */
if (eh->ether_dhost[0] == DEST_MAC0 &&
eh->ether_dhost[1] == DEST_MAC1 &&
eh->ether_dhost[2] == DEST_MAC2 &&
eh->ether_dhost[3] == DEST_MAC3 &&
eh->ether_dhost[4] == DEST_MAC4 &&
eh->ether_dhost[5] == DEST_MAC5) {
printf("Correct destination MAC address\n");
} else {
printf("Wrong destination MAC: %x:%x:%x:%x:%x:%x\n",
eh->ether_dhost[0],
eh->ether_dhost[1],
eh->ether_dhost[2],
eh->ether_dhost[3],
eh->ether_dhost[4],
eh->ether_dhost[5]);
ret = -1;
goto done;
}
/* Print packet */
printf("\tData:");
for (i=0; i<numbytes; i++) printf("%02x:", buf[i]);
printf("\n");
done: goto repeat;
close(sockfd);
return ret;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>
union ethframe
{
struct
{
struct ethhdr header;
unsigned char data[ETH_DATA_LEN];
} field;
unsigned char buffer[ETH_FRAME_LEN];
};
int main(int argc, char **argv) {
char *iface = "eth1";
unsigned char dest[ETH_ALEN]
= { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned short proto = 0x1234;
int recv_result,i;
char buff[ETH_FRAME_LEN];
unsigned short data_len;
int s;
if ((s = socket(AF_PACKET, SOCK_RAW, htons(proto))) < 0) {
printf("Error: could not open socket\n");
return -1;
}
struct ifreq buffer;
int ifindex;
memset(&buffer, 0x00, sizeof(buffer));
strncpy(buffer.ifr_name, iface, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, &buffer) < 0) {
printf("Error: could not get interface index\n");
close(s);
return -1;
}
ifindex = buffer.ifr_ifindex;
unsigned char source[ETH_ALEN];
if (ioctl(s, SIOCGIFHWADDR, &buffer) < 0) {
printf("Error: could not get interface address\n");
close(s);
return -1;
}
memcpy((void*)source, (void*)(buffer.ifr_hwaddr.sa_data),
ETH_ALEN);
struct sockaddr_ll saddrll;
memset((void*)&saddrll, 0, sizeof(saddrll));
saddrll.sll_family = PF_PACKET;
saddrll.sll_ifindex = ifindex;
saddrll.sll_halen = ETH_ALEN;
memcpy((void*)(saddrll.sll_addr), (void*)dest, ETH_ALEN);
socklen_t sll_len = (socklen_t)sizeof(saddrll);
if (recv_result = recvfrom(s, buff, ETH_FRAME_LEN, 0,
(struct sockaddr *)&saddrll, &sll_len) > 0)
printf("Success!\n");
else
printf("Error, could not send\n");
data_len=sizeof(buff);
printf("\tData:");
for (i=0; i<data_len; i++) printf("%c", buff[i]);
printf("\tDone: \n");
close(s);
return 0;
}