1 2 /* 3 * arp.c (C) 1995-1998 Darren Reed 4 * 5 * See the IPFILTER.LICENCE file for details on licencing. 6 */ 7 #if !defined(lint) 8 static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 9 static const char rcsid[] = "@(#)$Id$"; 10 #endif 11 #include <sys/types.h> 12 #include <sys/socket.h> 13 # include <sys/sockio.h> 14 #include <sys/ioctl.h> 15 #include <netinet/in_systm.h> 16 #include <netinet/in.h> 17 #include <net/if.h> 18 #include <netinet/if_ether.h> 19 # include <net/if_arp.h> 20 #include <netinet/in.h> 21 #include <netinet/ip.h> 22 #include <netinet/ip_var.h> 23 #include <netinet/tcp.h> 24 #include <stdio.h> 25 #include <errno.h> 26 #include <netdb.h> 27 #include "ipsend.h" 28 #include "iplang/iplang.h" 29 30 31 /* 32 * lookup host and return 33 * its IP address in address 34 * (4 bytes) 35 */ 36 int resolve(char *host, char *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 */ 61 int arp(ip, ether) 62 char *ip; 63 char *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 int fd; 71 72 #ifdef IPSEND 73 if (arp_getipv4(ip, ether) == 0) 74 return (0); 75 #endif 76 if (!bcmp(ipsave, ip, 4)) { 77 bcopy(ethersave, ether, 6); 78 return (0); 79 } 80 fd = -1; 81 bzero((char *)&ar, sizeof(ar)); 82 sin = (struct sockaddr_in *)&ar.arp_pa; 83 sin->sin_family = AF_INET; 84 bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); 85 if ((hp = gethostbyaddr(ip, 4, AF_INET))) 86 # if SOLARIS && (SOLARIS2 >= 10) 87 if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) 88 # else 89 if (!(ether_hostton(hp->h_name, ether))) 90 # endif 91 goto savearp; 92 93 if (sfd == -1) 94 if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 95 { 96 perror("arp: socket"); 97 return (-1); 98 } 99 tryagain: 100 if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) 101 { 102 if (fd == -1) 103 { 104 bzero((char *)&san, sizeof(san)); 105 san.sin_family = AF_INET; 106 san.sin_port = htons(1); 107 bcopy(ip, &san.sin_addr.s_addr, 4); 108 fd = socket(AF_INET, SOCK_DGRAM, 0); 109 (void) sendto(fd, ip, 4, 0, 110 (struct sockaddr *)&san, sizeof(san)); 111 sleep(1); 112 (void) close(fd); 113 goto tryagain; 114 } 115 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 116 if (errno != ENXIO) 117 perror("SIOCGARP"); 118 return (-1); 119 } 120 121 if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && 122 (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && 123 (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { 124 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 125 return (-1); 126 } 127 128 bcopy(ar.arp_ha.sa_data, ether, 6); 129 savearp: 130 bcopy(ether, ethersave, 6); 131 bcopy(ip, ipsave, 4); 132 return (0); 133 } 134