chiark / gitweb /
WIP mostly works, need to convert if index to name
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 27 May 2014 01:13:52 +0000 (02:13 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Tue, 27 May 2014 01:13:52 +0000 (02:13 +0100)
client/Makefile.in
client/addrtext.c [new file with mode: 0644]
src/addrfam.c

index 01f2fcda4d44ce394c48926a2ffbb97a70cc62ce..05880726e6e378efb00e3bd3819b8b940422989f 100644 (file)
@@ -27,7 +27,7 @@ PROGS_SYSDEP= @PROGS_HAVE_TSEARCH@
 ENABLE_DYNAMIC=        @ENABLE_DYNAMIC@
 
 PROGRAMS=      adnslogres adnsheloex adnshost $(PROGS_SYSDEP)
-PROGRAMS_LOCAL=        fanftest adnstest
+PROGRAMS_LOCAL=        fanftest adnstest addrtext
 PROGRAMS_ALL=  $(PROGRAMS) $(PROGRAMS_LOCAL)
 
 STATIC_LIB=    ../src/libadns.a
diff --git a/client/addrtext.c b/client/addrtext.c
new file mode 100644 (file)
index 0000000..0776935
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * addrtext.c
+ * - test program for address<->string conversion, not part of the library
+ */
+/*
+ *  This file is part of adns, which is
+ *    Copyright (C) 1997-2000,2003,2006,2014  Ian Jackson
+ *    Copyright (C) 1999-2000,2003,2006  Tony Finch
+ *    Copyright (C) 1991 Massachusetts Institute of Technology
+ *  (See the file INSTALL for full details.)
+ *  
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *  
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *  
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software Foundation,
+ *  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdbool.h>
+#include <string.h>
+#include <errno.h>
+#include <inttypes.h>
+
+#include "config.h"
+#include "adns.h"
+
+#define PORT 1234
+
+#define STRING(x) STRING2(x)
+#define STRING2(x) #x
+
+static int fails;
+
+static void hex(const void *data_v, int l) {
+  const uint8_t *data= data_v;
+  int i;
+  for (i=0; i<l; i++)
+    printf("%02x",data[i]);
+}
+
+static void dump(const char *pfx, struct sockaddr *sa, socklen_t salen) {
+  int i;
+  printf(" %s: ",pfx);
+  hex(sa, salen);
+
+  for (i=0; i<salen; i++)
+    printf("%02x",((const uint8_t*)sa)[i]);
+
+  printf(" %d ", sa->sa_family);
+
+  switch (sa->sa_family) {
+  case AF_INET: {
+    const struct sockaddr_in *s = (const void*)sa;
+    printf(".port=%d .addr=%08"PRIx32"",
+          ntohs(s->sin_port),
+          (uint32_t)ntohl(s->sin_addr.s_addr));
+    break;
+  }
+  case AF_INET6: {
+    const struct sockaddr_in6 *s = (const void*)sa;
+    printf(".port=%d .flowinfo=%08"PRIx32" .scope_id=%08"PRIx32" .addr=",
+          ntohs(s->sin6_port),
+          (uint32_t)ntohl(s->sin6_flowinfo),
+          (uint32_t)ntohl(s->sin6_scope_id));
+    hex(&s->sin6_addr, sizeof(s->sin6_addr));
+    break;
+  }
+  }
+  printf("\n");
+}
+
+static void dotest(const char *input) {
+  adns_sockaddr ours;
+  socklen_t socklen;
+  struct addrinfo aip;
+  struct addrinfo *air=0;
+  char ourbuf[ADNS_ADDR2TEXT_BUFLEN];
+  char theirbuf[ADNS_ADDR2TEXT_BUFLEN];
+
+  memset(&ours,0,sizeof(ours));
+
+  socklen= sizeof(ours);
+  int our_r= adns_text2addr(input,PORT,&ours.sa,&socklen);
+
+  memset(&aip,0,sizeof(aip));
+  aip.ai_flags= AI_NUMERICHOST|AI_NUMERICSERV;
+  aip.ai_socktype= SOCK_DGRAM;
+  aip.ai_protocol= IPPROTO_UDP;
+  air= 0;
+  int libc_r= getaddrinfo(input,STRING(PORT),&aip,&air);
+  printf("`%s': us %s; libc %s, air=%p",
+        input, strerror(our_r), libc_r ? gai_strerror(libc_r) : "0", air);
+  if (air)
+    printf(" .family=%d .socklen=%ld .addr=%p .next=%p",
+          air->ai_family, (long)air->ai_addrlen, air->ai_addr, air->ai_next);
+  printf(":");
+
+  if (our_r==EINVAL && libc_r==EAI_NONAME && !air) {
+    printf(" invalid");
+    goto ok;
+  }
+  printf(" valid");
+
+#define FAIL do{ printf(" | FAIL\n"); fails++; }while(0)
+#define WANT(x) if (!(x)) { printf(" not %s",STRING(x)); FAIL; return; } else;
+
+  WANT(!our_r);
+  WANT(!libc_r);
+  WANT(air);
+  WANT(air->ai_addr);
+  WANT(!air->ai_next);
+  if (air->ai_addrlen!=socklen || memcmp(&ours,air->ai_addr,socklen)) {
+    printf(" mismatch");
+    FAIL;
+    dump("ours",&ours.sa,socklen);
+    dump("libc",air->ai_addr,air->ai_addrlen);
+    return;
+  }
+
+  printf(" |");
+
+  int ourbuflen= sizeof(ourbuf);
+  int ourport;
+  our_r= adns_addr2text(&ours.sa, ourbuf,&ourbuflen, &ourport);
+
+  printf(" us %s",strerror(our_r));
+  if (!our_r)
+    printf(" `%s'",ourbuf);
+
+  size_t theirbuflen= sizeof(theirbuf);
+  libc_r= getnameinfo(&ours.sa,socklen, theirbuf,theirbuflen, 0,0,
+                     NI_NUMERICHOST|NI_NUMERICSERV);
+  printf("; libc %s", libc_r ? gai_strerror(libc_r) : "0");
+  if (!libc_r)
+    printf(" `%s'",theirbuf);
+
+  printf(":");
+
+  WANT(!our_r);
+  WANT(!libc_r);
+  WANT(ourport==PORT);
+  if (strcmp(ourbuf,theirbuf)) {
+    printf(" mismatch");
+    FAIL;
+    return;
+  }
+
+ ok:
+  printf(" | PASS\n");
+}
+
+int main(int argc, char **argv) {
+  const char *arg;
+  while ((arg= *++argv)) {
+    dotest(arg);
+  }
+  return !!fails;
+}
index 30ee96bab56c33c340d0645145db5cf9ff48be4d..69194cccae4e43007f7c7598e4ad0d01096ecb68 100644 (file)
@@ -228,8 +228,6 @@ int adns_text2addr(const char *addr, uint16_t port, struct sockaddr *sa,
   return EINVAL;                               \
 }while(0)
 
-  port= htons(port);
-
   if (!strchr(addr, ':')) { /* INET */
 
 #define AFCORE(INETx,SINx,sinx)                        \
@@ -268,6 +266,8 @@ int adns_text2addr(const char *addr, uint16_t port, struct sockaddr *sa,
   *salen = needlen;
 
   memset(sa, 0, needlen);
+
+  sa->sa_family= af;
   *portp = htons(port);
 
   int r= inet_pton(af,parse,dst);
@@ -332,7 +332,7 @@ int adns_text2addr(const char *addr, uint16_t port, struct sockaddr *sa,
       }
     } /* else; !!*ep */
 
-    SIN6(sa)->sin6_scope_id= htonl(scope);
+    SIN6(sa)->sin6_scope_id= scope;
   } /* if (scopestr) */
 
   return 0;
@@ -362,7 +362,6 @@ int adns_addr2text(const struct sockaddr *sa,
   if (sa->sa_family == AF_INET6) {
     uint32_t scope = CSIN6(sa)->sin6_scope_id;
     if (scope) {
-      scope = ntohl(scope);
       int scopeoffset = strlen(addr_buffer);
       int remain = *addr_buflen - scopeoffset;
       int r = snprintf(addr_buffer + scopeoffset, remain,