Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenaddrconv.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS WinSock 2 API 00004 * FILE: addrconv.c 00005 * PURPOSE: Address and Port Conversion Support 00006 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 #include "ws2_32.h" 00011 00012 //#define NDEBUG 00013 #include <debug.h> 00014 00015 /* DEFINES *******************************************************************/ 00016 00017 #ifndef BE 00018 00019 /* DWORD network to host byte order conversion for little endian machines */ 00020 #define DN2H(dw) \ 00021 ((((dw) & 0xFF000000L) >> 24) | \ 00022 (((dw) & 0x00FF0000L) >> 8) | \ 00023 (((dw) & 0x0000FF00L) << 8) | \ 00024 (((dw) & 0x000000FFL) << 24)) 00025 00026 /* DWORD host to network byte order conversion for little endian machines */ 00027 #define DH2N(dw) \ 00028 ((((dw) & 0xFF000000L) >> 24) | \ 00029 (((dw) & 0x00FF0000L) >> 8) | \ 00030 (((dw) & 0x0000FF00L) << 8) | \ 00031 (((dw) & 0x000000FFL) << 24)) 00032 00033 /* WORD network to host order conversion for little endian machines */ 00034 #define WN2H(w) \ 00035 ((((w) & 0xFF00) >> 8) | \ 00036 (((w) & 0x00FF) << 8)) 00037 00038 /* WORD host to network byte order conversion for little endian machines */ 00039 #define WH2N(w) \ 00040 ((((w) & 0xFF00) >> 8) | \ 00041 (((w) & 0x00FF) << 8)) 00042 00043 #else /* BE */ 00044 00045 /* DWORD network to host byte order conversion for big endian machines */ 00046 #define DN2H(dw) \ 00047 (dw) 00048 00049 /* DWORD host to network byte order conversion big endian machines */ 00050 #define DH2N(dw) \ 00051 (dw) 00052 00053 /* WORD network to host order conversion for big endian machines */ 00054 #define WN2H(w) \ 00055 (w) 00056 00057 /* WORD host to network byte order conversion for big endian machines */ 00058 #define WH2N(w) \ 00059 (w) 00060 00061 #endif /* BE */ 00062 00063 /* FUNCTIONS *****************************************************************/ 00064 00065 /* 00066 * @implemented 00067 */ 00068 ULONG 00069 WSAAPI 00070 inet_addr(IN CONST CHAR FAR* cp) 00071 { 00072 register u_long val, base, n; 00073 register unsigned char c; 00074 u_long parts[4], *pp = parts; 00075 00076 again: 00077 /* 00078 * Collect number up to ``.''. 00079 * Values are specified as for C: 00080 * 0x=hex, 0=octal, other=decimal. 00081 */ 00082 val = 0; base = 10; 00083 if (*cp == '0') { 00084 if (*++cp == 'x' || *cp == 'X') 00085 base = 16, cp++; 00086 else 00087 base = 8; 00088 } 00089 while ((c = *cp)) { 00090 if (isdigit(c)) { 00091 val = (val * base) + (c - '0'); 00092 cp++; 00093 continue; 00094 } 00095 if (base == 16 && isxdigit(c)) { 00096 val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A')); 00097 cp++; 00098 continue; 00099 } 00100 break; 00101 } 00102 if (*cp == '.') { 00103 /* 00104 * Internet format: 00105 * a.b.c.d 00106 * a.b.c (with c treated as 16-bits) 00107 * a.b (with b treated as 24 bits) 00108 */ 00109 if (pp >= parts + 4) return (INADDR_NONE); 00110 *pp++ = val; 00111 cp++; 00112 goto again; 00113 } 00114 /* 00115 * Check for trailing characters. 00116 */ 00117 if (*cp && !isspace((UCHAR)*cp)) return (INADDR_NONE); 00118 00119 *pp++ = val; 00120 /* 00121 * Concoct the address according to 00122 * the number of parts specified. 00123 */ 00124 n = (u_long)(pp - parts); 00125 switch (n) { 00126 00127 case 1: /* a -- 32 bits */ 00128 val = parts[0]; 00129 break; 00130 00131 case 2: /* a.b -- 8.24 bits */ 00132 val = (parts[0] << 24) | (parts[1] & 0xffffff); 00133 break; 00134 00135 case 3: /* a.b.c -- 8.8.16 bits */ 00136 val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) | 00137 (parts[2] & 0xffff); 00138 break; 00139 00140 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 00141 val = (parts[0] << 24) | ((parts[1] & 0xff) << 16) | 00142 ((parts[2] & 0xff) << 8) | (parts[3] & 0xff); 00143 break; 00144 00145 default: 00146 return (-1); 00147 } 00148 val = htonl(val); 00149 return (val); 00150 } 00151 00152 /* 00153 * @implemented 00154 */ 00155 CHAR FAR* 00156 WSAAPI 00157 inet_ntoa(IN IN_ADDR in) 00158 { 00159 PWSPROCESS Process; 00160 PWSTHREAD Thread; 00161 INT ErrorCode; 00162 WSADATA WsaData; 00163 BOOL ManualLoad = FALSE; 00164 CHAR b[10]; 00165 PCHAR p; 00166 DPRINT("inet_ntoa: %lx\n", in); 00167 00168 /* Enter prolog */ 00169 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) 00170 { 00171 DPRINT("MANUAL LOAD\n"); 00172 00173 /* Only fail if the error wasn't related to a missing WSAStartup */ 00174 if (ErrorCode != WSANOTINITIALISED) 00175 { 00176 /* Fail */ 00177 SetLastError(ErrorCode); 00178 return NULL; 00179 } 00180 00181 /* Apps aren't expected to call WSAStartup for this API, so we will */ 00182 if ((ErrorCode = WSAStartup(MAKEWORD(2,2), &WsaData)) != ERROR_SUCCESS) 00183 { 00184 /* We failed */ 00185 SetLastError(ErrorCode); 00186 return NULL; 00187 } 00188 00189 /* Try the prolog again */ 00190 ManualLoad = TRUE; 00191 if ((ErrorCode = WsApiProlog(&Process, &Thread)) != ERROR_SUCCESS) 00192 { 00193 /* Failed again... */ 00194 WSACleanup(); 00195 SetLastError(ErrorCode); 00196 return NULL; 00197 } 00198 } 00199 00200 p = Thread->Buffer; 00201 _itoa(in.S_un.S_addr & 0xFF, b, 10); 00202 strcpy(p, b); 00203 _itoa((in.S_un.S_addr >> 8) & 0xFF, b, 10); 00204 strcat(p, "."); 00205 strcat(p, b); 00206 _itoa((in.S_un.S_addr >> 16) & 0xFF, b, 10); 00207 strcat(p, "."); 00208 strcat(p, b); 00209 _itoa((in.S_un.S_addr >> 24) & 0xFF, b, 10); 00210 strcat(p, "."); 00211 strcat(p, b); 00212 00213 /* Cleanup the manual load */ 00214 if (ManualLoad) WSACleanup(); 00215 00216 /* Return the buffer */ 00217 return p; 00218 } 00219 00220 /* 00221 * @implemented 00222 */ 00223 ULONG 00224 WSAAPI 00225 htonl(IN ULONG hostlong) 00226 { 00227 return DH2N(hostlong); 00228 } 00229 00230 /* 00231 * @implemented 00232 */ 00233 USHORT 00234 WSAAPI 00235 htons(IN USHORT hostshort) 00236 { 00237 return WH2N(hostshort); 00238 } 00239 00240 /* 00241 * @implemented 00242 */ 00243 ULONG 00244 WSAAPI 00245 ntohl(IN ULONG netlong) 00246 { 00247 return DN2H(netlong); 00248 } 00249 00250 /* 00251 * @implemented 00252 */ 00253 USHORT 00254 WSAAPI 00255 ntohs(IN USHORT netshort) 00256 { 00257 return WN2H(netshort); 00258 } 00259 00260 /* 00261 * @implemented 00262 */ 00263 INT 00264 WSAAPI 00265 WSAHtonl(IN SOCKET s, 00266 IN ULONG hostlong, 00267 OUT ULONG FAR* lpnetlong) 00268 { 00269 INT ErrorCode; 00270 PWSSOCKET Socket; 00271 DPRINT("WSAHtonl: %p, %lx, %p\n", s, hostlong, lpnetlong); 00272 00273 /* Check for WSAStartup */ 00274 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00275 { 00276 /* Make sure we got a parameter */ 00277 if (!lpnetlong) 00278 { 00279 /* Fail */ 00280 SetLastError(WSAEFAULT); 00281 return SOCKET_ERROR; 00282 } 00283 00284 /* Get the Socket Context */ 00285 if ((Socket = WsSockGetSocket(s))) 00286 { 00287 /* Check which byte order to use */ 00288 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder == 00289 LITTLEENDIAN) 00290 { 00291 /* No conversion needed */ 00292 *lpnetlong = hostlong; 00293 } 00294 else 00295 { 00296 /* Use a swap */ 00297 *lpnetlong = DN2H(hostlong); 00298 } 00299 00300 /* Dereference the socket */ 00301 WsSockDereference(Socket); 00302 00303 /* Return success */ 00304 return ERROR_SUCCESS; 00305 } 00306 else 00307 { 00308 /* Set the error code */ 00309 ErrorCode = WSAENOTSOCK; 00310 } 00311 } 00312 00313 /* Return with error */ 00314 SetLastError(ErrorCode); 00315 return SOCKET_ERROR; 00316 } 00317 00318 /* 00319 * @implemented 00320 */ 00321 INT 00322 WSAAPI 00323 WSAHtons(IN SOCKET s, 00324 IN USHORT hostshort, 00325 OUT USHORT FAR* lpnetshort) 00326 { 00327 INT ErrorCode; 00328 PWSSOCKET Socket; 00329 DPRINT("WSAHtons: %p, %lx, %p\n", s, hostshort, lpnetshort); 00330 00331 /* Check for WSAStartup */ 00332 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00333 { 00334 /* Make sure we got a parameter */ 00335 if (!lpnetshort) 00336 { 00337 /* Fail */ 00338 SetLastError(WSAEFAULT); 00339 return SOCKET_ERROR; 00340 } 00341 00342 /* Get the Socket Context */ 00343 if ((Socket = WsSockGetSocket(s))) 00344 { 00345 /* Check which byte order to use */ 00346 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder == 00347 LITTLEENDIAN) 00348 { 00349 /* No conversion needed */ 00350 *lpnetshort = hostshort; 00351 } 00352 else 00353 { 00354 /* Use a swap */ 00355 *lpnetshort = WN2H(hostshort); 00356 } 00357 00358 /* Dereference the socket */ 00359 WsSockDereference(Socket); 00360 00361 /* Return success */ 00362 return ERROR_SUCCESS; 00363 } 00364 else 00365 { 00366 /* Set the error code */ 00367 ErrorCode = WSAENOTSOCK; 00368 } 00369 } 00370 00371 /* Return with error */ 00372 SetLastError(ErrorCode); 00373 return SOCKET_ERROR; 00374 } 00375 00376 /* 00377 * @implemented 00378 */ 00379 INT 00380 WSAAPI 00381 WSANtohl(IN SOCKET s, 00382 IN ULONG netlong, 00383 OUT ULONG FAR* lphostlong) 00384 { 00385 INT ErrorCode; 00386 PWSSOCKET Socket; 00387 DPRINT("WSANtohl: %p, %lx, %p\n", s, netlong, lphostlong); 00388 00389 /* Check for WSAStartup */ 00390 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00391 { 00392 /* Make sure we got a parameter */ 00393 if (!lphostlong) 00394 { 00395 /* Fail */ 00396 SetLastError(WSAEFAULT); 00397 return SOCKET_ERROR; 00398 } 00399 00400 /* Get the Socket Context */ 00401 if ((Socket = WsSockGetSocket(s))) 00402 { 00403 /* Check which byte order to use */ 00404 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder == 00405 LITTLEENDIAN) 00406 { 00407 /* No conversion needed */ 00408 *lphostlong = netlong; 00409 } 00410 else 00411 { 00412 /* Use a swap */ 00413 *lphostlong = DN2H(netlong); 00414 } 00415 00416 /* Dereference the socket */ 00417 WsSockDereference(Socket); 00418 00419 /* Return success */ 00420 return ERROR_SUCCESS; 00421 } 00422 else 00423 { 00424 /* Set the error code */ 00425 ErrorCode = WSAENOTSOCK; 00426 } 00427 } 00428 00429 /* Return with error */ 00430 SetLastError(ErrorCode); 00431 return SOCKET_ERROR; 00432 } 00433 00434 /* 00435 * @implemented 00436 */ 00437 INT 00438 WSAAPI 00439 WSANtohs(IN SOCKET s, 00440 IN USHORT netshort, 00441 OUT USHORT FAR* lphostshort) 00442 { 00443 INT ErrorCode; 00444 PWSSOCKET Socket; 00445 DPRINT("WSANtohs: %p, %lx, %p\n", s, netshort, lphostshort); 00446 00447 /* Check for WSAStartup */ 00448 if ((ErrorCode = WsQuickProlog()) == ERROR_SUCCESS) 00449 { 00450 /* Make sure we got a parameter */ 00451 if (!lphostshort) 00452 { 00453 /* Fail */ 00454 SetLastError(WSAEFAULT); 00455 return SOCKET_ERROR; 00456 } 00457 00458 /* Get the Socket Context */ 00459 if ((Socket = WsSockGetSocket(s))) 00460 { 00461 /* Check which byte order to use */ 00462 if (Socket->CatalogEntry->ProtocolInfo.iNetworkByteOrder == 00463 LITTLEENDIAN) 00464 { 00465 /* No conversion needed */ 00466 *lphostshort = netshort; 00467 } 00468 else 00469 { 00470 /* Use a swap */ 00471 *lphostshort = WN2H(netshort); 00472 } 00473 00474 /* Dereference the socket */ 00475 WsSockDereference(Socket); 00476 00477 /* Return success */ 00478 return ERROR_SUCCESS; 00479 } 00480 else 00481 { 00482 /* Set the error code */ 00483 ErrorCode = WSAENOTSOCK; 00484 } 00485 } 00486 00487 /* Return with error */ 00488 SetLastError(ErrorCode); 00489 return SOCKET_ERROR; 00490 } 00491 Generated on Sun May 27 2012 04:27:08 for ReactOS by
1.7.6.1
|