Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygeninet_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
1.7.6.1
|