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