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