The following reply was made to PR kern/92880; it has been noted by GNATS. From: Andrey Simonenko <si...@comsys.ntu-kpi.kiev.ua> To: bug-follo...@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 /* _______________________________________________ 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"