Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Jan 2011 15:00:20 GMT
From:      Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To:        freebsd-net@FreeBSD.org
Subject:   Re: kern/92880: [libc] [patch] almost rewritten inet_network(3) function
Message-ID:  <201101211500.p0LF0KOq080406@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/92880; it has been noted by GNATS.

From: Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/92880: [libc] [patch] almost rewritten inet_network(3)
 function
Date: Fri, 21 Jan 2011 16:12:49 +0200

 My previous modification had one typo and did not work correctly
 for IPv4 addresses given in `.' donation in hexadecimal form.
 
 Here another one update:
 
 1. Test program that shows difference between implementation of
    inet_network(3) from 9-CURRENT and my implementation.
 
 2. Diff for the src/lib/libc/inet/inet_network.c file.
 
 Look on output from the test program ("<---" shows different values):
 
 STRING			INET_NETWORK	INET_NETWORK_NEW
 "0x12"			0x00000012	0x00000012
 "127.1"			0x00007f01	0x00007f01
 "127.1.2.3"		0x7f010203	0x7f010203
 "0x123456"		INADDR_NONE	INADDR_NONE
 "0x12.0x34"		0x00001234	0x00001234
 "0x12.0x345"		INADDR_NONE	INADDR_NONE
 "1.2.3.4.5"		INADDR_NONE	INADDR_NONE
 "1..3.4"		INADDR_NONE	INADDR_NONE
 "."			INADDR_NONE	INADDR_NONE
 "1."			INADDR_NONE	INADDR_NONE
 ".1"			INADDR_NONE	INADDR_NONE
 "0x"			0x00000000	INADDR_NONE	<---
 "0"			0x00000000	0x00000000
 "01.02.07.077"		0x0102073f	0x0102073f
 "0x1.23.045.0"		0x01172500	0x01172500
 ""			INADDR_NONE	INADDR_NONE
 " "			INADDR_NONE	INADDR_NONE
 " f"			INADDR_NONE	INADDR_NONE
 "bar"			INADDR_NONE	INADDR_NONE
 "1.2bar"		INADDR_NONE	INADDR_NONE
 "1."			INADDR_NONE	INADDR_NONE
 "=CA=C3=D5=CB=C5=CE"		INADDR_NONE	INADDR_NONE
 "255.255.255.255"	INADDR_NONE	INADDR_NONE
 "x"			INADDR_NONE	INADDR_NONE
 "0X12"			0x00000012	0x00000012
 "078"			INADDR_NONE	INADDR_NONE
 "1 bar"			0x00000001	INADDR_NONE	<---
 "127.0xabcd"		INADDR_NONE	INADDR_NONE
 "128"			0x00000080	0x00000080
 "0.1.2"			0x00000102	0x00000102
 "0xff.010.23.0xa0"	0xff0817a0	0xff0817a0
 "x10"			0x00000010	INADDR_NONE	<---
 "X20"			0x00000020	INADDR_NONE	<---
 "x10.x20"		0x00001020	INADDR_NONE	<---
 "4294967297"		0x00000001	INADDR_NONE	<---
 "0x10000000f"		0x0000000f	INADDR_NONE	<---
 "040000000003"		0x00000003	INADDR_NONE	<---
 
 Test program:
 
 diff -ruNp inet_network_test.orig/Makefile inet_network_test/Makefile
 --- inet_network_test.orig/Makefile	1970-01-01 03:00:00.000000000 +0300
 +++ inet_network_test/Makefile	2011-01-21 12:48:48.000000000 +0200
 @@ -0,0 +1,9 @@
 +PROG=3Dinet_network
 +
 +NO_MAN=3Dtrue
 +
 +WARNS=3D6
 +
 +DEBUG_FLAGS=3D-g
 +
 +.include <bsd.prog.mk>
 diff -ruNp inet_network_test.orig/inet_network.c inet_network_test/inet_n=
 etwork.c
 --- inet_network_test.orig/inet_network.c	1970-01-01 03:00:00.000000000 +=
 0300
 +++ inet_network_test/inet_network.c	2011-01-21 15:29:47.000000000 +0200
 @@ -0,0 +1,105 @@
 +#include <sys/types.h>
 +#include <sys/socket.h>
 +
 +#include <netinet/in.h>
 +#include <arpa/inet.h>
 +
 +#include <ctype.h>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <string.h>
 +
 +static in_addr_t
 +inet_network_new(const char *s)
 +{
 +	u_int base, dots;
 +	in_addr_t res, val;
 +	u_char c;
 +	char got_data;
 +
 +	res =3D 0;
 +	dots =3D 0;
 +	for (;;) {
 +		val =3D 0;
 +		got_data =3D 0;
 +		if (*s =3D=3D '0') {
 +			s++;
 +			if (*s =3D=3D 'x' || *s =3D=3D 'X') {
 +				s++;
 +				base =3D 16;
 +			} else {
 +				base =3D 8;
 +				got_data =3D 1;
 +			}
 +		} else
 +			base =3D 10;
 +		while ((c =3D *s) !=3D '\0') {
 +			if (isdigit(c)) {
 +				if (base =3D=3D 8 && c > '7')
 +					return (INADDR_NONE);
 +				val =3D val * base + c - '0';
 +			} else if (base =3D=3D 16 && isxdigit(c))
 +				val =3D (val << 4) + c + 10 -
 +				    (islower(c) ? 'a' : 'A');
 +			else
 +				break;
 +			if (val > 0xff)
 +				return (INADDR_NONE);
 +			s++;
 +			got_data =3D 1;
 +		}
 +		if (!got_data)
 +			return (INADDR_NONE);
 +		if (dots !=3D 0)
 +			res <<=3D 8;
 +		res |=3D val;
 +		if (c !=3D '.')
 +			break;
 +		if (++dots =3D=3D 4)
 +			return (INADDR_NONE);
 +		s++;
 +	}
 +	return (c =3D=3D '\0' ? res : INADDR_NONE);
 +}
 +
 +int
 +main(void)
 +{
 +	const char *const addr_str_tbl[] =3D {
 +	    "0x12", "127.1", "127.1.2.3", "0x123456", "0x12.0x34",
 +	    "0x12.0x345", "1.2.3.4.5", "1..3.4", ".", "1.", ".1", "0x",
 +	    "0", "01.02.07.077", "0x1.23.045.0", "", " ", " f", "bar",
 +	    "1.2bar", "1.", "=CA=C3=D5=CB=C5=CE", "255.255.255.255", "x", "0X12=
 ", "078",
 +	    "1 bar", "127.0xabcd", "128", "0.1.2", "0xff.010.23.0xa0",
 +	    "x10", "X20", "x10.x20", "4294967297", "0x10000000f",
 +	    "040000000003", NULL };
 +	const char *const *addr_str;
 +	size_t len;
 +	in_addr_t addr1, addr2;
 +
 +	printf("STRING\t\t\tINET_NETWORK\tINET_NETWORK_NEW\n");
 +	for (addr_str =3D addr_str_tbl; *addr_str !=3D NULL; ++addr_str) {
 +		printf("\"%s\"", *addr_str);
 +		len =3D strlen(*addr_str) + 2;
 +		if (len < 8)
 +			printf("\t\t\t");
 +		else if (len < 16)
 +			printf("\t\t");
 +		else
 +			printf("\t");
 +		addr1 =3D inet_network(*addr_str);
 +		if (addr1 =3D=3D INADDR_NONE)
 +			printf("INADDR_NONE\t");
 +		else
 +			printf("0x%08x\t", addr1);
 +		addr2 =3D inet_network_new(*addr_str);
 +		if (addr2 =3D=3D INADDR_NONE)
 +			printf("INADDR_NONE");
 +		else
 +			printf("0x%08x", addr2);
 +		if (addr1 !=3D addr2)
 +			printf("\t<---");
 +		printf("\n");
 +	}
 +	return (0);
 +}
 
 Diff for src/lib/libc/inet/inet_network.c:
 
 --- inet_network.c.orig	2008-01-15 00:55:20.000000000 +0200
 +++ inet_network.c	2011-01-21 15:58:17.000000000 +0200
 @@ -48,57 +48,56 @@ __FBSDID("$FreeBSD: src/lib/libc/inet/in
   * network numbers.
   */
  in_addr_t
 -inet_network(cp)
 -	const char *cp;
 +inet_network(const char *s)
  {
 -	in_addr_t val, base, n;
 -	char c;
 -	in_addr_t parts[4], *pp =3D parts;
 -	int i, digit;
 +	u_int base, dots;
 +	in_addr_t res, val;
 +	u_char c;
 +	char got_data;
 =20
 -again:
 -	val =3D 0; base =3D 10; digit =3D 0;
 -	if (*cp =3D=3D '0')
 -		digit =3D 1, base =3D 8, cp++;
 -	if (*cp =3D=3D 'x' || *cp =3D=3D 'X')
 -		base =3D 16, cp++;
 -	while ((c =3D *cp) !=3D 0) {
 -		if (isdigit((unsigned char)c)) {
 -			if (base =3D=3D 8U && (c =3D=3D '8' || c =3D=3D '9'))
 +	res =3D 0;
 +	dots =3D 0;
 +	for (;;) {
 +		val =3D 0;
 +		got_data =3D 0;
 +		if (*s =3D=3D '0') {
 +			s++;
 +			if (*s =3D=3D 'x' || *s =3D=3D 'X') {
 +				s++;
 +				base =3D 16;
 +			} else {
 +				base =3D 8;
 +				got_data =3D 1;
 +			}
 +		} else
 +			base =3D 10;
 +		while ((c =3D *s) !=3D '\0') {
 +			if (isdigit(c)) {
 +				if (base =3D=3D 8 && c > '7')
 +					return (INADDR_NONE);
 +				val =3D val * base + c - '0';
 +			} else if (base =3D=3D 16 && isxdigit(c))
 +				val =3D (val << 4) + c + 10 -
 +				    (islower(c) ? 'a' : 'A');
 +			else
 +				break;
 +			if (val > 0xff)
  				return (INADDR_NONE);
 -			val =3D (val * base) + (c - '0');
 -			cp++;
 -			digit =3D 1;
 -			continue;
 +			s++;
 +			got_data =3D 1;
  		}
 -		if (base =3D=3D 16U && isxdigit((unsigned char)c)) {
 -			val =3D (val << 4) +
 -			      (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
 -			cp++;
 -			digit =3D 1;
 -			continue;
 -		}
 -		break;
 -	}
 -	if (!digit)
 -		return (INADDR_NONE);
 -	if (pp >=3D parts + 4 || val > 0xffU)
 -		return (INADDR_NONE);
 -	if (*cp =3D=3D '.') {
 -		*pp++ =3D val, cp++;
 -		goto again;
 -	}
 -	if (*cp && !isspace(*cp&0xff))
 -		return (INADDR_NONE);
 -	*pp++ =3D val;
 -	n =3D pp - parts;
 -	if (n > 4U)
 -		return (INADDR_NONE);
 -	for (val =3D 0, i =3D 0; i < n; i++) {
 -		val <<=3D 8;
 -		val |=3D parts[i] & 0xff;
 +		if (!got_data)
 +			return (INADDR_NONE);
 +		if (dots !=3D 0)
 +			res <<=3D 8;
 +		res |=3D val;
 +		if (c !=3D '.')
 +			break;
 +		if (++dots =3D=3D 4)
 +			return (INADDR_NONE);
 +		s++;
  	}
 -	return (val);
 +	return (c =3D=3D '\0' ? res : INADDR_NONE);
  }
 =20
  /*



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