/[svn]/hopm/trunk/src/inet.c
ViewVC logotype

Contents of /hopm/trunk/src/inet.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5135 - (show annotations)
Thu Dec 25 18:51:51 2014 UTC (5 years, 5 months ago) by michael
File MIME type: text/x-chdr
File size: 14720 byte(s)
- propset svn:eol-style native

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

Properties

Name Value
svn:eol-style native
svn:keywords Id

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28