1 /* $FreeBSD$ */ 2 3 /* 4 * arp.c (C) 1995-1998 Darren Reed 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8 #if !defined(lint) 9 static const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 10 static const char rcsid[] = "@(#)$Id$"; 11 #endif 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 # include <sys/sockio.h> 15 #include <sys/ioctl.h> 16 #include <netinet/in_systm.h> 17 #include <netinet/in.h> 18 #include <net/if.h> 19 #include <netinet/if_ether.h> 20 # include <net/if_arp.h> 21 #include <netinet/in.h> 22 #include <netinet/ip.h> 23 #include <netinet/ip_var.h> 24 #include <netinet/tcp.h> 25 #include <stdio.h> 26 #include <errno.h> 27 #include <netdb.h> 28 #include "ipsend.h" 29 #include "iplang/iplang.h" 30 31 32 /* 33 * lookup host and return 34 * its IP address in address 35 * (4 bytes) 36 */ 37 int resolve(char *host, char *address) 38 { 39 struct hostent *hp; 40 u_long add; 41 42 add = inet_addr(host); 43 if (add == -1) 44 { 45 if (!(hp = gethostbyname(host))) 46 { 47 fprintf(stderr, "unknown host: %s\n", host); 48 return (-1); 49 } 50 bcopy((char *)hp->h_addr, (char *)address, 4); 51 return (0); 52 } 53 bcopy((char*)&add, address, 4); 54 return (0); 55 } 56 57 /* 58 * ARP for the MAC address corresponding 59 * to the IP address. This taken from 60 * some BSD program, I cant remember which. 61 */ 62 int arp(ip, ether) 63 char *ip; 64 char *ether; 65 { 66 static int sfd = -1; 67 static char ethersave[6], ipsave[4]; 68 struct arpreq ar; 69 struct sockaddr_in *sin, san; 70 struct hostent *hp; 71 int fd; 72 73 #ifdef IPSEND 74 if (arp_getipv4(ip, ether) == 0) 75 return (0); 76 #endif 77 if (!bcmp(ipsave, ip, 4)) { 78 bcopy(ethersave, ether, 6); 79 return (0); 80 } 81 fd = -1; 82 bzero((char *)&ar, sizeof(ar)); 83 sin = (struct sockaddr_in *)&ar.arp_pa; 84 sin->sin_family = AF_INET; 85 bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); 86 if ((hp = gethostbyaddr(ip, 4, AF_INET))) 87 # if SOLARIS && (SOLARIS2 >= 10) 88 if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) 89 # else 90 if (!(ether_hostton(hp->h_name, ether))) 91 # endif 92 goto savearp; 93 94 if (sfd == -1) 95 if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 96 { 97 perror("arp: socket"); 98 return (-1); 99 } 100 tryagain: 101 if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) 102 { 103 if (fd == -1) 104 { 105 bzero((char *)&san, sizeof(san)); 106 san.sin_family = AF_INET; 107 san.sin_port = htons(1); 108 bcopy(ip, &san.sin_addr.s_addr, 4); 109 fd = socket(AF_INET, SOCK_DGRAM, 0); 110 (void) sendto(fd, ip, 4, 0, 111 (struct sockaddr *)&san, sizeof(san)); 112 sleep(1); 113 (void) close(fd); 114 goto tryagain; 115 } 116 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 117 if (errno != ENXIO) 118 perror("SIOCGARP"); 119 return (-1); 120 } 121 122 if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && 123 (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && 124 (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { 125 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 126 return (-1); 127 } 128 129 bcopy(ar.arp_ha.sa_data, ether, 6); 130 savearp: 131 bcopy(ether, ethersave, 6); 132 bcopy(ip, ipsave, 4); 133 return (0); 134 } 135