1 | /* $NetBSD: 44arp.c,v 1.2 2016/04/04 07:37:07 ozaki-r Exp $ */ |
2 | |
3 | /* |
4 | * Based upon 4.4BSD's /usr/sbin/arp |
5 | */ |
6 | #include <sys/param.h> |
7 | #include <sys/file.h> |
8 | #include <sys/socket.h> |
9 | #include <sys/sysctl.h> |
10 | #include <net/if.h> |
11 | #if __FreeBSD_version >= 300000 |
12 | # include <net/if_var.h> |
13 | #endif |
14 | #include <net/if_dl.h> |
15 | #include <net/if_types.h> |
16 | #ifndef __osf__ |
17 | # include <net/route.h> |
18 | #endif |
19 | #include <netinet/in.h> |
20 | #include <netinet/if_ether.h> |
21 | #include <arpa/inet.h> |
22 | #include <netinet/in.h> |
23 | #include <netinet/in_systm.h> |
24 | #include <netinet/ip.h> |
25 | #include <netinet/ip_var.h> |
26 | #include <netinet/tcp.h> |
27 | #include <unistd.h> |
28 | #include <string.h> |
29 | #include <stdlib.h> |
30 | #include <netdb.h> |
31 | #include <errno.h> |
32 | #include <nlist.h> |
33 | #include <stdio.h> |
34 | #include "ipsend.h" |
35 | #include "iplang/iplang.h" |
36 | |
37 | |
38 | /* |
39 | * lookup host and return |
40 | * its IP address in address |
41 | * (4 bytes) |
42 | */ |
43 | int resolve(host, address) |
44 | char *host, *address; |
45 | { |
46 | struct hostent *hp; |
47 | u_long add; |
48 | |
49 | add = inet_addr(host); |
50 | if (add == -1) |
51 | { |
52 | if (!(hp = gethostbyname(host))) |
53 | { |
54 | fprintf(stderr, "unknown host: %s\n" , host); |
55 | return -1; |
56 | } |
57 | bcopy((char *)hp->h_addr, (char *)address, 4); |
58 | return 0; |
59 | } |
60 | bcopy((char*)&add, address, 4); |
61 | return 0; |
62 | } |
63 | |
64 | |
65 | int arp(addr, eaddr) |
66 | char *addr, *eaddr; |
67 | { |
68 | int mib[6]; |
69 | size_t needed; |
70 | char *lim, *buf, *next; |
71 | struct rt_msghdr *rtm; |
72 | struct sockaddr_inarp *sin; |
73 | struct sockaddr_dl *sdl; |
74 | |
75 | #ifdef IPSEND |
76 | if (arp_getipv4(addr, ether) == 0) |
77 | return 0; |
78 | #endif |
79 | |
80 | if (!addr) |
81 | return -1; |
82 | |
83 | mib[0] = CTL_NET; |
84 | mib[1] = PF_ROUTE; |
85 | mib[2] = 0; |
86 | mib[3] = AF_INET; |
87 | mib[4] = NET_RT_FLAGS; |
88 | #ifdef RTF_LLINFO |
89 | mib[5] = RTF_LLINFO; |
90 | #else |
91 | mib[5] = 0; |
92 | #endif |
93 | if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) |
94 | { |
95 | perror("route-sysctl-estimate" ); |
96 | exit(-1); |
97 | } |
98 | if ((buf = malloc(needed)) == NULL) |
99 | { |
100 | perror("malloc" ); |
101 | exit(-1); |
102 | } |
103 | if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) |
104 | { |
105 | perror("actual retrieval of routing table" ); |
106 | exit(-1); |
107 | } |
108 | lim = buf + needed; |
109 | for (next = buf; next < lim; next += rtm->rtm_msglen) |
110 | { |
111 | rtm = (struct rt_msghdr *)next; |
112 | sin = (struct sockaddr_inarp *)(rtm + 1); |
113 | sdl = (struct sockaddr_dl *)(sin + 1); |
114 | if (!bcmp(addr, (char *)&sin->sin_addr, |
115 | sizeof(struct in_addr))) |
116 | { |
117 | bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen); |
118 | return 0; |
119 | } |
120 | } |
121 | return -1; |
122 | } |
123 | |