Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
5.9 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // inet.c
  8. //
  9. // SYNOPSIS
  10. //
  11. // Implements the functions ias_inet_addr and ias_inet_ntoa.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 09/17/1997 Original version.
  16. // 02/04/1998 Added ias_inet_htow.
  17. // 02/25/1998 Rewritten to use TCHAR macros.
  18. //
  19. ///////////////////////////////////////////////////////////////////////////////
  20. #include <tchar.h>
  21. //////////
  22. // Sentinel to indicate an invalid address.
  23. //////////
  24. #define INVALID_ADDRESS (0xFFFFFFFF)
  25. //////////
  26. // Macro to test if a character is a digit.
  27. //////////
  28. #define isdigit(p) ((_TUCHAR)(p - _T('0')) <= 9)
  29. //////////
  30. // Macro to strip whitespace characters
  31. //////////
  32. #define STRIP_WHITESPACE(p) \
  33. (p) += _tcsspn((p), _T(" \t"))
  34. //////////
  35. // Macro to strip one byte of an IP address from a character string.
  36. // 'p' pointer to the string to be parsed
  37. // 'ul' unsigned long that will receive the result.
  38. //////////
  39. #define STRIP_BYTE(p,ul) { \
  40. if (!isdigit(*p)) goto error; \
  41. ul = *p++ - _T('0'); \
  42. if (isdigit(*p)) { \
  43. ul *= 10; ul += *p++ - _T('0'); \
  44. if (isdigit(*p)) { \
  45. ul *= 10; ul += *p++ - _T('0'); \
  46. } \
  47. } \
  48. if (ul > 0xff) goto error; \
  49. }
  50. //////////
  51. // Macro to strip a subnet width.
  52. // 'p' pointer to the string to be parsed
  53. // 'ul' unsigned long that will receive the result.
  54. //////////
  55. #define STRIP_WIDTH(p,ul) { \
  56. if (!isdigit(*p)) goto error; \
  57. ul = *p++ - _T('0'); \
  58. if (isdigit(*p)) { \
  59. ul *= 10; ul += *p++ - _T('0'); \
  60. } \
  61. if (ul > 32) goto error; \
  62. }
  63. //////////
  64. // Helper function to parse a dotted decimal address.
  65. //////////
  66. static unsigned long __stdcall StringToAddress(
  67. const _TCHAR* cp,
  68. const _TCHAR** endptr
  69. )
  70. {
  71. unsigned long token;
  72. unsigned long addr;
  73. STRIP_WHITESPACE(cp);
  74. STRIP_BYTE(cp,addr);
  75. if (*cp++ != _T('.')) goto error;
  76. STRIP_BYTE(cp,token);
  77. if (*cp++ != _T('.')) goto error;
  78. addr <<= 8;
  79. addr |= token;
  80. STRIP_BYTE(cp,token);
  81. if (*cp++ != _T('.')) goto error;
  82. addr <<= 8;
  83. addr |= token;
  84. STRIP_BYTE(cp,token);
  85. addr <<= 8;
  86. addr |= token;
  87. if (endptr) { *endptr = cp; }
  88. return addr;
  89. error:
  90. if (endptr) { *endptr = cp; }
  91. return INVALID_ADDRESS;
  92. }
  93. ///////////////////////////////////////////////////////////////////////////////
  94. //
  95. // FUNCTION
  96. //
  97. // ias_inet_addr
  98. //
  99. // DESCRIPTION
  100. //
  101. // This function is similar to the WinSock inet_addr function (q.v.) except
  102. // it returns the address in host order and it can operate on both ANSI
  103. // and UNICODE strings.
  104. //
  105. ///////////////////////////////////////////////////////////////////////////////
  106. unsigned long __stdcall ias_inet_addr(const _TCHAR* cp)
  107. {
  108. unsigned long address;
  109. const _TCHAR* end;
  110. address = StringToAddress(cp, &end);
  111. STRIP_WHITESPACE(end);
  112. return (*end == _T('\0')) ? address : INVALID_ADDRESS;
  113. }
  114. ///////////////////////////////////////////////////////////////////////////////
  115. //
  116. // FUNCTION
  117. //
  118. // IASStringToSubNet
  119. //
  120. // DESCRIPTION
  121. //
  122. // Similar to ias_inet_addr except it also parses an optional subnet width.
  123. //
  124. ///////////////////////////////////////////////////////////////////////////////
  125. unsigned long __stdcall IASStringToSubNet(
  126. const _TCHAR* cp,
  127. unsigned long* widthptr
  128. )
  129. {
  130. unsigned long address, width;
  131. const _TCHAR* end;
  132. address = StringToAddress(cp, &end);
  133. if (*end == _T('/'))
  134. {
  135. ++end;
  136. STRIP_WIDTH(end,width);
  137. }
  138. else
  139. {
  140. width = 32;
  141. }
  142. STRIP_WHITESPACE(end);
  143. if (*end != _T('\0'))
  144. {
  145. goto error;
  146. }
  147. if (widthptr) { *widthptr = width; }
  148. return address;
  149. error:
  150. return INVALID_ADDRESS;
  151. }
  152. int __stdcall IASIsStringSubNet(
  153. const _TCHAR* cp
  154. )
  155. {
  156. unsigned long width;
  157. return (IASStringToSubNet(cp, &width) != INVALID_ADDRESS) && (width != 32);
  158. }
  159. //////////
  160. // Macro to shove one byte of an IP address into a character string.
  161. // 'p' pointer to the destination string.
  162. // 'ul' value to be shoved.
  163. //////////
  164. #define SHOVE_BYTE(p, ul) { \
  165. *--p = _T('0') + (_TCHAR)(ul % 10); \
  166. if (ul /= 10) { \
  167. *--p = _T('0') + (_TCHAR)(ul % 10); \
  168. if (ul /= 10) { \
  169. *--p = _T('0') + (_TCHAR)(ul % 10); \
  170. } \
  171. } \
  172. }
  173. ///////////////////////////////////////////////////////////////////////////////
  174. //
  175. // FUNCTION
  176. //
  177. // ias_inet_ntoa
  178. //
  179. // DESCRIPTION
  180. //
  181. // This function uses the supplied buffer to convert a host order IPv4
  182. // network address to dotted-decimal format.
  183. //
  184. ///////////////////////////////////////////////////////////////////////////////
  185. _TCHAR* __stdcall ias_inet_ntoa(unsigned long addr, _TCHAR* dst)
  186. {
  187. unsigned long token;
  188. _TCHAR buffer[16], *p;
  189. *(p = buffer + 15) = _T('\0');
  190. token = (addr ) & 0xff;
  191. SHOVE_BYTE(p, token);
  192. *--p = _T('.');
  193. token = (addr >> 8) & 0xff;
  194. SHOVE_BYTE(p, token);
  195. *--p = _T('.');
  196. token = (addr >> 16) & 0xff;
  197. SHOVE_BYTE(p, token);
  198. *--p = _T('.');
  199. token = (addr >> 24) & 0xff;
  200. SHOVE_BYTE(p, token);
  201. return _tcscpy(dst, p);
  202. }