2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS TCP/IP protocol driver
4 * FILE: tcpip/address.c
5 * PURPOSE: Routines for handling addresses
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * CSH 01/08-2000 Created
13 extern int sprintf( char *out
, const char *fmt
, ... );
20 * FUNCTION: Convert an IP address to a string (for debugging)
22 * Address = Pointer to an IP address structure
24 * Pointer to buffer with string representation of IP address
33 TI_DbgPrint(MIN_TRACE
, ("NULL address given.\n"));
38 switch (Address
->Type
) {
40 ip
= DN2H(Address
->Address
.IPv4Address
);
41 sprintf(p
, "%d.%d.%d.%d",
42 (INT
)((ip
>> 24) & 0xFF),
43 (INT
)((ip
>> 16) & 0xFF),
44 (INT
)((ip
>> 8) & 0xFF),
49 /* FIXME: IPv6 is not supported */
50 strcpy(p
, "(IPv6 address not supported)");
56 ULONG
IPv4NToHl( ULONG Address
) {
58 ((Address
& 0xff) << 24) |
59 ((Address
& 0xff00) << 8) |
60 ((Address
>> 8) & 0xff00) |
61 ((Address
>> 24) & 0xff);
64 UINT
AddrCountPrefixBits( PIP_ADDRESS Netmask
) {
66 if( Netmask
->Type
== IP_ADDRESS_V4
) {
67 ULONG BitTest
= 0x80000000;
69 /* The mask has been read in network order. Put it in host order
70 * in order to scan it. */
72 ULONG TestMask
= IPv4NToHl(Netmask
->Address
.IPv4Address
);
74 while( (BitTest
& TestMask
) == BitTest
) {
80 TI_DbgPrint(DEBUG_DATALINK
, ("Don't know address type %d\n",
86 VOID
AddrWidenAddress( PIP_ADDRESS Network
, PIP_ADDRESS Source
,
87 PIP_ADDRESS Netmask
) {
88 if( Netmask
->Type
== IP_ADDRESS_V4
) {
89 Network
->Type
= Netmask
->Type
;
90 Network
->Address
.IPv4Address
=
91 Source
->Address
.IPv4Address
& Netmask
->Address
.IPv4Address
;
93 TI_DbgPrint(DEBUG_DATALINK
, ("Don't know address type %d\n",
102 * FUNCTION: Frees an IP_ADDRESS object
104 * Object = Pointer to an IP address structure
109 ExFreePoolWithTag(Object
, IP_ADDRESS_TAG
);
113 BOOLEAN
AddrIsUnspecified(
116 * FUNCTION: Return wether IP address is an unspecified address
118 * Address = Pointer to an IP address structure
120 * TRUE if the IP address is an unspecified address, FALSE if not
123 switch (Address
->Type
) {
125 return (Address
->Address
.IPv4Address
== 0 ||
126 Address
->Address
.IPv4Address
== 0xFFFFFFFF);
129 /* FIXME: IPv6 is not supported */
137 * FUNCTION: Extract IP address from TDI address structure
139 * AddrList = Pointer to transport address list to extract from
140 * Address = Address of a pointer to where an IP address is stored
141 * Port = Pointer to where port number is stored
142 * Cache = Address of pointer to a cached address (updated on return)
144 * Status of operation
146 NTSTATUS
AddrGetAddress(
147 PTRANSPORT_ADDRESS AddrList
,
154 /* We can only use IP addresses. Search the list until we find one */
155 CurAddr
= AddrList
->Address
;
157 for (i
= 0; i
< AddrList
->TAAddressCount
; i
++) {
158 switch (CurAddr
->AddressType
) {
159 case TDI_ADDRESS_TYPE_IP
:
160 if (CurAddr
->AddressLength
>= TDI_ADDRESS_LENGTH_IP
) {
161 /* This is an IPv4 address */
162 PTDI_ADDRESS_IP ValidAddr
= (PTDI_ADDRESS_IP
)CurAddr
->Address
;
163 *Port
= ValidAddr
->sin_port
;
164 Address
->Type
= CurAddr
->AddressType
;
165 ValidAddr
= (PTDI_ADDRESS_IP
)CurAddr
->Address
;
166 AddrInitIPv4(Address
, ValidAddr
->in_addr
);
167 return STATUS_SUCCESS
;
172 return STATUS_INVALID_ADDRESS
;
176 * FUNCTION: Extract IP address from TDI address structure
178 * TdiAddress = Pointer to transport address list to extract from
179 * Address = Address of a pointer to where an IP address is stored
180 * Port = Pointer to where port number is stored
182 * Status of operation
184 NTSTATUS
AddrBuildAddress(
185 PTRANSPORT_ADDRESS TaAddress
,
189 PTDI_ADDRESS_IP ValidAddr
;
190 PTA_ADDRESS TdiAddress
= &TaAddress
->Address
[0];
192 if (TdiAddress
->AddressType
!= TDI_ADDRESS_TYPE_IP
) {
194 (MID_TRACE
,("AddressType %x, Not valid\n", TdiAddress
->AddressType
));
195 return STATUS_INVALID_ADDRESS
;
197 if (TdiAddress
->AddressLength
< TDI_ADDRESS_LENGTH_IP
) {
199 (MID_TRACE
,("AddressLength %x, Not valid (expected %x)\n",
200 TdiAddress
->AddressLength
, TDI_ADDRESS_LENGTH_IP
));
201 return STATUS_INVALID_ADDRESS
;
205 ValidAddr
= (PTDI_ADDRESS_IP
)TdiAddress
->Address
;
207 AddrInitIPv4(Address
, ValidAddr
->in_addr
);
208 *Port
= ValidAddr
->sin_port
;
210 return STATUS_SUCCESS
;
214 * FUNCTION: Returns wether two addresses are equal
216 * Address1 = Pointer to first address
217 * Address2 = Pointer to last address
219 * TRUE if Address1 = Address2, FALSE if not
222 PIP_ADDRESS Address1
,
223 PIP_ADDRESS Address2
)
225 if (Address1
->Type
!= Address2
->Type
) {
226 DbgPrint("AddrIsEqual: Unequal Address Types\n");
230 switch (Address1
->Type
) {
232 return (Address1
->Address
.IPv4Address
== Address2
->Address
.IPv4Address
);
235 return (RtlCompareMemory(&Address1
->Address
, &Address2
->Address
,
236 sizeof(IPv6_RAW_ADDRESS
)) == sizeof(IPv6_RAW_ADDRESS
));
240 DbgPrint("AddrIsEqual: Bad address type\n");
249 * FUNCTION: Returns wether Address1 is less than Address2
251 * Address1 = Pointer to first address
252 * Address2 = Pointer to last address
254 * -1 if Address1 < Address2, 1 if Address1 > Address2,
255 * or 0 if they are equal
258 PIP_ADDRESS Address1
,
259 PIP_ADDRESS Address2
)
261 switch (Address1
->Type
) {
262 case IP_ADDRESS_V4
: {
264 if (Address2
->Type
== IP_ADDRESS_V4
) {
265 Addr1
= DN2H(Address1
->Address
.IPv4Address
);
266 Addr2
= DN2H(Address2
->Address
.IPv4Address
);
275 /* FIXME: Support IPv6 */
279 /* FIXME: Support IPv6 */
289 * FUNCTION: Returns wether two addresses are equal with IPv4 as input
291 * Address1 = Pointer to first address
292 * Address2 = Pointer to last address
294 * TRUE if Address1 = Address2, FALSE if not
296 BOOLEAN
AddrIsEqualIPv4(
297 PIP_ADDRESS Address1
,
298 IPv4_RAW_ADDRESS Address2
)
300 if (Address1
->Type
== IP_ADDRESS_V4
)
301 return (Address1
->Address
.IPv4Address
== Address2
);
307 unsigned long NTAPI
inet_addr(const char *AddrString
)
309 * Convert an ansi string dotted-quad address to a ulong
311 * - this isn't quite like the real inet_addr() - * it doesn't
312 * handle "10.1" and similar - but it's good enough.
313 * - Returns in *host* byte order, unlike real inet_addr()
316 ULONG Octets
[4] = {0,0,0,0};
324 CHAR c
= *AddrString
;
333 if(c
< '0' || c
> '9')
337 Octets
[i
] += (c
- '0');
343 return (Octets
[3] << 24) + (Octets
[2] << 16) + (Octets
[1] << 8) + Octets
[0];