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 #ifndef IN6ADDRSZ
00020 #define IN6ADDRSZ   16
00021 #endif
00022 
00023 #ifndef INT16SZ
00024 #define INT16SZ     2
00025 #endif
00026 
00027 #ifdef SPRINTF_CHAR
00028 # define SPRINTF(x) strlen(sprintfx)
00029 #else
00030 # define SPRINTF(x) ((size_t)sprintf x)
00031 #endif
00032 
00033 /*
00034  * WARNING: Don't even consider trying to compile this on a system where
00035  * sizeof(int) < 4.  sizeof(int) > 4 is fine; all the world's not a VAX.
00036  */
00037 
00038 static const char *inet_ntop4(const u_char *src, char *dst, size_t size);
00039 
00040 #ifdef INET6
00041 static const char *inet_ntop6(const u_char *src, char *dst, size_t size);
00042 #endif
00043 
00044 /* char *
00045  * inet_ntop(af, src, dst, size)
00046  *  convert a network format address to presentation format.
00047  * return:
00048  *  pointer to presentation format address (`dst'), or NULL (see errno).
00049  * author:
00050  *  Paul Vixie, 1996.
00051  */
00052 const char *
00053 inet_ntop(int af, const void *src, char *dst, size_t size)
00054 {
00055 
00056     switch (af) {
00057     case AF_INET:
00058         return (inet_ntop4(src, dst, size));
00059 #ifdef INET6
00060     case AF_INET6:
00061         return (inet_ntop6(src, dst, size));
00062 #endif
00063     default:
00064         WSASetLastError(WSAEAFNOSUPPORT);
00065         return (NULL);
00066     }
00067     /* NOTREACHED */
00068 }
00069 
00070 /* const char *
00071  * inet_ntop4(src, dst, size)
00072  *  format an IPv4 address, more or less like inet_ntoa()
00073  * return:
00074  *  `dst' (as a const)
00075  * notes:
00076  *  (1) uses no statics
00077  *  (2) takes a u_char* not an in_addr as input
00078  * author:
00079  *  Paul Vixie, 1996.
00080  */
00081 static const char *
00082 inet_ntop4(const u_char *src, char *dst, size_t size)
00083 {
00084     static const char fmt[] = "%u.%u.%u.%u";
00085     char tmp[sizeof "255.255.255.255"];
00086 
00087     if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
00088         WSASetLastError(WSAEINVAL);
00089         return (NULL);
00090     }
00091     strcpy(dst, tmp);
00092     return (dst);
00093 }
00094 
00095 #ifdef INET6
00096 /* const char *
00097  * inet_ntop6(src, dst, size)
00098  *  convert IPv6 binary address into presentation (printable) format
00099  * author:
00100  *  Paul Vixie, 1996.
00101  */
00102 static const char *
00103 inet_ntop6(const u_char *src, char *dst, size_t size)
00104 {
00105     /*
00106      * Note that int32_t and int16_t need only be "at least" large enough
00107      * to contain a value of the specified size.  On some systems, like
00108      * Crays, there is no such thing as an integer variable with 16 bits.
00109      * Keep this in mind if you think this function should have been coded
00110      * to use pointer overlays.  All the world's not a VAX.
00111      */
00112     char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
00113     struct { int base, len; } best, cur;
00114     u_int words[IN6ADDRSZ / INT16SZ];
00115     int i;
00116 
00117     /*
00118      * Preprocess:
00119      *  Copy the input (bytewise) array into a wordwise array.
00120      *  Find the longest run of 0x00's in src[] for :: shorthanding.
00121      */
00122     memset(words, '\0', sizeof words);
00123     for (i = 0; i < IN6ADDRSZ; i++)
00124         words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
00125     best.base = -1;
00126     cur.base = -1;
00127     for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00128         if (words[i] == 0) {
00129             if (cur.base == -1)
00130                 cur.base = i, cur.len = 1;
00131             else
00132                 cur.len++;
00133         } else {
00134             if (cur.base != -1) {
00135                 if (best.base == -1 || cur.len > best.len)
00136                     best = cur;
00137                 cur.base = -1;
00138             }
00139         }
00140     }
00141     if (cur.base != -1) {
00142         if (best.base == -1 || cur.len > best.len)
00143             best = cur;
00144     }
00145     if (best.base != -1 && best.len < 2)
00146         best.base = -1;
00147 
00148     /*
00149      * Format the result.
00150      */
00151     tp = tmp;
00152     for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
00153         /* Are we inside the best run of 0x00's? */
00154         if (best.base != -1 && i >= best.base &&
00155             i < (best.base + best.len)) {
00156             if (i == best.base)
00157                 *tp++ = ':';
00158             continue;
00159         }
00160         /* Are we following an initial run of 0x00s or any real hex? */
00161         if (i != 0)
00162             *tp++ = ':';
00163         /* Is this address an encapsulated IPv4? */
00164         if (i == 6 && best.base == 0 &&
00165             (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
00166             if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
00167                 return (NULL);
00168             tp += strlen(tp);
00169             break;
00170         }
00171         tp += SPRINTF((tp, "%x", words[i]));
00172     }
00173     /* Was it a trailing run of 0x00's? */
00174     if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
00175         *tp++ = ':';
00176     *tp++ = '\0';
00177 
00178     /*
00179      * Check for overflow, copy, and we're done.
00180      */
00181     if ((size_t)(tp - tmp) > size) {
00182         WSASetLastError(WSAEINVAL);
00183         return (NULL);
00184     }
00185     strcpy(dst, tmp);
00186     return (dst);
00187 }
00188 #endif
00189 

Generated on Mon May 28 2012 04:26:29 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.