1 /* $FreeBSD$ */ 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 #include <net/if_dl.h> 12 #include <net/if_types.h> 13 # include <net/route.h> 14 #include <netinet/in.h> 15 #include <netinet/if_ether.h> 16 #include <arpa/inet.h> 17 #include <netinet/in.h> 18 #include <netinet/in_systm.h> 19 #include <netinet/ip.h> 20 #include <netinet/ip_var.h> 21 #include <netinet/tcp.h> 22 #include <unistd.h> 23 #include <string.h> 24 #include <stdlib.h> 25 #include <netdb.h> 26 #include <errno.h> 27 #include <nlist.h> 28 #include <stdio.h> 29 #include "ipsend.h" 30 #include "iplang/iplang.h" 31 32 33 /* 34 * lookup host and return 35 * its IP address in address 36 * (4 bytes) 37 */ 38 int resolve(host, address) 39 char *host, *address; 40 { 41 struct hostent *hp; 42 u_long add; 43 44 add = inet_addr(host); 45 if (add == -1) 46 { 47 if (!(hp = gethostbyname(host))) 48 { 49 fprintf(stderr, "unknown host: %s\n", host); 50 return -1; 51 } 52 bcopy((char *)hp->h_addr, (char *)address, 4); 53 return 0; 54 } 55 bcopy((char*)&add, address, 4); 56 return 0; 57 } 58 59 60 int arp(addr, eaddr) 61 char *addr, *eaddr; 62 { 63 int mib[6]; 64 size_t needed; 65 char *lim, *buf, *next; 66 struct rt_msghdr *rtm; 67 struct sockaddr_in *sin; 68 struct sockaddr_dl *sdl; 69 70 #ifdef IPSEND 71 if (arp_getipv4(addr, ether) == 0) 72 return 0; 73 #endif 74 75 if (!addr) 76 return -1; 77 78 mib[0] = CTL_NET; 79 mib[1] = PF_ROUTE; 80 mib[2] = 0; 81 mib[3] = AF_INET; 82 mib[4] = NET_RT_FLAGS; 83 #ifdef RTF_LLINFO 84 mib[5] = RTF_LLINFO; 85 #else 86 mib[5] = 0; 87 #endif 88 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_in *)(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