qfedu-network-advanced-level/day6/n4.c

80 lines
3.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*单播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(&ether_req, sizeof(ether_req));
strncpy(ether_req.ifr_name, ether_name, IF_NAMESIZE); // # define ifr_name ifr_ifrn.ifrn_name
if (ioctl(fd, SIOCGIFINDEX, &ether_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;
}