Package: knocker
Version: 0.7.1-3.1
Severity: normal
Tags: patch ipv6

I can offer a patch to implement support for IPv6 probing.
Successfully tested for GNU/Linux and GNU/kFreeBSD.

Best regards,
  Mats Erik Andersson, DM
Description: Adapt code and manpage to IPv6.
 Standard changes are implemented to make the
 knocker service able to probe also IPv6 hosts.
 .
 New command line options "-4/--ipv4" and "-6/--ipv6"
 restrict to a predetermined address domain.
 .
 A misconceived test for the root user is corrected
 in passing.
Author: Mats Erik Andersson <deb...@gisladisker.se>
Forwarded: no
Last-Update: 2011-03-03

diff -Naur knocker-0.7.1.debian/debian/knocker.1 knocker-0.7.1/debian/knocker.1
--- knocker-0.7.1.debian/debian/knocker.1	2011-03-03 09:48:59.000000000 +0100
+++ knocker-0.7.1/debian/knocker.1	2011-03-03 12:25:00.000000000 +0100
@@ -26,6 +26,12 @@
 \fB\-EP\fr, \fB\-\-end-port\fR
 port number to end the scan at
 .TP
+\fB\-4\fr, \fB\-\-ipv4\fR
+only IPv4 addressing (default is first address available)
+.TP
+\fB\-6\fr, \fB\-\-ipv6\fR
+use only IPv6 addressing
+.TP
 \fB\-\-last-host\fR
 uses the last scanned host as target
 .TP
diff -Naur knocker-0.7.1.debian/src/knocker_args.c knocker-0.7.1/src/knocker_args.c
--- knocker-0.7.1.debian/src/knocker_args.c	2002-05-24 01:58:33.000000000 +0200
+++ knocker-0.7.1/src/knocker_args.c	2011-03-03 12:19:12.000000000 +0100
@@ -80,9 +80,11 @@
   fprintf (stdout, "      %s              performs again the last port scan\n", LAST_SCAN_LONG_OPT);
   fprintf (stdout, "\n");
   fprintf (stdout, "Extra options:\n");
+  fprintf (stdout, "      %s,  %s              only IPv4 host addressing\n", HOST_IPV4_SHORT_OPT, HOST_IPV4_LONG_OPT);
+  fprintf (stdout, "      %s,  %s              only IPv6 host addressing\n", HOST_IPV6_SHORT_OPT, HOST_IPV6_LONG_OPT);
   fprintf (stdout, "      %s,  %s             quiet mode (no console output, logs to file)\n", QUIET_MODE_SHORT_OPT, QUIET_MODE_LONG_OPT);
   fprintf (stdout, "      %s, %s <logfile> log scan results to the specified file\n", ENABLE_LOGFILE_SHORT_OPT, ENABLE_LOGFILE_LONG_OPT);
-  fprintf (stdout, "      %s, %s          disable fency output\n", NO_FENCY_SHORT_OPT, NO_FENCY_LONG_OPT);
+  fprintf (stdout, "      %s, %s          disable fancy output\n", NO_FENCY_SHORT_OPT, NO_FENCY_LONG_OPT);
   fprintf (stdout, "      %s, %s         disable colored output\n", NO_COLORS_SHORT_OPT, NO_COLORS_LONG_OPT);
   fprintf (stdout, "\n");
   fprintf (stdout, "      %s              let you configure %s\n", CONFIGURE_LONG_OPT, PACKAGE);
@@ -105,6 +107,7 @@
   args->hname = NULL;
   args->hip = NULL;
   args->lfname = NULL;
+  args->hfamily = AF_UNSPEC;
   args->port = 0;
   args->sport = 0;
   args->eport = 0;
@@ -189,6 +192,16 @@
             }
           return (0);           /* we should have all arguments here */
         }
+      else if ((!strcmp (argv[i], HOST_IPV4_SHORT_OPT)) || (!strcmp (argv[i], HOST_IPV4_LONG_OPT)))
+        {
+          /* Accept only IPv4 addressing. */
+          args->hfamily = AF_INET;
+        }
+      else if ((!strcmp (argv[i], HOST_IPV6_SHORT_OPT)) || (!strcmp (argv[i], HOST_IPV6_LONG_OPT)))
+        {
+          /* Accept only IPv6 addressing. */
+          args->hfamily = AF_INET6;
+        }
       else if ((!strcmp (argv[i], NO_FENCY_SHORT_OPT)) || (!strcmp (argv[i], NO_FENCY_LONG_OPT)))
         {
           /* Disable fency output */
diff -Naur knocker-0.7.1.debian/src/knocker_args.h knocker-0.7.1/src/knocker_args.h
--- knocker-0.7.1.debian/src/knocker_args.h	2002-05-24 01:58:35.000000000 +0200
+++ knocker-0.7.1/src/knocker_args.h	2011-03-03 12:18:00.000000000 +0100
@@ -33,6 +33,12 @@
   /* host to scan, got with lasthost  */
 #define LAST_HOST_LONG_OPT  "--last-host"
 
+  /* preferred address family for hosts */
+#define HOST_IPV4_SHORT_OPT "-4"
+#define HOST_IPV4_LONG_OPT "--ipv4"
+#define HOST_IPV6_SHORT_OPT "-6"
+#define HOST_IPV6_LONG_OPT "--ipv6"
+
   /* single port number */
 #define SINGLE_PORT_SHORT_OPT "-P"
 #define SINGLE_PORT_LONG_OPT  "--port"
@@ -82,6 +88,7 @@
   char           *hname;      /* hostname string */
   char           *hip;        /* host IP string  */
   char           *lfname;     /* logfile name */
+  int            hfamily;     /* desired address domain */
   unsigned int   port;        /* Single port number, -P */
   unsigned int   sport;       /* Start port number, -SP */
   unsigned int   eport;       /* End port number, -EP   */
diff -Naur knocker-0.7.1.debian/src/knocker_core.c knocker-0.7.1/src/knocker_core.c
--- knocker-0.7.1.debian/src/knocker_core.c	2002-05-24 01:58:51.000000000 +0200
+++ knocker-0.7.1/src/knocker_core.c	2011-03-03 11:58:35.000000000 +0100
@@ -33,13 +33,13 @@
 
 static int knocker_core_init_socket_data (knocker_core_socket_t * sock);
 static void knocker_core_free_socket_data (knocker_core_socket_t * sock);
-static int knocker_core_open_socket (knocker_core_socket_t * sock, int protocol);
+static int knocker_core_open_socket (knocker_core_socket_t * sock, int family, int protocol);
 static void knocker_core_close_socket (knocker_core_socket_t * sock);
 
 static int knocker_core_init_host_data (knocker_core_host_t * host);
 static void knocker_core_free_host_data (knocker_core_host_t * host);
 
-static int knocker_core_gethostbyname (knocker_core_host_t * hinfo, const char *hostname);
+static int knocker_core_gethostbyname (knocker_core_host_t * hinfo, const char *hostname, int family);
 static int knocker_core_getservbyport (char *service, unsigned int port, int protocol);
 
 static char *knocker_core_get_host_name_string (knocker_core_host_t * hinfo);
@@ -364,7 +364,7 @@
   fprintf (stderr, "debug: connecting to port: %d\n", port);
 #endif
 
-  if (knocker_core_open_socket (&data->socket, PROTO_TCP) == KNOCKER_SOCKET_ERROR)
+  if (knocker_core_open_socket (&data->socket, data->host.hostaddr.ss_family, PROTO_TCP) == KNOCKER_SOCKET_ERROR)
     {
 #ifdef DEBUG
       fprintf (stderr, "debug: socket error, couldn't connect.\n");
@@ -372,12 +372,16 @@
       return -1;
     }
 
-  data->host.sockaddr_in.sin_family = AF_INET;
-  data->host.sockaddr_in.sin_port = htons (port);
-  data->host.sockaddr_in.sin_addr = *((struct in_addr *) data->host.info->h_addr);
-  memset (&(data->host.sockaddr_in.sin_zero), 0, 8);
+  memcpy (&(data->host.sockaddr_st), &(data->host.hostaddr), data->host.addrlen);
+  switch (data->host.hostaddr.ss_family) {
+    case AF_INET6:
+      ((struct sockaddr_in6 *) &(data->host.sockaddr_st))->sin6_port = htons (port);
+    case AF_INET:
+    default:
+      ((struct sockaddr_in *) &(data->host.sockaddr_st))->sin_port = htons (port);
+  }
 
-  if (!connect (data->socket.fd, (struct sockaddr *) &data->host.sockaddr_in, sizeof (struct sockaddr)))
+  if (!connect (data->socket.fd, (struct sockaddr *) &data->host.sockaddr_st, data->host.addrlen))
     /* here the port is open */
     {
       knocker_core_close_socket (&data->socket);
@@ -401,9 +405,9 @@
    ============================================================================
    ============================================================================
 */
-char *knocker_core_resolve_host (knocker_core_portscan_data_t * data, const char *hostname)
+char *knocker_core_resolve_host (knocker_core_portscan_data_t * data, const char *hostname, int family)
 {
-  if (knocker_core_gethostbyname (&data->host, hostname) == -1)
+  if (knocker_core_gethostbyname (&data->host, hostname, family) == -1)
     return NULL;
   else
     return (data->host.ip);
@@ -506,14 +510,14 @@
    ============================================================================
    ============================================================================
 */
-static int knocker_core_open_socket (knocker_core_socket_t * sock, int protocol)
+static int knocker_core_open_socket (knocker_core_socket_t * sock, int family, int protocol)
 {
 #ifdef DEBUG
   fprintf (stderr, "debug: function knocker_core_open_socket (...) called.\n");
 #endif
   if (protocol == PROTO_TCP)
     {
-      if ((sock->fd = socket (AF_INET, SOCK_STREAM, 0)) == KNOCKER_SOCKET_ERROR)
+      if ((sock->fd = socket (family, SOCK_STREAM, 0)) == KNOCKER_SOCKET_ERROR)
         {
 #ifdef DEBUG
           fprintf (stderr, "debug: couldn't open the socket: ");
@@ -524,7 +528,7 @@
     }
   else if (protocol == PROTO_UDP)
     {
-      if ((sock->fd = socket (AF_INET, SOCK_DGRAM, 0)) == KNOCKER_SOCKET_ERROR)
+      if ((sock->fd = socket (family, SOCK_DGRAM, 0)) == KNOCKER_SOCKET_ERROR)
         {
 #ifdef DEBUG
           fprintf (stderr, "debug: couldn't open the socket: ");
@@ -579,13 +583,47 @@
    ============================================================================
    ============================================================================
 */
-static int knocker_core_gethostbyname (knocker_core_host_t * hinfo, const char *hostname)
+static int knocker_core_gethostbyname (knocker_core_host_t * hinfo, const char *hostname, int family)
 {
-  if ((hinfo->info = gethostbyname (hostname)) == NULL)
+  struct addrinfo hints, *res, *ai;
+  char hostip[INET6_ADDRSTRLEN];
+  int err, fd;
+
+  memset (&hints, 0, sizeof (hints));
+  hints.ai_family = family;
+  hints.ai_flags = AI_ADDRCONFIG;
+
+  if ( (err = getaddrinfo (hostname, NULL, &hints, &res)) ) {
+#ifdef DEBUG
+    fprintf (stderr, "debug: knocker_core_gethostbyname(): %s", gai_strerror(err));
+#endif
+    return -1;
+  }
+
+  for (ai = res; ai; ai = ai->ai_next) {
+    if ( (ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6) )
+      continue;
+
+    fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+    if (fd < 0)
+      continue;
+    /* Valid socket indicates a functional address; accept it. */
+    close (fd);
+    hinfo->addrlen = ai->ai_addrlen;
+    memcpy(&(hinfo->hostaddr), ai->ai_addr, ai->ai_addrlen);
+    break;
+  }
+
+  if (res)
+    freeaddrinfo(res);
+
+  if (ai == NULL)
     return -1;
 
   knocker_core_set_host_name_string (hinfo, hostname);
-  knocker_core_set_host_ip_string (hinfo, inet_ntoa (*(struct in_addr *) *hinfo->info->h_addr_list));
+  getnameinfo ((struct sockaddr *) &(hinfo->hostaddr), hinfo->addrlen,
+      hostip, sizeof (hostip), NULL, 0, NI_NUMERICHOST);
+  knocker_core_set_host_ip_string (hinfo, hostip);
 
   return 0;
 }
diff -Naur knocker-0.7.1.debian/src/knocker_core.h knocker-0.7.1/src/knocker_core.h
--- knocker-0.7.1.debian/src/knocker_core.h	2002-05-24 01:58:53.000000000 +0200
+++ knocker-0.7.1/src/knocker_core.h	2011-03-03 11:59:27.000000000 +0100
@@ -135,8 +135,9 @@
 */
 
 typedef struct {
-  struct hostent                   *info;        /* hostent structure */
-  struct sockaddr_in               sockaddr_in;  /* sockaddr_in structure */
+  struct sockaddr_storage          hostaddr;     /* template address */
+  socklen_t                        addrlen;      /* active length */
+  struct sockaddr_storage          sockaddr_st;  /* working address */
   char                             *name;        /* hostname string   */
   char                             *ip;          /* host IP address string */
 } knocker_core_host_t;
@@ -185,7 +186,7 @@
 int   knocker_core_validate_port_number (unsigned int port);
 
 /* returns host ip address on success, NULL on failure */
-char *knocker_core_resolve_host (knocker_core_portscan_data_t *data, const char *hostname);
+char *knocker_core_resolve_host (knocker_core_portscan_data_t *data, const char *hostname, int family);
 
 /* return the hostname string from the structure */
 char *knocker_core_get_hostname (knocker_core_portscan_data_t *data);
@@ -203,13 +204,13 @@
 
 static int  knocker_core_init_socket_data   (knocker_core_socket_t *sock);
 static void knocker_core_free_socket_data   (knocker_core_socket_t *sock);
-static int  knocker_core_open_socket   (knocker_core_socket_t *sock, int protocol);
+static int  knocker_core_open_socket   (knocker_core_socket_t *sock, int family, int protocol);
 static void knocker_core_close_socket  (knocker_core_socket_t *sock);
 
 static int  knocker_core_init_host_data   (knocker_core_host_t *host);
 static void knocker_core_free_host_data   (knocker_core_host_t *host);
 
-static int   knocker_core_gethostbyname    (knocker_core_host_t *hinfo, const char *hostname);
+static int   knocker_core_gethostbyname    (knocker_core_host_t *hinfo, const char *hostname, int family);
 static int   knocker_core_getservbyport    (char *service, unsigned int port, int protocol);
 
 static char *knocker_core_get_host_name_string (knocker_core_host_t *hinfo);
diff -Naur knocker-0.7.1.debian/src/knocker_main.c knocker-0.7.1/src/knocker_main.c
--- knocker-0.7.1.debian/src/knocker_main.c	2011-03-03 09:48:59.000000000 +0100
+++ knocker-0.7.1/src/knocker_main.c	2011-03-03 12:00:20.000000000 +0100
@@ -132,7 +132,7 @@
 */
 static void resolve (void)
 {
-  if (knocker_core_resolve_host (&pscan_data, knocker_args.hname) == NULL)
+  if (knocker_core_resolve_host (&pscan_data, knocker_args.hname, knocker_args.hfamily) == NULL)
     {
       knocker_output_resolve_error (knocker_args.hname);
       knocker_log_resolve_error (knocker_args.hname);
diff -Naur knocker-0.7.1.debian/src/knocker_user.c knocker-0.7.1/src/knocker_user.c
--- knocker-0.7.1.debian/src/knocker_user.c	2002-05-24 02:00:03.000000000 +0200
+++ knocker-0.7.1/src/knocker_user.c	2011-03-03 11:48:06.000000000 +0100
@@ -82,7 +82,7 @@
       _dir_create (user->dir);
     }
 
-  if (knocker_user_is_root)
+  if (knocker_user_is_root())
     user->super = 1;
   else
     user->super = 0;

Attachment: signature.asc
Description: Digital signature

Reply via email to