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