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