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