Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 May 2010 23:22:11 -0700
From:      Alfred Perlstein <alfred@freebsd.org>
To:        freebsd-net@freebsd.org
Subject:   Patch for ip6_sprintf(), please review
Message-ID:  <20100516062211.GC6175@elvis.mu.org>

next in thread | raw e-mail | index | archive | help

--YiEDa0DAkWCtVeE4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

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

--YiEDa0DAkWCtVeE4
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="in6.diff"

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++ = ':';

--YiEDa0DAkWCtVeE4--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20100516062211.GC6175>