Quake II RTX doxygen  1.0 dev
inet_ntop.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 1996-2001, 2003 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 const char *inet_ntop4(const unsigned char *src, char *dst,
27  size_t size);
28 static const char *inet_ntop6(const unsigned char *src, char *dst,
29  size_t size);
30 
39 static const char *
40 os_inet_ntop(int af, const void *src, char *dst, size_t size)
41 {
42  switch (af) {
43  case AF_INET:
44  return (inet_ntop4(src, dst, size));
45  case AF_INET6:
46  return (inet_ntop6(src, dst, size));
47  default:
48  /* errno = EAFNOSUPPORT; */
49  return (NULL);
50  }
51  /* NOTREACHED */
52 }
53 
65 static const char *
66 inet_ntop4(const unsigned char *src, char *dst, size_t size)
67 {
68  static const char fmt[] = "%u.%u.%u.%u";
69  char tmp[sizeof("255.255.255.255")];
70  size_t len;
71 
72  len = Q_snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
73  if (len >= size) {
74  /* errno = ENOSPC; */
75  return (NULL);
76  }
77  strcpy(dst, tmp);
78 
79  return (dst);
80 }
81 
88 static const char *
89 inet_ntop6(const unsigned char *src, char *dst, size_t size)
90 {
98  char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
99  struct {
100  int base, len;
101  } best, cur;
102  unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
103  int i;
104 
105  /*
106  * Preprocess:
107  * Copy the input (bytewise) array into a wordwise array.
108  * Find the longest run of 0x00's in src[] for :: shorthanding.
109  */
110  memset(words, '\0', sizeof(words));
111  for (i = 0; i < NS_IN6ADDRSZ; i++)
112  words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
113  best.base = -1;
114  best.len = 0;
115  cur.base = -1;
116  cur.len = 0;
117  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
118  if (words[i] == 0) {
119  if (cur.base == -1)
120  cur.base = i, cur.len = 1;
121  else
122  cur.len++;
123  } else {
124  if (cur.base != -1) {
125  if (best.base == -1 || cur.len > best.len)
126  best = cur;
127  cur.base = -1;
128  }
129  }
130  }
131  if (cur.base != -1) {
132  if (best.base == -1 || cur.len > best.len)
133  best = cur;
134  }
135  if (best.base != -1 && best.len < 2)
136  best.base = -1;
137 
138  /*
139  * Format the result.
140  */
141  tp = tmp;
142  for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
143  /* Are we inside the best run of 0x00's? */
144  if (best.base != -1 && i >= best.base &&
145  i < (best.base + best.len)) {
146  if (i == best.base)
147  *tp++ = ':';
148  continue;
149  }
150  /* Are we following an initial run of 0x00s or any real hex? */
151  if (i != 0)
152  *tp++ = ':';
153  /* Is this address an encapsulated IPv4? */
154  if (i == 6 && best.base == 0 &&
155  (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
156  if (!inet_ntop4(src + 12, tp,
157  sizeof(tmp) - (tp - tmp)))
158  return (NULL);
159  tp += strlen(tp);
160  break;
161  }
162  tp += sprintf(tp, "%x", words[i]); /* XXX */
163  }
164  /* Was it a trailing run of 0x00's? */
165  if (best.base != -1 && (best.base + best.len) ==
167  *tp++ = ':';
168  *tp++ = '\0';
169 
170  /*
171  * Check for overflow, copy, and we're done.
172  */
173  if ((size_t)(tp - tmp) > size) {
174  /* errno = ENOSPC; */
175  return (NULL);
176  }
177  strcpy(dst, tmp);
178  return (dst);
179 }
Q_snprintf
size_t Q_snprintf(char *dest, size_t size, const char *fmt,...)
Definition: shared.c:846
inet_ntop4
static const char * inet_ntop4(const unsigned char *src, char *dst, size_t size)
Definition: inet_ntop.h:66
inet_ntop6
static const char * inet_ntop6(const unsigned char *src, char *dst, size_t size)
Definition: inet_ntop.h:89
NS_IN6ADDRSZ
#define NS_IN6ADDRSZ
Definition: net.c:208
os_inet_ntop
static const char * os_inet_ntop(int af, const void *src, char *dst, size_t size)
Definition: inet_ntop.h:40
NS_INT16SZ
#define NS_INT16SZ
Definition: net.c:206