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

address.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 doxygen 1.7.6.1

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