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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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