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>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <arpa/inet.h>
39 static pthread_mutex_t _network_lock
= PTHREAD_MUTEX_INITIALIZER
;
45 extern struct netent
*_res_getnetbyaddr();
46 extern struct netent
*_res_getnetbyname();
47 extern struct netent
*_old_getnetbyaddr();
48 extern struct netent
*_old_getnetbyname();
49 extern struct netent
*_old_getnetent();
50 extern void _old_setnetent();
51 extern void _old_endnetent();
53 #define ENTRY_SIZE sizeof(struct netent)
54 #define ENTRY_KEY _li_data_key_network
56 static struct netent
*
57 copy_network(struct netent
*in
)
59 if (in
== NULL
) return NULL
;
61 return (struct netent
*)LI_ils_create("s*44", in
->n_name
, in
->n_aliases
, in
->n_addrtype
, in
->n_net
);
65 * Extract the next network entry from a kvarray.
68 extract_network(kvarray_t
*in
)
71 uint32_t d
, k
, kcount
;
74 if (in
== NULL
) return NULL
;
79 if (d
>= in
->count
) return NULL
;
82 memset(&tmp
, 0, ENTRY_SIZE
);
84 tmp
.n_addrtype
= AF_INET
;
86 kcount
= in
->dict
[d
].kcount
;
88 for (k
= 0; k
< kcount
; k
++)
90 if (!strcmp(in
->dict
[d
].key
[k
], "n_name"))
92 if (tmp
.n_name
!= NULL
) continue;
93 if (in
->dict
[d
].vcount
[k
] == 0) continue;
95 tmp
.n_name
= (char *)in
->dict
[d
].val
[k
][0];
97 else if (!strcmp(in
->dict
[d
].key
[k
], "n_net"))
99 if (in
->dict
[d
].vcount
[k
] == 0) continue;
100 tmp
.n_net
= inet_network(in
->dict
[d
].val
[k
][0]);
102 else if (!strcmp(in
->dict
[d
].key
[k
], "n_addrtype"))
104 if (in
->dict
[d
].vcount
[k
] == 0) continue;
105 tmp
.n_addrtype
= atoi(in
->dict
[d
].val
[k
][0]);
107 else if (!strcmp(in
->dict
[d
].key
[k
], "n_aliases"))
109 if (tmp
.n_aliases
!= NULL
) continue;
110 if (in
->dict
[d
].vcount
[k
] == 0) continue;
112 tmp
.n_aliases
= (char **)in
->dict
[d
].val
[k
];
116 if (tmp
.n_name
== NULL
) tmp
.n_name
= "";
117 if (tmp
.n_aliases
== NULL
) tmp
.n_aliases
= empty
;
119 return copy_network(&tmp
);
122 static struct netent
*
123 ds_getnetbyaddr(uint32_t addr
, int type
)
125 static int proc
= -1;
126 unsigned char f1
, f2
, f3
;
129 if (type
!= AF_INET
) return NULL
;
137 if (f3
!= 0) snprintf(val
, sizeof(val
), "%u.%u.%u", f3
, f2
, f1
);
138 else if (f2
!= 0) snprintf(val
, sizeof(val
), "%u.%u", f2
, f1
);
139 else snprintf(val
, sizeof(val
), "%u", f1
);
141 return (struct netent
*)LI_getone("getnetbyaddr", &proc
, extract_network
, "net", val
);
144 static struct netent
*
145 ds_getnetbyname(const char *name
)
147 static int proc
= -1;
149 return (struct netent
*)LI_getone("getnetbyname", &proc
, extract_network
, "name", name
);
155 LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY
));
164 static struct netent
*
167 static int proc
= -1;
169 return (struct netent
*)LI_getent("getnetent", &proc
, extract_network
, ENTRY_KEY
, ENTRY_SIZE
);
172 static struct netent
*
173 getnet(const char *name
, uint32_t addr
, int type
, int source
)
175 struct netent
*res
= NULL
;
176 struct li_thread_info
*tdata
;
178 tdata
= LI_data_create_key(ENTRY_KEY
, ENTRY_SIZE
);
179 if (tdata
== NULL
) return NULL
;
186 res
= ds_getnetbyname(name
);
189 res
= ds_getnetbyaddr(addr
, type
);
192 res
= ds_getnetent();
199 pthread_mutex_lock(&_network_lock
);
204 res
= copy_network(_old_getnetbyname(name
));
207 res
= copy_network(_old_getnetbyaddr(addr
, type
));
210 res
= copy_network(_old_getnetent());
215 pthread_mutex_unlock(&_network_lock
);
218 LI_data_recycle(tdata
, res
, ENTRY_SIZE
);
219 return (struct netent
*)tdata
->li_entry
;
223 getnetbyaddr(uint32_t addr
, int type
)
225 return getnet(NULL
, addr
, type
, N_GET_ADDR
);
229 getnetbyname(const char *name
)
231 return getnet(name
, 0, 0, N_GET_NAME
);
237 return getnet(NULL
, 0, 0, N_GET_ENT
);
241 setnetent(int stayopen
)
243 if (_ds_running()) ds_setnetent();
244 else _old_setnetent(stayopen
);
250 if (_ds_running()) ds_endnetent();
251 else _old_endnetent();