1 /* $NetBSD: 44arp.c,v 1.1.1.1 2012/03/23 21:20:06 christos 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 mib[5] = RTF_LLINFO; 89 if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) 90 { 91 perror("route-sysctl-estimate"); 92 exit(-1); 93 } 94 if ((buf = malloc(needed)) == NULL) 95 { 96 perror("malloc"); 97 exit(-1); 98 } 99 if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) 100 { 101 perror("actual retrieval of routing table"); 102 exit(-1); 103 } 104 lim = buf + needed; 105 for (next = buf; next < lim; next += rtm->rtm_msglen) 106 { 107 rtm = (struct rt_msghdr *)next; 108 sin = (struct sockaddr_inarp *)(rtm + 1); 109 sdl = (struct sockaddr_dl *)(sin + 1); 110 if (!bcmp(addr, (char *)&sin->sin_addr, 111 sizeof(struct in_addr))) 112 { 113 bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen); 114 return 0; 115 } 116 } 117 return -1; 118 } 119