support nslookup command 86/48486/2
authorHyejin Kim <hyejin0906.kim@samsung.com>
Tue, 22 Sep 2015 06:13:33 +0000 (15:13 +0900)
committerHyejin Kim <hyejin0906.kim@samsung.com>
Tue, 22 Sep 2015 09:02:47 +0000 (18:02 +0900)
Change-Id: I8f677c6b41e1244af404e4fe995599780d01480e

packaging/config
packaging/toybox.spec
packaging/usrbin.links
toys/samsung/README [new file with mode: 0644]
toys/samsung/nslookup.c [new file with mode: 0644]

index 6258959..998fbe5 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
 # ToyBox version: KCONFIG_VERSION
-# Thu Aug 20 11:23:54 2015
+# Tue Sep 22 14:54:41 2015
 #
 CONFIG_TOYBOX_CONTAINER=y
 CONFIG_TOYBOX_FIFREEZE=y
@@ -13,6 +13,11 @@ CONFIG_TOYBOX_SHADOW=y
 CONFIG_TOYBOX_FORK=y
 
 #
+# Samsung developed commands
+#
+CONFIG_NSLOOKUP=y
+
+#
 # Posix commands
 #
 # CONFIG_BASENAME is not set
index 10ba854..dd6d12f 100644 (file)
@@ -117,6 +117,7 @@ cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/toybox-symlinks-dhcpd
 %doc LICENSE
 %{_datadir}/license/toybox
 /bin/toybox
+/usr/bin/nslookup
 %if "%{?profile}"=="tv"
 /sbin/ping
 /bin/ping
index 424150e..2ed0e8d 100644 (file)
@@ -1,2 +1,3 @@
 dumpleases
 dhcp
+nslookup
diff --git a/toys/samsung/README b/toys/samsung/README
new file mode 100644 (file)
index 0000000..fa82bef
--- /dev/null
@@ -0,0 +1,3 @@
+Samsung developed commands
+
+These are commands developed at Samsung Electrnocis Co. Ltd.
diff --git a/toys/samsung/nslookup.c b/toys/samsung/nslookup.c
new file mode 100644 (file)
index 0000000..ac8f8ec
--- /dev/null
@@ -0,0 +1,181 @@
+/* nslookup.c - query Internet name servers
+ *
+ * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com>
+ * Copyright 2015 Rajni Kant <rajnikant12345@gmail.com>
+ *
+
+USE_NSLOOKUP(NEWTOY(nslookup, "<1?", TOYFLAG_USR|TOYFLAG_BIN))
+
+config NSLOOKUP
+  bool "nslookup"
+  default y
+  help
+    usage: nslookup [HOST] [SERVER]
+
+    Query the nameserver for the IP address of the given HOST
+    optionally using a specified DNS server.
+
+    Note:- Only non-interactive mode is supported.
+*/
+
+#define FOR_nslookup
+#include "toys.h"
+#include <resolv.h>
+
+static char *address_to_name(struct sockaddr *sock)
+{
+  //man page of getnameinfo.
+  char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,};
+  int status = 0;
+  if (sock->sa_family == AF_INET) {
+    socklen_t len = sizeof(struct sockaddr_in);
+    if ((status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, sizeof(sbuf),
+            NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
+      return xmprintf("%s:%s", hbuf, sbuf);
+    else {
+      fprintf(stderr, "getnameinfo: %s\n", gai_strerror(status));
+      return NULL;
+    }
+  }
+  else if (sock->sa_family == AF_INET6) {
+    socklen_t len = sizeof(struct sockaddr_in6);
+    if ((status = getnameinfo(sock, len, hbuf, sizeof(hbuf), sbuf, 
+            sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0) {
+      //verification for resolved hostname.
+      if (strchr(hbuf, ':')) return xmprintf("[%s]:%s", hbuf, sbuf);
+      else return xmprintf("%s:%s", hbuf, sbuf);
+    }
+    else {
+      fprintf(stderr, "getnameinfo: %s\n", gai_strerror(status));
+      return NULL;
+    }
+  }
+  else if (sock->sa_family == AF_UNIX) {
+    struct sockaddr_un *sockun = (void*)sock;
+    return xmprintf("local:%.*s", (int) sizeof(sockun->sun_path), sockun->sun_path);
+  }
+  return NULL;
+}
+
+static void print_addrs(char *hostname, char *msg)
+{
+  struct addrinfo hints, *res = NULL, *cur = NULL;
+  int ret_ga;
+  char *n = xstrdup(hostname), *p, *tmp;
+  tmp = n;
+  if ((*n == '[') && (p = strrchr(n, ']')) != NULL ) {
+    n++;
+    *p = '\0';
+  }
+
+  memset(&hints, 0, sizeof(struct addrinfo));
+  hints.ai_socktype = SOCK_STREAM;
+
+  ret_ga = getaddrinfo(n, NULL, &hints, &res);                                                                                                       
+  if (ret_ga) perror_exit("Hostname %s", gai_strerror(ret_ga));
+
+  cur = res;
+  while(cur) {
+    char *colon = NULL;
+    char *name = address_to_name(cur->ai_addr);
+    if (name) {
+      colon = strrchr(name, ':');
+      if (colon) *colon = '\0';
+      xprintf("%-8s %s\n",msg, hostname);
+      xprintf("Address: %s\n", name);
+      free(name);
+    }
+    cur = cur->ai_next;
+  }
+  if (!res->ai_addr) error_exit("getaddrinfo failed");
+
+  freeaddrinfo(res);
+  free(tmp);
+}
+
+static void resolve_addr(char *host, void *addr, char* port)
+{
+  struct addrinfo *info, hint;
+  int ret = atolx(port);
+  
+  if(ret <0 || ret > 65535 ) error_exit("bad port:  %s", port);
+  if (strncmp(host, "local:", 6) == 0) {  
+    struct sockaddr *sockun = (struct sockaddr *)addr;   
+    sockun->sa_family = AF_UNIX;
+    strncpy(((struct sockaddr_un *)sockun)->sun_path, host + 6, 
+            sizeof(((struct sockaddr_un *)sockun)->sun_path));
+    return ;   
+  }   
+  memset(&hint, 0, sizeof(hint));
+
+  ret = getaddrinfo(host, port , &hint, &info);
+  
+  if (ret || !info) error_exit("bad address:  %s", host);
+
+  memcpy(addr, info->ai_addr, info->ai_addrlen);
+  freeaddrinfo(info);
+}
+
+void nslookup_main(void)
+{
+  struct sockaddr* sock;
+  char *args[2] = {0,0}, *colon = NULL, *name = NULL;
+  
+  res_init(); //initialize the _res struct, for DNS name.
+
+  for (;*toys.optargs; toys.optargs++) {
+    if (**toys.optargs == '-') {
+      if (!strncmp(&toys.optargs[0][1], "retry=", 6)) {
+        _res.retry = atolx(toys.optargs[0]+7);
+      } else if (!strncmp(&toys.optargs[0][1], "timeout=", 8)) {
+        _res.retrans = atolx(toys.optargs[0]+9);
+      } else error_msg("invalid option '%s'", *toys.optargs);
+    } else if (!args[0]) args[0] = *toys.optargs;
+    else if (!args[1]) args[1] = *toys.optargs;
+    else error_exit("bad arg '%s'",*toys.optargs);
+  }
+
+  if ( !*args) {
+    toys.exithelp++;
+    error_exit("Needs 1 args minimum");
+  }
+  if (args[1]) { //set the default DNS
+    struct sockaddr_storage addr;
+    char* port = NULL ;
+    
+    if (args[1][0] == '[') {
+      int len = strchr(args[1],']') - &args[1][0];
+      if (len > 45|| len <= 0 ) error_exit("bad address:  %s", args[1]);
+      strncpy(toybuf,&args[1][1], len-1);
+      args[1] += len;
+    }
+    if ((port = strchr(args[1],':'))) {
+      *port = '\0';
+      port++;
+    }
+    else port = "53";
+    resolve_addr((toybuf[0])?toybuf:args[1], &addr, port );
+
+    if (addr.ss_family == AF_INET) {
+      _res.nscount = 1;
+      _res.nsaddr_list[0] = *((struct sockaddr_in*)&addr);
+    }
+    else if (addr.ss_family == AF_INET6) {
+      _res._u._ext.nscount = 1;
+      _res._u._ext.nsaddrs[0] = ((struct sockaddr_in6*)&addr);
+    }
+  }
+
+  sock = (struct sockaddr*)_res._u._ext.nsaddrs[0];
+  if (!sock) sock = (struct sockaddr*)&_res.nsaddr_list[0];
+  if ((name = address_to_name(sock))) {
+    colon = strrchr(name, ':');
+    if (colon) *colon = '\0';
+    print_addrs(name, "Server:");
+    free(name);
+  }
+  puts("");
+
+  print_addrs(args[0], "Name:");  
+}