80 lines
3.0 KiB
C
80 lines
3.0 KiB
C
/*单播ARP应答*/
|
||
#include <arpa/inet.h>
|
||
#include <netinet/in.h>
|
||
#include <netinet/ether.h>
|
||
#include <netpacket/packet.h>
|
||
#include <sys/ioctl.h>
|
||
#include <net/if.h> // ifreq
|
||
#include <unistd.h>
|
||
#include <string.h> // bzero
|
||
#include <stdio.h>
|
||
|
||
// 发送原始数据报
|
||
ssize_t send_datapacket(int fd, unsigned char *buf, ssize_t buf_size, const char *ether_name);
|
||
|
||
ssize_t send_datapacket(int fd, unsigned char *buf, ssize_t buf_size, const char *ether_name)
|
||
{
|
||
// 1. 获取网络接口类型(通过网卡名查找网卡索引)
|
||
struct ifreq ether_req;
|
||
bzero(ðer_req, sizeof(ether_req));
|
||
strncpy(ether_req.ifr_name, ether_name, IF_NAMESIZE); // # define ifr_name ifr_ifrn.ifrn_name
|
||
|
||
if (ioctl(fd, SIOCGIFINDEX, ðer_req) == -1)
|
||
{
|
||
perror("ioctl");
|
||
return -1;
|
||
}
|
||
|
||
// 2. 选择发送数据的网络接口索引(选择合适的网卡索引)
|
||
struct sockaddr_ll sll;
|
||
bzero(&sll, sizeof(sll));
|
||
sll.sll_ifindex = ether_req.ifr_ifindex; // # define ifr_ifindex ifr_ifru.ifru_ivalue
|
||
|
||
// 3. 发送数据
|
||
ssize_t len = sendto(fd, buf, buf_size, 0, (struct sockaddr *)&sll, sizeof(sll));
|
||
return len;
|
||
}
|
||
|
||
int main(int argc, char const *argv[])
|
||
{
|
||
// 创建原始套接字
|
||
int sock_fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
|
||
if (sock_fd < 0)
|
||
{
|
||
perror("raw socket");
|
||
return -1;
|
||
}
|
||
|
||
// 组ARP应答报文(如果是ARP欺骗,则源MAC为0x00,0x00,0x00,0x00,0x00,0x00)
|
||
uint32_t src_ip = inet_addr("10.12.156.204"); // 发送的 ip 地址
|
||
uint32_t dst_ip = inet_addr("10.12.156.178"); // 点分十进制转换为数字字符串
|
||
|
||
unsigned char *src_ip_p = (unsigned char *)&src_ip; // src_ip 的字符类型指针
|
||
unsigned char *dst_ip_p = (unsigned char *)&dst_ip;
|
||
|
||
unsigned char buf[] = {
|
||
0x00, 0x0c, 0x29, 0xf7, 0x81, 0x4c, /*目的MAC地址*/
|
||
0x00, 0x0c, 0x29, 0x85, 0xcc, 0x67, /* 源MAC地址 */
|
||
0x08, 0x06, /* ARP帧类型 */
|
||
0x00, 0x01, /* 硬件类型 */
|
||
0x08, 0x00, /* 协议类型(IP协议0x0800) */
|
||
0x06, 0x04, /* 硬件地址长度(MAC地址长度) 和 协议地址长度(IP 地址长度) */
|
||
0x00, 0x02, /* OP操作类型(ARP应答 = 2) */
|
||
0x00, 0x0c, 0x29, 0x85, 0xcc, 0x67, /* 发送端MAC地址 */
|
||
src_ip_p[0], src_ip_p[1], src_ip_p[2], src_ip_p[3], /* 源(发送端) IP 地址 */
|
||
0x00, 0x0c, 0x29, 0xf7, 0x81, 0x4c, /*接收端MAC地址*/
|
||
dst_ip_p[0], dst_ip_p[1], dst_ip_p[2], dst_ip_p[3] /* 接收端 IP 地址 */
|
||
};
|
||
|
||
// 单播发送ARP应答
|
||
ssize_t len = send_datapacket(sock_fd, buf, sizeof(buf), "ens38");
|
||
if (len > 0)
|
||
{
|
||
printf("send arp success! \n");
|
||
}
|
||
|
||
close(sock_fd);
|
||
|
||
return 0;
|
||
}
|