1 /* $NetBSD: arp.c,v 1.2 2012/07/22 14:27:35 darrenr Exp $ */ 2 3 /* 4 * arp.c (C) 1995-1998 Darren Reed 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8 #if !defined(lint) 9 static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 10 static const char rcsid[] = "@(#)Id: arp.c,v 1.1.1.2 2012/07/22 13:44:35 darrenr Exp $"; 11 #endif 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #if !defined(ultrix) && !defined(hpux) && !defined(__hpux) && !defined(__osf__) && !defined(_AIX51) 15 # include <sys/sockio.h> 16 #endif 17 #include <sys/ioctl.h> 18 #include <netinet/in_systm.h> 19 #include <netinet/in.h> 20 #include <net/if.h> 21 #include <netinet/if_ether.h> 22 #ifndef ultrix 23 # include <net/if_arp.h> 24 #endif 25 #include <netinet/in.h> 26 #include <netinet/ip.h> 27 #include <netinet/ip_var.h> 28 #include <netinet/tcp.h> 29 #include <stdio.h> 30 #include <errno.h> 31 #include <netdb.h> 32 #include "ipsend.h" 33 #include "iplang/iplang.h" 34 35 36 /* 37 * lookup host and return 38 * its IP address in address 39 * (4 bytes) 40 */ 41 int resolve(host, address) 42 char *host, *address; 43 { 44 struct hostent *hp; 45 u_long add; 46 47 add = inet_addr(host); 48 if (add == -1) 49 { 50 if (!(hp = gethostbyname(host))) 51 { 52 fprintf(stderr, "unknown host: %s\n", host); 53 return -1; 54 } 55 bcopy((char *)hp->h_addr, (char *)address, 4); 56 return 0; 57 } 58 bcopy((char*)&add, address, 4); 59 return 0; 60 } 61 62 /* 63 * ARP for the MAC address corresponding 64 * to the IP address. This taken from 65 * some BSD program, I cant remember which. 66 */ 67 int arp(ip, ether) 68 char *ip; 69 char *ether; 70 { 71 static int sfd = -1; 72 static char ethersave[6], ipsave[4]; 73 struct arpreq ar; 74 struct sockaddr_in *sin, san; 75 struct hostent *hp; 76 int fd; 77 78 #ifdef IPSEND 79 if (arp_getipv4(ip, ether) == 0) 80 return 0; 81 #endif 82 if (!bcmp(ipsave, ip, 4)) { 83 bcopy(ethersave, ether, 6); 84 return 0; 85 } 86 fd = -1; 87 bzero((char *)&ar, sizeof(ar)); 88 sin = (struct sockaddr_in *)&ar.arp_pa; 89 sin->sin_family = AF_INET; 90 bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); 91 #ifndef hpux 92 if ((hp = gethostbyaddr(ip, 4, AF_INET))) 93 # if SOLARIS && (SOLARIS2 >= 10) 94 if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) 95 # else 96 if (!(ether_hostton(hp->h_name, ether))) 97 # endif 98 goto savearp; 99 #endif 100 101 if (sfd == -1) 102 if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 103 { 104 perror("arp: socket"); 105 return -1; 106 } 107 tryagain: 108 if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) 109 { 110 if (fd == -1) 111 { 112 bzero((char *)&san, sizeof(san)); 113 san.sin_family = AF_INET; 114 san.sin_port = htons(1); 115 bcopy(ip, &san.sin_addr.s_addr, 4); 116 fd = socket(AF_INET, SOCK_DGRAM, 0); 117 (void) sendto(fd, ip, 4, 0, 118 (struct sockaddr *)&san, sizeof(san)); 119 sleep(1); 120 (void) close(fd); 121 goto tryagain; 122 } 123 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 124 if (errno != ENXIO) 125 perror("SIOCGARP"); 126 return -1; 127 } 128 129 if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && 130 (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && 131 (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { 132 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 133 return -1; 134 } 135 136 bcopy(ar.arp_ha.sa_data, ether, 6); 137 savearp: 138 bcopy(ether, ethersave, 6); 139 bcopy(ip, ipsave, 4); 140 return 0; 141 } 142