Commit | Line | Data |
---|---|---|
a7233f40 TM |
1 | #define _DEFAULT_SOURCE 1 |
2 | #define _POSIX_C_SOURCE 200809L | |
3 | #define _XOPEN_SOURCE 700 | |
4 | ||
5 | #include <stdio.h> | |
6 | #include <endian.h> | |
7 | #include <unistd.h> | |
8 | #include <stdint.h> | |
9 | #include <arpa/inet.h> | |
10 | #include <sys/ioctl.h> | |
11 | #include <string.h> | |
12 | #include <net/if_arp.h> | |
13 | ||
14 | uint64_t arp_ip2mac(const char *dev, const char *ip) { | |
15 | int ret; | |
16 | struct arpreq arpreq; | |
17 | int iArpFD; | |
18 | ||
19 | struct sockaddr_in *sin = (struct sockaddr_in *) &arpreq.arp_pa; | |
20 | uint64_t mac = 0; | |
21 | ||
22 | memset(&arpreq, 0, sizeof(struct arpreq)); | |
23 | ||
24 | strcpy(arpreq.arp_dev, dev); | |
25 | //sprintf(arpreq.arp_dev, "eth-pub.%d", vlan); | |
26 | ||
27 | iArpFD = socket(AF_INET, SOCK_DGRAM, 0); | |
28 | if (iArpFD == -1) | |
29 | { | |
30 | printf("Cannot open packet socket"); | |
31 | return 0; | |
32 | } | |
33 | ||
34 | struct timeval tv = { | |
35 | .tv_sec = 0, | |
36 | .tv_usec = 200000 | |
37 | }; | |
38 | setsockopt(iArpFD, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(struct timeval)); | |
39 | ||
40 | sin->sin_family = AF_INET; | |
41 | sin->sin_addr.s_addr = inet_addr(ip); | |
42 | sin->sin_port = htons(4242); | |
43 | ||
44 | sendto(iArpFD, "PING", 4, MSG_NOSIGNAL, | |
45 | (struct sockaddr*) sin, sizeof(struct sockaddr_in)); | |
46 | ||
47 | ||
48 | char blah[5]; | |
49 | if(recvfrom(iArpFD, blah, sizeof(blah), 0, | |
50 | (struct sockaddr *) sin, (socklen_t * restrict) sizeof(struct sockaddr)) < 0) | |
51 | { | |
52 | //printf("UDP ping timeout\n"); | |
53 | } | |
54 | ||
55 | ret = ioctl(iArpFD, SIOCGARP, &arpreq); | |
56 | close(iArpFD); | |
57 | ||
58 | if(ret < 0) { | |
59 | printf("RET: %d FAMILY: %d\n", ret, arpreq.arp_ha.sa_family); | |
60 | perror("SIOCGARP"); | |
61 | return 0; | |
62 | } | |
63 | ||
64 | memcpy(&mac, &arpreq.arp_ha.sa_data[0], 6); | |
65 | mac = be64toh(mac<<16); | |
66 | ||
67 | return mac; | |
68 | } | |
69 | ||
70 | int main() { | |
71 | char *dev = "eth0"; | |
72 | char *ip = "10.10.161.3"; | |
73 | uint64_t mac = arp_ip2mac(dev, ip); | |
74 | ||
75 | printf("DEV %s IP %s MAC: %.12lX %s\n", dev, ip, mac, mac?"OK":"FAIL"); | |
76 | } | |
77 |