首先,我對以太網和數據鏈路層的主題相當陌生,我試圖編寫一個C程序,它允許發送和接收以太網幀。執行發送和接收原始以太網幀的C程序的問題
我想讓我的程序發送以太網幀給自己,所以程序將有相同的源和目標MAC地址。
,我正在使用的程序是從http://hacked10bits.blogspot.com/2011/12/sending-raw-ethernet-frames-in-6-easy.html
我一直有與recvfrom的()函數故障代碼的修改版本,它似乎只是阻止該程序不會終止。從代碼中,我嘗試發送以太網幀並使recvfrom()函數能夠檢索幀並將其存儲在緩衝區中。但是因爲recvfrom()函數只是阻塞,所以在我看來,sendto()函數無法成功發送幀。
任何想法我怎麼能解決這個問題?
這裏是我的代碼:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h> /* Must precede if*.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 = "eth0";
unsigned char dest[ETH_ALEN]
= { 0x00, 0x12, 0x34, 0x56, 0x78, 0x90 };
unsigned short proto = 0x1234;
unsigned char *data = "hello world";
unsigned short data_len = strlen(data);
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);
//edited part... here we have it so that the destination mac address is
//the same as the source mac address
memcpy((void*)dest, (void*)(buffer.ifr_hwaddr.sa_data),
ETH_ALEN);
//probe source mac address
int k;
for(k = 0; k !=ETH_ALEN; k++)
{
printf("%x\n",source[k]);
printf("%x\n",dest[k]);
}
union ethframe frame;
memcpy(frame.field.header.h_dest, dest, ETH_ALEN);
memcpy(frame.field.header.h_source, source, ETH_ALEN);
frame.field.header.h_proto = htons(proto);
memcpy(frame.field.data, data, data_len);
unsigned int frame_len = data_len + ETH_HLEN;
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);
if (sendto(s, frame.buffer, frame_len, 0,
(struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)
printf("Frame successfully sent!\n");
else
printf("Error, could not send\n");
struct sockaddr_ll saddrll_receive;
memset((void*)&saddrll_receive, 0, sizeof(saddrll_receive));
socklen_t sll_len = (socklen_t)sizeof(saddrll_receive);
int recv_result;
char buffer_receive[ETH_FRAME_LEN];
recv_result = recvfrom(s, buffer_receive, ETH_FRAME_LEN, 0,
(struct sockaddr*)&saddrll_receive, &sll_len);
close(s);
return 0;
}
當然,這是一臺Linux機器上。
我知道這是一箇舊的線程,但嘿..它可能有可能你的框架形成,甚至傳輸,但在你的操作系統的驅動程序不夠聰明,'包裝'框架回來;據它所知,它是外向的,就是這樣。如果您有連接到端口的交換機,交換機可能會爲您反彈。 – JustJeff