arp.c revision 22514
1311966Sngie/* 2311966Sngie * arp.c (C) 1995 Darren Reed 3311966Sngie * 4311966Sngie * The author provides this program as-is, with no gaurantee for its 5311966Sngie * suitability for any specific purpose. The author takes no responsibility 6311966Sngie * for the misuse/abuse of this program and provides it for the sole purpose 7311966Sngie * of testing packet filter policies. This file maybe distributed freely 8311966Sngie * providing it is not modified and that this notice remains in tact. 9311966Sngie */ 10311966Sngie#if !defined(lint) && defined(LIBC_SCCS) 11311966Sngiestatic char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 12311966Sngie#endif 13311966Sngie#include <stdio.h> 14311966Sngie#include <errno.h> 15311966Sngie#include <sys/types.h> 16311966Sngie#include <sys/socket.h> 17311966Sngie#include <sys/sockio.h> 18311966Sngie#include <sys/ioctl.h> 19311966Sngie#include <netdb.h> 20311966Sngie#include <netinet/in.h> 21311966Sngie#include <net/if.h> 22311966Sngie#include <net/if_arp.h> 23311966Sngie 24311966Sngie#if defined(__SVR4) || defined(__svr4__) 25311966Sngie#define bcopy(a,b,c) memmove(b,a,c) 26311966Sngie#define bzero(a,c) memset(a,0,c) 27311966Sngie#define bcmp(a,b,c) memcmp(a,b,c) 28311966Sngie#endif 29311966Sngie 30311966Sngie/* 31 * lookup host and return 32 * its IP address in address 33 * (4 bytes) 34 */ 35int resolve(host, address) 36char *host, *address; 37{ 38 struct hostent *hp; 39 u_long add; 40 41 add = inet_addr(host); 42 if (add == -1) 43 { 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