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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5081 - (hide annotations)
Mon Dec 22 19:16:10 2014 UTC (5 years, 1 month ago) by michael
File MIME type: text/x-chdr
File size: 15046 byte(s)
- Removed rcs tags

1 michael 5052 /*
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

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