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