ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

inet_ntop.c
Go to the documentation of this file.
00001 /* from NetBSD: inet_ntop.c,v 1.9 2000/01/22 22:19:16 mycroft Exp */
00002 
00003 /* Copyright (c) 1996 by Internet Software Consortium.
00004  *
00005  * Permission to use, copy, modify, and distribute this software for any
00006  * purpose with or without fee is hereby granted, provided that the above
00007  * copyright notice and this permission notice appear in all copies.
00008  *
00009  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
00010  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
00011  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
00012  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00013  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00014  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00015  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00016  * SOFTWARE.
00017  */
00018 
00019 #include <stdio.h>
00020 
00021 #ifndef IN6ADDRSZ
00022 #define IN6ADDRSZ   16
00023 #endif
00024 
00025 #ifndef INT16SZ
00026 #define INT16SZ     2
00027 #endif
00028 
00029 #ifdef SPRINTF_CHAR
00030 # define SPRINTF(x) strlen(sprintfx)
00031 #else
00032 # define SPRINTF(x) ((size_t)sprintf x)
00033 #endif
00034 
00035 /*
00036  * WARNING: Don't even consider trying to compile this on a system where
00037  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
00038  */
00039 
00040 static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
00041 
00042 #ifdef INET6
00043 static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
00044 #endif
00045 
00046 /* char *
00047  * inet_ntop(af, src, dst, size)
00048  *  convert a network format address to presentation format.
00049  * return:
00050  *  pointer to presentation format address (`dst'), or NULL (see errno).
00051  * author:
00052  *  Paul Vixie, 1996.
00053  */
00054 const char *
00055 inet_ntop(int af, const void *src, char *dst, size_t size)
00056 {
00057 
00058     switch (af) {
00059     case AF_INET:
00060         return (inet_ntop4(src, dst, size));
00061 #ifdef INET6
00062     case AF_INET6:
00063         return (inet_ntop6(src, dst, size));
00064 #endif
00065     default:
00066         WSASetLastError(WSAEAFNOSUPPORT);
00067         return (NULL);
00068     }
00069     /* NOTREACHED */
00070 }
00071 
00072 /* const char *
00073  * inet_ntop4(src, dst, size)
00074  *  format an IPv4 address, more or less like inet_ntoa()
00075  * return:
00076  *  `dst' (as a const)
00077  * notes:
00078  *  (1) uses no statics
00079  *  (2) takes a u_char* not an in_addr as input
00080  * author:
00081  *  Paul Vixie, 1996.
00082  */
00083 static const char *
00084 inet_ntop4(const u_char *src, char *dst, size_t size)
00085 {
00086     static const char fmt[] = "%u.%u.%u.%u";
00087     char tmp[sizeof "255.255.255.255"];
00088 
00089     if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
00090         WSASetLastError(WSAEINVAL);
00091         return (NULL);
00092     }
00093     strcpy(dst, tmp);
00094     return (dst);
00095 }
00096 
00097 #ifdef INET6
00098 /* const char *
00099  * inet_ntop6(src, dst, size)
00100  *  convert IPv6 binary address into presentation (printable) format
00101  * author:
00102  *  Paul Vixie, 1996.
00103  */
00104 static const char *
00105 inet_ntop6(const u_char *src, char *dst, size_t size)
00106 {
00107     /*
00108      * Note that int32_t and int16_t need only be "at least" large enough
00109      * to contain a value of the specified size.  On some systems, like
00110      * Crays, there is no such thing as an integer variable with 16 bits.
00111      * Keep this in mind if you think this function should have been coded
00112      * to use pointer overlays.  All the world's not a VAX.
00113      */
00114     char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
00115     struct { int base, len; } best, cur;
00116     u_int words[IN6ADDRSZ / INT16SZ];
00117     int i;
00118 
00119     /*
00120      * Preprocess:
00121      *  Copy the input (bytewise) array into a wordwise array.
00122      *  Find the longest run of 0x00's in src[] for :: shorthanding.
00123      */
00124     memset(words, '\0', sizeof words);
00125     for (i = 0; i < IN6ADDRSZ; i++)
00126         words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
00127     best.base = -1;
00128     cur.base = -1;
00129     for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00130         if (words[i] == 0) {
00131             if (cur.base == -1)
00132                 cur.base = i, cur.len = 1;
00133             else
00134                 cur.len++;
00135         } else {
00136             if (cur.base != -1) {
00137                 if (best.base == -1 || cur.len > best.len)
00138                     best = cur;
00139                 cur.base = -1;
00140             }
00141         }
00142     }
00143     if (cur.base != -1) {
00144         if (best.base == -1 || cur.len > best.len)
00145             best = cur;
00146     }
00147     if (best.base != -1 && best.len < 2)
00148         best.base = -1;
00149 
00150     /*
00151      * Format the result.
00152      */
00153     tp = tmp;
00154     for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00155         /* Are we inside the best run of 0x00's? */
00156         if (best.base != -1 && i >= best.base &&
00157             i < (best.base + best.len)) {
00158             if (i == best.base)
00159                 *tp++ = ':';
00160             continue;
00161         }
00162         /* Are we following an initial run of 0x00s or any real hex? */
00163         if (i != 0)
00164             *tp++ = ':';
00165         /* Is this address an encapsulated IPv4? */
00166         if (i == 6 && best.base == 0 &&
00167             (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
00168             if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
00169                 return (NULL);
00170             tp += strlen(tp);
00171             break;
00172         }
00173         tp += SPRINTF((tp, "%x", words[i]));
00174     }
00175     /* Was it a trailing run of 0x00's? */
00176     if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
00177         *tp++ = ':';
00178     *tp++ = '\0';
00179 
00180     /*
00181      * Check for overflow, copy, and we're done.
00182      */
00183     if ((size_t)(tp - tmp) > size) {
00184         WSASetLastError(WSAEINVAL);
00185         return (NULL);
00186     }
00187     strcpy(dst, tmp);
00188     return (dst);
00189 }
00190 #endif
00191 

Generated on Sat May 26 2012 04:25:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.