linux 发包函数,Linux下发包(3)

大多数时候,我们要根据需要去发送一些包,这里把发包代码添上,同时处理了头文件的引入。

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; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值