]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ipfilter/ipsend/arp.c
Import of ipfilter 3.3.3 in anticipation of its revival.
[FreeBSD/FreeBSD.git] / contrib / ipfilter / ipsend / arp.c
1 /*
2  * arp.c (C) 1995-1998 Darren Reed
3  *
4  * Redistribution and use in source and binary forms are permitted
5  * provided that this notice is preserved and due credit is given
6  * to the original author and the contributors.
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.1 1999/08/04 17:31:03 darrenr Exp $";
11 #endif
12 #include <stdio.h>
13 #include <errno.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #if !defined(ultrix) && !defined(hpux)
17 #include <sys/sockio.h>
18 #endif
19 #include <sys/ioctl.h>
20 #include <netdb.h>
21 #include <netinet/in.h>
22 #include <net/if.h>
23 #include <netinet/if_ether.h>
24 #ifndef ultrix
25 #include <net/if_arp.h>
26 #endif
27 #include <netinet/in.h>
28 #include <netinet/ip_var.h>
29 #include <netinet/tcp.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 (!(ether_hostton(hp->h_name, ether)))
92                         goto savearp;
93 #endif
94
95         if (sfd == -1)
96                 if ((sfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
97                     {
98                         perror("arp: socket");
99                         return -1;
100                     }
101 tryagain:
102         if (ioctl(sfd, SIOCGARP, (caddr_t)&ar) == -1)
103             {
104                 if (fd == -1)
105                     {
106                         bzero((char *)&san, sizeof(san));
107                         san.sin_family = AF_INET;
108                         san.sin_port = htons(1);
109                         bcopy(ip, &san.sin_addr.s_addr, 4);
110                         fd = socket(AF_INET, SOCK_DGRAM, 0);
111                         (void) sendto(fd, ip, 4, 0,
112                                       (struct sockaddr *)&san, sizeof(san));
113                         sleep(1);
114                         (void) close(fd);
115                         goto tryagain;
116                     }
117                 fprintf(stderr, "(%s):", inet_ntoa(sin->sin_addr));
118                 if (errno != ENXIO)
119                         perror("SIOCGARP");
120                 return -1;
121             }
122
123         bcopy(ar.arp_ha.sa_data, ether, 6);
124 savearp:
125         bcopy(ether, ethersave, 6);
126         bcopy(ip, ipsave, 4);
127         return 0;
128 }