用c语言写一个检测ARP协议的算法
时间: 2024-04-05 19:29:48 浏览: 104
以下是一个简单的用C语言实现ARP协议检测的算法:
```c
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h>
#include <arpa/inet.h>
#include <netinet/if_ether.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <net/if.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define ARP_REQUEST 1
#define ARP_REPLY 2
typedef struct _arp_hdr arp_hdr;
struct _arp_hdr {
u_int16_t htype; // Hardware Type
u_int16_t ptype; // Protocol Type
u_char hlen; // Hardware Address Length
u_char plen; // Protocol Address Length
u_int16_t opcode; // ARP Opcode
u_char sender_mac[6]; // Sender MAC Address
u_char sender_ip[4]; // Sender IP Address
u_char target_mac[6]; // Target MAC Address
u_char target_ip[4]; // Target IP Address
};
void get_local_mac(char *dev, u_char *mac_addr) {
int fd;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name, dev, IFNAMSIZ-1);
ioctl(fd, SIOCGIFHWADDR, &ifr);
close(fd);
memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6);
}
void send_arp_request(pcap_t *handle, u_char *src_mac, u_char *src_ip, u_char *dst_ip) {
arp_hdr arp;
memset(&arp, 0, sizeof(arp));
arp.htype = htons(ARPHRD_ETHER);
arp.ptype = htons(ETH_P_IP);
arp.hlen = 6;
arp.plen = 4;
arp.opcode = htons(ARP_REQUEST);
memcpy(arp.sender_mac, src_mac, 6);
memcpy(arp.sender_ip, src_ip, 4);
memset(arp.target_mac, 0xff, 6);
memcpy(arp.target_ip, dst_ip, 4);
u_char packet[sizeof(arp_hdr)];
memcpy(packet, &arp, sizeof(arp_hdr));
pcap_sendpacket(handle, packet, sizeof(arp_hdr));
}
int main(int argc, char *argv[]) {
char *dev = argv[1];
pcap_t *handle;
char errbuf[PCAP_ERRBUF_SIZE];
struct pcap_pkthdr header;
const u_char *packet;
u_char local_mac[6], local_ip[4];
u_char target_ip[4];
if (argc != 3) {
printf("Usage: arp_detect <interface> <target_ip>\n");
return 1;
}
handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);
if (handle == NULL) {
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return 2;
}
get_local_mac(dev, local_mac);
if (pcap_lookupnet(dev, NULL, NULL, errbuf) == -1) {
fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
return 2;
}
if (pcap_compile(handle, &fp, "arp", 0, net) == -1) {
fprintf(stderr, "Couldn't compile filter: %s\n", pcap_geterr(handle));
return 2;
}
if (pcap_setfilter(handle, &fp) == -1) {
fprintf(stderr, "Couldn't set filter: %s\n", pcap_geterr(handle));
return 2;
}
inet_pton(AF_INET, argv[2], target_ip);
get_local_ip(dev, local_ip);
send_arp_request(handle, local_mac, local_ip, target_ip);
while(1) {
packet = pcap_next(handle, &header);
if (packet == NULL) continue;
arp_hdr *arp = (arp_hdr*)(packet + sizeof(struct ether_header));
if (ntohs(arp->htype) == ARPHRD_ETHER &&
ntohs(arp->ptype) == ETH_P_IP &&
arp->hlen == 6 &&
arp->plen == 4 &&
ntohs(arp->opcode) == ARP_REPLY &&
memcmp(arp->sender_ip, target_ip, 4) == 0) {
printf("ARP reply received from %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n",
arp->sender_mac[0], arp->sender_mac[1], arp->sender_mac[2],
arp->sender_mac[3], arp->sender_mac[4], arp->sender_mac[5]);
break;
}
}
pcap_close(handle);
return 0;
}
```
该算法使用libpcap库来捕获ARP协议数据包并解析其中的数据。它首先获取本地MAC地址和IP地址,然后构造一个ARP请求数据包并发送。接着它使用pcap_next()函数来捕获接收到的数据包,解析其中的ARP数据并检查是否是来自目标IP的ARP回复。如果是,它将打印出发送方的MAC地址。
阅读全文