ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/hopm/trunk/src/libopm/src/inet.c
Revision: 5134
Committed: Thu Dec 25 18:50:02 2014 UTC (9 years, 3 months ago) by michael
Content type: text/x-csrc
File size: 15046 byte(s)
Log Message:
- propset svn:keywords "Id"

File Contents

# Content
1 /*
2 Copyright (C) 2002 by the past and present ircd coders, and others.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to
16
17 The Free Software Foundation, Inc.
18 59 Temple Place - Suite 330
19 Boston, MA 02111-1307, USA.
20
21 */
22
23 /*
24 * This code is borrowed from ircd-hybrid version 7
25 * -TimeMr14C
26 */
27
28 #include "setup.h"
29
30 #include <errno.h>
31 #include <stdio.h>
32 #include <assert.h>
33 #if STDC_HEADERS
34 # include <string.h>
35 # include <stdlib.h>
36 #endif
37 #ifdef HAVE_STRINGS_H
38 # include <strings.h>
39 #endif
40 #include <sys/types.h>
41 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <netdb.h>
44
45 #include "inet.h"
46 #include "opm.h"
47
48 #ifndef INADDRSZ
49 #define INADDRSZ 4
50 #endif
51
52 #ifdef IPV6
53 #ifndef IN6ADDRSZ
54 #define IN6ADDRSZ 16
55 #endif
56 #endif
57
58
59 #ifndef INT16SZ
60 #define INT16SZ 2
61 #endif
62
63 #ifdef IPV6
64 #define HOSTIPLEN 53
65 #else
66 #define HOSTIPLEN 15
67 #endif
68
69
70 extern const unsigned char ToLowerTab[];
71 #define ToLower(c) (ToLowerTab[(unsigned char)(c)])
72
73 /*
74 * From: Thomas Helvey <tomh@inxpress.net>
75 */
76 #if 0
77 static const char *IpQuadTab[] = {
78 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
79 "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
80 "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
81 "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
82 "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
83 "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
84 "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
85 "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
86 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
87 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
88 "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
89 "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
90 "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
91 "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
92 "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
93 "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
94 "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
95 "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
96 "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
97 "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
98 "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
99 "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
100 "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
101 "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
102 "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
103 "250", "251", "252", "253", "254", "255"
104 };
105 #endif
106
107 /*
108 * inetntoa - in_addr to string
109 * changed name to remove collision possibility and
110 * so behaviour is guaranteed to take a pointer arg.
111 * -avalon 23/11/92
112 * inet_ntoa -- returned the dotted notation of a given
113 * internet number
114 * argv 11/90).
115 * inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
116 *
117 * XXX - Again not used anywhere?
118 * -grifferz
119 */
120
121 #if 0
122 static char *inetntoa(char *in)
123 {
124 static char buf[16];
125 register char *bufptr = buf;
126 register const unsigned char *a = (const unsigned char *) in;
127 register const char *n;
128
129 n = IpQuadTab[*a++];
130 while (*n)
131 *bufptr++ = *n++;
132 *bufptr++ = '.';
133 n = IpQuadTab[*a++];
134 while (*n)
135 *bufptr++ = *n++;
136 *bufptr++ = '.';
137 n = IpQuadTab[*a++];
138 while (*n)
139 *bufptr++ = *n++;
140 *bufptr++ = '.';
141 n = IpQuadTab[*a];
142 while (*n)
143 *bufptr++ = *n++;
144 *bufptr = '\0';
145 return buf;
146 }
147 #endif
148
149 /*
150 * Copyright (c) 1996-1999 by Internet Software Consortium.
151 *
152 * Permission to use, copy, modify, and distribute this software for any
153 * purpose with or without fee is hereby granted, provided that the above
154 * copyright notice and this permission notice appear in all copies.
155 *
156 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
157 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
158 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
159 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
160 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
161 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
162 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
163 * SOFTWARE.
164 */
165
166 /*
167 * WARNING: Don't even consider trying to compile this on a system where
168 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
169 */
170
171 /*
172 * XXX - this does not seem to be used anywhere currently.
173 * -grifferz
174 */
175 #if 0
176 static const char *inet_ntop4(const u_char *src, char *dst, unsigned int size);
177 #endif
178
179 #ifdef IPV6
180 static const char *inet_ntop6(const u_char *src, char *dst, unsigned int size);
181 #endif
182
183 /* const char *
184 * inet_ntop4(src, dst, size)
185 * format an IPv4 address
186 * return:
187 * `dst' (as a const)
188 * notes:
189 * (1) uses no statics
190 * (2) takes a u_char* not an in_addr as input
191 * author:
192 * Paul Vixie, 1996.
193 *
194 * XXX - this does not seem to be used anywhere currently.
195 * -grifferz
196 */
197 #if 0
198 static const char *inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
199 {
200 if (size < 15)
201 return NULL;
202 return strcpy(dst, inetntoa((char *) src));
203 }
204 #endif
205
206 /* const char *
207 * inet_ntop6(src, dst, size)
208 * convert IPv6 binary address into presentation (printable) format
209 * author:
210 * Paul Vixie, 1996.
211 */
212 #ifdef IPV6
213 static const char *inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
214 {
215 /*
216 * Note that int32_t and int16_t need only be "at least" large enough
217 * to contain a value of the specified size. On some systems, like
218 * Crays, there is no such thing as an integer variable with 16 bits.
219 * Keep this in mind if you think this function should have been coded
220 * to use pointer overlays. All the world's not a VAX.
221 */
222 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
223 struct {
224 int base, len;
225 } best, cur;
226 u_int words[IN6ADDRSZ / INT16SZ];
227 int i;
228
229 /*
230 * Preprocess:
231 * Copy the input (bytewise) array into a wordwise array.
232 * Find the longest run of 0x00's in src[] for :: shorthanding.
233 */
234 memset(words, '\0', sizeof words);
235 for (i = 0; i < IN6ADDRSZ; i += 2)
236 words[i / 2] = (src[i] << 8) | src[i + 1];
237 best.base = -1;
238 cur.base = -1;
239 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
240 if (words[i] == 0) {
241 if (cur.base == -1)
242 cur.base = i, cur.len = 1;
243 else
244 cur.len++;
245 } else {
246 if (cur.base != -1) {
247 if (best.base == -1 || cur.len > best.len)
248 best = cur;
249 cur.base = -1;
250 }
251 }
252 }
253 if (cur.base != -1) {
254 if (best.base == -1 || cur.len > best.len)
255 best = cur;
256 }
257 if (best.base != -1 && best.len < 2)
258 best.base = -1;
259
260 /*
261 * Format the result.
262 */
263 tp = tmp;
264 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
265 /* Are we inside the best run of 0x00's? */
266 if (best.base != -1 && i >= best.base && i < (best.base + best.len)) {
267 if (i == best.base)
268 *tp++ = ':';
269 continue;
270 }
271 /* Are we following an initial run of 0x00s or any real hex? */
272 if (i != 0)
273 *tp++ = ':';
274 /* Is this address an encapsulated IPv4? */
275 if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
276 if (!inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp)))
277 return (NULL);
278 tp += strlen(tp);
279 break;
280 }
281 tp += sprintf(tp, "%x", words[i]);
282 }
283 /* Was it a trailing run of 0x00's? */
284 if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
285 *tp++ = ':';
286
287 *tp++ = '\0';
288
289 /*
290 * Check for overflow, copy, and we're done.
291 */
292
293 if ((tp - tmp) > size) {
294 return (NULL);
295 }
296 return strcpy(dst, tmp);
297 }
298 #endif
299
300 #if 0
301
302 /*
303 * This code doesn't seem to be used anywhere currently?
304 * -grifferz
305 */
306
307 /* char *
308 * inetntop(af, src, dst, size)
309 * convert a network format address to presentation format.
310 * return:
311 * pointer to presentation format address (`dst'), or NULL (see errno).
312 * author:
313 * Paul Vixie, 1996.
314 */
315 const char *inetntop(int af, const void *src, char *dst, unsigned int size)
316 {
317 switch (af) {
318 case AF_INET:
319 return (inet_ntop4(src, dst, size));
320 #ifdef IPV6
321 case AF_INET6:
322 if (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *) src) ||
323 IN6_IS_ADDR_V4COMPAT((const struct in6_addr *) src))
324 return (inet_ntop4
325 ((unsigned char *) &((struct in6_addr *) src)->s6_addr[12], dst, size));
326 else
327 return (inet_ntop6(src, dst, size));
328
329 #endif
330 default:
331 return (NULL);
332 }
333 /* NOTREACHED */
334 }
335 #endif
336
337 /*
338 * WARNING: Don't even consider trying to compile this on a system where
339 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
340 */
341
342 /* int
343 * inet_pton(af, src, dst)
344 * convert from presentation format (which usually means ASCII printable)
345 * to network format (which is usually some kind of binary format).
346 * return:
347 * 1 if the address was valid for the specified address family
348 * 0 if the address wasn't valid (`dst' is untouched in this case)
349 * -1 if some other error occurred (`dst' is untouched in this case, too)
350 * author:
351 * Paul Vixie, 1996.
352 */
353
354 /* int
355 * inet_pton4(src, dst)
356 * like inet_aton() but without all the hexadecimal and shorthand.
357 * return:
358 * 1 if `src' is a valid dotted quad, else 0.
359 * notice:
360 * does not touch `dst' unless it's returning 1.
361 * author:
362 * Paul Vixie, 1996.
363 */
364
365 #ifndef HAVE_INET_PTON
366
367 static int inet_pton4(src, dst)
368 const char *src;
369 unsigned char *dst;
370 {
371 int saw_digit, octets, ch;
372 unsigned char tmp[INADDRSZ], *tp;
373
374 saw_digit = 0;
375 octets = 0;
376 *(tp = tmp) = 0;
377 while ((ch = *src++) != '\0') {
378
379 if (ch >= '0' && ch <= '9') {
380 unsigned int new = *tp * 10 + (ch - '0');
381
382 if (new > 255)
383 return (0);
384 *tp = new;
385 if (!saw_digit) {
386 if (++octets > 4)
387 return (0);
388 saw_digit = 1;
389 }
390 } else if (ch == '.' && saw_digit) {
391 if (octets == 4)
392 return (0);
393 *++tp = 0;
394 saw_digit = 0;
395 } else
396 return (0);
397 }
398 if (octets < 4)
399 return (0);
400 memcpy(dst, tmp, INADDRSZ);
401 return (1);
402 }
403
404 #ifdef IPV6
405 /* int
406 * inet_pton6(src, dst)
407 * convert presentation level address to network order binary form.
408 * return:
409 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
410 * notice:
411 * (1) does not touch `dst' unless it's returning 1.
412 * (2) :: in a full address is silently ignored.
413 * credit:
414 * inspired by Mark Andrews.
415 * author:
416 * Paul Vixie, 1996.
417 */
418
419 static int inet_pton6(src, dst)
420 const char *src;
421 unsigned char *dst;
422 {
423 static const char xdigits[] = "0123456789abcdef";
424 unsigned char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
425 const char *curtok;
426 int ch, saw_xdigit;
427 unsigned int val;
428
429 tp = memset(tmp, '\0', IN6ADDRSZ);
430 endp = tp + IN6ADDRSZ;
431 colonp = NULL;
432 /* Leading :: requires some special handling. */
433 if (*src == ':')
434 if (*++src != ':')
435 return (0);
436 curtok = src;
437 saw_xdigit = 0;
438 val = 0;
439 while ((ch = ToLower(*src++)) != '\0') {
440 const char *pch;
441
442 pch = strchr(xdigits, ch);
443 if (pch != NULL) {
444 val <<= 4;
445 val |= (pch - xdigits);
446 if (val > 0xffff)
447 return (0);
448 saw_xdigit = 1;
449 continue;
450 }
451 if (ch == ':') {
452 curtok = src;
453 if (!saw_xdigit) {
454 if (colonp)
455 return (0);
456 colonp = tp;
457 continue;
458 } else if (*src == '\0') {
459 return (0);
460 }
461 if (tp + INT16SZ > endp)
462 return (0);
463 *tp++ = (unsigned char) (val >> 8) & 0xff;
464 *tp++ = (unsigned char) val & 0xff;
465 saw_xdigit = 0;
466 val = 0;
467 continue;
468 }
469
470 if (*src != '\0' && ch == '.') {
471 if (((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0) {
472 tp += INADDRSZ;
473 saw_xdigit = 0;
474 break; /* '\0' was seen by inet_pton4(). */
475 }
476 } else
477 continue;
478 return (0);
479 }
480 if (saw_xdigit) {
481 if (tp + INT16SZ > endp)
482 return (0);
483 *tp++ = (unsigned char) (val >> 8) & 0xff;
484 *tp++ = (unsigned char) val & 0xff;
485 }
486 if (colonp != NULL) {
487 /*
488 * Since some memmove()'s erroneously fail to handle
489 * overlapping regions, we'll do the shift by hand.
490 */
491 const int n = tp - colonp;
492 int i;
493
494 if (tp == endp)
495 return (0);
496 for (i = 1; i <= n; i++) {
497 endp[-i] = colonp[n - i];
498 colonp[n - i] = 0;
499 }
500 tp = endp;
501 }
502 if (tp != endp)
503 return (0);
504 memcpy(dst, tmp, IN6ADDRSZ);
505 return (1);
506 }
507 #endif /* IPv6 */
508
509 int inet_pton(af, src, dst)
510 int af;
511 const char *src;
512 void *dst;
513 {
514 switch (af) {
515 case AF_INET:
516 return (inet_pton4(src, dst));
517 #ifdef IPV6
518 case AF_INET6:
519 /* Somebody might have passed as an IPv4 address this is sick but it works */
520 if (inet_pton4(src, dst)) {
521 char tmp[HOSTIPLEN];
522 sprintf(tmp, "::ffff:%s", src);
523 return (inet_pton6(tmp, dst));
524 } else
525 return (inet_pton6(src, dst));
526 #endif /* IPv6 */
527 default:
528 return (-1);
529 }
530 /* NOTREACHED */
531 }
532
533 #endif

Properties

Name Value
svn:keywords Id