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(char *host, char *address) 39 { 40 struct hostent *hp; 41 u_long add; 42 43 add = inet_addr(host); 44 if (add == -1) 45 { 46 if (!(hp = gethostbyname(host))) 47 { 48 fprintf(stderr, "unknown host: %s\n", host); 49 return (-1); 50 } 51 bcopy((char *)hp->h_addr, (char *)address, 4); 52 return (0); 53 } 54 bcopy((char*)&add, address, 4); 55 return (0); 56 } 57 58 59 int arp(char *addr, char *eaddr) 60 { 61 int mib[6]; 62 size_t needed; 63 char *lim, *buf, *next; 64 struct rt_msghdr *rtm; 65 struct sockaddr_in *sin; 66 struct sockaddr_dl *sdl; 67 68 #ifdef IPSEND 69 if (arp_getipv4(addr, ether) == 0) 70 return (0); 71 #endif 72 73 if (!addr) 74 return (-1); 75 76 mib[0] = CTL_NET; 77 mib[1] = PF_ROUTE; 78 mib[2] = 0; 79 mib[3] = AF_INET; 80 mib[4] = NET_RT_FLAGS; 81 #ifdef RTF_LLINFO 82 mib[5] = RTF_LLINFO; 83 #else 84 mib[5] = 0; 85 #endif 86 87 if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) 88 { 89 perror("route-sysctl-estimate"); 90 exit(-1); 91 } 92 if ((buf = malloc(needed)) == NULL) 93 { 94 perror("malloc"); 95 exit(-1); 96 } 97 if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) 98 { 99 perror("actual retrieval of routing table"); 100 exit(-1); 101 } 102 lim = buf + needed; 103 for (next = buf; next < lim; next += rtm->rtm_msglen) 104 { 105 rtm = (struct rt_msghdr *)next; 106 sin = (struct sockaddr_in *)(rtm + 1); 107 sdl = (struct sockaddr_dl *)(sin + 1); 108 if (!bcmp(addr, (char *)&sin->sin_addr, 109 sizeof(struct in_addr))) 110 { 111 bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen); 112 return (0); 113 } 114 } 115 return (-1); 116 } 117