Source code of Windows XP (NT5)
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.

233 lines
5.8 KiB

  1. /*++
  2. Copyright(c) 1998,99 Microsoft Corporation
  3. Module Name:
  4. tcpip.c
  5. Abstract:
  6. Windows Load Balancing Service (WLBS)
  7. Driver - IP/TCP/UDP support
  8. Author:
  9. kyrilf
  10. --*/
  11. #include <ndis.h>
  12. #include "wlbsip.h"
  13. #include "univ.h"
  14. #include "wlbsparm.h"
  15. #include "params.h"
  16. #include "log.h"
  17. /* GLOBALS */
  18. static ULONG log_module_id = LOG_MODULE_TCPIP;
  19. /* constant encoded shadow computer name that will replace our cluster name */
  20. static UCHAR nbt_encoded_shadow_name [NBT_ENCODED_NAME_LEN] =
  21. NBT_ENCODED_NAME_SHADOW;
  22. /* PROCEDURES */
  23. BOOLEAN Tcpip_init (
  24. PTCPIP_CTXT ctxtp,
  25. PVOID parameters)
  26. {
  27. ULONG i, j;
  28. PCVY_PARAMS params = (PCVY_PARAMS) parameters;
  29. /* extract cluster computer name from full internet name */
  30. j = 0;
  31. while (params -> domain_name [j] != 0)
  32. {
  33. if (params -> domain_name [j] == L'.' ||
  34. params -> domain_name [j] == 0)
  35. break;
  36. j ++;
  37. }
  38. /* build encoded cluster computer name for checking against arriving NBT
  39. session requests */
  40. for (i = 0; i < NBT_NAME_LEN; i ++)
  41. {
  42. if (i >= j)
  43. {
  44. ctxtp -> nbt_encoded_cluster_name [2 * i] =
  45. NBT_ENCODE_FIRST (' ');
  46. ctxtp -> nbt_encoded_cluster_name [2 * i + 1] =
  47. NBT_ENCODE_SECOND (' ');
  48. }
  49. else
  50. {
  51. ctxtp -> nbt_encoded_cluster_name [2 * i] =
  52. NBT_ENCODE_FIRST (toupper ((UCHAR) (params -> domain_name [i])));
  53. ctxtp -> nbt_encoded_cluster_name [2 * i + 1] =
  54. NBT_ENCODE_SECOND (toupper ((UCHAR) (params -> domain_name [i])));
  55. }
  56. }
  57. return TRUE;
  58. } /* Tcpip_init */
  59. VOID Tcpip_nbt_handle (
  60. PTCPIP_CTXT ctxtp,
  61. PIP_HDR ip_hdrp,
  62. PTCP_HDR tcp_hdrp,
  63. ULONG len,
  64. PNBT_HDR nbt_hdrp)
  65. {
  66. PUCHAR called_name;
  67. ULONG i;
  68. /* if this is an NBT session request packet, check to see if it's calling
  69. the cluster machine name, which should be replaced with the shadow name */
  70. if (len >= sizeof (NBT_HDR) &&
  71. NBT_GET_PKT_TYPE (nbt_hdrp) == NBT_SESSION_REQUEST)
  72. {
  73. /* pass the field length byte - assume all names are
  74. NBT_ENCODED_NAME_LEN bytes long */
  75. called_name = NBT_GET_CALLED_NAME (nbt_hdrp) + 1;
  76. /* match called name to cluster name */
  77. for (i = 0; i < NBT_ENCODED_NAME_LEN; i ++)
  78. {
  79. if (called_name [i] != ctxtp -> nbt_encoded_cluster_name [i])
  80. break;
  81. }
  82. /* replace cluster computer name with the shadom name */
  83. if (i >= NBT_ENCODED_NAME_LEN)
  84. {
  85. USHORT checksum;
  86. for (i = 0; i < NBT_ENCODED_NAME_LEN; i ++)
  87. called_name [i] = nbt_encoded_shadow_name [i];
  88. /* re-compute checksum */
  89. checksum = Tcpip_chksum (ctxtp, ip_hdrp, (PUCHAR) tcp_hdrp,
  90. TCPIP_PROTOCOL_TCP);
  91. TCP_SET_CHKSUM (tcp_hdrp, checksum);
  92. }
  93. }
  94. } /* end Tcpip_nbt_handle */
  95. USHORT Tcpip_chksum (
  96. PTCPIP_CTXT ctxtp,
  97. PIP_HDR ip_hdrp,
  98. PUCHAR prot_hdrp,
  99. ULONG prot)
  100. {
  101. ULONG checksum = 0, i, len;
  102. PUCHAR ptr;
  103. USHORT original, tmp;
  104. /* preserve original checksum */
  105. if (prot == TCPIP_PROTOCOL_TCP)
  106. {
  107. original = TCP_GET_CHKSUM ((PTCP_HDR) prot_hdrp);
  108. TCP_SET_CHKSUM ((PTCP_HDR) prot_hdrp, 0);
  109. }
  110. else if (prot == TCPIP_PROTOCOL_UDP)
  111. {
  112. original = UDP_GET_CHKSUM ((PUDP_HDR) prot_hdrp);
  113. UDP_SET_CHKSUM ((PUDP_HDR) prot_hdrp, 0);
  114. }
  115. else
  116. {
  117. original = IP_GET_CHKSUM (ip_hdrp);
  118. IP_SET_CHKSUM (ip_hdrp, 0);
  119. }
  120. /* computer appropriate checksum for specified protocol */
  121. if (prot != TCPIP_PROTOCOL_IP)
  122. {
  123. /* checksum in computed over the source IP address, destination IP address,
  124. protocol (6 for TCP), TCP segment length value and entire TCP segment
  125. (setting checksum field within TCP header to 0). code is taken from
  126. page 185 of "Internetworking with TCP/IP: Volume II" by
  127. Comer/Stevens, 1991 */
  128. ptr = (PUCHAR) IP_GET_SRC_ADDR_PTR (ip_hdrp);
  129. /* 2*IP_ADDR_LEN bytes = IP_ADDR_LEN shorts */
  130. for (i = 0; i < IP_ADDR_LEN; i ++, ptr += 2)
  131. checksum += (ULONG) ((ptr [0] << 8) | ptr [1]);
  132. }
  133. if (prot == TCPIP_PROTOCOL_TCP)
  134. {
  135. len = IP_GET_PLEN (ip_hdrp) - IP_GET_HLEN (ip_hdrp) * sizeof (ULONG);
  136. checksum += TCPIP_PROTOCOL_TCP + len;
  137. ptr = prot_hdrp;
  138. }
  139. else if (prot == TCPIP_PROTOCOL_UDP)
  140. {
  141. len = IP_GET_PLEN (ip_hdrp) - IP_GET_HLEN (ip_hdrp) * sizeof (ULONG);
  142. checksum += TCPIP_PROTOCOL_UDP + UDP_GET_LEN ((PUDP_HDR) prot_hdrp);
  143. ptr = prot_hdrp;
  144. }
  145. else
  146. {
  147. len = IP_GET_HLEN (ip_hdrp) * sizeof (ULONG);
  148. ptr = (PUCHAR) ip_hdrp;
  149. prot_hdrp = (PUCHAR) ip_hdrp;
  150. }
  151. for (i = 0; i < len / 2; i ++, ptr += 2)
  152. checksum += (ULONG) ((ptr [0] << 8) | ptr [1]);
  153. if (len % 2)
  154. checksum += (ULONG) (prot_hdrp [len - 1] << 8);
  155. checksum = (checksum >> 16) + (checksum & 0xffff);
  156. checksum += (checksum >> 16);
  157. /* restore original checksum */
  158. if (prot == TCPIP_PROTOCOL_TCP)
  159. {
  160. TCP_SET_CHKSUM ((PTCP_HDR) prot_hdrp, original);
  161. }
  162. else if (prot == TCPIP_PROTOCOL_UDP)
  163. {
  164. UDP_SET_CHKSUM ((PUDP_HDR) prot_hdrp, original);
  165. }
  166. else
  167. {
  168. IP_SET_CHKSUM (ip_hdrp, original);
  169. }
  170. return (USHORT) (~checksum & 0xffff);
  171. } /* end Tcpip_chksum */