kern/92880: [libc] [patch] almost rewritten inet_network(3)
function
Andrey Simonenko
simon at comsys.ntu-kpi.kiev.ua
Fri Jan 21 15:00:21 UTC 2011
The following reply was made to PR kern/92880; it has been noted by GNATS.
From: Andrey Simonenko <simon at comsys.ntu-kpi.kiev.ua>
To: bug-followup at 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
/*
More information about the freebsd-net
mailing list