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"

Reply via email to