Advertisement

linux socket raw发送,使用raw socket发送以太网帧

阅读量:

/*

  • send a raw ethernet frame

*/

#include //memcpy()

#include //strxxx()

#include //close()

#include //socket()

#include //htons()

#include //struct ifreq

#include //ETH_ALEN(6),ETH_HLEN(14),ETH_FRAME_LEN(1514),struct ethhdr

#include //struct sockaddr_ll

#include //ioctl()

union ethframe {

struct {

struct ethhdr header;

char data[ETH_DATA_LEN];

} field;

char buffer[ETH_FRAME_LEN];

};

int main(void)

{

char *iface = "ext1";

char dest[ETH_ALEN] = {0x00, 0x12, 0x34, 0x56, 0x78, 0x90};

short proto = 0x1234;

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;

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;

}

int ifindex;

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(source, buffer.ifr_hwaddr.sa_data, ETH_ALEN);

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(&saddrll, 0, sizeof(saddrll));

saddrll.sll_family = PF_PACKET;

saddrll.sll_ifindex = ifindex;

saddrll.sll_halen = ETH_ALEN;

memcpy(saddrll.sll_addr, dest, ETH_ALEN);

if (sendto(s, frame.buffer, frame_len, 0, (struct sockaddr*)&saddrll, sizeof(saddrll)) > 0)

如果发送到s的frame.buffer中的frame_len个字节,并通过saddrll结构体指针传递给该函数得到的结果大于零,则返回真

printf("Success!\n");

else

printf("Error, could not send\n");

close(s);

return 0;

}

$ gcc -Wall a.c && sudo ./a.out

$ sudo tcpdump -ni ext1 -vv -XX not ip6 and proto not 89

tcpdump: listening on ext1, link-type EN10MB (Ethernet), capture size 262144 bytes

10:07:59.629576 fa:16:3e:d5:0e:e0 > 00:12:34:56:78:90, ethertype Unknown (0x1234), length 25:

0x0000: 0012 3456 7890 fa16 3ed5 0ee0 1234 6865 ..4Vx...>....4he

0x0010: 6c6c 6f20 776f 726c 64 llo.world

^C

1 packet captured

1 packet received by filter

0 packets dropped by kernel

参考

全部评论 (0)

还没有任何评论哟~