1568 lines
38 KiB
Diff
1568 lines
38 KiB
Diff
diff -rupN uClibc-0.9.32-ori/extra/Configs/Config.in uClibc-0.9.32/extra/Configs/Config.in
|
|
--- uClibc-0.9.32-ori/extra/Configs/Config.in 2011-06-08 12:35:20.000000000 -0700
|
|
+++ uClibc-0.9.32/extra/Configs/Config.in 2012-11-14 00:13:00.485546754 -0800
|
|
@@ -1268,6 +1268,16 @@ config UCLIBC_HAS_EXTRA_COMPAT_RES_STATE
|
|
Answer Y if selecting UCLIBC_HAS_COMPAT_RES_STATE is not enough.
|
|
As far as I can say, this should never be needed.
|
|
|
|
+config UCLIBC_HAS_RESOLVER_SUPPORT
|
|
+ bool "DNS resolver functions"
|
|
+ select UCLIBC_HAS_COMPAT_RES_STATE
|
|
+ help
|
|
+ Provide implementations for DNS resolver functions.
|
|
+ In particular, the following functions will be added to the
|
|
+ library:
|
|
+
|
|
+ ns_get16, ns_get32, ns_put16, ns_put32
|
|
+
|
|
config UCLIBC_HAS_LIBRESOLV_STUB
|
|
bool "Provide libresolv stub"
|
|
default n
|
|
diff -rupN uClibc-0.9.32-ori/include/arpa/nameser.h uClibc-0.9.32/include/arpa/nameser.h
|
|
--- uClibc-0.9.32-ori/include/arpa/nameser.h 2011-06-08 12:35:20.000000000 -0700
|
|
+++ uClibc-0.9.32/include/arpa/nameser.h 2012-11-14 00:13:23.481545598 -0800
|
|
@@ -120,13 +120,9 @@ typedef struct __ns_msg {
|
|
|
|
/* Private data structure - do not use from outside library. */
|
|
struct _ns_flagdata { int mask, shift; };
|
|
-extern struct _ns_flagdata _ns_flagdata[];
|
|
+extern const struct _ns_flagdata _ns_flagdata[];
|
|
|
|
/* Accessor macros - this is part of the public interface. */
|
|
-#define ns_msg_getflag(handle, flag) ( \
|
|
- ((handle)._flags & _ns_flagdata[flag].mask) \
|
|
- >> _ns_flagdata[flag].shift \
|
|
- )
|
|
#define ns_msg_id(handle) ((handle)._id + 0)
|
|
#define ns_msg_base(handle) ((handle)._msg + 0)
|
|
#define ns_msg_end(handle) ((handle)._eom + 0)
|
|
@@ -499,6 +495,7 @@ typedef enum __ns_cert_types {
|
|
#define ns_samename __ns_samename
|
|
|
|
__BEGIN_DECLS
|
|
+int ns_msg_getflag (ns_msg, int) __THROW;
|
|
u_int ns_get16 (const u_char *) __THROW;
|
|
u_long ns_get32 (const u_char *) __THROW;
|
|
void ns_put16 (u_int, u_char *) __THROW;
|
|
@@ -521,6 +518,7 @@ int ns_name_ntol (const u_char *, u_cha
|
|
int ns_name_ntop (const u_char *, char *, size_t) __THROW;
|
|
libc_hidden_proto(ns_name_ntop)
|
|
int ns_name_pton (const char *, u_char *, size_t) __THROW;
|
|
+libc_hidden_proto(ns_name_pton)
|
|
int ns_name_unpack (const u_char *, const u_char *,
|
|
const u_char *, u_char *, size_t) __THROW;
|
|
libc_hidden_proto(ns_name_unpack)
|
|
diff -rupN uClibc-0.9.32-ori/include/resolv.h uClibc-0.9.32/include/resolv.h
|
|
--- uClibc-0.9.32-ori/include/resolv.h 2011-06-08 12:35:20.000000000 -0700
|
|
+++ uClibc-0.9.32/include/resolv.h 2012-11-14 00:13:36.605544938 -0800
|
|
@@ -138,7 +138,6 @@ struct __res_state {
|
|
} sort_list[MAXRESOLVSORT];
|
|
#endif
|
|
|
|
-#ifdef __UCLIBC_HAS_IPV6__
|
|
/* I assume that the intention is to store all
|
|
* DNS servers' addresses here, and duplicate in nsaddr_list[]
|
|
* those which have IPv4 address. In the case of IPv4 address
|
|
@@ -152,7 +151,9 @@ struct __res_state {
|
|
*/
|
|
union {
|
|
struct {
|
|
+#ifdef __UCLIBC_HAS_IPV6__
|
|
struct sockaddr_in6 *nsaddrs[MAXNS];
|
|
+#endif
|
|
u_int8_t nscount; /* (was: u_int16_t) */
|
|
#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
|
|
/* rather obscure, and differs in BSD and glibc */
|
|
@@ -166,7 +167,6 @@ struct __res_state {
|
|
#endif
|
|
} _ext;
|
|
} _u;
|
|
-#endif
|
|
|
|
#ifdef __UCLIBC_HAS_EXTRA_COMPAT_RES_STATE__
|
|
/* Truly obscure stuff.
|
|
@@ -292,8 +292,8 @@ __END_DECLS
|
|
#define res_init __res_init
|
|
#if 0
|
|
#define res_isourserver __res_isourserver
|
|
-#define res_mkquery __res_mkquery
|
|
#endif
|
|
+#define res_mkquery __res_mkquery
|
|
#define res_query __res_query
|
|
#define res_querydomain __res_querydomain
|
|
#define res_search __res_search
|
|
@@ -315,9 +315,9 @@ int res_init (void) __THROW;
|
|
libc_hidden_proto(res_init)
|
|
#if 0
|
|
int res_isourserver (const struct sockaddr_in *) __THROW;
|
|
+#endif
|
|
int res_mkquery (int, const char *, int, int, const u_char *,
|
|
int, const u_char *, u_char *, int) __THROW;
|
|
-#endif
|
|
int res_query (const char *, int, int, u_char *, int) __THROW;
|
|
libc_hidden_proto(res_query)
|
|
int res_querydomain (const char *, const char *, int, int,
|
|
@@ -332,12 +332,14 @@ __END_DECLS
|
|
#if 0
|
|
#define b64_ntop __b64_ntop
|
|
#define b64_pton __b64_pton
|
|
-#define dn_comp __dn_comp
|
|
#define dn_count_labels __dn_count_labels
|
|
#endif
|
|
+#define dn_comp __dn_comp
|
|
#define dn_expand __dn_expand
|
|
-#if 0
|
|
#define dn_skipname __dn_skipname
|
|
+#define res_ninit __res_ninit
|
|
+#define res_nclose __res_nclose
|
|
+#if 0
|
|
#define fp_resstat __fp_resstat
|
|
#define loc_aton __loc_aton
|
|
#define loc_ntoa __loc_ntoa
|
|
@@ -359,8 +361,6 @@ __END_DECLS
|
|
#define res_hostalias __res_hostalias
|
|
#define res_mailok __res_mailok
|
|
#define res_nameinquery __res_nameinquery
|
|
-#define res_nclose __res_nclose
|
|
-#define res_ninit __res_ninit
|
|
#define res_nmkquery __res_nmkquery
|
|
#define res_npquery __res_npquery
|
|
#define res_nquery __res_nquery
|
|
@@ -388,7 +388,6 @@ int b64_ntop (u_char const *, size_t, c
|
|
int b64_pton (char const *, u_char *, size_t) __THROW;
|
|
int loc_aton (const char *ascii, u_char *binary) __THROW;
|
|
const char * loc_ntoa (const u_char *binary, char *ascii) __THROW;
|
|
-int dn_skipname (const u_char *, const u_char *) __THROW;
|
|
void putlong (u_int32_t, u_char *) __THROW;
|
|
void putshort (u_int16_t, u_char *) __THROW;
|
|
const char * p_class (int) __THROW;
|
|
@@ -404,11 +403,14 @@ const u_char * p_fqname (const u_char *,
|
|
const char * p_option (u_long option) __THROW;
|
|
char * p_secstodate (u_long) __THROW;
|
|
int dn_count_labels (const char *) __THROW;
|
|
+#endif
|
|
+int dn_skipname (const u_char *, const u_char *) __THROW;
|
|
int dn_comp (const char *, u_char *, int, u_char **, u_char **)
|
|
__THROW;
|
|
-#endif
|
|
int dn_expand (const u_char *, const u_char *, const u_char *,
|
|
char *, int) __THROW;
|
|
+int res_ninit (res_state) __THROW;
|
|
+void res_nclose (res_state) __THROW;
|
|
#if 0
|
|
u_int res_randomid (void) __THROW;
|
|
int res_nameinquery (const char *, int, int,
|
|
@@ -417,7 +419,6 @@ int res_queriesmatch (const u_char *, c
|
|
const u_char *, const u_char *) __THROW;
|
|
const char * p_section (int section, int opcode) __THROW;
|
|
/* Things involving a resolver context. */
|
|
-int res_ninit (res_state) __THROW;
|
|
int res_nisourserver (const res_state,
|
|
const struct sockaddr_in *) __THROW;
|
|
void fp_resstat (const res_state, FILE *) __THROW;
|
|
@@ -436,7 +437,6 @@ int res_nmkquery (res_state, int, const
|
|
int) __THROW;
|
|
int res_nsend (res_state, const u_char *, int, u_char *, int)
|
|
__THROW;
|
|
-void res_nclose (res_state) __THROW;
|
|
#endif
|
|
__END_DECLS
|
|
|
|
diff -rupN uClibc-0.9.32-ori/libc/inet/Makefile.in uClibc-0.9.32/libc/inet/Makefile.in
|
|
--- uClibc-0.9.32-ori/libc/inet/Makefile.in 2011-06-08 12:35:20.000000000 -0700
|
|
+++ uClibc-0.9.32/libc/inet/Makefile.in 2012-11-14 00:13:40.317544752 -0800
|
|
@@ -37,7 +37,8 @@ CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(
|
|
get_hosts_byaddr_r.c get_hosts_byname_r.c \
|
|
gethostbyaddr_r.c gethostbyname_r.c gethostbyname2_r.c \
|
|
gethostbyaddr.c gethostbyname.c gethostbyname2.c
|
|
-CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += \
|
|
+CSRC-$(findstring y,$(UCLIBC_HAS_RESOLVER_SUPPORT)) += \
|
|
+ ns_netint.c ns_parse.c res_data.c \
|
|
res_init.c res_query.c res_comp.c ns_name.c \
|
|
_res_state.c
|
|
## # unused ATM
|
|
diff -rupN uClibc-0.9.32-ori/libc/inet/ns_netint.c uClibc-0.9.32/libc/inet/ns_netint.c
|
|
--- uClibc-0.9.32-ori/libc/inet/ns_netint.c 1969-12-31 16:00:00.000000000 -0800
|
|
+++ uClibc-0.9.32/libc/inet/ns_netint.c 2012-11-14 00:13:00.485546754 -0800
|
|
@@ -0,0 +1,8 @@
|
|
+/*
|
|
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
|
|
+ *
|
|
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
|
|
+ */
|
|
+
|
|
+#define L_ns_netint
|
|
+#include RESOLVER
|
|
diff -rupN uClibc-0.9.32-ori/libc/inet/ns_parse.c uClibc-0.9.32/libc/inet/ns_parse.c
|
|
--- uClibc-0.9.32-ori/libc/inet/ns_parse.c 1969-12-31 16:00:00.000000000 -0800
|
|
+++ uClibc-0.9.32/libc/inet/ns_parse.c 2012-11-14 00:13:23.485545598 -0800
|
|
@@ -0,0 +1,8 @@
|
|
+/*
|
|
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
|
|
+ *
|
|
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
|
|
+ */
|
|
+
|
|
+#define L_ns_parse
|
|
+#include RESOLVER
|
|
diff -rupN uClibc-0.9.32-ori/libc/inet/res_data.c uClibc-0.9.32/libc/inet/res_data.c
|
|
--- uClibc-0.9.32-ori/libc/inet/res_data.c 1969-12-31 16:00:00.000000000 -0800
|
|
+++ uClibc-0.9.32/libc/inet/res_data.c 2012-11-14 00:13:27.849545379 -0800
|
|
@@ -0,0 +1,8 @@
|
|
+/*
|
|
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
|
|
+ *
|
|
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
|
|
+ */
|
|
+
|
|
+#define L_res_data
|
|
+#include RESOLVER
|
|
diff -rupN uClibc-0.9.32-ori/libc/inet/resolv.c uClibc-0.9.32/libc/inet/resolv.c
|
|
--- uClibc-0.9.32-ori/libc/inet/resolv.c 2011-06-08 12:35:20.000000000 -0700
|
|
+++ uClibc-0.9.32/libc/inet/resolv.c 2012-11-14 00:13:32.697545135 -0800
|
|
@@ -297,6 +297,7 @@ Domain name in a message can be represen
|
|
#include <features.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
+#include <stdio_ext.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <sys/poll.h>
|
|
@@ -339,6 +340,9 @@ Domain name in a message can be represen
|
|
#define BUFSZ (80) /* one line */
|
|
#define SBUFSIZE (BUFSZ + 1 + (sizeof(char *) * MAXALIASES))
|
|
|
|
+#define NS_TYPE_ELT 0x40 /*%< EDNS0 extended label type */
|
|
+#define DNS_LABELTYPE_BITSTRING 0x41
|
|
+
|
|
#undef DEBUG
|
|
/* #define DEBUG */
|
|
|
|
@@ -590,7 +594,7 @@ int attribute_hidden __encode_header(str
|
|
|
|
return HFIXEDSZ;
|
|
}
|
|
-#endif
|
|
+#endif /* L_encodeh */
|
|
|
|
|
|
#ifdef L_decodeh
|
|
@@ -611,7 +615,7 @@ void attribute_hidden __decode_header(un
|
|
h->nscount = (data[8] << 8) | data[9];
|
|
h->arcount = (data[10] << 8) | data[11];
|
|
}
|
|
-#endif
|
|
+#endif /* L_decodeh */
|
|
|
|
|
|
#ifdef L_encoded
|
|
@@ -650,7 +654,7 @@ int attribute_hidden __encode_dotted(con
|
|
|
|
return used;
|
|
}
|
|
-#endif
|
|
+#endif /* L_encoded */
|
|
|
|
|
|
#ifdef L_decoded
|
|
@@ -717,7 +721,7 @@ int attribute_hidden __decode_dotted(con
|
|
|
|
return total;
|
|
}
|
|
-#endif
|
|
+#endif /* L_decoded */
|
|
|
|
|
|
#ifdef L_encodeq
|
|
@@ -745,7 +749,7 @@ int attribute_hidden __encode_question(c
|
|
|
|
return i + 4;
|
|
}
|
|
-#endif
|
|
+#endif /* L_encodeq */
|
|
|
|
|
|
#ifdef L_encodea
|
|
@@ -778,7 +782,7 @@ int attribute_hidden __encode_answer(str
|
|
|
|
return i + RRFIXEDSZ + a->rdlength;
|
|
}
|
|
-#endif
|
|
+#endif /* L_encodea */
|
|
|
|
|
|
#ifdef CURRENTLY_UNUSED
|
|
@@ -844,7 +848,7 @@ int __encode_packet(struct resolv_header
|
|
|
|
return total;
|
|
}
|
|
-#endif
|
|
+#endif /* L_encodep */
|
|
|
|
|
|
#ifdef L_decodep
|
|
@@ -855,7 +859,7 @@ int __decode_packet(unsigned char *data,
|
|
__decode_header(data, h);
|
|
return HFIXEDSZ;
|
|
}
|
|
-#endif
|
|
+#endif /* L_decodep */
|
|
|
|
|
|
#ifdef L_formquery
|
|
@@ -893,7 +897,7 @@ int __form_query(int id,
|
|
|
|
return i + j;
|
|
}
|
|
-#endif
|
|
+#endif /* L_formquery */
|
|
#endif /* CURRENTLY_UNUSED */
|
|
|
|
|
|
@@ -1116,7 +1120,7 @@ void attribute_hidden __open_nameservers
|
|
if (__res_sync)
|
|
__res_sync();
|
|
}
|
|
-#endif
|
|
+#endif /* L_opennameservers */
|
|
|
|
|
|
#ifdef L_closenameservers
|
|
@@ -1134,7 +1138,7 @@ void attribute_hidden __close_nameserver
|
|
__searchdomain = NULL;
|
|
/*__searchdomains = 0; - already is */
|
|
}
|
|
-#endif
|
|
+#endif /* L_closenameservers */
|
|
|
|
|
|
#ifdef L_dnslookup
|
|
@@ -1400,7 +1404,7 @@ int attribute_hidden __dns_lookup(const
|
|
goto try_next_server;
|
|
}
|
|
reply_timeout--;
|
|
-#else
|
|
+#else /* !USE_SELECT */
|
|
reply_timeout = __resolv_timeout * 1000;
|
|
wait_again:
|
|
fds.fd = fd;
|
|
@@ -1413,7 +1417,7 @@ int attribute_hidden __dns_lookup(const
|
|
}
|
|
/*TODO: better timeout accounting?*/
|
|
reply_timeout -= 1000;
|
|
-#endif
|
|
+#endif /* USE_SELECT */
|
|
|
|
/* vda: a bogus response seen in real world (caused SEGV in uclibc):
|
|
* "ping www.google.com" sending AAAA query and getting
|
|
@@ -1571,7 +1575,7 @@ int attribute_hidden __dns_lookup(const
|
|
free(packet);
|
|
return -1;
|
|
}
|
|
-#endif
|
|
+#endif /* L_dnslookup */
|
|
|
|
|
|
#ifdef L_read_etc_hosts_r
|
|
@@ -1700,7 +1704,7 @@ found:
|
|
return ret;
|
|
#undef in6
|
|
}
|
|
-#endif
|
|
+#endif /* L_read_etc_hosts_r */
|
|
|
|
|
|
#ifdef L_get_hosts_byname_r
|
|
@@ -1716,7 +1720,7 @@ int attribute_hidden __get_hosts_byname_
|
|
return __read_etc_hosts_r(NULL, name, type, GET_HOSTS_BYNAME,
|
|
result_buf, buf, buflen, result, h_errnop);
|
|
}
|
|
-#endif
|
|
+#endif /* L_get_hosts_byname_r */
|
|
|
|
|
|
#ifdef L_get_hosts_byaddr_r
|
|
@@ -1758,7 +1762,7 @@ int attribute_hidden __get_hosts_byaddr_
|
|
return __read_etc_hosts_r(NULL, ipaddr, type, GET_HOSTS_BYADDR,
|
|
result_buf, buf, buflen, result, h_errnop);
|
|
}
|
|
-#endif
|
|
+#endif /* L_get_hosts_byaddr_r */
|
|
|
|
|
|
#ifdef L_getnameinfo
|
|
@@ -1961,7 +1965,7 @@ DONE:
|
|
return 0;
|
|
}
|
|
libc_hidden_def(getnameinfo)
|
|
-#endif
|
|
+#endif /* L_getnameinfo */
|
|
|
|
|
|
#ifdef L_gethostbyname_r
|
|
@@ -2175,7 +2179,7 @@ int gethostbyname_r(const char *name,
|
|
}
|
|
libc_hidden_def(gethostbyname_r)
|
|
link_warning(gethostbyname_r, "gethostbyname_r is obsolescent, use getnameinfo() instead.");
|
|
-#endif
|
|
+#endif /* L_gethostbyname_r */
|
|
|
|
|
|
#ifdef L_gethostbyname2_r
|
|
@@ -2332,7 +2336,7 @@ int gethostbyname2_r(const char *name,
|
|
#endif /* __UCLIBC_HAS_IPV6__ */
|
|
}
|
|
libc_hidden_def(gethostbyname2_r)
|
|
-#endif
|
|
+#endif /* L_gethostbyname2_r */
|
|
|
|
|
|
#ifdef L_gethostbyaddr_r
|
|
@@ -2493,7 +2497,7 @@ int gethostbyaddr_r(const void *addr, so
|
|
}
|
|
libc_hidden_def(gethostbyaddr_r)
|
|
link_warning(gethostbyaddr_r, "gethostbyaddr_r is obsolescent, use getaddrinfo() instead.");
|
|
-#endif
|
|
+#endif /* L_gethostbyaddr_r */
|
|
|
|
|
|
#ifdef L_gethostent_r
|
|
@@ -2550,7 +2554,7 @@ DONE:
|
|
return ret;
|
|
}
|
|
libc_hidden_def(gethostent_r)
|
|
-#endif
|
|
+#endif /* L_gethostent_r */
|
|
|
|
|
|
#ifdef L_gethostent
|
|
@@ -2570,7 +2574,7 @@ struct hostent *gethostent(void)
|
|
gethostent_r(&hoste, buf, sizeof(buf), &host, &h_errno);
|
|
return host;
|
|
}
|
|
-#endif
|
|
+#endif /* L_gethostent */
|
|
|
|
|
|
#ifdef L_gethostbyname2
|
|
@@ -2591,7 +2595,7 @@ struct hostent *gethostbyname2(const cha
|
|
#endif
|
|
}
|
|
libc_hidden_def(gethostbyname2)
|
|
-#endif
|
|
+#endif /* L_gethostbyname2 */
|
|
|
|
|
|
#ifdef L_gethostbyname
|
|
@@ -2613,7 +2617,7 @@ struct hostent *gethostbyname(const char
|
|
}
|
|
libc_hidden_def(gethostbyname)
|
|
link_warning(gethostbyname, "gethostbyname is obsolescent, use getnameinfo() instead.");
|
|
-#endif
|
|
+#endif /* L_gethostbyname */
|
|
|
|
|
|
#ifdef L_gethostbyaddr
|
|
@@ -2635,7 +2639,7 @@ struct hostent *gethostbyaddr(const void
|
|
}
|
|
libc_hidden_def(gethostbyaddr)
|
|
link_warning(gethostbyaddr, "gethostbyaddr is obsolescent, use getaddrinfo() instead.");
|
|
-#endif
|
|
+#endif /* L_gethostbyaddr */
|
|
|
|
|
|
#ifdef L_res_comp
|
|
@@ -2656,6 +2660,20 @@ int dn_expand(const u_char *msg, const u
|
|
dst[0] = '\0';
|
|
return n;
|
|
}
|
|
+
|
|
+/*
|
|
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
|
|
+ * Return the size of the compressed name or -1.
|
|
+ * 'length' is the size of the array pointed to by 'comp_dn'.
|
|
+ */
|
|
+int
|
|
+dn_comp(const char *src, u_char *dst, int dstsiz,
|
|
+ u_char **dnptrs, u_char **lastdnptr)
|
|
+{
|
|
+ return ns_name_compress(src, dst, (size_t) dstsiz,
|
|
+ (const u_char **) dnptrs,
|
|
+ (const u_char **) lastdnptr);
|
|
+}
|
|
#endif /* L_res_comp */
|
|
|
|
|
|
@@ -2792,6 +2810,259 @@ int ns_name_ntop(const u_char *src, char
|
|
}
|
|
libc_hidden_def(ns_name_ntop)
|
|
|
|
+static const char digits[] = "0123456789";
|
|
+
|
|
+static const char digitvalue[256] = {
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
|
|
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, /*64*/
|
|
+ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
|
|
+ -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
|
|
+};
|
|
+
|
|
+static int encode_bitstring(const char **bp, const char *end,
|
|
+ unsigned char **labelp,
|
|
+ unsigned char ** dst,
|
|
+ unsigned const char *eom)
|
|
+{
|
|
+ int afterslash = 0;
|
|
+ const char *cp = *bp;
|
|
+ unsigned char *tp;
|
|
+ char c;
|
|
+ const char *beg_blen;
|
|
+ char *end_blen = NULL;
|
|
+ int value = 0, count = 0, tbcount = 0, blen = 0;
|
|
+
|
|
+ beg_blen = end_blen = NULL;
|
|
+
|
|
+ /* a bitstring must contain at least 2 characters */
|
|
+ if (end - cp < 2)
|
|
+ return (EINVAL);
|
|
+
|
|
+ /* XXX: currently, only hex strings are supported */
|
|
+ if (*cp++ != 'x')
|
|
+ return (EINVAL);
|
|
+ if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */
|
|
+ return (EINVAL);
|
|
+
|
|
+ for (tp = *dst + 1; cp < end && tp < eom; cp++) {
|
|
+ switch((c = *cp)) {
|
|
+ case ']': /*%< end of the bitstring */
|
|
+ if (afterslash) {
|
|
+ if (beg_blen == NULL)
|
|
+ return (EINVAL);
|
|
+ blen = (int)strtol(beg_blen, &end_blen, 10);
|
|
+ if (*end_blen != ']')
|
|
+ return (EINVAL);
|
|
+ }
|
|
+ if (count)
|
|
+ *tp++ = ((value << 4) & 0xff);
|
|
+ cp++; /*%< skip ']' */
|
|
+ goto done;
|
|
+ case '/':
|
|
+ afterslash = 1;
|
|
+ break;
|
|
+ default:
|
|
+ if (afterslash) {
|
|
+ if (!isdigit(c&0xff))
|
|
+ return (EINVAL);
|
|
+ if (beg_blen == NULL) {
|
|
+
|
|
+ if (c == '0') {
|
|
+ /* blen never begings with 0 */
|
|
+ return (EINVAL);
|
|
+ }
|
|
+ beg_blen = cp;
|
|
+ }
|
|
+ } else {
|
|
+ if (!isxdigit(c&0xff))
|
|
+ return (EINVAL);
|
|
+ value <<= 4;
|
|
+ value += digitvalue[(int)c];
|
|
+ count += 4;
|
|
+ tbcount += 4;
|
|
+ if (tbcount > 256)
|
|
+ return (EINVAL);
|
|
+ if (count == 8) {
|
|
+ *tp++ = value;
|
|
+ count = 0;
|
|
+ }
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ done:
|
|
+ if (cp >= end || tp >= eom)
|
|
+ return (EMSGSIZE);
|
|
+
|
|
+ /*
|
|
+ * bit length validation:
|
|
+ * If a <length> is present, the number of digits in the <bit-data>
|
|
+ * MUST be just sufficient to contain the number of bits specified
|
|
+ * by the <length>. If there are insignificant bits in a final
|
|
+ * hexadecimal or octal digit, they MUST be zero.
|
|
+ * RFC2673, Section 3.2.
|
|
+ */
|
|
+ if (blen > 0) {
|
|
+ int traillen;
|
|
+
|
|
+ if (((blen + 3) & ~3) != tbcount)
|
|
+ return (EINVAL);
|
|
+ traillen = tbcount - blen; /*%< between 0 and 3 */
|
|
+ if (((value << (8 - traillen)) & 0xff) != 0)
|
|
+ return (EINVAL);
|
|
+ }
|
|
+ else
|
|
+ blen = tbcount;
|
|
+ if (blen == 256)
|
|
+ blen = 0;
|
|
+
|
|
+ /* encode the type and the significant bit fields */
|
|
+ **labelp = DNS_LABELTYPE_BITSTRING;
|
|
+ **dst = blen;
|
|
+
|
|
+ *bp = cp;
|
|
+ *dst = tp;
|
|
+
|
|
+ return (0);
|
|
+}
|
|
+
|
|
+int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
|
|
+{
|
|
+ u_char *label, *bp, *eom;
|
|
+ int c, n, escaped, e = 0;
|
|
+ char *cp;
|
|
+
|
|
+ escaped = 0;
|
|
+ bp = dst;
|
|
+ eom = dst + dstsiz;
|
|
+ label = bp++;
|
|
+
|
|
+ while ((c = *src++) != 0) {
|
|
+ if (escaped) {
|
|
+ if (c == '[') { /*%< start a bit string label */
|
|
+ if ((cp = strchr(src, ']')) == NULL) {
|
|
+ errno = EINVAL; /*%< ??? */
|
|
+ return (-1);
|
|
+ }
|
|
+ if ((e = encode_bitstring(&src, cp + 2,
|
|
+ &label, &bp, eom))
|
|
+ != 0) {
|
|
+ errno = e;
|
|
+ return (-1);
|
|
+ }
|
|
+ escaped = 0;
|
|
+ label = bp++;
|
|
+ if ((c = *src++) == 0)
|
|
+ goto done;
|
|
+ else if (c != '.') {
|
|
+ errno = EINVAL;
|
|
+ return (-1);
|
|
+ }
|
|
+ continue;
|
|
+ }
|
|
+ else if ((cp = strchr(digits, c)) != NULL) {
|
|
+ n = (cp - digits) * 100;
|
|
+ if ((c = *src++) == 0 ||
|
|
+ (cp = strchr(digits, c)) == NULL) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ n += (cp - digits) * 10;
|
|
+ if ((c = *src++) == 0 ||
|
|
+ (cp = strchr(digits, c)) == NULL) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ n += (cp - digits);
|
|
+ if (n > 255) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ c = n;
|
|
+ }
|
|
+ escaped = 0;
|
|
+ } else if (c == '\\') {
|
|
+ escaped = 1;
|
|
+ continue;
|
|
+ } else if (c == '.') {
|
|
+ c = (bp - label - 1);
|
|
+ if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ if (label >= eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ *label = c;
|
|
+ /* Fully qualified ? */
|
|
+ if (*src == '\0') {
|
|
+ if (c != 0) {
|
|
+ if (bp >= eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ *bp++ = '\0';
|
|
+ }
|
|
+ if ((bp - dst) > MAXCDNAME) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ return (1);
|
|
+ }
|
|
+ if (c == 0 || *src == '.') {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ label = bp++;
|
|
+ continue;
|
|
+ }
|
|
+ if (bp >= eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ *bp++ = (u_char)c;
|
|
+ }
|
|
+ c = (bp - label - 1);
|
|
+ if ((c & NS_CMPRSFLGS) != 0) { /*%< Label too big. */
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ done:
|
|
+ if (label >= eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ *label = c;
|
|
+ if (c != 0) {
|
|
+ if (bp >= eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+ *bp++ = 0;
|
|
+ }
|
|
+ if ((bp - dst) > MAXCDNAME) { /*%< src too big */
|
|
+ errno = EMSGSIZE;
|
|
+ return (-1);
|
|
+ }
|
|
+
|
|
+ return (0);
|
|
+}
|
|
+libc_hidden_def(ns_name_pton)
|
|
+
|
|
/*
|
|
* ns_name_unpack(msg, eom, src, dst, dstsiz)
|
|
* Unpack a domain name from a message, source may be compressed.
|
|
@@ -2866,6 +3137,270 @@ int ns_name_unpack(const u_char *msg, co
|
|
return len;
|
|
}
|
|
libc_hidden_def(ns_name_unpack)
|
|
+
|
|
+static int labellen(const unsigned char *lp)
|
|
+{
|
|
+ int bitlen;
|
|
+ unsigned char l = *lp;
|
|
+
|
|
+ if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
|
|
+ /* should be avoided by the caller */
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
|
|
+ if (l == DNS_LABELTYPE_BITSTRING) {
|
|
+ if ((bitlen = *(lp + 1)) == 0)
|
|
+ bitlen = 256;
|
|
+ return ((bitlen + 7 ) / 8 + 1);
|
|
+ }
|
|
+
|
|
+ return -1; /*%< unknwon ELT */
|
|
+ }
|
|
+
|
|
+ return l;
|
|
+}
|
|
+
|
|
+static int mklower(int ch)
|
|
+{
|
|
+ if (ch >= 0x41 && ch <= 0x5A)
|
|
+ return (ch + 0x20);
|
|
+
|
|
+ return (ch);
|
|
+}
|
|
+
|
|
+static int dn_find(const unsigned char *domain,
|
|
+ const unsigned char *msg,
|
|
+ const unsigned char * const *dnptrs,
|
|
+ const unsigned char * const *lastdnptr)
|
|
+{
|
|
+ const unsigned char *dn, *cp, *sp;
|
|
+ const unsigned char * const *cpp;
|
|
+ u_int n;
|
|
+
|
|
+ for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
|
|
+ sp = *cpp;
|
|
+ /*
|
|
+ * terminate search on:
|
|
+ * root label
|
|
+ * compression pointer
|
|
+ * unusable offset
|
|
+ */
|
|
+ while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
|
|
+ (sp - msg) < 0x4000) {
|
|
+ dn = domain;
|
|
+ cp = sp;
|
|
+
|
|
+ while ((n = *cp++) != 0) {
|
|
+ /*
|
|
+ * check for indirection
|
|
+ */
|
|
+ switch (n & NS_CMPRSFLGS) {
|
|
+ case 0: /*%< normal case, n == len */
|
|
+ n = labellen(cp - 1); /*%< XXX */
|
|
+ if (n != *dn++)
|
|
+ goto next;
|
|
+
|
|
+ for (; n > 0; n--)
|
|
+ if (mklower(*dn++) !=
|
|
+ mklower(*cp++))
|
|
+ goto next;
|
|
+ /* Is next root for both ? */
|
|
+ if (*dn == '\0' && *cp == '\0')
|
|
+ return (sp - msg);
|
|
+ if (*dn)
|
|
+ continue;
|
|
+ goto next;
|
|
+ case NS_CMPRSFLGS: /*%< indirection */
|
|
+ cp = msg + (((n & 0x3f) << 8) | *cp);
|
|
+ break;
|
|
+
|
|
+ default: /*%< illegal type */
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+next:
|
|
+ sp += *sp + 1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ errno = ENOENT;
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+int ns_name_pack(const unsigned char *src,
|
|
+ unsigned char *dst, int dstsiz,
|
|
+ const unsigned char **dnptrs,
|
|
+ const unsigned char **lastdnptr)
|
|
+{
|
|
+ unsigned char *dstp;
|
|
+ const unsigned char **cpp, **lpp, *eob, *msg;
|
|
+ const unsigned char *srcp;
|
|
+ int n, l, first = 1;
|
|
+
|
|
+ srcp = src;
|
|
+ dstp = dst;
|
|
+ eob = dstp + dstsiz;
|
|
+ lpp = cpp = NULL;
|
|
+
|
|
+ if (dnptrs != NULL) {
|
|
+ if ((msg = *dnptrs++) != NULL) {
|
|
+ for (cpp = dnptrs; *cpp != NULL; cpp++)
|
|
+ continue;
|
|
+
|
|
+ lpp = cpp; /*%< end of list to search */
|
|
+ }
|
|
+ } else {
|
|
+ msg = NULL;
|
|
+ }
|
|
+
|
|
+ /* make sure the domain we are about to add is legal */
|
|
+ l = 0;
|
|
+ do {
|
|
+ int l0;
|
|
+
|
|
+ n = *srcp;
|
|
+ if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if ((l0 = labellen(srcp)) < 0) {
|
|
+ errno = EINVAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ l += l0 + 1;
|
|
+ if (l > MAXCDNAME) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ srcp += l0 + 1;
|
|
+ } while (n != 0);
|
|
+
|
|
+ /* from here on we need to reset compression pointer array on error */
|
|
+ srcp = src;
|
|
+
|
|
+ do {
|
|
+ /* Look to see if we can use pointers. */
|
|
+ n = *srcp;
|
|
+
|
|
+ if (n != 0 && msg != NULL) {
|
|
+ l = dn_find(srcp, msg, (const unsigned char * const *) dnptrs,
|
|
+ (const unsigned char * const *) lpp);
|
|
+ if (l >= 0) {
|
|
+ if (dstp + 1 >= eob) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ *dstp++ = ((u_int32_t)l >> 8) | NS_CMPRSFLGS;
|
|
+ *dstp++ = l % 256;
|
|
+ return (dstp - dst);
|
|
+ }
|
|
+
|
|
+ /* Not found, save it. */
|
|
+ if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
|
|
+ (dstp - msg) < 0x4000 && first) {
|
|
+ *cpp++ = dstp;
|
|
+ *cpp = NULL;
|
|
+ first = 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* copy label to buffer */
|
|
+ if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
|
|
+ /* Should not happen. */
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ n = labellen(srcp);
|
|
+ if (dstp + 1 + n >= eob) {
|
|
+ goto cleanup;
|
|
+ }
|
|
+
|
|
+ memcpy(dstp, srcp, (size_t)(n + 1));
|
|
+ srcp += n + 1;
|
|
+ dstp += n + 1;
|
|
+ } while (n != 0);
|
|
+
|
|
+ if (dstp > eob) {
|
|
+cleanup:
|
|
+ if (msg != NULL)
|
|
+ *lpp = NULL;
|
|
+
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return dstp - dst;
|
|
+}
|
|
+
|
|
+int ns_name_compress(const char *src,
|
|
+ unsigned char *dst, size_t dstsiz,
|
|
+ const unsigned char **dnptrs,
|
|
+ const unsigned char **lastdnptr)
|
|
+{
|
|
+ unsigned char tmp[NS_MAXCDNAME];
|
|
+
|
|
+ if (ns_name_pton(src, tmp, sizeof(tmp)) == -1)
|
|
+ return -1;
|
|
+
|
|
+ return ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr);
|
|
+}
|
|
+
|
|
+int ns_name_skip(const unsigned char **ptrptr,
|
|
+ const unsigned char *eom)
|
|
+{
|
|
+ const unsigned char *cp;
|
|
+ u_int n;
|
|
+ int l;
|
|
+
|
|
+ cp = *ptrptr;
|
|
+ while (cp < eom && (n = *cp++) != 0) {
|
|
+ /* Check for indirection. */
|
|
+ switch (n & NS_CMPRSFLGS) {
|
|
+ case 0: /*%< normal case, n == len */
|
|
+ cp += n;
|
|
+ continue;
|
|
+ case NS_TYPE_ELT: /*%< EDNS0 extended label */
|
|
+ if ((l = labellen(cp - 1)) < 0) {
|
|
+ errno = EMSGSIZE; /*%< XXX */
|
|
+ return -1;
|
|
+ }
|
|
+ cp += l;
|
|
+ continue;
|
|
+ case NS_CMPRSFLGS: /*%< indirection */
|
|
+ cp++;
|
|
+ break;
|
|
+ default: /*%< illegal type */
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (cp > eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ *ptrptr = cp;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int dn_skipname(const unsigned char *ptr, const unsigned char *eom)
|
|
+{
|
|
+ const unsigned char *saveptr = ptr;
|
|
+
|
|
+ if (ns_name_skip(&ptr, eom) == -1)
|
|
+ return -1;
|
|
+
|
|
+ return ptr - saveptr;
|
|
+}
|
|
#endif /* L_ns_name */
|
|
|
|
|
|
@@ -2906,12 +3441,10 @@ static void res_sync_func(void)
|
|
*/
|
|
}
|
|
|
|
-/* Our res_init never fails (always returns 0) */
|
|
-int res_init(void)
|
|
+static int
|
|
+__res_vinit(res_state rp, int preinit)
|
|
{
|
|
- struct __res_state *rp = &(_res);
|
|
- int i;
|
|
- int n;
|
|
+ int i, n, options, retrans, retry, ndots;
|
|
#ifdef __UCLIBC_HAS_IPV6__
|
|
int m = 0;
|
|
#endif
|
|
@@ -2920,13 +3453,27 @@ int res_init(void)
|
|
__close_nameservers();
|
|
__open_nameservers();
|
|
|
|
- __res_sync = res_sync_func;
|
|
+ if (preinit) {
|
|
+ options = rp->options;
|
|
+ retrans = rp->retrans;
|
|
+ retry = rp->retry;
|
|
+ ndots = rp->ndots;
|
|
+ }
|
|
|
|
memset(rp, 0, sizeof(*rp));
|
|
- rp->options = RES_INIT;
|
|
- rp->retrans = RES_TIMEOUT;
|
|
- rp->retry = RES_DFLRETRY;
|
|
- rp->ndots = 1;
|
|
+
|
|
+ if (!preinit) {
|
|
+ rp->options = RES_DEFAULT;
|
|
+ rp->retrans = RES_TIMEOUT;
|
|
+ rp->retry = RES_DFLRETRY;
|
|
+ rp->ndots = 1;
|
|
+ } else {
|
|
+ rp->options = options;
|
|
+ rp->retrans = retrans;
|
|
+ rp->retry = retry;
|
|
+ rp->ndots = ndots;
|
|
+ }
|
|
+
|
|
#ifdef __UCLIBC_HAS_COMPAT_RES_STATE__
|
|
/* Was: "rp->id = random();" but:
|
|
* - random() pulls in largish static buffers
|
|
@@ -2992,13 +3539,14 @@ int res_init(void)
|
|
rp->_u._ext.nscount = m;
|
|
#endif
|
|
|
|
+ rp->options |= RES_INIT;
|
|
+
|
|
__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
|
|
return 0;
|
|
}
|
|
-libc_hidden_def(res_init)
|
|
|
|
-#ifdef __UCLIBC_HAS_BSD_RES_CLOSE__
|
|
-void res_close(void)
|
|
+static void
|
|
+__res_iclose(res_state statp, int free_addr)
|
|
{
|
|
__UCLIBC_MUTEX_LOCK(__resolv_lock);
|
|
__close_nameservers();
|
|
@@ -3018,7 +3566,27 @@ void res_close(void)
|
|
memset(&_res, 0, sizeof(_res));
|
|
__UCLIBC_MUTEX_UNLOCK(__resolv_lock);
|
|
}
|
|
-#endif
|
|
+
|
|
+/*
|
|
+ * This routine is for closing the socket if a virtual circuit is used and
|
|
+ * the program wants to close it. This provides support for endhostent()
|
|
+ * which expects to close the socket.
|
|
+ *
|
|
+ * This routine is not expected to be user visible.
|
|
+ */
|
|
+
|
|
+void
|
|
+res_nclose(res_state statp)
|
|
+{
|
|
+ __res_iclose(statp, 1);
|
|
+}
|
|
+
|
|
+#ifdef __UCLIBC_HAS_BSD_RES_CLOSE__
|
|
+void res_close(void)
|
|
+{
|
|
+ __res_iclose(&_res, 0);
|
|
+}
|
|
+#endif /* __UCLIBC_HAS_BSD_RES_CLOSE__ */
|
|
|
|
/* This needs to be after the use of _res in res_init, above. */
|
|
#undef _res
|
|
@@ -3047,7 +3615,88 @@ extern __thread struct __res_state *__li
|
|
# undef __resp
|
|
struct __res_state *__resp = &_res;
|
|
# endif
|
|
-#endif
|
|
+#endif /* !__UCLIBC_HAS_THREADS__ */
|
|
+
|
|
+static unsigned int
|
|
+res_randomid(void) {
|
|
+ return 0xffff & getpid();
|
|
+}
|
|
+
|
|
+/* Our res_init never fails (always returns 0) */
|
|
+int
|
|
+res_init(void)
|
|
+{
|
|
+ /*
|
|
+ * These three fields used to be statically initialized. This made
|
|
+ * it hard to use this code in a shared library. It is necessary,
|
|
+ * now that we're doing dynamic initialization here, that we preserve
|
|
+ * the old semantics: if an application modifies one of these three
|
|
+ * fields of _res before res_init() is called, res_init() will not
|
|
+ * alter them. Of course, if an application is setting them to
|
|
+ * _zero_ before calling res_init(), hoping to override what used
|
|
+ * to be the static default, we can't detect it and unexpected results
|
|
+ * will follow. Zero for any of these fields would make no sense,
|
|
+ * so one can safely assume that the applications were already getting
|
|
+ * unexpected results.
|
|
+ *
|
|
+ * _res.options is tricky since some apps were known to diddle the bits
|
|
+ * before res_init() was first called. We can't replicate that semantic
|
|
+ * with dynamic initialization (they may have turned bits off that are
|
|
+ * set in RES_DEFAULT). Our solution is to declare such applications
|
|
+ * "broken". They could fool us by setting RES_INIT but none do (yet).
|
|
+ */
|
|
+
|
|
+ __UCLIBC_MUTEX_LOCK(__resolv_lock);
|
|
+
|
|
+ if (!_res.retrans)
|
|
+ _res.retrans = RES_TIMEOUT;
|
|
+ if (!_res.retry)
|
|
+ _res.retry = 4;
|
|
+ if (!(_res.options & RES_INIT))
|
|
+ _res.options = RES_DEFAULT;
|
|
+
|
|
+ /*
|
|
+ * This one used to initialize implicitly to zero, so unless the app
|
|
+ * has set it to something in particular, we can randomize it now.
|
|
+ */
|
|
+ if (!_res.id)
|
|
+ _res.id = res_randomid();
|
|
+ __res_sync = res_sync_func;
|
|
+
|
|
+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
|
|
+
|
|
+ __res_vinit(&_res, 1);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+libc_hidden_def(res_init)
|
|
+
|
|
+/*
|
|
+ * Set up default settings. If the configuration file exist, the values
|
|
+ * there will have precedence. Otherwise, the server address is set to
|
|
+ * INADDR_ANY and the default domain name comes from the gethostname().
|
|
+ *
|
|
+ * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
|
|
+ * rather than INADDR_ANY ("0.0.0.0") as the default name server address
|
|
+ * since it was noted that INADDR_ANY actually meant ``the first interface
|
|
+ * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
|
|
+ * it had to be "up" in order for you to reach your own name server. It
|
|
+ * was later decided that since the recommended practice is to always
|
|
+ * install local static routes through 127.0.0.1 for all your network
|
|
+ * interfaces, that we could solve this problem without a code change.
|
|
+ *
|
|
+ * The configuration file should always be used, since it is the only way
|
|
+ * to specify a default domain. If you are running a server on your local
|
|
+ * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
|
|
+ * in the configuration file.
|
|
+ *
|
|
+ * Return 0 if completes successfully, -1 on error
|
|
+ */
|
|
+int
|
|
+res_ninit(res_state statp)
|
|
+{
|
|
+ return __res_vinit(statp, 0);
|
|
+}
|
|
|
|
#endif /* L_res_init */
|
|
|
|
@@ -3071,7 +3720,7 @@ __res_state (void)
|
|
}
|
|
# endif
|
|
|
|
-#endif
|
|
+#endif /* L_res_state */
|
|
|
|
|
|
#ifdef L_res_query
|
|
@@ -3324,9 +3973,343 @@ int res_querydomain(const char *name, co
|
|
return res_query(longname, class, type, answer, anslen);
|
|
}
|
|
libc_hidden_def(res_querydomain)
|
|
+#endif /* L_res_query */
|
|
+
|
|
+#ifdef L_ns_netint
|
|
+unsigned int ns_get16(const unsigned char *src)
|
|
+{
|
|
+ unsigned int dst;
|
|
+ NS_GET16(dst, src);
|
|
+ return dst;
|
|
+}
|
|
+
|
|
+unsigned long ns_get32(const unsigned char *src)
|
|
+{
|
|
+ unsigned long dst;
|
|
+ NS_GET32(dst, src);
|
|
+ return dst;
|
|
+}
|
|
+
|
|
+void ns_put16(unsigned int src, unsigned char *dst)
|
|
+{
|
|
+ NS_PUT16(src, dst);
|
|
+}
|
|
+
|
|
+void ns_put32(unsigned long src, unsigned char *dst)
|
|
+{
|
|
+ NS_PUT32(src, dst);
|
|
+}
|
|
+#endif /* L_ns_netint */
|
|
+
|
|
+#ifdef L_ns_parse
|
|
+/* These need to be in the same order as the nres.h:ns_flag enum. */
|
|
+const struct _ns_flagdata _ns_flagdata[16] = {
|
|
+ { 0x8000, 15 }, /*%< qr. */
|
|
+ { 0x7800, 11 }, /*%< opcode. */
|
|
+ { 0x0400, 10 }, /*%< aa. */
|
|
+ { 0x0200, 9 }, /*%< tc. */
|
|
+ { 0x0100, 8 }, /*%< rd. */
|
|
+ { 0x0080, 7 }, /*%< ra. */
|
|
+ { 0x0040, 6 }, /*%< z. */
|
|
+ { 0x0020, 5 }, /*%< ad. */
|
|
+ { 0x0010, 4 }, /*%< cd. */
|
|
+ { 0x000f, 0 }, /*%< rcode. */
|
|
+ { 0x0000, 0 }, /*%< expansion (1/6). */
|
|
+ { 0x0000, 0 }, /*%< expansion (2/6). */
|
|
+ { 0x0000, 0 }, /*%< expansion (3/6). */
|
|
+ { 0x0000, 0 }, /*%< expansion (4/6). */
|
|
+ { 0x0000, 0 }, /*%< expansion (5/6). */
|
|
+ { 0x0000, 0 }, /*%< expansion (6/6). */
|
|
+};
|
|
+
|
|
+static void setsection(ns_msg *msg, ns_sect sect)
|
|
+{
|
|
+ msg->_sect = sect;
|
|
+ if (sect == ns_s_max) {
|
|
+ msg->_rrnum = -1;
|
|
+ msg->_ptr = NULL;
|
|
+ } else {
|
|
+ msg->_rrnum = 0;
|
|
+ msg->_ptr = msg->_sections[(int)sect];
|
|
+ }
|
|
+}
|
|
+
|
|
+int ns_skiprr(const unsigned char *ptr,
|
|
+ const unsigned char *eom,
|
|
+ ns_sect section, int count)
|
|
+{
|
|
+ const u_char *optr = ptr;
|
|
+
|
|
+ for (; count > 0; count--) {
|
|
+ int b, rdlength;
|
|
+
|
|
+ b = dn_skipname(ptr, eom);
|
|
+ if (b < 0) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
|
|
+ if (section != ns_s_qd) {
|
|
+ if (ptr + NS_INT32SZ + NS_INT16SZ > eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ ptr += NS_INT32SZ/*TTL*/;
|
|
+ NS_GET16(rdlength, ptr);
|
|
+ ptr += rdlength/*RData*/;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (ptr > eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return ptr - optr;
|
|
+}
|
|
+
|
|
+int
|
|
+ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
|
|
+{
|
|
+ const u_char *eom = msg + msglen;
|
|
+ int i;
|
|
+
|
|
+ handle->_msg = msg;
|
|
+ handle->_eom = eom;
|
|
+ if (msg + NS_INT16SZ > eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ NS_GET16(handle->_id, msg);
|
|
+ if (msg + NS_INT16SZ > eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ NS_GET16(handle->_flags, msg);
|
|
+ for (i = 0; i < ns_s_max; i++) {
|
|
+ if (msg + NS_INT16SZ > eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ NS_GET16(handle->_counts[i], msg);
|
|
+ }
|
|
+ for (i = 0; i < ns_s_max; i++)
|
|
+ if (handle->_counts[i] == 0)
|
|
+ handle->_sections[i] = NULL;
|
|
+ else {
|
|
+ int b = ns_skiprr(msg, eom, (ns_sect)i,
|
|
+ handle->_counts[i]);
|
|
+
|
|
+ if (b < 0)
|
|
+ return -1;
|
|
+ handle->_sections[i] = msg;
|
|
+ msg += b;
|
|
+ }
|
|
+
|
|
+ if (msg != eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ setsection(handle, ns_s_max);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
|
|
+{
|
|
+ int b;
|
|
+ int tmp;
|
|
+
|
|
+ /* Make section right. */
|
|
+ tmp = section;
|
|
+ if (tmp < 0 || section >= ns_s_max) {
|
|
+ errno = ENODEV;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (section != handle->_sect)
|
|
+ setsection(handle, section);
|
|
+
|
|
+ /* Make rrnum right. */
|
|
+ if (rrnum == -1)
|
|
+ rrnum = handle->_rrnum;
|
|
+ if (rrnum < 0 || rrnum >= handle->_counts[(int)section]) {
|
|
+ errno = ENODEV;
|
|
+ return -1;
|
|
+ }
|
|
+ if (rrnum < handle->_rrnum)
|
|
+ setsection(handle, section);
|
|
+ if (rrnum > handle->_rrnum) {
|
|
+ b = ns_skiprr(handle->_ptr, handle->_eom, section,
|
|
+ rrnum - handle->_rrnum);
|
|
+
|
|
+ if (b < 0)
|
|
+ return (-1);
|
|
+ handle->_ptr += b;
|
|
+ handle->_rrnum = rrnum;
|
|
+ }
|
|
+
|
|
+ /* Do the parse. */
|
|
+ b = dn_expand(handle->_msg, handle->_eom,
|
|
+ handle->_ptr, rr->name, NS_MAXDNAME);
|
|
+ if (b < 0)
|
|
+ return (-1);
|
|
+ handle->_ptr += b;
|
|
+ if (handle->_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+ NS_GET16(rr->type, handle->_ptr);
|
|
+ NS_GET16(rr->rr_class, handle->_ptr);
|
|
+ if (section == ns_s_qd) {
|
|
+ rr->ttl = 0;
|
|
+ rr->rdlength = 0;
|
|
+ rr->rdata = NULL;
|
|
+ } else {
|
|
+ if (handle->_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+ NS_GET32(rr->ttl, handle->_ptr);
|
|
+ NS_GET16(rr->rdlength, handle->_ptr);
|
|
+ if (handle->_ptr + rr->rdlength > handle->_eom) {
|
|
+ errno = EMSGSIZE;
|
|
+ return -1;
|
|
+ }
|
|
+ rr->rdata = handle->_ptr;
|
|
+ handle->_ptr += rr->rdlength;
|
|
+ }
|
|
+ if (++handle->_rrnum > handle->_counts[(int)section])
|
|
+ setsection(handle, (ns_sect)((int)section + 1));
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int ns_msg_getflag(ns_msg handle, int flag) {
|
|
+ return ((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift;
|
|
+}
|
|
+#endif /* L_ns_parse */
|
|
+
|
|
+#ifdef L_res_data
|
|
+int res_mkquery(int op, const char *dname, int class, int type,
|
|
+ const unsigned char *data, int datalen,
|
|
+ const unsigned char *newrr_in,
|
|
+ unsigned char *buf, int buflen)
|
|
+{
|
|
+ HEADER *hp;
|
|
+ unsigned char *cp, *ep;
|
|
+ unsigned char *dnptrs[20], **dpp, **lastdnptr;
|
|
+ uint32_t _res_options;
|
|
+ int n;
|
|
+
|
|
+ if (!buf || buflen < HFIXEDSZ) {
|
|
+ h_errno = NETDB_INTERNAL;
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ again:
|
|
+ __UCLIBC_MUTEX_LOCK(__resolv_lock);
|
|
+ _res_options = _res.options;
|
|
+ __UCLIBC_MUTEX_UNLOCK(__resolv_lock);
|
|
+ if (!(_res_options & RES_INIT)) {
|
|
+ res_init(); /* our res_init never fails */
|
|
+ goto again;
|
|
+ }
|
|
+
|
|
+#ifdef DEBUG
|
|
+ if (_res_options & RES_DEBUG)
|
|
+ printf(";; res_mkquery(%d, %s, %s, %d, %d)\n",
|
|
+ name, (op, dname ? dname : "<Nil>"), class, type);
|
|
#endif
|
|
|
|
+ memset(buf, 0, HFIXEDSZ);
|
|
+ hp = (HEADER *) buf;
|
|
+ hp->id = getpid() & 0xffff;
|
|
+ hp->opcode = op;
|
|
+ hp->rd = (_res.options & RES_RECURSE) != 0U;
|
|
+ hp->rcode = NOERROR;
|
|
+
|
|
+ cp = buf + HFIXEDSZ;
|
|
+ ep = buf + buflen;
|
|
+ dpp = dnptrs;
|
|
+ *dpp++ = buf;
|
|
+ *dpp++ = NULL;
|
|
+ lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
|
|
+
|
|
+ /*
|
|
+ * perform opcode specific processing
|
|
+ */
|
|
+ switch (op) {
|
|
+ case QUERY:
|
|
+ case NS_NOTIFY_OP:
|
|
+ if (ep - cp < QFIXEDSZ)
|
|
+ return -1;
|
|
+
|
|
+ if ((n = dn_comp(dname, cp, ep - cp - QFIXEDSZ, dnptrs, lastdnptr)) < 0)
|
|
+ return -1;
|
|
+
|
|
+ cp += n;
|
|
+ NS_PUT16(type, cp);
|
|
+ NS_PUT16(class, cp);
|
|
+ hp->qdcount = htons(1);
|
|
+
|
|
+ if (op == QUERY || data == NULL)
|
|
+ break;
|
|
+
|
|
+ /*
|
|
+ * Make an additional record for completion domain.
|
|
+ */
|
|
+ if ((ep - cp) < RRFIXEDSZ)
|
|
+ return -1;
|
|
+
|
|
+ n = dn_comp((const char *)data, cp, ep - cp - RRFIXEDSZ,
|
|
+ dnptrs, lastdnptr);
|
|
+ if (n < 0)
|
|
+ return -1;
|
|
+
|
|
+ cp += n;
|
|
+ NS_PUT16(T_NULL, cp);
|
|
+ NS_PUT16(class, cp);
|
|
+ NS_PUT32(0, cp);
|
|
+ NS_PUT16(0, cp);
|
|
+ hp->arcount = htons(1);
|
|
+
|
|
+ break;
|
|
+
|
|
+ case IQUERY:
|
|
+ /*
|
|
+ * Initialize answer section
|
|
+ */
|
|
+ if (ep - cp < 1 + RRFIXEDSZ + datalen)
|
|
+ return -1;
|
|
+
|
|
+ *cp++ = '\0'; /*%< no domain name */
|
|
+ NS_PUT16(type, cp);
|
|
+ NS_PUT16(class, cp);
|
|
+ NS_PUT32(0, cp);
|
|
+ NS_PUT16(datalen, cp);
|
|
+
|
|
+ if (datalen) {
|
|
+ memcpy(cp, data, (size_t)datalen);
|
|
+ cp += datalen;
|
|
+ }
|
|
+
|
|
+ hp->ancount = htons(1);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return cp - buf;
|
|
+}
|
|
+#endif /* L_res_data */
|
|
+
|
|
/* Unimplemented: */
|
|
-/* res_mkquery */
|
|
/* res_send */
|
|
-/* dn_comp */
|