ReactOS  0.4.14-dev-614-gbfd8a84
address.c
Go to the documentation of this file.
1 /*
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)
7  * REVISIONS:
8  * CSH 01/08-2000 Created
9  */
10 
11 #include "precomp.h"
12 
13 extern int sprintf( char *out, const char *fmt, ... );
14 
15 CHAR A2SStr[128];
16 
19 /*
20  * FUNCTION: Convert an IP address to a string (for debugging)
21  * ARGUMENTS:
22  * Address = Pointer to an IP address structure
23  * RETURNS:
24  * Pointer to buffer with string representation of IP address
25  */
26 {
27  ULONG ip;
28  PCHAR p;
29 
30  p = A2SStr;
31 
32  if (!Address) {
33  TI_DbgPrint(MIN_TRACE, ("NULL address given.\n"));
34  strcpy(p, "(NULL)");
35  return p;
36  }
37 
38  switch (Address->Type) {
39  case IP_ADDRESS_V4:
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),
45  (INT)(ip & 0xFF));
46  break;
47 
48  case IP_ADDRESS_V6:
49  /* FIXME: IPv6 is not supported */
50  strcpy(p, "(IPv6 address not supported)");
51  break;
52  }
53  return p;
54 }
55 
57  return
58  ((Address & 0xff) << 24) |
59  ((Address & 0xff00) << 8) |
60  ((Address >> 8) & 0xff00) |
61  ((Address >> 24) & 0xff);
62 }
63 
65  UINT Prefix = 0;
66  if( Netmask->Type == IP_ADDRESS_V4 ) {
67  ULONG BitTest = 0x80000000;
68 
69  /* The mask has been read in network order. Put it in host order
70  * in order to scan it. */
71 
72  ULONG TestMask = IPv4NToHl(Netmask->Address.IPv4Address);
73 
74  while( (BitTest & TestMask) == BitTest ) {
75  Prefix++;
76  BitTest >>= 1;
77  }
78  return Prefix;
79  } else {
80  TI_DbgPrint(DEBUG_DATALINK, ("Don't know address type %d\n",
81  Netmask->Type));
82  return 0;
83  }
84 }
85 
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;
92  } else {
93  TI_DbgPrint(DEBUG_DATALINK, ("Don't know address type %d\n",
94  Netmask->Type));
95  *Network = *Source;
96  }
97 }
98 
100  PVOID Object)
101 /*
102  * FUNCTION: Frees an IP_ADDRESS object
103  * ARGUMENTS:
104  * Object = Pointer to an IP address structure
105  * RETURNS:
106  * Nothing
107  */
108 {
110 }
111 
112 
115 /*
116  * FUNCTION: Return wether IP address is an unspecified address
117  * ARGUMENTS:
118  * Address = Pointer to an IP address structure
119  * RETURNS:
120  * TRUE if the IP address is an unspecified address, FALSE if not
121  */
122 {
123  switch (Address->Type) {
124  case IP_ADDRESS_V4:
125  return (Address->Address.IPv4Address == 0 ||
126  Address->Address.IPv4Address == 0xFFFFFFFF);
127 
128  case IP_ADDRESS_V6:
129  /* FIXME: IPv6 is not supported */
130  default:
131  return FALSE;
132  }
133 }
134 
135 
136 /*
137  * FUNCTION: Extract IP address from TDI address structure
138  * ARGUMENTS:
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)
143  * RETURNS:
144  * Status of operation
145  */
147  PTRANSPORT_ADDRESS AddrList,
149  PUSHORT Port)
150 {
151  PTA_ADDRESS CurAddr;
152  INT i;
153 
154  /* We can only use IP addresses. Search the list until we find one */
155  CurAddr = AddrList->Address;
156 
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;
168  }
169  }
170  }
171 
172  return STATUS_INVALID_ADDRESS;
173 }
174 
175 /*
176  * FUNCTION: Extract IP address from TDI address structure
177  * ARGUMENTS:
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
181  * RETURNS:
182  * Status of operation
183  */
185  PTRANSPORT_ADDRESS TaAddress,
187  PUSHORT Port)
188 {
189  PTDI_ADDRESS_IP ValidAddr;
190  PTA_ADDRESS TdiAddress = &TaAddress->Address[0];
191 
192  if (TdiAddress->AddressType != TDI_ADDRESS_TYPE_IP) {
194  (MID_TRACE,("AddressType %x, Not valid\n", TdiAddress->AddressType));
195  return STATUS_INVALID_ADDRESS;
196  }
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;
202  }
203 
204 
205  ValidAddr = (PTDI_ADDRESS_IP)TdiAddress->Address;
206 
207  AddrInitIPv4(Address, ValidAddr->in_addr);
208  *Port = ValidAddr->sin_port;
209 
210  return STATUS_SUCCESS;
211 }
212 
213 /*
214  * FUNCTION: Returns wether two addresses are equal
215  * ARGUMENTS:
216  * Address1 = Pointer to first address
217  * Address2 = Pointer to last address
218  * RETURNS:
219  * TRUE if Address1 = Address2, FALSE if not
220  */
222  PIP_ADDRESS Address1,
223  PIP_ADDRESS Address2)
224 {
225  if (Address1->Type != Address2->Type) {
226  DbgPrint("AddrIsEqual: Unequal Address Types\n");
227  return FALSE;
228  }
229 
230  switch (Address1->Type) {
231  case IP_ADDRESS_V4:
232  return (Address1->Address.IPv4Address == Address2->Address.IPv4Address);
233 
234  case IP_ADDRESS_V6:
235  return (RtlCompareMemory(&Address1->Address, &Address2->Address,
236  sizeof(IPv6_RAW_ADDRESS)) == sizeof(IPv6_RAW_ADDRESS));
237  break;
238 
239  default:
240  DbgPrint("AddrIsEqual: Bad address type\n");
241  break;
242  }
243 
244  return FALSE;
245 }
246 
247 
248 /*
249  * FUNCTION: Returns wether Address1 is less than Address2
250  * ARGUMENTS:
251  * Address1 = Pointer to first address
252  * Address2 = Pointer to last address
253  * RETURNS:
254  * -1 if Address1 < Address2, 1 if Address1 > Address2,
255  * or 0 if they are equal
256  */
258  PIP_ADDRESS Address1,
259  PIP_ADDRESS Address2)
260 {
261  switch (Address1->Type) {
262  case IP_ADDRESS_V4: {
263  ULONG Addr1, Addr2;
264  if (Address2->Type == IP_ADDRESS_V4) {
265  Addr1 = DN2H(Address1->Address.IPv4Address);
266  Addr2 = DN2H(Address2->Address.IPv4Address);
267  if (Addr1 < Addr2)
268  return -1;
269  else
270  if (Addr1 == Addr2)
271  return 0;
272  else
273  return 1;
274  } else
275  /* FIXME: Support IPv6 */
276  return -1;
277 
278  case IP_ADDRESS_V6:
279  /* FIXME: Support IPv6 */
280  break;
281  }
282  }
283 
284  return FALSE;
285 }
286 
287 
288 /*
289  * FUNCTION: Returns wether two addresses are equal with IPv4 as input
290  * ARGUMENTS:
291  * Address1 = Pointer to first address
292  * Address2 = Pointer to last address
293  * RETURNS:
294  * TRUE if Address1 = Address2, FALSE if not
295  */
297  PIP_ADDRESS Address1,
298  IPv4_RAW_ADDRESS Address2)
299 {
300  if (Address1->Type == IP_ADDRESS_V4)
301  return (Address1->Address.IPv4Address == Address2);
302 
303  return FALSE;
304 }
305 
306 
307 unsigned long NTAPI inet_addr(const char *AddrString)
308 /*
309  * Convert an ansi string dotted-quad address to a ulong
310  * NOTES:
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()
314  */
315 {
316  ULONG Octets[4] = {0,0,0,0};
317  ULONG i = 0;
318 
319  if(!AddrString)
320  return -1;
321 
322  while(*AddrString)
323  {
324  CHAR c = *AddrString;
325  AddrString++;
326 
327  if(c == '.')
328  {
329  i++;
330  continue;
331  }
332 
333  if(c < '0' || c > '9')
334  return -1;
335 
336  Octets[i] *= 10;
337  Octets[i] += (c - '0');
338 
339  if(Octets[i] > 255)
340  return -1;
341  }
342 
343  return (Octets[3] << 24) + (Octets[2] << 16) + (Octets[1] << 8) + Octets[0];
344 }
345 
346 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
#define TI_DbgPrint(_t_, _x_)
Definition: debug.h:45
ULONG IPv4NToHl(ULONG Address)
Definition: address.c:56
CPPORT Port[4]
Definition: headless.c:34
IPv4_RAW_ADDRESS IPv4Address
Definition: ip.h:26
ULONG IPv4_RAW_ADDRESS
Definition: ip.h:15
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1631
#define MID_TRACE
Definition: debug.h:15
int sprintf(char *out, const char *fmt,...)
Definition: utprint.c:762
#define BitTest
Definition: interlocked.h:7
UCHAR Address[1]
Definition: tdi.h:340
NTSTATUS AddrBuildAddress(PTRANSPORT_ADDRESS TaAddress, PIP_ADDRESS Address, PUSHORT Port)
Definition: address.c:184
INT AddrCompare(PIP_ADDRESS Address1, PIP_ADDRESS Address2)
Definition: address.c:257
#define DbgPrint
Definition: loader.c:25
#define DEBUG_DATALINK
Definition: debug.h:24
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
int32_t INT
Definition: typedefs.h:56
Definition: ip.h:23
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define IP_ADDRESS_V4
Definition: ip.h:32
int ip[4]
Definition: rtl.c:1176
unsigned char BOOLEAN
VOID AddrWidenAddress(PIP_ADDRESS Network, PIP_ADDRESS Source, PIP_ADDRESS Netmask)
Definition: address.c:86
static WCHAR Address[46]
Definition: ping.c:68
UINT AddrCountPrefixBits(PIP_ADDRESS Netmask)
Definition: address.c:64
#define IP_ADDRESS_V6
Definition: ip.h:33
unsigned long NTAPI inet_addr(const char *AddrString)
Definition: address.c:307
BOOLEAN AddrIsEqual(PIP_ADDRESS Address1, PIP_ADDRESS Address2)
Definition: address.c:221
#define IP_ADDRESS_TAG
Definition: tags.h:18
Definition: dhcpd.h:61
struct _TDI_ADDRESS_IP * PTDI_ADDRESS_IP
#define AddrInitIPv4(IPAddress, RawAddress)
Definition: address.h:16
NTSTATUS AddrGetAddress(PTRANSPORT_ADDRESS AddrList, PIP_ADDRESS Address, PUSHORT Port)
Definition: address.c:146
const GLubyte * c
Definition: glext.h:8905
static FILE * out
Definition: regtests2xml.c:44
ULONG in_addr
Definition: tdi.h:409
LONG TAAddressCount
Definition: tdi.h:376
static IUnknown Object
Definition: main.c:512
VOID IPAddressFree(PVOID Object)
Definition: address.c:99
#define TDI_ADDRESS_TYPE_IP
Definition: tdi.h:345
USHORT AddressType
Definition: tdi.h:339
USHORT sin_port
Definition: tdi.h:408
TA_ADDRESS Address[1]
Definition: tdi.h:377
UCHAR Type
Definition: ip.h:24
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:543
#define DN2H(dw)
Definition: addrconv.c:21
unsigned int UINT
Definition: ndis.h:50
USHORT IPv6_RAW_ADDRESS[8]
Definition: ip.h:19
USHORT AddressLength
Definition: tdi.h:338
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
BOOLEAN AddrIsUnspecified(PIP_ADDRESS Address)
Definition: address.c:113
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
BOOLEAN AddrIsEqualIPv4(PIP_ADDRESS Address1, IPv4_RAW_ADDRESS Address2)
Definition: address.c:296
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define TDI_ADDRESS_LENGTH_IP
Definition: tdi.h:413
GLfloat GLfloat p
Definition: glext.h:8902
return STATUS_SUCCESS
Definition: btrfs.c:2938
Definition: dsound.c:943
union IP_ADDRESS::@990 Address
unsigned short * PUSHORT
Definition: retypes.h:2
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
PCHAR A2S(PIP_ADDRESS Address)
Definition: address.c:17
CHAR A2SStr[128]
Definition: address.c:15