--- tools/addr6.c_orig	2015-04-05 09:59:52.000000000 -0400
+++ tools/addr6.c	2017-06-27 23:39:54.803660387 -0400
@@ -42,7 +42,7 @@
 void					usage(void);
 void					print_help(void);
 void					stat_ipv6_address(struct decode6 *, struct stats6 *);
-void					print_dec_address_script(struct decode6 *);
+void					print_dec_address_script(const char *line, size_t len, struct decode6 *);
 int						init_host_list(struct hashed_host_list *);
 uint16_t				key(struct hashed_host_list *, struct in6_addr *);
 struct hashed_host_entry *		add_hashed_host_entry(struct hashed_host_list *, struct in6_addr *);
@@ -50,7 +50,8 @@
 void					print_stats(struct stats6 *);
 
 unsigned char			stdin_f=FALSE, addr_f=FALSE, verbose_f=FALSE, decode_f=FALSE, print_unique_f=FALSE;
-unsigned char			stats_f=FALSE, filter_f=FALSE, canonic_f=FALSE, reverse_f=FALSE;
+unsigned char			stats_f=FALSE, filter_f=FALSE, canonic_f=FALSE, fixed_f=FALSE, hex_f = FALSE, reverse_f=FALSE;
+unsigned char			passthru_f=FALSE;
 char					line[MAX_LINE_SIZE];
 
 extern char			*optarg;
@@ -81,7 +82,10 @@
 	static struct option longopts[] = {
 		{"address", required_argument, 0, 'a'},
 		{"stdin", no_argument, 0, 'i'},
+		{"pass-thru", no_argument, 0, 'p'},
 		{"print-canonic", no_argument, 0, 'c'},
+		{"print-fixed", no_argument, 0, 'F'},
+		{"print-hex", no_argument, 0, 'H'},
 		{"print-decode", no_argument, 0, 'd'},
 		{"print-reverse", no_argument, 0, 'r'},
 		{"print-stats", no_argument, 0, 's'},
@@ -101,7 +105,7 @@
 		{0, 0, 0,  0 },
 	};
 
-	char shortopts[]= "a:icrdsqj:b:k:w:g:J:B:K:W:G:vh";
+	char shortopts[]= "a:icFHrdsqj:b:k:w:g:J:B:K:W:G:vhp";
 
 	char option;
 
@@ -129,10 +133,22 @@
 				stdin_f=1;
 				break;
 
+			case 'p':  /* Pass address to output, e.g., prepend to -d info */
+				passthru_f=1;
+				break;
+
 			case 'c':	/* Print addresses in canonic form */
 				canonic_f=1;
 				break;
 
+			case 'F':	/* Print addresses in fixed-length form */
+				fixed_f=1;
+				break;
+
+			case 'H':	/* Print addresses in hex form */
+				hex_f=1;
+				break;
+
 			case 'd':	/* Decode IPv6 addresses */
 				decode_f=1;
 				break;
@@ -518,13 +534,18 @@
 		exit(EXIT_FAILURE);
 	}
 
+	if(canonic_f + fixed_f + hex_f > 1){
+		puts("Cannot specify '-c', '-H', '-F' the same time (try only one of them at a time)");
+		exit(EXIT_FAILURE);
+	}
+
 	if(stats_f && !stdin_f){
 		puts("Cannot obtain statistics based on a single IPv6 address (should be using '-i')");
 		exit(EXIT_FAILURE);
 	}
 
 	/* By default, addr6 decodes IPv6 addresses */
-	if(!print_unique_f && !filter_f && !stats_f && !canonic_f && !reverse_f)
+	if(!print_unique_f && !filter_f && !stats_f && !canonic_f && !fixed_f && !hex_f && !reverse_f)
 		decode_f=1;
 
 	if(print_unique_f){
@@ -545,7 +566,7 @@
 			if(r==1){
 				if ( inet_pton(AF_INET6, ptr, &(addr.ip6)) <= 0){
 					if(decode_f)
-						puts("Error: Invalid IPv6 address");
+						fprintf(stderr, "Error: Invalid IPv6 address \"%s\"", ptr);
 
 					continue;
 				}
@@ -598,12 +619,30 @@
 					stat_ipv6_address(&addr, &stats);
 				}
 				else if(decode_f){
-						print_dec_address_script(&addr);
+						if (passthru_f) {
+							size_t len = strlen(line);
+							/* add a space as a separator (to print before the decode info) */
+							if ('\n' == line[len-1]) {
+							   line[len-1] = ' ';
+							} else {
+							   line[len] = ' ';
+							   len++;
+							}
+							print_dec_address_script(line, len, &addr);
+						} else {
+							print_dec_address_script("", 0, &addr);
+						}
 				}
 				else if(reverse_f){
 						print_ipv6_address_rev(&(addr.ip6));
 				}
-				else{
+				else if(fixed_f){
+						print_ipv6_address_flp("", &(addr.ip6));
+				}
+				else if(hex_f){
+						print_ipv6_address_hex("", &(addr.ip6));
+				}
+				else{ /* canonic_f? */
 					if(inet_ntop(AF_INET6, &(addr.ip6), pv6addr, sizeof(pv6addr)) == NULL){
 						puts("inet_ntop(): Error converting IPv6 address to presentation format");
 						exit(EXIT_FAILURE);
@@ -622,12 +661,21 @@
 		/* If we were not asked to decode the address, we should print it on stdout */
 		if(decode_f){
 			decode_ipv6_address(&addr);
-			print_dec_address_script(&addr);
+			/*FIXME*/
+			print_dec_address_script("", 0, &addr);
 		}
 		else if(canonic_f){
 			if(print_ipv6_address("", &(addr.ip6)) != EXIT_SUCCESS)
 				exit(EXIT_FAILURE);
 		}
+		else if(fixed_f){
+			if(print_ipv6_address_flp("", &(addr.ip6)) != EXIT_SUCCESS)
+				exit(EXIT_FAILURE);
+		}
+		else if(hex_f){
+			if(print_ipv6_address_hex("", &(addr.ip6)) != EXIT_SUCCESS)
+				exit(EXIT_FAILURE);
+		}
 		else if(reverse_f){
 			if(print_ipv6_address_rev(&(addr.ip6)) != EXIT_SUCCESS)
 				exit(EXIT_FAILURE);
@@ -822,7 +870,7 @@
  * Print the IPv6 address decode obtained by decode_ipv6_address
  */
 
-void print_dec_address_script(struct decode6 *addr){
+void print_dec_address_script(const char *line, size_t len, struct decode6 *addr){
 	unsigned int r;
 
 	char *nullstring="";
@@ -1079,7 +1127,7 @@
 			break;
 	}
 
-	printf("%s=%s=%s=%s=%s\n", type, subtype, scope, iidtype, iidsubtype);
+	printf("%.*s%s=%s=%s=%s=%s\n", (int)len, line, type, subtype, scope, iidtype, iidsubtype);
 }
 
 
@@ -1090,7 +1138,7 @@
  */
 
 void usage(void){
-	puts("usage: addr6 (-i | -a) [-c | -d | -r | -s | -q] [-v] [-h]");
+	puts("usage: addr6 (-i | -a) [-p] [-c | -F | -H | -d | -r | -s | -q] [-v] [-h]");
 }
 
 
@@ -1108,7 +1156,10 @@
 	puts("\nOPTIONS:\n"
 	     "  --address, -a             IPv6 address to be decoded\n"
 	     "  --stdin, -i               Read IPv6 addresses from stdin (standard input)\n"
+	     "  --pass-thru, -p           Pass address to output, e.g., prepend to -d info\n"
 	     "  --print-canonic, -c       Print IPv6 addresses in canonic form\n"
+	     "  --print-fixed, -F         Print IPv6 addresses in fixed-length form\n"
+	     "  --print-hex, -H           Print IPv6 addresses in hex form\n"
 	     "  --print-reverse, -r       Print reversed IPv6 address\n"
 	     "  --print-decode, -d        Decode IPv6 addresses\n"
 	     "  --print-stats, -s         Print statistics about IPv6 addresses\n"
--- tools/libipv6.c_orig	2015-04-05 10:01:29.000000000 -0400
+++ tools/libipv6.c	2016-08-09 16:27:30.000000000 -0400
@@ -274,7 +274,7 @@
 			addr->subtype==UCAST_LINKLOCAL || addr->subtype==UCAST_SITELOCAL || addr->subtype==UCAST_UNIQUELOCAL ||\
 			addr->subtype == UCAST_6TO4){
 
-			if( (addr->ip6.s6_addr32[2] & htonl(0x020000ff)) == htonl(0x020000ff) && 
+			if( (addr->ip6.s6_addr32[2] & htonl(0x000000ff)) == htonl(0x000000ff) && 
 				(addr->ip6.s6_addr32[3] & htonl(0xff000000)) == htonl(0xfe000000)){
 				addr->iidtype= IID_MACDERIVED;
 				addr->iidsubtype= (ntohl(addr->ip6.s6_addr32[2]) >> 8) & 0xfffdffff;
@@ -2914,7 +2914,7 @@
 
 
 /*
- * Function: print_ipv6_addresss()
+ * Function: print_ipv6_address()
  *
  * Prints an IPv6 address with a legend
  */
@@ -2933,6 +2933,44 @@
 
 
 /*
+ * Function: print_ipv6_address_hex()
+ *
+ * Prints an IPv6 address in hex format with a legend
+ */
+
+unsigned int print_ipv6_address_hex(char *s, struct in6_addr *v6addr){
+	char pv6addr[sizeof "00112233445566778899aabbccddeeff"];
+
+	if(inet_ntoh(AF_INET6, v6addr, pv6addr, sizeof(pv6addr)) == NULL){
+		puts("inet_ntoh(): Error converting IPv6 Source Address to hex format");
+		return(EXIT_FAILURE);
+	}
+
+	printf("%s%s\n", s, pv6addr);
+	return(EXIT_SUCCESS);
+}
+
+
+/*
+ * Function: print_ipv6_address_flp()
+ *
+ * Prints an IPv6 address in fixed-length presentation format with a legend
+ */
+
+unsigned int print_ipv6_address_flp(char *s, struct in6_addr *v6addr){
+	char pv6addr[sizeof "0011:2233:4455:6677:8899:aabb:ccdd:eeff"];
+
+	if(inet_ntoflp(AF_INET6, v6addr, pv6addr, sizeof(pv6addr)) == NULL){
+		puts("inet_ntoflp(): Error converting IPv6 Source Address to hex format");
+		return(EXIT_FAILURE);
+	}
+
+	printf("%s%s\n", s, pv6addr);
+	return(EXIT_SUCCESS);
+}
+
+
+/*
  * Function: print_ipv6_address_rev()
  *
  * Prints an IPv6 address in reversed form
@@ -4611,3 +4649,198 @@
 	return TRUE;
 }
 
+/* int
+ * inet_hton6(src, dst)
+ *      convert hex_ip format address to network order binary form,
+ *      like inet_pton[6].
+ * Dave Plonka, 2015. Based on code by Paul Vixie, 1996.
+ */
+static int
+inet_hton6(const char *src, unsigned char *dst)
+{
+  static const char xdigits_l[] = "0123456789abcdef",
+    xdigits_u[] = "0123456789ABCDEF";
+  unsigned char tmp[IN6ADDRSZ], *tp, *endp;
+  const char *xdigits;
+  int ch, saw_xdigit;
+  unsigned int val;
+
+  memset((tp = tmp), 0, IN6ADDRSZ);
+  endp = tp + IN6ADDRSZ;
+  saw_xdigit = 0;
+  val = 0;
+  while((ch = *src++) != '\0') {
+    const char *pch;
+
+    if((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+      pch = strchr((xdigits = xdigits_u), ch);
+    if(pch != NULL) {
+      val <<= 4;
+      val |= (pch - xdigits);
+      saw_xdigit++;
+      if(4 == saw_xdigit) {
+        if(tp + INT16SZ > endp)
+          return (0);
+        *tp++ = (unsigned char) (val >> 8) & 0xff;
+        *tp++ = (unsigned char) val & 0xff;
+        saw_xdigit = 0;
+        val = 0;
+      }
+      continue;
+    }
+    return (0);
+  }
+  if(tp != endp)
+    return (0);
+  memcpy(dst, tmp, IN6ADDRSZ);
+  return (1);
+}
+
+/* int
+ * inet_hton(af, src, dst)
+ *      convert from hex_ip format (which usually means ASCII printable)
+ *      to network format (which is usually some kind of binary format).
+ * Dave Plonka, 2015. Based on code by Paul Vixie, 1996.
+ */
+int
+inet_hton(int af, const char *src, void *dst)
+{
+  switch (af) {
+  case AF_INET6:
+    if (32 == strspn(src, "0123456789abcdefABCDEF")) { /* hex_ip IPv6 addr? */
+       return inet_hton6(src, (unsigned char *)dst);
+    } else {
+#      undef inet_pton
+       return inet_pton(af, src, (unsigned char *)dst);
+    }
+    /* NOTREACHED */
+  case AF_INET: /* FIXME: handle IPv4? */
+  default:
+    return (-1);
+  }
+  /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntoh(af, src, dst, size)
+ *      convert from network format to hex_ip format.
+ * Dave Plonka, 2016.
+ */
+const char *
+inet_ntoh(int af, const void *src, char *dst, socklen_t size)
+{
+  size_t s; /* current index into src */ 
+  size_t d; /* current index into dst */
+  const char *digits = "0123456789abcdef";
+
+  if ((void *)0 ==src || (char *)0 == dst || size < sizeof "") {
+     errno = ENOSPC;
+     return (char *)0;
+     /* NOTREACHED */
+  }
+
+# define HEX_CHAR_BIT 4
+  switch (af) {
+  case AF_INET6: {
+    const struct in6_addr *src6 = src;
+    for (s = 0, d = 0;
+         s < (CHAR_BIT/HEX_CHAR_BIT) * sizeof src6->s6_addr &&
+            d < (size - sizeof "");
+         d++) {
+       if (0 == (d % 2)) { /* high nybble */
+          dst[d] = digits[src6->s6_addr[s] >> HEX_CHAR_BIT];
+       } else { /* low nybble */
+          dst[d] = digits[src6->s6_addr[s] & 0xf];
+          s++;
+       }
+    }
+    dst[d] = '\0';
+    return dst;
+    /* NOTREACHED */
+  }
+  case AF_INET: /* FIXME: handle IPv4? */
+  default:
+    errno = EAFNOSUPPORT;
+    return (char *)0;
+  }
+  /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntoflp(af, src, dst, size)
+ *      convert from network format to fixed-length presentation format.
+ * Dave Plonka, 2016.
+ */
+const char *
+inet_ntoflp(int af, const void *src, char *dst, socklen_t size)
+{
+  size_t s; /* current index into src */ 
+  size_t d; /* current index into dst */
+  const char *digits = "0123456789abcdef";
+
+  if ((void *)0 ==src || (char *)0 == dst || size < sizeof "") {
+     errno = ENOSPC;
+     return (char *)0;
+     /* NOTREACHED */
+  }
+
+# define HEX_CHAR_BIT 4
+  switch (af) {
+  case AF_INET6: {
+    const struct in6_addr *src6 = src;
+    for (s = 0, d = 0;
+         s < (CHAR_BIT/HEX_CHAR_BIT) * sizeof src6->s6_addr &&
+            d < (size - sizeof "");
+         d++) {
+       /* a diagram of a v6 with positions numbered, to determine cases below:
+        *           1         2         3
+        * 012345678901234567890123456789012345678
+        * hlhl:hlhl:hlhl:hlhl:hlhl:hlhl:hlhl:hlhl
+	* ^^  ^
+	* ||  colon (positions 4, 9, 14, ...)
+	* ||
+	* |low nybble (default below)
+	* |
+	* high nybble (positions 0, 2, 5, ...)
+	*/
+       switch (d) {
+       /* These are indexes into dst where a ':' character belongs: */
+       case  4: case  9:
+       case 14: case 19:
+       case 24: case 29:
+       case 34:
+          dst[d] = ':';
+          if (++d == size - sizeof "") {
+             goto done_label;
+          }
+          /* FALLTHRU */
+       /* These are indexes into dst where a high nybble belongs: */
+       case  0: case  2:
+       case  5: case  7:
+       case 10: case 12:
+       case 15: case 17:
+       case 20: case 22:
+       case 25: case 27:
+       case 30: case 32:
+       case 35: case 37:
+          dst[d] = digits[src6->s6_addr[s] >> HEX_CHAR_BIT]; /* high nybble */
+          break;
+
+       default:
+          dst[d] = digits[src6->s6_addr[s] & 0xf]; /* low nybble */
+          s++;
+          break;
+       }
+    }
+done_label:
+    dst[d] = '\0';
+    return dst;
+    /* NOTREACHED */
+  }
+  case AF_INET: /* FIXME: handle IPv4? */
+  default:
+    errno = EAFNOSUPPORT;
+    return (char *)0;
+  }
+  /* NOTREACHED */
+}
--- tools/libipv6.h_orig	2015-03-15 22:37:45.000000000 -0400
+++ tools/libipv6.h	2017-07-24 12:10:08.741705985 -0400
@@ -5,6 +5,14 @@
 #include <netdb.h>
 #include <net/if.h>  /* For  IFNAMSIZ */
 
+/* { for inet_hton, inet_ntoh */
+
+#define IN6ADDRSZ       16
+#define INADDRSZ         4
+#define INT16SZ          2
+
+/* } */
+
 /* General constants */
 #define SUCCESS		1
 #define FAILURE		0
@@ -933,6 +941,15 @@
 #endif
 #endif
 
+#if 1
+/* use our local version that understands "hex_ip" format IPv6 addresses too */
+/* Note that in FreeBSD 11.0-RELEASE-p9 inet_pton is already a macro, so we
+ * [re]define this unconditionally.
+ */
+#	undef inet_pton
+#	define inet_pton inet_hton
+#endif
+
 int					address_contains_colons(char *);
 int					address_contains_ranges(char *);
 void				change_endianness(uint32_t *, unsigned int);
@@ -980,6 +997,8 @@
 void				print_filters(struct iface_data *, struct filters *);
 void				print_filter_result(struct iface_data *, const u_char *, unsigned char);
 unsigned int		print_ipv6_address(char *s, struct in6_addr *);
+unsigned int		print_ipv6_address_hex(char *s, struct in6_addr *);
+unsigned int		print_ipv6_address_flp(char *s, struct in6_addr *);
 unsigned int		print_ipv6_address_rev(struct in6_addr *);
 int					print_local_addrs(struct iface_data *);
 void				randomize_ether_addr(struct ether_addr *);
@@ -1002,4 +1021,6 @@
 struct timeval		timeval_sub(struct timeval *, struct timeval *);
 float				time_diff_ms(struct timeval *, struct timeval *);
 unsigned int		zero_byte_iid(struct in6_addr *);
-
+int inet_hton(int af, const char *src, void *dst);
+const char *inet_ntoh(int af, const void *src, char *dst, socklen_t size);
+const char *inet_ntoflp(int af, const void *src, char *dst, socklen_t size);
