a format error in pf_print_host()

JINMEI Tatuya / 神明達哉 jinmei at isl.rdc.toshiba.co.jp
Tue Nov 20 06:48:30 PST 2007


At Tue, 20 Nov 2007 23:17:43 +0900,
JINMEI Tatuya <jinmei at isl.rdc.toshiba.co.jp> wrote:

> formats "1:2:3:4:5:6:7:8" as ":2:3:4:5:6:7:8".  This can be confirmed
> by the sample code attached to this message by
> - saving the file as e.g. "foo.c"
> - cc -o foo foo.c
> - ./foo 1:2:3:4:5:6:7:8
> 
> I've also attached a proposed patch to this problem.  The diff was
> made against 6-STABLE, but it's probably applicable to other versions.

Hmm...apparently attachments were stripped.  I'm directly copying the
file contents below:

=================== sample program ===================
#include <sys/param.h>
#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

struct pf_addr {
	union {
		struct in_addr		v4;
		struct in6_addr		v6;
		u_int8_t		addr8[16];
		u_int16_t		addr16[8];
		u_int32_t		addr32[4];
	} pfa;		    /* 128-bit address */
#define v4	pfa.v4
#define v6	pfa.v6
#define addr8	pfa.addr8
#define addr16	pfa.addr16
#define addr32	pfa.addr32
};

static void
pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af)
{
	switch (af) {
	case AF_INET: {
		u_int32_t a = ntohl(addr->addr32[0]);
		printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255,
		    (a>>8)&255, a&255);
		if (p) {
			p = ntohs(p);
			printf(":%u", p);
		}
		break;
	}
	case AF_INET6: {
		u_int16_t b;
		u_int8_t i, curstart = 255, curend = 0,
		    maxstart = 0, maxend = 0;
		for (i = 0; i < 8; i++) {
			if (!addr->addr16[i]) {
				if (curstart == 255)
					curstart = i;
				else
					curend = i;
			} else {
				if (curstart) {
					if ((curend - curstart) >
					    (maxend - maxstart)) {
						maxstart = curstart;
						maxend = curend;
						curstart = 255;
					}
				}
			}
		}
		for (i = 0; i < 8; i++) {
			if (i >= maxstart && i <= maxend) {
				if (maxend != 7) {
					if (i == maxstart)
						printf(":");
				} else {
					if (i == maxend)
						printf(":");
				}
			} else {
				b = ntohs(addr->addr16[i]);
				printf("%x", b);
				if (i < 7)
					printf(":");
			}
		}
		if (p) {
			p = ntohs(p);
			printf("[%u]", p);
		}
		break;
	}
	}
}

main(int argc, char *argv[])
{
	struct pf_addr addr;

	if (argc < 2) {
		fprintf(stderr, "specify an address\n");
		exit(1);
	}

	if (inet_pton(AF_INET6, argv[1], &addr) != 1) {
		fprintf(stderr, "inet_pton failed for %s\n", argv[1]);
		exit(1);
	}
	pf_print_host(&addr, 0, AF_INET6);
	putchar('\n');

	exit(0);
}
=================== sample program ===================

=================== patch for pf.c ===================
Index: pf.c
===================================================================
RCS file: /home/ncvs/src/sys/contrib/pf/net/pf.c,v
retrieving revision 1.34.2.6
diff -u -r1.34.2.6 pf.c
--- pf.c	23 Aug 2007 09:38:14 -0000	1.34.2.6
+++ pf.c	20 Nov 2007 14:06:34 -0000
@@ -1211,7 +1211,7 @@
 	case AF_INET6: {
 		u_int16_t b;
 		u_int8_t i, curstart = 255, curend = 0,
-		    maxstart = 0, maxend = 0;
+		    maxstart = 255, maxend = 255;
 		for (i = 0; i < 8; i++) {
 			if (!addr->addr16[i]) {
 				if (curstart == 255)
=================== patch for pf.c ===================


More information about the freebsd-net mailing list