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 *)∈
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 *)∈
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