Quake II RTX doxygen  1.0 dev
inet_pton.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004, 2005, 2007, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1996-2001 Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17 
21 /*
22  * WARNING: Don't even consider trying to compile this on a system where
23  * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
24  */
25 
26 static int inet_pton4(const char *src, unsigned char *dst);
27 static int inet_pton6(const char *src, unsigned char *dst);
28 
41 static int os_inet_pton(int af, const char *src, void *dst)
42 {
43  switch (af) {
44  case AF_INET:
45  return (inet_pton4(src, dst));
46  case AF_INET6:
47  return (inet_pton6(src, dst));
48  default:
49  /* errno = EAFNOSUPPORT */;
50  return (-1);
51  }
52  /* NOTREACHED */
53 }
54 
65 static int inet_pton4(const char *src, unsigned char *dst)
66 {
67  static const char digits[] = "0123456789";
68  int saw_digit, octets, ch;
69  unsigned char tmp[NS_INADDRSZ], *tp;
70 
71  saw_digit = 0;
72  octets = 0;
73  *(tp = tmp) = 0;
74  while ((ch = *src++) != '\0') {
75  const char *pch;
76 
77  if ((pch = strchr(digits, ch)) != NULL) {
78  unsigned int new = *tp * 10;
79 
80  new += (unsigned int)(pch - digits);
81  if (new > 255)
82  return (0);
83  *tp = new;
84  if (!saw_digit) {
85  if (++octets > 4)
86  return (0);
87  saw_digit = 1;
88  }
89  } else if (ch == '.' && saw_digit) {
90  if (octets == 4)
91  return (0);
92  /*
93  * "clang --analyse" generates warnings using:
94  * *++tp = 0;
95  */
96  tp++;
97  *tp = 0;
98  saw_digit = 0;
99  } else
100  return (0);
101  }
102  if (octets < 4)
103  return (0);
104  memmove(dst, tmp, NS_INADDRSZ);
105  return (1);
106 }
107 
121 static int inet_pton6(const char *src, unsigned char *dst)
122 {
123  static const char xdigits_l[] = "0123456789abcdef",
124  xdigits_u[] = "0123456789ABCDEF";
125  unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
126  const char *xdigits, *curtok;
127  int ch, seen_xdigits;
128  unsigned int val;
129 
130  memset((tp = tmp), '\0', NS_IN6ADDRSZ);
131  endp = tp + NS_IN6ADDRSZ;
132  colonp = NULL;
133  /* Leading :: requires some special handling. */
134  if (*src == ':')
135  if (*++src != ':')
136  return (0);
137  curtok = src;
138  seen_xdigits = 0;
139  val = 0;
140  while ((ch = *src++) != '\0') {
141  const char *pch;
142 
143  if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
144  pch = strchr((xdigits = xdigits_u), ch);
145  if (pch != NULL) {
146  val <<= 4;
147  val |= (pch - xdigits);
148  if (++seen_xdigits > 4)
149  return (0);
150  continue;
151  }
152  if (ch == ':') {
153  curtok = src;
154  if (!seen_xdigits) {
155  if (colonp)
156  return (0);
157  colonp = tp;
158  continue;
159  }
160  if (tp + NS_INT16SZ > endp)
161  return (0);
162  *tp++ = (unsigned char)(val >> 8) & 0xff;
163  *tp++ = (unsigned char)val & 0xff;
164  seen_xdigits = 0;
165  val = 0;
166  continue;
167  }
168  if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
169  inet_pton4(curtok, tp) > 0) {
170  tp += NS_INADDRSZ;
171  seen_xdigits = 0;
172  break; /* '\0' was seen by inet_pton4(). */
173  }
174  return (0);
175  }
176  if (seen_xdigits) {
177  if (tp + NS_INT16SZ > endp)
178  return (0);
179  *tp++ = (unsigned char)(val >> 8) & 0xff;
180  *tp++ = (unsigned char)val & 0xff;
181  }
182  if (colonp != NULL) {
183  /*
184  * Since some memmove()'s erroneously fail to handle
185  * overlapping regions, we'll do the shift by hand.
186  */
187  const int n = (int)(tp - colonp);
188  int i;
189 
190  for (i = 1; i <= n; i++) {
191  endp[-i] = colonp[n - i];
192  colonp[n - i] = 0;
193  }
194  tp = endp;
195  }
196  if (tp != endp)
197  return (0);
198  memmove(dst, tmp, NS_IN6ADDRSZ);
199  return (1);
200 }
inet_pton4
static int inet_pton4(const char *src, unsigned char *dst)
Definition: inet_pton.h:65
inet_pton6
static int inet_pton6(const char *src, unsigned char *dst)
Definition: inet_pton.h:121
NS_IN6ADDRSZ
#define NS_IN6ADDRSZ
Definition: net.c:208
os_inet_pton
static int os_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.h:41
NS_INADDRSZ
#define NS_INADDRSZ
Definition: net.c:207
NS_INT16SZ
#define NS_INT16SZ
Definition: net.c:206
int
CONST PIXELFORMATDESCRIPTOR int
Definition: wgl.c:26