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