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