OSDN Git Service

inet/resolv: add res_mkquery
authorDaniel Mack <zonque@gmail.com>
Tue, 12 Jul 2011 22:30:53 +0000 (00:30 +0200)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Fri, 26 Aug 2011 07:29:53 +0000 (09:29 +0200)
Signed-off-by: Daniel Mack <zonque@gmail.com>
include/resolv.h
libc/inet/Makefile.in
libc/inet/res_data.c [new file with mode: 0644]
libc/inet/resolv.c

index 6556365..96ad4ab 100644 (file)
@@ -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,
index f2a495a..09ba65d 100644 (file)
@@ -41,7 +41,7 @@ CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += \
        res_init.c res_query.c res_comp.c ns_name.c \
        _res_state.c
 CSRC-$(findstring y,$(UCLIBC_HAS_RESOLVER_SUPPORT)) += \
-       ns_netint.c ns_parse.c
+       ns_netint.c ns_parse.c res_data.c
 ## # unused ATM
 ## CSRC-y += encodep.c decodep.c formquery.c
 
diff --git a/libc/inet/res_data.c b/libc/inet/res_data.c
new file mode 100644 (file)
index 0000000..b554b93
--- /dev/null
@@ -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
index 011cd5e..627423b 100644 (file)
@@ -4081,6 +4081,120 @@ int ns_msg_getflag(ns_msg handle, int flag) {
 }
 #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 */