Libinfo-78.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_network.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * network lookup
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28 #include <stdlib.h>
29 #include <mach/mach.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include "lookup.h"
33 #include <rpc/types.h>
34 #include <rpc/xdr.h>
35 #include "_lu_types.h"
36 #include <netdb.h>
37 #include "lu_utils.h"
38 #include <sys/socket.h>
39 #import <netinet/in.h>
40
41 extern struct netent *_res_getnetbyaddr();
42 extern struct netent *_res_getnetbyname();
43 extern struct netent *_old_getnetbyaddr();
44 extern struct netent *_old_getnetbyname();
45 extern struct netent *_old_getnetent();
46 extern void _old_setnetent();
47 extern void _old_endnetent();
48
49 static lookup_state n_state = LOOKUP_CACHE;
50 static struct netent global_n;
51 static int global_free = 1;
52 static char *n_data = NULL;
53 static unsigned n_datalen;
54 static int n_nentries;
55 static int n_start = 1;
56 static XDR n_xdr;
57
58 static void
59 freeold(void)
60 {
61 char **aliases;
62
63 if (global_free == 1) return;
64
65 free(global_n.n_name);
66
67 aliases = global_n.n_aliases;
68 if (aliases != NULL)
69 {
70 while (*aliases != NULL) free(*aliases++);
71 free(global_n.n_aliases);
72 }
73
74 global_free = 1;
75 }
76
77 static void
78 convert_n(_lu_netent *lu_n)
79 {
80 int i, len;
81
82 freeold();
83
84 global_n.n_name = strdup(lu_n->n_names.n_names_val[0]);
85
86 len = lu_n->n_names.n_names_len - 1;
87 global_n.n_aliases = malloc((len + 1) * sizeof(char *));
88
89 for (i = 0; i < len; i++)
90 {
91 global_n.n_aliases[i] = strdup(lu_n->n_names.n_names_val[i + 1]);
92 }
93
94 global_n.n_aliases[len] = NULL;
95
96 global_n.n_addrtype = AF_INET;
97 global_n.n_net = lu_n->n_net;
98
99 global_free = 0;
100 }
101
102 static struct netent *
103 lu_getnetbyaddr(long addr, int type)
104 {
105 unsigned datalen;
106 _lu_netent_ptr lu_n;
107 XDR xdr;
108 static int proc = -1;
109 unit lookup_buf[MAX_INLINE_UNITS];
110
111 if (type != AF_INET)
112 {
113 return (NULL);
114 }
115
116 if (proc < 0)
117 {
118 if (_lookup_link(_lu_port, "getnetbyaddr", &proc) != KERN_SUCCESS)
119 {
120 return (NULL);
121 }
122 }
123
124 addr = htonl(addr);
125 datalen = MAX_INLINE_UNITS;
126 if (_lookup_one(_lu_port, proc, (unit *)&addr, 1, lookup_buf, &datalen)
127 != KERN_SUCCESS)
128 {
129 return (NULL);
130 }
131
132 datalen *= BYTES_PER_XDR_UNIT;
133 xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE);
134 lu_n = NULL;
135 if (!xdr__lu_netent_ptr(&xdr, &lu_n) || (lu_n == NULL))
136 {
137 xdr_destroy(&xdr);
138 return (NULL);
139 }
140
141 xdr_destroy(&xdr);
142
143 convert_n(lu_n);
144 xdr_free(xdr__lu_netent_ptr, &lu_n);
145 return (&global_n);
146 }
147
148 static struct netent *
149 lu_getnetbyname(const char *name)
150 {
151 unsigned datalen;
152 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
153 XDR outxdr;
154 XDR inxdr;
155 _lu_netent_ptr lu_n;
156 static int proc = -1;
157 unit lookup_buf[MAX_INLINE_UNITS];
158
159 if (proc < 0)
160 {
161 if (_lookup_link(_lu_port, "getnetbyname", &proc) != KERN_SUCCESS)
162 {
163 return (NULL);
164 }
165 }
166
167 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
168 if (!xdr__lu_string(&outxdr, &name))
169 {
170 xdr_destroy(&outxdr);
171 return (NULL);
172 }
173
174 datalen = MAX_INLINE_UNITS;
175 if (_lookup_one(_lu_port, proc, (unit *)namebuf,
176 xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen)
177 != KERN_SUCCESS)
178 {
179 xdr_destroy(&outxdr);
180 return (NULL);
181 }
182
183 xdr_destroy(&outxdr);
184
185 datalen *= BYTES_PER_XDR_UNIT;
186 xdrmem_create(&inxdr, lookup_buf, datalen,
187 XDR_DECODE);
188 lu_n = NULL;
189 if (!xdr__lu_netent_ptr(&inxdr, &lu_n) || (lu_n == NULL))
190 {
191 xdr_destroy(&inxdr);
192 return (NULL);
193 }
194
195 xdr_destroy(&inxdr);
196
197 convert_n(lu_n);
198 xdr_free(xdr__lu_netent_ptr, &lu_n);
199 return (&global_n);
200 }
201
202 static void
203 lu_endnetent()
204 {
205 n_nentries = 0;
206 if (n_data != NULL)
207 {
208 freeold();
209 vm_deallocate(mach_task_self(), (vm_address_t)n_data, n_datalen);
210 n_data = NULL;
211 }
212 }
213
214 static void
215 lu_setnetent()
216 {
217 lu_endnetent();
218 n_start = 1;
219 }
220
221 static struct netent *
222 lu_getnetent()
223 {
224 static int proc = -1;
225 _lu_netent lu_n;
226
227 if (n_start == 1)
228 {
229 n_start = 0;
230
231 if (proc < 0)
232 {
233 if (_lookup_link(_lu_port, "getnetent", &proc) != KERN_SUCCESS)
234 {
235 lu_endnetent();
236 return (NULL);
237 }
238 }
239
240 if (_lookup_all(_lu_port, proc, NULL, 0, &n_data, &n_datalen)
241 != KERN_SUCCESS)
242 {
243 lu_endnetent();
244 return (NULL);
245 }
246
247 #ifdef NOTDEF
248 /* NOTDEF because OOL buffers are counted in bytes with untyped IPC */
249 n_datalen *= BYTES_PER_XDR_UNIT;
250 #endif
251 xdrmem_create(&n_xdr, n_data, n_datalen,
252 XDR_DECODE);
253 if (!xdr_int(&n_xdr, &n_nentries))
254 {
255 xdr_destroy(&n_xdr);
256 lu_endnetent();
257 return (NULL);
258 }
259 }
260
261 if (n_nentries == 0)
262 {
263 xdr_destroy(&n_xdr);
264 lu_endnetent();
265 return (NULL);
266 }
267
268 bzero(&lu_n, sizeof(lu_n));
269 if (!xdr__lu_netent(&n_xdr, &lu_n))
270 {
271 xdr_destroy(&n_xdr);
272 lu_endnetent();
273 return (NULL);
274 }
275
276 n_nentries--;
277 convert_n(&lu_n);
278 xdr_free(xdr__lu_netent, &lu_n);
279 return (&global_n);
280 }
281
282 struct netent *
283 getnetbyaddr(long addr, int type)
284 {
285 struct netent *res;
286
287 if (_lu_running())
288 {
289 res = lu_getnetbyaddr(addr, type);
290 }
291 else
292 {
293 res = _res_getnetbyaddr(addr, type);
294 if (res == NULL) res = _old_getnetbyaddr(addr, type);
295 }
296
297 return res;
298 }
299
300 struct netent *
301 getnetbyname(const char *name)
302 {
303 struct netent *res;
304
305 if (_lu_running())
306 {
307 res = lu_getnetbyname(name);
308 }
309 else
310 {
311 res = _res_getnetbyname(name);
312 if (res == NULL) res = _old_getnetbyname(name);
313 }
314
315 return res;
316 }
317
318 struct netent *
319 getnetent(void)
320 {
321 GETENT(lu_getnetent, _old_getnetent, &n_state, struct netent);
322 }
323
324 void
325 setnetent(int stayopen)
326 {
327 SETSTATE(lu_setnetent, _old_setnetent, &n_state, stayopen);
328 }
329
330 void
331 endnetent(void)
332 {
333 UNSETSTATE(lu_endnetent, _old_endnetent, &n_state);
334 }