arp.c revision 22514
119370Spst/* 219370Spst * arp.c (C) 1995 Darren Reed 319370Spst * 419370Spst * The author provides this program as-is, with no gaurantee for its 598944Sobrien * suitability for any specific purpose. The author takes no responsibility 619370Spst * for the misuse/abuse of this program and provides it for the sole purpose 798944Sobrien * of testing packet filter policies. This file maybe distributed freely 898944Sobrien * providing it is not modified and that this notice remains in tact. 998944Sobrien */ 1098944Sobrien#if !defined(lint) && defined(LIBC_SCCS) 1119370Spststatic char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 1298944Sobrien#endif 1398944Sobrien#include <stdio.h> 1498944Sobrien#include <errno.h> 1598944Sobrien#include <sys/types.h> 1619370Spst#include <sys/socket.h> 1798944Sobrien#include <sys/sockio.h> 1898944Sobrien#include <sys/ioctl.h> 1998944Sobrien#include <netdb.h> 2098944Sobrien#include <netinet/in.h> 2119370Spst#include <net/if.h> 2219370Spst#include <net/if_arp.h> 2398944Sobrien 2419370Spst#if defined(__SVR4) || defined(__svr4__) 2598944Sobrien#define bcopy(a,b,c) memmove(b,a,c) 2698944Sobrien#define bzero(a,c) memset(a,0,c) 2798944Sobrien#define bcmp(a,b,c) memcmp(a,b,c) 2898944Sobrien#endif 2998944Sobrien 3098944Sobrien/* 3198944Sobrien * lookup host and return 3298944Sobrien * its IP address in address 3319370Spst * (4 bytes) 3419370Spst */ 3519370Spstint resolve(host, address) 3619370Spstchar *host, *address; 3719370Spst{ 3819370Spst struct hostent *hp; 3919370Spst u_long add; 4019370Spst 4119370Spst add = inet_addr(host); 4219370Spst if (add == -1) 4319370Spst { 44 if (!(hp = gethostbyname(host))) 45 { 46 fprintf(stderr, "unknown host: %s\n", host); 47 return -1; 48 } 49 bcopy((char *)hp->h_addr, (char *)address, 4); 50 return 0; 51 } 52 bcopy((char*)&add, address, 4); 53 return 0; 54} 55 56/* 57 * ARP for the MAC address corresponding 58 * to the IP address. This taken from 59 * some BSD program, I cant remember which. 60 */ 61int arp(ip, ether) 62char *ip; 63char *ether; 64{ 65 static int sfd = -1; 66 static char ethersave[6], ipsave[4]; 67 struct arpreq ar; 68 struct sockaddr_in *sin, san; 69 struct hostent *hp; 70 char *inet_ntoa(); 71 int fd; 72 73 if (!bcmp(ipsave, ip, 4)) { 74 bcopy(ethersave, ether, 6); 75 return 0; 76 } 77 fd = -1; 78 bzero((char *)&ar, sizeof(ar)); 79 sin = (struct sockaddr_in *)&ar.arp_pa; 80 sin->sin_family = AF_INET; 81 bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); 82 if ((hp = gethostbyaddr(ip, 4, AF_INET))) 83 if (!(ether_hostton(hp->h_name, ether))) 84 goto savearp; 85 86 if (sfd == -1) 87 if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 88 { 89 perror("arp: socket"); 90 return -1; 91 } 92tryagain: 93 if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) 94 { 95 if (fd == -1) 96 { 97 bzero((char *)&san, sizeof(san)); 98 san.sin_family = AF_INET; 99 san.sin_port = htons(1); 100 bcopy(ip, &san.sin_addr.s_addr, 4); 101 fd = socket(AF_INET, SOCK_DGRAM, 0); 102 (void) sendto(fd, ip, 4, 0, 103 (struct sockaddr *)&san, sizeof(san)); 104 sleep(1); 105 (void) close(fd); 106 goto tryagain; 107 } 108 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 109 if (errno != ENXIO) 110 perror("SIOCGARP"); 111 return -1; 112 } 113 114 bcopy(ar.arp_ha.sa_data, ether, 6); 115savearp: 116 bcopy(ether, ethersave, 6); 117 bcopy(ip, ipsave, 4); 118 return 0; 119} 120