123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- * Copyright (C) 2010 Bernhard Reutner-Fischer <uclibc@uclibc.org>
- *
- * Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball.
- */
- /* /etc/networks
- # network-name number [aliases ...]
- loopback 127.0.0.0 # optional aliases
- network-name: symbolic name of the netwkork
- number: official number of the network in dotted quad
- aliases: case sensitive optional space or tab separated list of other names
- */
- #include <features.h>
- #include <netdb.h>
- #include <string.h>
- #include <stdlib.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <errno.h>
- #include <unistd.h>
- #include "internal/parse_config.h"
- #include <bits/uClibc_mutex.h>
- __UCLIBC_MUTEX_STATIC(mylock, PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP);
- #define MINTOKENS 2
- #define MAXALIASES 8
- #define MAXTOKENS (MINTOKENS + MAXALIASES + 1)
- #define BUFSZ (255) /* one line */
- #define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXTOKENS))
- static parser_t *netp = NULL;
- static struct netent nete;
- static char *netbuf = NULL;
- static smallint net_stayopen;
- void setnetent(int stayopen)
- {
- __UCLIBC_MUTEX_LOCK(mylock);
- if (netp)
- config_close(netp);
- netp = config_open(_PATH_NETWORKS);
- if (stayopen)
- net_stayopen = 1;
- __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- libc_hidden_def(setnetent)
- void endnetent(void)
- {
- __UCLIBC_MUTEX_LOCK(mylock);
- if (netp) {
- config_close(netp);
- netp = NULL;
- }
- net_stayopen = 0;
- __UCLIBC_MUTEX_UNLOCK(mylock);
- }
- libc_hidden_def(endnetent)
- int getnetent_r(struct netent *result_buf,
- char *buf, size_t buflen, struct netent **result,
- int *h_errnop
- )
- {
- char **tok = NULL;
- const size_t aliaslen = sizeof(char *) * MAXTOKENS;
- int ret = ERANGE;
- (void)h_errnop;
- *result = NULL;
- if (buflen < aliaslen
- || (buflen - aliaslen) < BUFSZ + 1)
- goto DONE_NOUNLOCK;
- __UCLIBC_MUTEX_LOCK(mylock);
- ret = ENOENT;
- if (netp == NULL)
- setnetent(net_stayopen);
- if (netp == NULL)
- goto DONE;
- netp->data = buf;
- netp->data_len = aliaslen;
- netp->line_len = buflen - aliaslen;
- /* <name>[[:space:]]<netnumber>[[:space:]][<aliases>] */
- if (!config_read(netp, &tok, MAXTOKENS-1, MINTOKENS, "# \t/", PARSE_NORMAL)) {
- goto DONE;
- }
- result_buf->n_name = *(tok++);
- {
- struct addrinfo hints, *addri;
- # define sa4_to_uint32(sa) \
- (ntohl(((struct sockaddr_in*)sa)->sin_addr.s_addr))
- #ifdef __UCLIBC_HAS_IPV6__
- # define sa6_to_uint8(sa) \
- (ntohl(((struct sockaddr_in6*)sa)->sin6_addr.s6_addr))
- #endif
- memset(&hints, 0, sizeof(struct addrinfo));
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_NUMERICHOST;
- getaddrinfo(*(tok++), NULL, &hints, &addri);
- result_buf->n_addrtype = addri->ai_family;
- result_buf->n_net =
- #if 0 /*FIXME: implement me! def __UCLIBC_HAS_IPV6__ */
- addri->ai_family == AF_INET6 ? sa6_to_uint8(addri->ai_addr) :
- #endif
- sa4_to_uint32(addri->ai_addr);
- freeaddrinfo(addri);
- }
- result_buf->n_aliases = tok;
- *result = result_buf;
- ret = 0;
- DONE:
- __UCLIBC_MUTEX_UNLOCK(mylock);
- DONE_NOUNLOCK:
- errno = ret;
- return errno;
- }
- libc_hidden_def(getnetent_r)
- static void __initbuf(void)
- {
- if (!netbuf) {
- netbuf = malloc(SBUFSIZE);
- if (!netbuf)
- abort();
- }
- }
- struct netent *getnetent(void)
- {
- struct netent *result;
- int herrnop;
- __initbuf();
- getnetent_r(&nete, netbuf, SBUFSIZE, &result, &herrnop);
- return result;
- }
- int getnetbyname_r(const char *name,
- struct netent *result_buf, char *buf, size_t buflen,
- struct netent **result,
- int *h_errnop
- )
- {
- register char **cp;
- int ret, herrnop;
- (void)h_errnop;
- __UCLIBC_MUTEX_LOCK(mylock);
- setnetent(net_stayopen);
- while (!(ret = getnetent_r(result_buf, buf, buflen, result, &herrnop))) {
- if (strcmp(name, result_buf->n_name) == 0)
- break;
- for (cp = result_buf->n_aliases; *cp; cp++)
- if (strcmp(name, *cp) == 0)
- goto gotname;
- }
- gotname:
- if (!net_stayopen)
- endnetent();
- __UCLIBC_MUTEX_UNLOCK(mylock);
- return *result ? 0 : ret;
- }
- libc_hidden_def(getnetbyname_r)
- struct netent *getnetbyname(const char *name)
- {
- struct netent *result;
- int herrnop;
- __initbuf();
- getnetbyname_r(name, &nete, netbuf, SBUFSIZE, &result, &herrnop);
- return result;
- }
- int getnetbyaddr_r(uint32_t net, int type,
- struct netent *result_buf, char *buf,
- size_t buflen, struct netent **result,
- int *h_errnop)
- {
- int ret, herrnop;
- (void)h_errnop;
- __UCLIBC_MUTEX_LOCK(mylock);
- setnetent(net_stayopen);
- while (!(ret = getnetent_r(result_buf, buf, buflen, result, &herrnop))) {
- if (net == result_buf->n_net && type == result_buf->n_addrtype)
- break;
- }
- if (!net_stayopen)
- endnetent();
- __UCLIBC_MUTEX_UNLOCK(mylock);
- return *result ? 0 : ret;
- }
- libc_hidden_def(getnetbyaddr_r)
- struct netent *getnetbyaddr(uint32_t net, int type)
- {
- struct netent *result;
- int herrnop;
- __initbuf();
- getnetbyaddr_r(net, type, &nete, netbuf, SBUFSIZE, &result, &herrnop);
- return result;
- }
|