1 /* vi: set sw=4 ts=4: */
3 * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
5 * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
9 # network-name number [aliases ...]
10 loopback 127.0.0.0 # optional aliases
12 network-name: symbolic name of the netwkork
13 number: official number of the network in dotted quad
14 aliases: case sensitive optional space or tab separated list of other names
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
25 #include "internal/parse_config.h"
27 #include <bits/uClibc_mutex.h>
28 __UCLIBC_MUTEX_STATIC(mylock
, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
);
32 #define MAXTOKENS (MINTOKENS + MAXALIASES + 1)
33 #define BUFSZ (255) /* one line */
34 #define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))
36 static parser_t
*netp
= NULL
;
37 static struct netent nete
;
38 static char *netbuf
= NULL
;
39 static smallint net_stayopen
;
41 void setnetent(int stayopen
)
43 __UCLIBC_MUTEX_LOCK(mylock
);
46 netp
= config_open(_PATH_NETWORKS
);
49 __UCLIBC_MUTEX_UNLOCK(mylock
);
51 libc_hidden_def(setnetent
)
55 __UCLIBC_MUTEX_LOCK(mylock
);
61 __UCLIBC_MUTEX_UNLOCK(mylock
);
63 libc_hidden_def(endnetent
)
65 int getnetent_r(struct netent
*result_buf
,
66 char *buf
, size_t buflen
, struct netent
**result
,
71 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
,
152 __UCLIBC_MUTEX_LOCK(mylock
);
153 setnetent(net_stayopen
);
154 while (!(ret
= getnetent_r(result_buf
, buf
, buflen
, result
, &herrnop
))) {
155 if (strcmp(name
, result_buf
->n_name
) == 0)
157 for (cp
= result_buf
->n_aliases
; *cp
; cp
++)
158 if (strcmp(name
, *cp
) == 0)
164 __UCLIBC_MUTEX_UNLOCK(mylock
);
165 return *result
? 0 : ret
;
167 libc_hidden_def(getnetbyname_r
)
169 struct netent
*getnetbyname(const char *name
)
171 struct netent
*result
;
175 getnetbyname_r(name
, &nete
, netbuf
, SBUFSIZE
, &result
, &herrnop
);
179 int getnetbyaddr_r(uint32_t net
, int type
,
180 struct netent
*result_buf
, char *buf
,
181 size_t buflen
, struct netent
**result
,
186 __UCLIBC_MUTEX_LOCK(mylock
);
187 setnetent(net_stayopen
);
188 while (!(ret
= getnetent_r(result_buf
, buf
, buflen
, result
, &herrnop
))) {
189 if (net
== result_buf
->n_net
&& type
== result_buf
->n_addrtype
)
194 __UCLIBC_MUTEX_UNLOCK(mylock
);
195 return *result
? 0 : ret
;
197 libc_hidden_def(getnetbyaddr_r
)
199 struct netent
*getnetbyaddr(uint32_t net
, int type
)
201 struct netent
*result
;
205 getnetbyaddr_r(net
, type
, &nete
, netbuf
, SBUFSIZE
, &result
, &herrnop
);