Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenaddress.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS TCP/IP protocol driver 00004 * FILE: tcpip/address.c 00005 * PURPOSE: Routines for handling addresses 00006 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net) 00007 * REVISIONS: 00008 * CSH 01/08-2000 Created 00009 */ 00010 00011 #include "precomp.h" 00012 00013 extern int sprintf( char *out, const char *fmt, ... ); 00014 00015 CHAR A2SStr[128]; 00016 00017 PCHAR A2S( 00018 PIP_ADDRESS Address) 00019 /* 00020 * FUNCTION: Convert an IP address to a string (for debugging) 00021 * ARGUMENTS: 00022 * Address = Pointer to an IP address structure 00023 * RETURNS: 00024 * Pointer to buffer with string representation of IP address 00025 */ 00026 { 00027 ULONG ip; 00028 PCHAR p; 00029 00030 p = A2SStr; 00031 00032 if (!Address) { 00033 TI_DbgPrint(MIN_TRACE, ("NULL address given.\n")); 00034 strcpy(p, "(NULL)"); 00035 return p; 00036 } 00037 00038 switch (Address->Type) { 00039 case IP_ADDRESS_V4: 00040 ip = DN2H(Address->Address.IPv4Address); 00041 sprintf(p, "%d.%d.%d.%d", 00042 (INT)((ip >> 24) & 0xFF), 00043 (INT)((ip >> 16) & 0xFF), 00044 (INT)((ip >> 8) & 0xFF), 00045 (INT)(ip & 0xFF)); 00046 break; 00047 00048 case IP_ADDRESS_V6: 00049 /* FIXME: IPv6 is not supported */ 00050 strcpy(p, "(IPv6 address not supported)"); 00051 break; 00052 } 00053 return p; 00054 } 00055 00056 ULONG IPv4NToHl( ULONG Address ) { 00057 return 00058 ((Address & 0xff) << 24) | 00059 ((Address & 0xff00) << 8) | 00060 ((Address >> 8) & 0xff00) | 00061 ((Address >> 24) & 0xff); 00062 } 00063 00064 UINT AddrCountPrefixBits( PIP_ADDRESS Netmask ) { 00065 UINT Prefix = 0; 00066 if( Netmask->Type == IP_ADDRESS_V4 ) { 00067 ULONG BitTest = 0x80000000; 00068 00069 /* The mask has been read in network order. Put it in host order 00070 * in order to scan it. */ 00071 00072 ULONG TestMask = IPv4NToHl(Netmask->Address.IPv4Address); 00073 00074 while( (BitTest & TestMask) == BitTest ) { 00075 Prefix++; 00076 BitTest >>= 1; 00077 } 00078 return Prefix; 00079 } else { 00080 TI_DbgPrint(DEBUG_DATALINK, ("Don't know address type %d\n", 00081 Netmask->Type)); 00082 return 0; 00083 } 00084 } 00085 00086 VOID AddrWidenAddress( PIP_ADDRESS Network, PIP_ADDRESS Source, 00087 PIP_ADDRESS Netmask ) { 00088 if( Netmask->Type == IP_ADDRESS_V4 ) { 00089 Network->Type = Netmask->Type; 00090 Network->Address.IPv4Address = 00091 Source->Address.IPv4Address & Netmask->Address.IPv4Address; 00092 } else { 00093 TI_DbgPrint(DEBUG_DATALINK, ("Don't know address type %d\n", 00094 Netmask->Type)); 00095 *Network = *Source; 00096 } 00097 } 00098 00099 VOID IPAddressFree( 00100 PVOID Object) 00101 /* 00102 * FUNCTION: Frees an IP_ADDRESS object 00103 * ARGUMENTS: 00104 * Object = Pointer to an IP address structure 00105 * RETURNS: 00106 * Nothing 00107 */ 00108 { 00109 ExFreePoolWithTag(Object, IP_ADDRESS_TAG); 00110 } 00111 00112 00113 BOOLEAN AddrIsUnspecified( 00114 PIP_ADDRESS Address) 00115 /* 00116 * FUNCTION: Return wether IP address is an unspecified address 00117 * ARGUMENTS: 00118 * Address = Pointer to an IP address structure 00119 * RETURNS: 00120 * TRUE if the IP address is an unspecified address, FALSE if not 00121 */ 00122 { 00123 switch (Address->Type) { 00124 case IP_ADDRESS_V4: 00125 return (Address->Address.IPv4Address == 0 || 00126 Address->Address.IPv4Address == 0xFFFFFFFF); 00127 00128 case IP_ADDRESS_V6: 00129 /* FIXME: IPv6 is not supported */ 00130 default: 00131 return FALSE; 00132 } 00133 } 00134 00135 00136 /* 00137 * FUNCTION: Extract IP address from TDI address structure 00138 * ARGUMENTS: 00139 * AddrList = Pointer to transport address list to extract from 00140 * Address = Address of a pointer to where an IP address is stored 00141 * Port = Pointer to where port number is stored 00142 * Cache = Address of pointer to a cached address (updated on return) 00143 * RETURNS: 00144 * Status of operation 00145 */ 00146 NTSTATUS AddrGetAddress( 00147 PTRANSPORT_ADDRESS AddrList, 00148 PIP_ADDRESS Address, 00149 PUSHORT Port) 00150 { 00151 PTA_ADDRESS CurAddr; 00152 INT i; 00153 00154 /* We can only use IP addresses. Search the list until we find one */ 00155 CurAddr = AddrList->Address; 00156 00157 for (i = 0; i < AddrList->TAAddressCount; i++) { 00158 switch (CurAddr->AddressType) { 00159 case TDI_ADDRESS_TYPE_IP: 00160 if (CurAddr->AddressLength >= TDI_ADDRESS_LENGTH_IP) { 00161 /* This is an IPv4 address */ 00162 PTDI_ADDRESS_IP ValidAddr = (PTDI_ADDRESS_IP)CurAddr->Address; 00163 *Port = ValidAddr->sin_port; 00164 Address->Type = CurAddr->AddressType; 00165 ValidAddr = (PTDI_ADDRESS_IP)CurAddr->Address; 00166 AddrInitIPv4(Address, ValidAddr->in_addr); 00167 return STATUS_SUCCESS; 00168 } 00169 } 00170 } 00171 00172 return STATUS_INVALID_ADDRESS; 00173 } 00174 00175 /* 00176 * FUNCTION: Extract IP address from TDI address structure 00177 * ARGUMENTS: 00178 * TdiAddress = Pointer to transport address list to extract from 00179 * Address = Address of a pointer to where an IP address is stored 00180 * Port = Pointer to where port number is stored 00181 * RETURNS: 00182 * Status of operation 00183 */ 00184 NTSTATUS AddrBuildAddress( 00185 PTRANSPORT_ADDRESS TaAddress, 00186 PIP_ADDRESS Address, 00187 PUSHORT Port) 00188 { 00189 PTDI_ADDRESS_IP ValidAddr; 00190 PTA_ADDRESS TdiAddress = &TaAddress->Address[0]; 00191 00192 if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) { 00193 TI_DbgPrint 00194 (MID_TRACE,("AddressType %x, Not valid\n", TdiAddress->AddressType)); 00195 return STATUS_INVALID_ADDRESS; 00196 } 00197 if (TdiAddress->AddressLength < TDI_ADDRESS_LENGTH_IP) { 00198 TI_DbgPrint 00199 (MID_TRACE,("AddressLength %x, Not valid (expected %x)\n", 00200 TdiAddress->AddressLength, TDI_ADDRESS_LENGTH_IP)); 00201 return STATUS_INVALID_ADDRESS; 00202 } 00203 00204 00205 ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address; 00206 00207 AddrInitIPv4(Address, ValidAddr->in_addr); 00208 *Port = ValidAddr->sin_port; 00209 00210 return STATUS_SUCCESS; 00211 } 00212 00213 /* 00214 * FUNCTION: Returns wether two addresses are equal 00215 * ARGUMENTS: 00216 * Address1 = Pointer to first address 00217 * Address2 = Pointer to last address 00218 * RETURNS: 00219 * TRUE if Address1 = Address2, FALSE if not 00220 */ 00221 BOOLEAN AddrIsEqual( 00222 PIP_ADDRESS Address1, 00223 PIP_ADDRESS Address2) 00224 { 00225 if (Address1->Type != Address2->Type) { 00226 DbgPrint("AddrIsEqual: Unequal Address Types\n"); 00227 return FALSE; 00228 } 00229 00230 switch (Address1->Type) { 00231 case IP_ADDRESS_V4: 00232 return (Address1->Address.IPv4Address == Address2->Address.IPv4Address); 00233 00234 case IP_ADDRESS_V6: 00235 return (RtlCompareMemory(&Address1->Address, &Address2->Address, 00236 sizeof(IPv6_RAW_ADDRESS)) == sizeof(IPv6_RAW_ADDRESS)); 00237 break; 00238 00239 default: 00240 DbgPrint("AddrIsEqual: Bad address type\n"); 00241 break; 00242 } 00243 00244 return FALSE; 00245 } 00246 00247 00248 /* 00249 * FUNCTION: Returns wether Address1 is less than Address2 00250 * ARGUMENTS: 00251 * Address1 = Pointer to first address 00252 * Address2 = Pointer to last address 00253 * RETURNS: 00254 * -1 if Address1 < Address2, 1 if Address1 > Address2, 00255 * or 0 if they are equal 00256 */ 00257 INT AddrCompare( 00258 PIP_ADDRESS Address1, 00259 PIP_ADDRESS Address2) 00260 { 00261 switch (Address1->Type) { 00262 case IP_ADDRESS_V4: { 00263 ULONG Addr1, Addr2; 00264 if (Address2->Type == IP_ADDRESS_V4) { 00265 Addr1 = DN2H(Address1->Address.IPv4Address); 00266 Addr2 = DN2H(Address2->Address.IPv4Address); 00267 if (Addr1 < Addr2) 00268 return -1; 00269 else 00270 if (Addr1 == Addr2) 00271 return 0; 00272 else 00273 return 1; 00274 } else 00275 /* FIXME: Support IPv6 */ 00276 return -1; 00277 00278 case IP_ADDRESS_V6: 00279 /* FIXME: Support IPv6 */ 00280 break; 00281 } 00282 } 00283 00284 return FALSE; 00285 } 00286 00287 00288 /* 00289 * FUNCTION: Returns wether two addresses are equal with IPv4 as input 00290 * ARGUMENTS: 00291 * Address1 = Pointer to first address 00292 * Address2 = Pointer to last address 00293 * RETURNS: 00294 * TRUE if Address1 = Address2, FALSE if not 00295 */ 00296 BOOLEAN AddrIsEqualIPv4( 00297 PIP_ADDRESS Address1, 00298 IPv4_RAW_ADDRESS Address2) 00299 { 00300 if (Address1->Type == IP_ADDRESS_V4) 00301 return (Address1->Address.IPv4Address == Address2); 00302 00303 return FALSE; 00304 } 00305 00306 00307 unsigned long NTAPI inet_addr(const char *AddrString) 00308 /* 00309 * Convert an ansi string dotted-quad address to a ulong 00310 * NOTES: 00311 * - this isn't quite like the real inet_addr() - * it doesn't 00312 * handle "10.1" and similar - but it's good enough. 00313 * - Returns in *host* byte order, unlike real inet_addr() 00314 */ 00315 { 00316 ULONG Octets[4] = {0,0,0,0}; 00317 ULONG i = 0; 00318 00319 if(!AddrString) 00320 return -1; 00321 00322 while(*AddrString) 00323 { 00324 CHAR c = *AddrString; 00325 AddrString++; 00326 00327 if(c == '.') 00328 { 00329 i++; 00330 continue; 00331 } 00332 00333 if(c < '0' || c > '9') 00334 return -1; 00335 00336 Octets[i] *= 10; 00337 Octets[i] += (c - '0'); 00338 00339 if(Octets[i] > 255) 00340 return -1; 00341 } 00342 00343 return (Octets[3] << 24) + (Octets[2] << 16) + (Octets[1] << 8) + Octets[0]; 00344 } 00345 00346 /* EOF */ Generated on Fri May 25 2012 04:34:29 for ReactOS by
1.7.6.1
|