Hello,

The following patch seems appropriate to apply
to fix the kernel ip6_sprintf() function.

What it is doing is ensuring that when we
abbreviate addresses that the longest string
of zeros is shortend, not the first run of
zeros.

Our internal commit log is:
problem:
Unification of IPv6 address representation
fix:
recommended format of text representing an IPv6 address
is summarized as follows.

1. omit leading zeros

2. "::" used to their maximum extent whenever possible

3. "::" used where shortens address the most

4. "::" used in the former part in case of a tie breaker

5. do not shorten one 16 bit 0 field

6. use lower case

Present code in ip6_sprintf() is following rules 1,2,5,6.
Adding fix for following other rules also.For following
rules 3 and 4, finding out the index where to replace zero's
with '::' and using that index.
References:
http://tools.ietf.org/html/draft-ietf-6man-text-addr-representation-04.html


Diff is attached in text format.

-- 
- Alfred Perlstein
.- AMA, VMOA #5191, 03 vmax, 92 gs500, 85 ch250, 07 zx10
.- FreeBSD committer
Index: in6.c
===================================================================
--- in6.c	(revision 207329)
+++ in6.c	(working copy)
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: head/sys/netinet6/in6.c 207268 2010-04-27 09:47:14Z kib $");
 
 #include "opt_compat.h"
 #include "opt_inet.h"
@@ -1898,7 +1898,7 @@
 char *
 ip6_sprintf(char *ip6buf, const struct in6_addr *addr)
 {
-	int i;
+	int i, cnt = 0, maxcnt = 0, idx = 0, index = 0;
 	char *cp;
 	const u_int16_t *a = (const u_int16_t *)addr;
 	const u_int8_t *d;
@@ -1907,6 +1907,23 @@
 	cp = ip6buf;
 
 	for (i = 0; i < 8; i++) {
+		if (*(a + i) == 0) {
+			cnt++;
+			if (cnt == 1)
+				idx = i;
+		}
+		else if (maxcnt < cnt) {
+			maxcnt = cnt;
+			index = idx;
+			cnt = 0;
+		}
+	}
+	if (maxcnt < cnt) {
+		maxcnt = cnt;
+		index = idx;
+	}
+
+	for (i = 0; i < 8; i++) {
 		if (dcolon == 1) {
 			if (*a == 0) {
 				if (i == 7)
@@ -1917,7 +1934,7 @@
 				dcolon = 2;
 		}
 		if (*a == 0) {
-			if (dcolon == 0 && *(a + 1) == 0) {
+			if (dcolon == 0 && *(a + 1) == 0 && i == index) {
 				if (i == 0)
 					*cp++ = ':';
 				*cp++ = ':';
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to