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