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