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