2 * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (C) 1989 by NeXT, Inc.
29 #include <mach/mach.h>
32 #include <rpc/types.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
40 #include "_lu_types.h"
44 static pthread_mutex_t _network_lock
= PTHREAD_MUTEX_INITIALIZER
;
50 extern struct netent
*_res_getnetbyaddr();
51 extern struct netent
*_res_getnetbyname();
52 extern struct netent
*_old_getnetbyaddr();
53 extern struct netent
*_old_getnetbyname();
54 extern struct netent
*_old_getnetent();
55 extern void _old_setnetent();
56 extern void _old_endnetent();
58 extern mach_port_t _lu_port
;
59 extern int _lu_running(void);
62 free_network_data(struct netent
*n
)
66 if (n
== NULL
) return;
70 aliases
= n
->n_aliases
;
73 while (*aliases
!= NULL
) free(*aliases
++);
79 free_network(struct netent
*n
)
81 if (n
== NULL
) return;
87 free_lu_thread_info_network(void *x
)
89 struct lu_thread_info
*tdata
;
91 if (x
== NULL
) return;
93 tdata
= (struct lu_thread_info
*)x
;
95 if (tdata
->lu_entry
!= NULL
)
97 free_network((struct netent
*)tdata
->lu_entry
);
98 tdata
->lu_entry
= NULL
;
101 _lu_data_free_vm_xdr(tdata
);
106 static struct netent
*
107 extract_network(XDR
*xdr
)
110 int i
, j
, nvals
, nkeys
, status
;
113 if (xdr
== NULL
) return NULL
;
115 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
117 n
= (struct netent
*)calloc(1, sizeof(struct netent
));
119 n
->n_addrtype
= AF_INET
;
121 for (i
= 0; i
< nkeys
; i
++)
127 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
142 if ((n
->n_name
== NULL
) && (!strcmp("name", key
)))
147 n
->n_aliases
= (char **)calloc(nvals
, sizeof(char *));
148 for (j
= 1; j
< nvals
; j
++) n
->n_aliases
[j
-1] = vals
[j
];
152 else if (!strcmp("address", key
))
154 n
->n_net
= inet_network(vals
[0]);
160 for (; j
< nvals
; j
++) free(vals
[j
]);
165 if (n
->n_name
== NULL
) n
->n_name
= strdup("");
166 if (n
->n_aliases
== NULL
) n
->n_aliases
= (char **)calloc(1, sizeof(char *));
171 static struct netent
*
172 copy_network(struct netent
*in
)
177 if (in
== NULL
) return NULL
;
179 n
= (struct netent
*)calloc(1, sizeof(struct netent
));
181 n
->n_name
= LU_COPY_STRING(in
->n_name
);
184 if (in
->n_aliases
!= NULL
)
186 for (len
= 0; in
->n_aliases
[len
] != NULL
; len
++);
189 n
->n_aliases
= (char **)calloc(len
+ 1, sizeof(char *));
190 for (i
= 0; i
< len
; i
++)
192 n
->n_aliases
[i
] = strdup(in
->n_aliases
[i
]);
195 n
->n_addrtype
= in
->n_addrtype
;
196 n
->n_net
= in
->n_net
;
202 recycle_network(struct lu_thread_info
*tdata
, struct netent
*in
)
206 if (tdata
== NULL
) return;
207 n
= (struct netent
*)tdata
->lu_entry
;
212 tdata
->lu_entry
= NULL
;
215 if (tdata
->lu_entry
== NULL
)
217 tdata
->lu_entry
= in
;
221 free_network_data(n
);
223 n
->n_name
= in
->n_name
;
224 n
->n_aliases
= in
->n_aliases
;
225 n
->n_addrtype
= in
->n_addrtype
;
226 n
->n_net
= in
->n_net
;
231 static struct netent
*
232 lu_getnetbyaddr(long addr
, int type
)
237 static int proc
= -1;
241 if (type
!= AF_INET
) return NULL
;
245 if (_lookup_link(_lu_port
, "getnetbyaddr", &proc
) != KERN_SUCCESS
)
255 if (_lookup_all(_lu_port
, proc
, (unit
*)&addr
, 1, &lookup_buf
, &datalen
) != KERN_SUCCESS
)
260 datalen
*= BYTES_PER_XDR_UNIT
;
261 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
263 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
266 if (!xdr_int(&inxdr
, &count
))
269 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
276 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
280 n
= extract_network(&inxdr
);
282 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
287 static struct netent
*
288 lu_getnetbyname(const char *name
)
292 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
295 static int proc
= -1;
301 if (_lookup_link(_lu_port
, "getnetbyname", &proc
) != KERN_SUCCESS
)
307 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
308 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
310 xdr_destroy(&outxdr
);
317 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
,
318 xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
)
321 xdr_destroy(&outxdr
);
325 xdr_destroy(&outxdr
);
327 datalen
*= BYTES_PER_XDR_UNIT
;
328 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
330 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
333 if (!xdr_int(&inxdr
, &count
))
336 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
343 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
347 n
= extract_network(&inxdr
);
349 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
357 struct lu_thread_info
*tdata
;
359 tdata
= _lu_data_create_key(_lu_data_key_network
, free_lu_thread_info_network
);
360 _lu_data_free_vm_xdr(tdata
);
369 static struct netent
*
372 static int proc
= -1;
373 struct lu_thread_info
*tdata
;
376 tdata
= _lu_data_create_key(_lu_data_key_network
, free_lu_thread_info_network
);
379 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
380 _lu_data_set_key(_lu_data_key_network
, tdata
);
383 if (tdata
->lu_vm
== NULL
)
387 if (_lookup_link(_lu_port
, "getnetent", &proc
) != KERN_SUCCESS
)
394 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
400 /* mig stubs measure size in words (4 bytes) */
401 tdata
->lu_vm_length
*= 4;
403 if (tdata
->lu_xdr
!= NULL
)
405 xdr_destroy(tdata
->lu_xdr
);
408 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
410 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
411 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
418 if (tdata
->lu_vm_cursor
== 0)
424 n
= extract_network(tdata
->lu_xdr
);
431 tdata
->lu_vm_cursor
--;
436 static struct netent
*
437 getnet(const char *name
, long addr
, int type
, int source
)
439 struct netent
*res
= NULL
;
440 struct lu_thread_info
*tdata
;
442 tdata
= _lu_data_create_key(_lu_data_key_network
, free_lu_thread_info_network
);
445 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
446 _lu_data_set_key(_lu_data_key_network
, tdata
);
454 res
= lu_getnetbyname(name
);
457 res
= lu_getnetbyaddr(addr
, type
);
460 res
= lu_getnetent();
467 pthread_mutex_lock(&_network_lock
);
471 res
= copy_network(_old_getnetbyname(name
));
474 res
= copy_network(_old_getnetbyaddr(addr
, type
));
477 res
= copy_network(_old_getnetent());
481 pthread_mutex_unlock(&_network_lock
);
484 recycle_network(tdata
, res
);
485 return (struct netent
*)tdata
->lu_entry
;
489 getnetbyaddr(long addr
, int type
)
491 return getnet(NULL
, addr
, type
, N_GET_ADDR
);
495 getnetbyname(const char *name
)
497 return getnet(name
, 0, 0, N_GET_NAME
);
503 return getnet(NULL
, 0, 0, N_GET_ENT
);
507 setnetent(int stayopen
)
509 if (_lu_running()) lu_setnetent();
510 else _old_setnetent(stayopen
);
516 if (_lu_running()) lu_endnetent();
517 else _old_endnetent();