1 /*
2  *  $Id: resolve.c,v 1.2 1999/05/27 02:32:19 dugsong Exp $
3  *
4  *  libnet
5  *  resolve.c - various name resolution type routines
6  *
7  *  Copyright (c) 1998, 1999 Mike D. Schiffman <mike@infonexus.com>
8  *                           route|daemon9 <route@infonexus.com>
9  *  All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  */
33 
34 #if (HAVE_CONFIG_H)
35 #include "../include/config.h"
36 #endif
37 #include "../include/libnet.h"
38 
39 u_char *
host_lookup(u_long in,u_short use_name)40 host_lookup(u_long in, u_short use_name)
41 {
42     static u_char hostname[512], hostname2[512];
43     static u_short which;
44     u_char *p;
45 
46     struct hostent *host_ent = NULL;
47     struct in_addr addr;
48 
49     /*
50      *  Swap to the other buffer.  We swap static buffers to avoid having to
51      *  pass in a char *.  This makes the code that calls this function more
52      *  intuitive, but makes this function ugly.  This function is seriously
53      *  non-reentrant.  For threaded applications (or for signal handler code)
54      *  use host_lookup_r().
55      */
56     which++;
57 
58     if (use_name)
59     {
60         addr.s_addr = in;
61         host_ent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
62     }
63     if (!host_ent)
64     {
65 
66         p = (u_char *)&in;
67         sprintf(((which % 2) ? hostname : hostname2),  "%d.%d.%d.%d",
68                 (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
69     }
70     else if (use_name)
71     {
72         strncpy(((which % 2) ? hostname : hostname2), host_ent->h_name,
73                                                         sizeof(hostname));
74     }
75     return (which % 2) ? (hostname) : (hostname2);
76 }
77 
78 
79 void
host_lookup_r(u_long in,u_short use_name,u_char * hostname)80 host_lookup_r(u_long in, u_short use_name, u_char *hostname)
81 {
82     u_char *p;
83     struct hostent *host_ent = NULL;
84     struct in_addr addr;
85 
86     if (use_name)
87     {
88         addr.s_addr = in;
89         host_ent = gethostbyaddr((char *)&addr, sizeof(struct in_addr), AF_INET);
90     }
91     if (!host_ent)
92     {
93 
94         p = (u_char *)&in;
95         sprintf(hostname, "%d.%d.%d.%d",
96                 (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255));
97     }
98     else
99     {
100         /* XXX - sizeof(hostname) == 4 bytes you moron.  FIX THAT. - r */
101         strncpy(hostname, host_ent->h_name, sizeof(hostname));
102     }
103 }
104 
105 
106 u_long
name_resolve(u_char * host_name,u_short use_name)107 name_resolve(u_char *host_name, u_short use_name)
108 {
109     struct in_addr addr;
110     struct hostent *host_ent;
111     u_long l;
112     u_int val;
113     int i;
114 
115     if (use_name)
116     {
117         if ((addr.s_addr = inet_addr(host_name)) == -1)
118         {
119             if (!(host_ent = gethostbyname(host_name))) return (-1);
120             memcpy((char *)&addr.s_addr, host_ent->h_addr, host_ent->h_length);
121         }
122         return (addr.s_addr);
123     }
124     else
125     {
126         /*
127          *  We only want dots 'n decimals.
128          */
129         if (!isdigit(host_name[0])) return (-1L);
130 
131         l = 0;
132         for (i = 0; i < 4; i++)
133         {
134             l <<= 8;
135             if (*host_name)
136             {
137                 val = 0;
138                 while (*host_name && *host_name != '.')
139                 {
140                     val *= 10;
141                     val += *host_name - '0';
142                     if (val > 255) return (-1L);
143                     host_name++;
144                 }
145                 l |= val;
146                 if (*host_name) host_name++;
147             }
148         }
149         return (htonl(l));
150     }
151 }
152 
153 
154 u_long
get_ipaddr(struct link_int * l,const u_char * device,char * ebuf)155 get_ipaddr(struct link_int *l, const u_char *device, char *ebuf)
156 {
157     struct ifreq ifr;
158     register struct sockaddr_in *sin;
159     int fd;
160 
161     /*
162      *  Create dummy socket to perform an ioctl upon.
163      */
164     fd = socket(PF_INET, SOCK_DGRAM, 0);
165     if (fd < 0)
166     {
167         sprintf(ebuf, "socket: %s", strerror(errno));
168         return (0);
169     }
170 
171     memset(&ifr, 0, sizeof(ifr));
172     sin = (struct sockaddr_in *)&ifr.ifr_addr;
173     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
174 
175     ifr.ifr_addr.sa_family = AF_INET;
176 
177     if (ioctl(fd, SIOCGIFADDR, (char*) &ifr) < 0)
178     {
179         close(fd);
180         return(0);
181     }
182     close(fd);
183     return (ntohl(sin->sin_addr.s_addr));
184 }
185 
186 #if (RAW_IS_COOKED)
187 u_long
libnet_get_interface_by_dest(u_long dest,char * ebuf)188 libnet_get_interface_by_dest(u_long dest, char *ebuf)
189 {
190     int fd, len;
191 
192     struct sockaddr_in destsin;
193     struct sockaddr_in resultsin;
194 
195     memset(&destsin,0,sizeof(destsin));
196 
197     destsin.sin_family=AF_INET;
198     destsin.sin_port=4096;
199     destsin.sin_addr.s_addr=dest;
200 
201     fd=socket(PF_INET, SOCK_DGRAM, 0);
202     if (fd < 0)
203     {
204         sprintf(ebuf, "socket: %s", strerror(errno));
205         return (0);
206     }
207 
208     if (connect(fd,(struct sockaddr *)&destsin,sizeof destsin)==-1)
209     {
210         sprintf(ebuf, "connect: %s", strerror(errno));
211         close(fd);
212         return (0);
213     }
214 
215     len=sizeof(resultsin);
216     if (getsockname(fd,(struct sockaddr *)&resultsin,&len)==-1)
217     {
218         sprintf(ebuf, "getsockname: %s", strerror(errno));
219         close(fd);
220         return (0);
221     }
222 
223     close(fd);
224 
225     return ntohl(resultsin.sin_addr.s_addr);
226 }
227 #endif /* RAW_IS_COOKED */
228 /*
229  *  get_hwaddr routine moved to arch specifc files (sockpacket.c, bpf.c, etc)
230  */
231 
232 /* EOF */
233