1145519Sdarrenr/* $FreeBSD$ */ 2145510Sdarrenr 322514Sdarrenr/* 453024Sguido * arp.c (C) 1995-1998 Darren Reed 522514Sdarrenr * 680486Sdarrenr * See the IPFILTER.LICENCE file for details on licencing. 722514Sdarrenr */ 8145510Sdarrenr#if !defined(lint) 9145510Sdarrenrstatic const char sccsid[] = "@(#)arp.c 1.4 1/11/96 (C)1995 Darren Reed"; 10255332Scystatic const char rcsid[] = "@(#)$Id$"; 1192686Sdarrenr#endif 1222514Sdarrenr#include <sys/types.h> 1322514Sdarrenr#include <sys/socket.h> 14153881Sguido#if !defined(ultrix) && !defined(hpux) && !defined(__hpux) && !defined(__osf__) && !defined(_AIX51) 15170268Sdarrenr# include <sys/sockio.h> 1631183Speter#endif 1722514Sdarrenr#include <sys/ioctl.h> 18145510Sdarrenr#include <netinet/in_systm.h> 1922514Sdarrenr#include <netinet/in.h> 2022514Sdarrenr#include <net/if.h> 2153024Sguido#include <netinet/if_ether.h> 2231183Speter#ifndef ultrix 23170268Sdarrenr# include <net/if_arp.h> 2431183Speter#endif 2524583Sdarrenr#include <netinet/in.h> 26145510Sdarrenr#include <netinet/ip.h> 2724583Sdarrenr#include <netinet/ip_var.h> 2824583Sdarrenr#include <netinet/tcp.h> 29145510Sdarrenr#include <stdio.h> 30145510Sdarrenr#include <errno.h> 31145510Sdarrenr#include <netdb.h> 3224583Sdarrenr#include "ipsend.h" 3353024Sguido#include "iplang/iplang.h" 3422514Sdarrenr 3522514Sdarrenr 3622514Sdarrenr/* 3722514Sdarrenr * lookup host and return 3822514Sdarrenr * its IP address in address 3922514Sdarrenr * (4 bytes) 4022514Sdarrenr */ 41145510Sdarrenrint resolve(host, address) 42255332Scy char *host, *address; 4322514Sdarrenr{ 4422514Sdarrenr struct hostent *hp; 4522514Sdarrenr u_long add; 4622514Sdarrenr 4722514Sdarrenr add = inet_addr(host); 4822514Sdarrenr if (add == -1) 4922514Sdarrenr { 5022514Sdarrenr if (!(hp = gethostbyname(host))) 5122514Sdarrenr { 5222514Sdarrenr fprintf(stderr, "unknown host: %s\n", host); 5322514Sdarrenr return -1; 5422514Sdarrenr } 5522514Sdarrenr bcopy((char *)hp->h_addr, (char *)address, 4); 5622514Sdarrenr return 0; 5722514Sdarrenr } 5822514Sdarrenr bcopy((char*)&add, address, 4); 5922514Sdarrenr return 0; 6022514Sdarrenr} 6122514Sdarrenr 6222514Sdarrenr/* 6322514Sdarrenr * ARP for the MAC address corresponding 6422514Sdarrenr * to the IP address. This taken from 6522514Sdarrenr * some BSD program, I cant remember which. 6622514Sdarrenr */ 6722514Sdarrenrint arp(ip, ether) 68255332Scy char *ip; 69255332Scy char *ether; 7022514Sdarrenr{ 7122514Sdarrenr static int sfd = -1; 7222514Sdarrenr static char ethersave[6], ipsave[4]; 7322514Sdarrenr struct arpreq ar; 7422514Sdarrenr struct sockaddr_in *sin, san; 7522514Sdarrenr struct hostent *hp; 7622514Sdarrenr int fd; 7722514Sdarrenr 7853024Sguido#ifdef IPSEND 7953024Sguido if (arp_getipv4(ip, ether) == 0) 8053024Sguido return 0; 8153024Sguido#endif 8222514Sdarrenr if (!bcmp(ipsave, ip, 4)) { 8322514Sdarrenr bcopy(ethersave, ether, 6); 8422514Sdarrenr return 0; 8522514Sdarrenr } 8622514Sdarrenr fd = -1; 8722514Sdarrenr bzero((char *)&ar, sizeof(ar)); 8822514Sdarrenr sin = (struct sockaddr_in *)&ar.arp_pa; 8922514Sdarrenr sin->sin_family = AF_INET; 9022514Sdarrenr bcopy(ip, (char *)&sin->sin_addr.s_addr, 4); 9131183Speter#ifndef hpux 9222514Sdarrenr if ((hp = gethostbyaddr(ip, 4, AF_INET))) 93145510Sdarrenr# if SOLARIS && (SOLARIS2 >= 10) 94145510Sdarrenr if (!(ether_hostton(hp->h_name, (struct ether_addr *)ether))) 95145510Sdarrenr# else 9622514Sdarrenr if (!(ether_hostton(hp->h_name, ether))) 97145510Sdarrenr# endif 9822514Sdarrenr goto savearp; 9931183Speter#endif 10022514Sdarrenr 10122514Sdarrenr if (sfd == -1) 10222514Sdarrenr if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) 10322514Sdarrenr { 10422514Sdarrenr perror("arp: socket"); 10522514Sdarrenr return -1; 10622514Sdarrenr } 10722514Sdarrenrtryagain: 10822514Sdarrenr if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1) 10922514Sdarrenr { 11022514Sdarrenr if (fd == -1) 11122514Sdarrenr { 11222514Sdarrenr bzero((char *)&san, sizeof(san)); 11322514Sdarrenr san.sin_family = AF_INET; 11422514Sdarrenr san.sin_port = htons(1); 11522514Sdarrenr bcopy(ip, &san.sin_addr.s_addr, 4); 11622514Sdarrenr fd = socket(AF_INET, SOCK_DGRAM, 0); 11722514Sdarrenr (void) sendto(fd, ip, 4, 0, 11822514Sdarrenr (struct sockaddr *)&san, sizeof(san)); 11922514Sdarrenr sleep(1); 12022514Sdarrenr (void) close(fd); 12122514Sdarrenr goto tryagain; 12222514Sdarrenr } 12322514Sdarrenr fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 12422514Sdarrenr if (errno != ENXIO) 12522514Sdarrenr perror("SIOCGARP"); 12622514Sdarrenr return -1; 12722514Sdarrenr } 12822514Sdarrenr 129145510Sdarrenr if ((ar.arp_ha.sa_data[0] == 0) && (ar.arp_ha.sa_data[1] == 0) && 130145510Sdarrenr (ar.arp_ha.sa_data[2] == 0) && (ar.arp_ha.sa_data[3] == 0) && 131145510Sdarrenr (ar.arp_ha.sa_data[4] == 0) && (ar.arp_ha.sa_data[5] == 0)) { 132145510Sdarrenr fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr)); 133145510Sdarrenr return -1; 134145510Sdarrenr } 135145510Sdarrenr 13622514Sdarrenr bcopy(ar.arp_ha.sa_data, ether, 6); 13722514Sdarrenrsavearp: 13822514Sdarrenr bcopy(ether, ethersave, 6); 13922514Sdarrenr bcopy(ip, ipsave, 4); 14022514Sdarrenr return 0; 14122514Sdarrenr} 142