/*单播ARP应答*/ #include #include #include #include #include #include // ifreq #include #include // bzero #include // 发送原始数据报 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; }