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#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 */ 43int 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 65int 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_in *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#ifdef RTF_LLINFO 89 mib[5] = RTF_LLINFO; 90#else 91 mib[5] = 0; 92#endif 93 94 if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) 95 { 96 perror("route-sysctl-estimate"); 97 exit(-1); 98 } 99 if ((buf = malloc(needed)) == NULL) 100 { 101 perror("malloc"); 102 exit(-1); 103 } 104 if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) 105 { 106 perror("actual retrieval of routing table"); 107 exit(-1); 108 } 109 lim = buf + needed; 110 for (next = buf; next < lim; next += rtm->rtm_msglen) 111 { 112 rtm = (struct rt_msghdr *)next; 113 sin = (struct sockaddr_in *)(rtm + 1); 114 sdl = (struct sockaddr_dl *)(sin + 1); 115 if (!bcmp(addr, (char *)&sin->sin_addr, 116 sizeof(struct in_addr))) 117 { 118 bcopy(LLADDR(sdl), eaddr, sdl->sdl_alen); 119 return 0; 120 } 121 } 122 return -1; 123} 124