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.

457 lines
13 KiB

  1. /*++
  2. Copyright(c) 1998,99 Microsoft Corporation
  3. Module Name:
  4. univ.c
  5. Abstract:
  6. Windows Load Balancing Service (WLBS)
  7. Driver - global variables
  8. Author:
  9. kyrilf
  10. --*/
  11. #include <stdlib.h>
  12. #include <ndis.h>
  13. #include "univ.h"
  14. #include "wlbsparm.h"
  15. #if defined (NLB_TCP_NOTIFICATION)
  16. #include <ntddnlb.h>
  17. #endif
  18. /* GLOBALS */
  19. /* The global teaming list spin lock. */
  20. NDIS_SPIN_LOCK univ_bda_teaming_lock;
  21. WCHAR empty_str [] = L"";
  22. UNIV_IOCTL_HDLR univ_ioctl_hdlr = NULL;
  23. PVOID univ_driver_ptr = NULL;
  24. NDIS_HANDLE univ_driver_handle = NULL;
  25. NDIS_HANDLE univ_wrapper_handle = NULL;
  26. NDIS_HANDLE univ_prot_handle = NULL;
  27. NDIS_HANDLE univ_ctxt_handle = NULL;
  28. NDIS_SPIN_LOCK univ_bind_lock;
  29. ULONG univ_changing_ip = 0;
  30. NDIS_HANDLE univ_device_handle = NULL;
  31. PDEVICE_OBJECT univ_device_object = NULL;
  32. ULONG univ_tcp_cleanup = TRUE;
  33. #if defined (NLB_TCP_NOTIFICATION)
  34. ULONG univ_notification = NLB_CONNECTION_CALLBACK_TCP;
  35. PCALLBACK_OBJECT univ_tcp_callback_object = NULL;
  36. PVOID univ_tcp_callback_function = NULL;
  37. PCALLBACK_OBJECT univ_alternate_callback_object = NULL;
  38. PVOID univ_alternate_callback_function = NULL;
  39. #endif
  40. NDIS_PHYSICAL_ADDRESS univ_max_addr = NDIS_PHYSICAL_ADDRESS_CONST (-1,-1);
  41. NDIS_MEDIUM univ_medium_array [UNIV_NUM_MEDIUMS] = UNIV_MEDIUMS;
  42. UNICODE_STRING DriverEntryRegistryPath;
  43. PWCHAR univ_reg_path = NULL;
  44. ULONG univ_reg_path_len = 0;
  45. NDIS_OID univ_oids [UNIV_NUM_OIDS] =
  46. { OID_GEN_SUPPORTED_LIST,
  47. OID_GEN_HARDWARE_STATUS,
  48. OID_GEN_MEDIA_SUPPORTED,
  49. OID_GEN_MEDIA_IN_USE,
  50. OID_GEN_MAXIMUM_LOOKAHEAD,
  51. OID_GEN_MAXIMUM_FRAME_SIZE,
  52. OID_GEN_LINK_SPEED,
  53. OID_GEN_TRANSMIT_BUFFER_SPACE,
  54. OID_GEN_RECEIVE_BUFFER_SPACE,
  55. OID_GEN_TRANSMIT_BLOCK_SIZE,
  56. OID_GEN_RECEIVE_BLOCK_SIZE,
  57. OID_GEN_VENDOR_ID,
  58. OID_GEN_VENDOR_DESCRIPTION,
  59. OID_GEN_CURRENT_PACKET_FILTER,
  60. OID_GEN_CURRENT_LOOKAHEAD,
  61. OID_GEN_DRIVER_VERSION,
  62. OID_GEN_MAXIMUM_TOTAL_SIZE,
  63. OID_GEN_PROTOCOL_OPTIONS,
  64. OID_GEN_MAC_OPTIONS,
  65. OID_GEN_MEDIA_CONNECT_STATUS,
  66. OID_GEN_MAXIMUM_SEND_PACKETS,
  67. OID_GEN_VENDOR_DRIVER_VERSION,
  68. OID_GEN_XMIT_OK,
  69. OID_GEN_RCV_OK,
  70. OID_GEN_XMIT_ERROR,
  71. OID_GEN_RCV_ERROR,
  72. OID_GEN_RCV_NO_BUFFER,
  73. OID_GEN_DIRECTED_BYTES_XMIT,
  74. OID_GEN_DIRECTED_FRAMES_XMIT,
  75. OID_GEN_MULTICAST_BYTES_XMIT,
  76. OID_GEN_MULTICAST_FRAMES_XMIT,
  77. OID_GEN_BROADCAST_BYTES_XMIT,
  78. OID_GEN_BROADCAST_FRAMES_XMIT,
  79. OID_GEN_DIRECTED_BYTES_RCV,
  80. OID_GEN_DIRECTED_FRAMES_RCV,
  81. OID_GEN_MULTICAST_BYTES_RCV,
  82. OID_GEN_MULTICAST_FRAMES_RCV,
  83. OID_GEN_BROADCAST_BYTES_RCV,
  84. OID_GEN_BROADCAST_FRAMES_RCV,
  85. OID_GEN_RCV_CRC_ERROR,
  86. OID_GEN_TRANSMIT_QUEUE_LENGTH,
  87. OID_802_3_PERMANENT_ADDRESS,
  88. OID_802_3_CURRENT_ADDRESS,
  89. OID_802_3_MULTICAST_LIST,
  90. OID_802_3_MAXIMUM_LIST_SIZE,
  91. OID_802_3_MAC_OPTIONS,
  92. OID_802_3_RCV_ERROR_ALIGNMENT,
  93. OID_802_3_XMIT_ONE_COLLISION,
  94. OID_802_3_XMIT_MORE_COLLISIONS,
  95. OID_802_3_XMIT_DEFERRED,
  96. OID_802_3_XMIT_MAX_COLLISIONS,
  97. OID_802_3_RCV_OVERRUN,
  98. OID_802_3_XMIT_UNDERRUN,
  99. OID_802_3_XMIT_HEARTBEAT_FAILURE,
  100. OID_802_3_XMIT_TIMES_CRS_LOST,
  101. OID_802_3_XMIT_LATE_COLLISIONS };
  102. /* PROCEDURES */
  103. VOID Univ_ndis_string_alloc (
  104. PNDIS_STRING string,
  105. PCHAR src)
  106. {
  107. PWCHAR tmp;
  108. /* allocate enough space for the string */
  109. string -> Length = strlen (src) * sizeof (WCHAR);
  110. string -> MaximumLength = string -> Length + sizeof (WCHAR);
  111. NdisAllocateMemoryWithTag (& (string -> Buffer), string -> MaximumLength,
  112. UNIV_POOL_TAG);
  113. if (string -> Buffer == NULL)
  114. {
  115. string -> Length = 0;
  116. string -> MaximumLength = 0;
  117. return;
  118. }
  119. /* copy characters */
  120. tmp = string -> Buffer;
  121. while (* src != '\0')
  122. {
  123. * tmp = (WCHAR) (* src);
  124. src ++;
  125. tmp ++;
  126. }
  127. * tmp = UNICODE_NULL;
  128. } /* end Univ_ndis_string_free */
  129. VOID Univ_ndis_string_free (
  130. PNDIS_STRING string)
  131. {
  132. if (string -> Buffer == NULL)
  133. return;
  134. /* free memory */
  135. NdisFreeMemory (string -> Buffer, string -> MaximumLength, 0);
  136. string -> Length = 0;
  137. string -> MaximumLength = 0;
  138. } /* end Univ_ndis_string_free */
  139. VOID Univ_ansi_string_alloc (
  140. PANSI_STRING string,
  141. PWCHAR src)
  142. {
  143. PCHAR tmp;
  144. PWCHAR wtmp;
  145. USHORT len;
  146. /* compute length of the string in characters */
  147. wtmp = src;
  148. len = 0;
  149. while (* wtmp != UNICODE_NULL)
  150. {
  151. len ++;
  152. wtmp ++;
  153. }
  154. /* allocate enough space for the string */
  155. string -> Length = len;
  156. string -> MaximumLength = len + sizeof (CHAR);
  157. NdisAllocateMemoryWithTag (& (string -> Buffer), string -> MaximumLength,
  158. UNIV_POOL_TAG);
  159. if (string -> Buffer == NULL)
  160. {
  161. string -> Length = 0;
  162. string -> MaximumLength = 0;
  163. return;
  164. }
  165. /* copy characters */
  166. tmp = string -> Buffer;
  167. while (* src != '\0')
  168. {
  169. * tmp = (CHAR) (* src);
  170. src ++;
  171. tmp ++;
  172. }
  173. * tmp = 0;
  174. } /* end Univ_ansi_string_free */
  175. VOID Univ_ansi_string_free (
  176. PANSI_STRING string)
  177. {
  178. if (string == NULL)
  179. return;
  180. /* free memory */
  181. NdisFreeMemory (string -> Buffer, string -> MaximumLength, 0);
  182. string -> Length = 0;
  183. string -> MaximumLength = 0;
  184. } /* end Univ_ansi_string_free */
  185. ULONG Univ_str_to_ulong (
  186. PULONG retp,
  187. PWCHAR start_ptr,
  188. PWCHAR * end_ptr,
  189. ULONG width,
  190. ULONG base)
  191. {
  192. PWCHAR ptr;
  193. WCHAR c;
  194. ULONG number = 0;
  195. ULONG val, pos = 0;
  196. /* check base */
  197. if (base != 2 && base != 8 && base != 10 && base != 16)
  198. {
  199. if (end_ptr != NULL)
  200. * end_ptr = start_ptr;
  201. return FALSE;
  202. }
  203. /* skip space */
  204. ptr = start_ptr;
  205. number = 0;
  206. while (* ptr == 0x20)
  207. ptr ++;
  208. /* extract digits and build the number */
  209. while (pos < width)
  210. {
  211. c = * ptr;
  212. if (0x30 <= c && c <= 0x39)
  213. val = c - 0x30;
  214. else if (0x41 <= c && c <= 0x46)
  215. val = c - 0x41 + 0xa;
  216. else if (0x61 <= c && c <= 0x66)
  217. val = c - 0x61 + 0xa;
  218. else
  219. break;
  220. if (val >= base)
  221. break;
  222. number = number * base + val;
  223. ptr ++;
  224. pos ++;
  225. }
  226. /* makre sure we extracted something */
  227. if (pos == 0)
  228. {
  229. ptr = start_ptr;
  230. * retp = 0;
  231. return FALSE;
  232. }
  233. /* return resulting number */
  234. if (end_ptr != NULL)
  235. * end_ptr = ptr;
  236. * retp = number;
  237. return TRUE;
  238. } /* end Univ_str_to_ulong */
  239. PWCHAR Univ_ulong_to_str (
  240. ULONG val,
  241. PWCHAR buf,
  242. ULONG base)
  243. {
  244. ULONG dig;
  245. PWCHAR p, sav;
  246. WCHAR tmp;
  247. /* check base */
  248. if (base != 2 && base != 8 && base != 10 && base != 16)
  249. {
  250. buf [0] = 0;
  251. return buf;
  252. }
  253. /* extract digits from the number and output to string */
  254. p = buf;
  255. do
  256. {
  257. /* get next digit */
  258. dig = (ULONG) (val % base);
  259. val /= base;
  260. /* convert to ascii and store */
  261. if (dig > 9)
  262. * p = (CHAR) (dig - 10 + L'a');
  263. else
  264. * p = (CHAR) (dig + L'0');
  265. p ++;
  266. }
  267. while (val > 0);
  268. * p = 0;
  269. sav = p;
  270. /* swap the characters, since operation above creates inverted string */
  271. p --;
  272. do
  273. {
  274. tmp = * p;
  275. * p = * buf;
  276. * buf = tmp;
  277. p --; buf ++;
  278. }
  279. while (buf < p); /* repeat until halfway */
  280. return sav;
  281. } /* end Univ_ulong_to_str */
  282. void Univ_ip_addr_ulong_to_str (
  283. ULONG val,
  284. PWCHAR buf)
  285. {
  286. int idx;
  287. PWCHAR str_begin, str_end, cur_str;
  288. PUCHAR ptr;
  289. WCHAR tmp;
  290. UCHAR cur_val;
  291. // Access the ip address in the dword as an array of bytes
  292. ptr = (PUCHAR)&val;
  293. cur_str = str_begin = buf;
  294. for (idx = 0 ; idx < 4 ; idx++)
  295. {
  296. // Get current byte
  297. cur_val = *ptr++;
  298. // Convert current byte to string
  299. do
  300. {
  301. *cur_str = (cur_val % 10) + L'0';
  302. cur_val /= 10;
  303. cur_str++;
  304. }
  305. while (cur_val > 0);
  306. // Swap the characters, since operation above creates inverted string.
  307. // There could atmost be three characters ("255" is the highest),
  308. // so, it is enough if we swap once. In other words, a "if" will do
  309. // in the place of a "while" in the below loop.
  310. str_end = cur_str - 1;
  311. if (str_begin < str_end)
  312. {
  313. tmp = *str_end;
  314. *str_end = *str_begin;
  315. *str_begin = tmp;
  316. }
  317. *cur_str = L'.';
  318. // Position the destination string to fill in the next byte as a string
  319. str_begin = ++cur_str;
  320. }
  321. // Overwrite the last '.' with the Null terminator
  322. *(cur_str - 1) = UNICODE_NULL;
  323. return;
  324. } /* end Univ_ip_addr_ulong_to_str */
  325. BOOL Univ_equal_unicode_string (PWSTR string1, PWSTR string2, ULONG length)
  326. {
  327. /* Loop until "length" characters have been compared. */
  328. while (length > 0) {
  329. /* If the two characters are not equal, then check to see if they only
  330. differ by case - if so, its ok, if not, the strings are not equal. */
  331. if (*string1 != *string2) {
  332. /* Convert uppercase letters to a lowercase comparison: A - Z */
  333. if ((*string1 >= 65) && (*string1 <= 90)) {
  334. if (*string2 != (*string1 + 32)) return FALSE;
  335. /* Convert lowercase letters to an uppercase comparison: a - z */
  336. } else if ((*string1 >= 97) && (*string1 <= 122)) {
  337. if (*string2 != (*string1 - 32)) return FALSE;
  338. /* If the character is not a letter, then it must match exactly - fail. */
  339. } else {
  340. return FALSE;
  341. }
  342. }
  343. /* Increment the string pointers and decrement the
  344. number of characters left to check. */
  345. string1++;
  346. string2++;
  347. length--;
  348. }
  349. /* If we got this far, the strings match. */
  350. return TRUE;
  351. }