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