4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <netinet/in.h>
32 #include <arpa/inet.h>
36 #include <nss_dbdefs.h>
39 int str2netent(const char *, int, void *, char *, int);
41 static int net_stayopen
;
43 * Unsynchronized, but it affects only
44 * efficiency, not correctness
47 static DEFINE_NSS_DB_ROOT(db_root
);
48 static DEFINE_NSS_GETENT(context
);
51 _nss_initf_net(nss_db_params_t
*p
)
53 p
->name
= NSS_DBNAM_NETWORKS
;
54 p
->default_config
= NSS_DEFCONF_NETWORKS
;
58 getnetbyname_r(const char *name
, struct netent
*result
,
59 char *buffer
, int buflen
)
64 if (name
== (const char *)NULL
) {
68 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2netent
);
70 arg
.stayopen
= net_stayopen
;
71 res
= nss_search(&db_root
, _nss_initf_net
,
72 NSS_DBOP_NETWORKS_BYNAME
, &arg
);
74 (void) NSS_XbyY_FINI(&arg
);
75 return ((struct netent
*)arg
.returnval
);
79 getnetbyaddr_r(long net
, int type
, struct netent
*result
,
80 char *buffer
, int buflen
)
85 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2netent
);
86 arg
.key
.netaddr
.net
= (uint32_t)net
;
87 arg
.key
.netaddr
.type
= type
;
88 arg
.stayopen
= net_stayopen
;
89 res
= nss_search(&db_root
, _nss_initf_net
,
90 NSS_DBOP_NETWORKS_BYADDR
, &arg
);
92 (void) NSS_XbyY_FINI(&arg
);
93 return ((struct netent
*)arg
.returnval
);
99 net_stayopen
|= stay
; /* === Or maybe just "=" ? */
100 nss_setent(&db_root
, _nss_initf_net
, &context
);
108 nss_endent(&db_root
, _nss_initf_net
, &context
);
109 nss_delete(&db_root
);
114 getnetent_r(struct netent
*result
, char *buffer
, int buflen
)
119 NSS_XbyY_INIT(&arg
, result
, buffer
, buflen
, str2netent
);
120 /* No stayopen flag; of course you stay open for iteration */
121 res
= nss_getent(&db_root
, _nss_initf_net
, &context
, &arg
);
123 (void) NSS_XbyY_FINI(&arg
);
124 return ((struct netent
*)arg
.returnval
);
128 * Return values: 0 = success, 1 = parse error, 2 = erange ...
129 * The structure pointer passed in is a structure in the caller's space
130 * wherein the field pointers would be set to areas in the buffer if
131 * need be. instring and buffer should be separate areas.
134 str2netent(const char *instr
, int lenstr
,
135 void *ent
/* really (struct netnet *) */, char *buffer
, int buflen
)
137 struct netent
*net
= (struct netent
*)ent
;
138 const char *p
, *numstart
, *limit
, *namestart
;
143 if ((instr
>= buffer
&& (buffer
+ buflen
) > instr
) ||
144 (buffer
>= instr
&& (instr
+ lenstr
) > buffer
)) {
145 return (NSS_STR_PARSE_PARSE
);
151 while (p
< limit
&& isspace(*p
)) {
155 while (p
< limit
&& !isspace(*p
)) {
156 p
++; /* Skip over the canonical name */
158 namelen
= (int)(p
- namestart
);
160 if (buflen
<= namelen
) { /* not enough buffer */
161 return (NSS_STR_PARSE_ERANGE
);
163 (void) memcpy(buffer
, namestart
, namelen
);
164 buffer
[namelen
] = '\0';
165 net
->n_name
= buffer
;
167 while (p
< limit
&& isspace(*p
)) {
171 /* Syntax error -- no net number */
172 return (NSS_STR_PARSE_PARSE
);
176 p
++; /* Find the end of the net number */
177 } while (p
< limit
&& !isspace(*p
));
178 numlen
= p
- numstart
;
179 if (numlen
>= (ptrdiff_t)sizeof (numbuf
)) {
180 /* Syntax error -- supposed number is too long */
181 return (NSS_STR_PARSE_PARSE
);
183 (void) memcpy(numbuf
, numstart
, numlen
);
184 numbuf
[numlen
] = '\0';
185 net
->n_net
= inet_network(numbuf
);
186 if (net
->n_net
== (in_addr_t
)-1) {
187 /* inet_network failed to parse the string */
188 return (NSS_STR_PARSE_PARSE
);
191 net
->n_addrtype
= AF_INET
;
193 while (p
< limit
&& isspace(*p
)) {
197 * Although nss_files_XY_all calls us with # stripped,
198 * we should be able to deal with it here in order to
201 if (p
>= limit
|| *p
== '#') { /* no aliases, no problem */
204 ptr
= (char **)ROUND_UP(buffer
+ namelen
+ 1,
206 if ((char *)ptr
>= buffer
+ buflen
) {
207 net
->n_aliases
= 0; /* hope they don't try to peek in */
208 return (NSS_STR_PARSE_ERANGE
);
211 net
->n_aliases
= ptr
;
212 return (NSS_STR_PARSE_SUCCESS
);
215 net
->n_aliases
= _nss_netdb_aliases(p
, lenstr
- (int)(p
- instr
),
216 buffer
+ namelen
+ 1, buflen
- namelen
- 1);
217 return (NSS_STR_PARSE_SUCCESS
);