2 * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
4 * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
8 # network-name number [aliases ...]
9 loopback 127.0.0.0 # optional aliases
11 network-name: symbolic name of the netwkork
12 number: official number of the network in dotted quad
13 aliases: case sensitive optional space or tab separated list of other names
20 #include <netinet/in.h>
21 #include <arpa/inet.h>
24 #include "internal/parse_config.h"
26 #include <bits/uClibc_mutex.h>
27 __UCLIBC_MUTEX_STATIC(mylock
, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
);
31 #define MAXTOKENS (MINTOKENS + MAXALIASES + 1)
32 #define BUFSZ (255) /* one line */
33 #define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))
35 static parser_t
*netp
= NULL
;
36 static struct netent nete
;
37 static char *netbuf
= NULL
;
38 static smallint net_stayopen
;
40 void setnetent(int stayopen
)
42 __UCLIBC_MUTEX_LOCK(mylock
);
45 netp
= config_open(_PATH_NETWORKS
);
48 __UCLIBC_MUTEX_UNLOCK(mylock
);
50 libc_hidden_def(setnetent
)
54 __UCLIBC_MUTEX_LOCK(mylock
);
60 __UCLIBC_MUTEX_UNLOCK(mylock
);
62 libc_hidden_def(endnetent
)
64 int getnetent_r(struct netent
*result_buf
,
65 char *buf
, size_t buflen
, struct netent
**result
,
70 const size_t aliaslen
= sizeof(char *) * MAXTOKENS
;
76 || (buflen
- aliaslen
) < BUFSZ
+ 1)
79 __UCLIBC_MUTEX_LOCK(mylock
);
82 setnetent(net_stayopen
);
86 netp
->data_len
= aliaslen
;
87 netp
->line_len
= buflen
- aliaslen
;
88 /* <name>[[:space:]]<netnumber>[[:space:]][<aliases>] */
89 if (!config_read(netp
, &tok
, MAXTOKENS
-1, MINTOKENS
, "# \t/", PARSE_NORMAL
)) {
92 result_buf
->n_name
= *(tok
++);
94 struct addrinfo hints
, *addri
;
95 # define sa4_to_uint32(sa) \
96 (ntohl(((struct sockaddr_in*)sa)->sin_addr.s_addr))
97 #ifdef __UCLIBC_HAS_IPV6__
98 # define sa6_to_uint8(sa) \
99 (ntohl(((struct sockaddr_in6*)sa)->sin6_addr.s6_addr))
101 memset(&hints
, 0, sizeof(struct addrinfo
));
102 hints
.ai_family
= AF_UNSPEC
;
103 hints
.ai_flags
= AI_NUMERICHOST
;
104 getaddrinfo(*(tok
++), NULL
, &hints
, &addri
);
105 result_buf
->n_addrtype
= addri
->ai_family
;
107 #if 0 /*FIXME: implement me! def __UCLIBC_HAS_IPV6__ */
108 addri
->ai_family
== AF_INET6
? sa6_to_uint8(addri
->ai_addr
) :
110 sa4_to_uint32(addri
->ai_addr
);
113 result_buf
->n_aliases
= tok
;
114 *result
= result_buf
;
117 __UCLIBC_MUTEX_UNLOCK(mylock
);
122 libc_hidden_def(getnetent_r
)
124 static void __initbuf(void)
127 netbuf
= malloc(SBUFSIZE
);
133 struct netent
*getnetent(void)
135 struct netent
*result
;
139 getnetent_r(&nete
, netbuf
, SBUFSIZE
, &result
, &herrnop
);
143 int getnetbyname_r(const char *name
,
144 struct netent
*result_buf
, char *buf
, size_t buflen
,
145 struct netent
**result
,
153 __UCLIBC_MUTEX_LOCK(mylock
);
154 setnetent(net_stayopen
);
155 while (!(ret
= getnetent_r(result_buf
, buf
, buflen
, result
, &herrnop
))) {
156 if (strcmp(name
, result_buf
->n_name
) == 0)
158 for (cp
= result_buf
->n_aliases
; *cp
; cp
++)
159 if (strcmp(name
, *cp
) == 0)
165 __UCLIBC_MUTEX_UNLOCK(mylock
);
166 return *result
? 0 : ret
;
168 libc_hidden_def(getnetbyname_r
)
170 struct netent
*getnetbyname(const char *name
)
172 struct netent
*result
;
176 getnetbyname_r(name
, &nete
, netbuf
, SBUFSIZE
, &result
, &herrnop
);
180 int getnetbyaddr_r(uint32_t net
, int type
,
181 struct netent
*result_buf
, char *buf
,
182 size_t buflen
, struct netent
**result
,
188 __UCLIBC_MUTEX_LOCK(mylock
);
189 setnetent(net_stayopen
);
190 while (!(ret
= getnetent_r(result_buf
, buf
, buflen
, result
, &herrnop
))) {
191 if (net
== result_buf
->n_net
&& type
== result_buf
->n_addrtype
)
196 __UCLIBC_MUTEX_UNLOCK(mylock
);
197 return *result
? 0 : ret
;
199 libc_hidden_def(getnetbyaddr_r
)
201 struct netent
*getnetbyaddr(uint32_t net
, int type
)
203 struct netent
*result
;
207 getnetbyaddr_r(net
, type
, &nete
, netbuf
, SBUFSIZE
, &result
, &herrnop
);