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 */ 37int 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 58int 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