bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new module: inet_pton


From: Simon Josefsson
Subject: new module: inet_pton
Date: Sat, 17 Jun 2006 21:01:30 +0200
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.0.50 (gnu/linux)

Instead of a "inet" module with both inet_ntop and inet_pton, here is
one new module for inet_pton only, to smooth backwards compatibility
with people using the current "inet_ntop" module.

The code is from glibc, with fixes similar to those in the current
inet_ntop module.  I'm not sure it is a good idea to touch inet_pton.c
too much (read: to clean it up), as that would make syncing it harder.

Ok to install?

Hmm..  for those files we don't sync exactly, would it make sense to
store a glibc->gnulib patch in the gnulib repository, and have a tool
import the original file from glibc CVS, and apply the patch?  Then
we'd be sure to catch any upstream updates.  It would also be more
clear exactly which modifications we had to make.  No, I don't
volunteer to write this tool right now. :)

Index: lib/inet_pton.c
===================================================================
RCS file: lib/inet_pton.c
diff -N lib/inet_pton.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/inet_pton.c     17 Jun 2006 19:00:55 -0000
@@ -0,0 +1,259 @@
+/* inet_pton.c -- convert IPv4 and IPv6 addresses from text to binary form
+   Copyright (c) 2006  Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+/*
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Specification.  */
+#include "inet_pton.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+
+#ifndef EAFNOSUPPORT
+# define EAFNOSUPPORT EINVAL
+#endif
+
+#define NS_INADDRSZ 4
+#define NS_IN6ADDRSZ 16
+#define NS_INT16SZ 2
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 (const char *src, unsigned char *dst);
+#if HAVE_IPV6
+static int inet_pton6 (const char *src, unsigned char *dst);
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ *     convert from presentation format (which usually means ASCII printable)
+ *     to network format (which is usually some kind of binary format).
+ * return:
+ *     1 if the address was valid for the specified address family
+ *     0 if the address wasn't valid (`dst' is untouched in this case)
+ *     -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ *     Paul Vixie, 1996.
+ */
+int
+inet_pton (int af, const char *restrict src, void *restrict dst)
+{
+  switch (af)
+    {
+    case AF_INET:
+      return (inet_pton4 (src, dst));
+
+#if HAVE_IPV4
+    case AF_INET6:
+      return (inet_pton6 (src, dst));
+#endif
+
+    default:
+      errno = EAFNOSUPPORT;
+      return (-1);
+    }
+  /* NOTREACHED */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *     like inet_aton() but without all the hexadecimal, octal (with the
+ *     exception of 0) and shorthand.
+ * return:
+ *     1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *     does not touch `dst' unless it's returning 1.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton4 (const char *restrict src, unsigned char *restrict dst)
+{
+  int saw_digit, octets, ch;
+  unsigned char tmp[NS_INADDRSZ], *tp;
+
+  saw_digit = 0;
+  octets = 0;
+  *(tp = tmp) = 0;
+  while ((ch = *src++) != '\0')
+    {
+
+      if (ch >= '0' && ch <= '9')
+       {
+         unsigned new = *tp * 10 + (ch - '0');
+
+         if (saw_digit && *tp == 0)
+           return (0);
+         if (new > 255)
+           return (0);
+         *tp = new;
+         if (!saw_digit)
+           {
+             if (++octets > 4)
+               return (0);
+             saw_digit = 1;
+           }
+       }
+      else if (ch == '.' && saw_digit)
+       {
+         if (octets == 4)
+           return (0);
+         *++tp = 0;
+         saw_digit = 0;
+       }
+      else
+       return (0);
+    }
+  if (octets < 4)
+    return (0);
+  memcpy (dst, tmp, NS_INADDRSZ);
+  return (1);
+}
+
+#if HAVE_IPV6
+
+/* int
+ * inet_pton6(src, dst)
+ *     convert presentation level address to network order binary form.
+ * return:
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *     (1) does not touch `dst' unless it's returning 1.
+ *     (2) :: in a full address is silently ignored.
+ * credit:
+ *     inspired by Mark Andrews.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton6 (const char *restrict src, unsigned char *restrict dst)
+{
+  static const char xdigits[] = "0123456789abcdef";
+  unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+  const char *curtok;
+  int ch, saw_xdigit;
+  unsigned val;
+
+  tp = memset (tmp, '\0', NS_IN6ADDRSZ);
+  endp = tp + NS_IN6ADDRSZ;
+  colonp = NULL;
+  /* Leading :: requires some special handling. */
+  if (*src == ':')
+    if (*++src != ':')
+      return (0);
+  curtok = src;
+  saw_xdigit = 0;
+  val = 0;
+  while ((ch = tolower (*src++)) != '\0')
+    {
+      const char *pch;
+
+      pch = strchr (xdigits, ch);
+      if (pch != NULL)
+       {
+         val <<= 4;
+         val |= (pch - xdigits);
+         if (val > 0xffff)
+           return (0);
+         saw_xdigit = 1;
+         continue;
+       }
+      if (ch == ':')
+       {
+         curtok = src;
+         if (!saw_xdigit)
+           {
+             if (colonp)
+               return (0);
+             colonp = tp;
+             continue;
+           }
+         else if (*src == '\0')
+           {
+             return (0);
+           }
+         if (tp + NS_INT16SZ > endp)
+           return (0);
+         *tp++ = (u_char) (val >> 8) & 0xff;
+         *tp++ = (u_char) val & 0xff;
+         saw_xdigit = 0;
+         val = 0;
+         continue;
+       }
+      if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+         inet_pton4 (curtok, tp) > 0)
+       {
+         tp += NS_INADDRSZ;
+         saw_xdigit = 0;
+         break;                /* '\0' was seen by inet_pton4(). */
+       }
+      return (0);
+    }
+  if (saw_xdigit)
+    {
+      if (tp + NS_INT16SZ > endp)
+       return (0);
+      *tp++ = (u_char) (val >> 8) & 0xff;
+      *tp++ = (u_char) val & 0xff;
+    }
+  if (colonp != NULL)
+    {
+      /*
+       * Since some memmove()'s erroneously fail to handle
+       * overlapping regions, we'll do the shift by hand.
+       */
+      const int n = tp - colonp;
+      int i;
+
+      if (tp == endp)
+       return (0);
+      for (i = 1; i <= n; i++)
+       {
+         endp[-i] = colonp[n - i];
+         colonp[n - i] = 0;
+       }
+      tp = endp;
+    }
+  if (tp != endp)
+    return (0);
+  memcpy (dst, tmp, NS_IN6ADDRSZ);
+  return (1);
+}
+#endif
Index: lib/inet_pton.h
===================================================================
RCS file: lib/inet_pton.h
diff -N lib/inet_pton.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/inet_pton.h     17 Jun 2006 19:00:55 -0000
@@ -0,0 +1,26 @@
+/* Convert internet address from text to binary format.
+   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_ARPA_INET_H
+# include <arpa/inet.h>
+#endif
+
+#if !HAVE_DECL_INET_PTON
+extern int inet_pton (int af, const char *restrict src, void *restrict dst);
+#endif
Index: m4/inet_pton.m4
===================================================================
RCS file: m4/inet_pton.m4
diff -N m4/inet_pton.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/inet_pton.m4     17 Jun 2006 19:00:55 -0000
@@ -0,0 +1,18 @@
+# inet_pton.m4 serial 1
+dnl Copyright (C) 2006 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_INET_PTON],
+[
+  AC_REPLACE_FUNCS(inet_pton)
+  gl_PREREQ_INET_PTON
+])
+
+# Prerequisites of lib/inet_pton.h and lib/inet_pton.c.
+AC_DEFUN([gl_PREREQ_INET_PTON], [
+  AC_CHECK_HEADERS_ONCE(arpa/inet.h)
+  AC_CHECK_DECLS([inet_pton],,,[#include <arpa/inet.h>])
+  AC_REQUIRE([gl_SOCKET_FAMILIES])
+])
Index: modules/inet_pton
===================================================================
RCS file: modules/inet_pton
diff -N modules/inet_pton
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ modules/inet_pton   17 Jun 2006 19:00:55 -0000
@@ -0,0 +1,28 @@
+Description:
+Convert internet address from presentation to internal, binary, format.
+
+Files:
+lib/inet_pton.h
+lib/inet_pton.c
+m4/inet_pton.m4
+m4/sockpfaf.m4
+
+Depends-on:
+restrict
+socklen
+sys_socket
+
+configure.ac:
+gl_INET_PTON
+
+Makefile.am:
+lib_SOURCES += inet_pton.h
+
+License:
+LGPL
+
+Include:
+"inet_pton.h"
+
+Maintainer:
+Simon Josefsson, glibc




reply via email to

[Prev in Thread] Current Thread [Next in Thread]