大多数时候,我们要根据需要去发送一些包,这里把发包代码添上,同时处理了头文件的引入。
sys/ioctl.h定义了ioctl函数及其所需要的宏;
arpa/inet.h 中定义了htons,之前htons编译时会有警告,是因为编译时没有找到定义;
netpacket/packet.h中定义了sockaddr 的相关结构体。
运行结果可以通过抓包工具看到,当发现包中写有'hello'时,就是我们的刚刚发的包了,从结果来看,大多数的目标地址是广播地址。
这里介绍两款不错的抓包工具,一个是commview,另一个是wireshark,后者要在属性中新增hardaddressc的源地址和目标地址列。
#include
#include
#include
#include
#include
#include
#include
#include
#include
/**
* Set misc mode for interface
* \param if_name interface name we will set
* \param sockfd the socket id we will set
* \return 0 is success
* */
int set_promisc (char *if_name, int sockfd)
{
struct ifreq ifr;
if (NULL == if_name)
return -1;
strcpy (ifr.ifr_name, if_name);
if (0 != ioctl (sockfd, SIOCGIFFLAGS, &ifr))
{
printf ("Get interface flag failed\n");
return -1;
}
/* add the misc mode */
ifr.ifr_flags |= IFF_PROMISC;
if (0 != ioctl (sockfd, SIOCSIFFLAGS, &ifr))
{
printf ("Set interface flag failed\n");
return -1;
}
return 0;
}
/**
* Send the package
* \param the interface name that we will be send from
* \param the destination mac address
* \return 0 is success
* */
int send_package (char *if_name, char *send_mac)
{
int send_skt;
struct sockaddr_ll s_ll;
struct ifreq ifr;
/* package size must above or equal (14 + 46 + 4) */
char send_buffer[64] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x08, 0x00 };
if (NULL == if_name || NULL == send_mac)
return -1;
/* create send socket */
if ((send_skt = socket (AF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
{
printf ("create send socket failed\n");
return -1;
}
/* get the index of interface */
strcpy (ifr.ifr_name, if_name);
if (0 != ioctl (send_skt, SIOCGIFINDEX, &ifr))
{
printf ("get interface index failed\n");
return -1;
}
s_ll.sll_family = AF_PACKET; /* AF_PACKET is same with PF_PACKET, the
only different maybe A is mean Address,
and P is mean protocol, so here we use
Address to set sock address option */
s_ll.sll_protocol = 0; /* send any protocol packet */
s_ll.sll_ifindex = ifr.ifr_ifindex;
/* push the address and data into the package */
memcpy (send_buffer, send_mac, 6);
memcpy (send_buffer + 14, "hello", 5);
/* bind the sock handle to the interface by index */
if (0 != bind (send_skt, (struct sockaddr *) &s_ll, sizeof (s_ll)))
{
printf ("bind the send sockfd to interface failed\n");
return -1;
}
/* send buffer, it will be return buffer length that we have send */
if (send (send_skt, send_buffer, sizeof (send_buffer), 0) < 0)
{
printf ("send package failed\n");
return -1;
}
return 0;
}
int main (int argc, char *argv[])
{
int sockfd;
int ret = 0;
char buffer[1518] = {0};
char *eth_head = NULL;
char send_mac[6] = {0};
if ((sockfd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
{
printf ("create socket failed\n");
return -1;
}
if (0 != set_promisc ("eth0", sockfd))
{
printf ("Failed to set interface promisc mode\n");
}
while (1)
{
memset (buffer, 0x0, sizeof (buffer));
ret = recvfrom (sockfd, buffer, sizeof (buffer), 0, NULL, NULL);
printf ("recview package length : %d\n", ret);
eth_head = buffer;
printf ("PACKAGE START\n");
/* get source and dectination mac address */
printf ("dectination mac:%02x-%02x-%02x-%02x-%02x-%02x,"
"source mac:%02x-%02x-%02x-%02x-%02x-%02x;\n", eth_head[0],
eth_head[1], eth_head[2], eth_head[3], eth_head[4],
eth_head[5], eth_head[6], eth_head[7], eth_head[8],
eth_head[9], eth_head[10], eth_head[11]);
printf ("eth_type:%02x%02x\n", eth_head[12], eth_head[13]);
/* ARP protocol flag */
if (0x08 == eth_head[12] && 0x06 == eth_head[13])
{
printf ("ARP source ip:%d.%d.%d.%d,destination ip:%d.%d.%d.%d;\n",
eth_head[28], eth_head[29], eth_head[30], eth_head[31],
eth_head[38], eth_head[39], eth_head[40], eth_head[41]);
/* send a package to the source mac */
memcpy (send_mac, eth_head, 6);
if (0 != send_package ("eth0", send_mac))
{
printf ("say hello to %02x-%02x-%02x-%02x-%02x-%02x failed\n",
eth_head[0], eth_head[1], eth_head[2], eth_head[3],
eth_head[4], eth_head[5]);
}
else
{
printf ("say hello to %02x-%02x-%02x-%02x-%02x-%02x already\n",
eth_head[0], eth_head[1], eth_head[2], eth_head[3],
eth_head[4], eth_head[5]);
}
}
/* IPv4 protocol flag */
else if (0x08 == eth_head[12] && 0x00 == eth_head[13])
{
if (0x45 == eth_head[14])
{
printf ("IPv4 source ip:%d.%d.%d.%d,destination ip:%d.%d.%d."
"%d;\n", eth_head[26], eth_head[27], eth_head[28],
eth_head[29], eth_head[30], eth_head[31],
eth_head[32], eth_head[33]);
/* send a package to the source mac */
memcpy (send_mac, eth_head, 6);
if (0 != send_package ("eth0", send_mac))
{
printf ("say hello to %02x-%02x-%02x-%02x-%02x-%02x failed\n",
eth_head[0], eth_head[1], eth_head[2], eth_head[3],
eth_head[4], eth_head[5]);
}
else
{
printf ("say hello to %02x-%02x-%02x-%02x-%02x-%02x already\n",
eth_head[0], eth_head[1], eth_head[2], eth_head[3],
eth_head[4], eth_head[5]);
}
}
else
{
printf ("p_head:%02x\n", eth_head[14]);
}
}
printf ("PACKAGE END\n");
}
return 0;
}