arp.c revision 26119
1/* 2 * arp.c (C) 1995 Darren Reed 3 * 4 * The author provides this program as-is, with no gaurantee for its 5 * suitability for any specific purpose. The author takes no responsibility 6 * for the misuse/abuse of this program and provides it for the sole purpose 7 * of testing packet filter policies. This file maybe distributed freely 8 * providing it is not modified and that this notice remains in tact. 9 */ 10#if !defined(lint) && defined(LIBC_SCCS) 11static char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 12#endif 13#include <stdio.h> 14#include <errno.h> 15#include <sys/types.h> 16#include <sys/socket.h> 17#include <sys/sockio.h> 18#include <sys/ioctl.h> 19#include <netdb.h> 20#include <netinet/in.h> 21#include <net/if.h> 22#include <net/if_arp.h> 23#include <netinet/in.h> 24#include <netinet/ip_var.h> 25#include <netinet/tcp.h> 26#include "ipsend.h" 27 28 29/* 30 * lookup host and return 31 * its IP address in address 32 * (4 bytes) 33 */ 34int resolve(host, address) 35char *host, *address; 36{ 37 struct hostent *hp; 38 u_long add; 39 40 add = inet_addr(host); 41 if (add == -1) 42 { 43 if (!(hp = gethostbyname(host))) 44 { 45 fprintf(stderr, "unknown host: %s\n", host); 46 return -1; 47 } 48 bcopy((char *)hp->h_addr, (char *)address, 4); 49 return 0; 50 } 51 bcopy((char*)&add, address, 4); 52 return 0; 53} 54 55/* 56 * ARP for the MAC address corresponding 57 * to the IP address. This taken from 58 * some BSD program, I cant remember which. 59 */ 60int arp(ip, ether) 61char *ip; 62char *ether; 63{ 64 static int sfd = -1; 65 static char ethersave[6], ipsave[4]; 66 struct arpreq ar; 67 struct sockaddr_in *sin, san; 68 struct hostent *hp; 69 int fd; 70 71 if (!bcmp(ipsave, ip, 4)) { 72 bcopy(ethersave, ether, 6); 73 return 0; 74 } 75 fd = -1; 76 bzero((char *)&ar, sizeof(ar)); 77 sin = (struct sockaddr_in *)&ar.arp_pa; 78 sin->sin_family = AF_INET; 79 bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); 80 if ((hp = gethostbyaddr(ip, 4, AF_INET))) 81 if (!(ether_hostton(hp->h_name, ether))) 82 goto savearp; 83 84 if (sfd == -1) 85 if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 86 { 87 perror("arp: socket"); 88 return -1; 89 } 90tryagain: 91 if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) 92 { 93 if (fd == -1) 94 { 95 bzero((char *)&san, sizeof(san)); 96 san.sin_family = AF_INET; 97 san.sin_port = htons(1); 98 bcopy(ip, &san.sin_addr.s_addr, 4); 99 fd = socket(AF_INET, SOCK_DGRAM, 0); 100 (void) sendto(fd, ip, 4, 0, 101 (struct sockaddr *)&san, sizeof(san)); 102 sleep(1); 103 (void) close(fd); 104 goto tryagain; 105 } 106 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 107 if (errno != ENXIO) 108 perror("SIOCGARP"); 109 return -1; 110 } 111 112 bcopy(ar.arp_ha.sa_data, ether, 6); 113savearp: 114 bcopy(ether, ethersave, 6); 115 bcopy(ip, ipsave, 4); 116 return 0; 117} 118