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.

295 lines
6.6 KiB

  1. /*++
  2. Copyright (c) 1998, Microsoft Corporation
  3. Module Name:
  4. natarp.c
  5. Abstract:
  6. This module contains code for the NAT's user-mode proxy-ARP entry
  7. management. Proxy-ARP entries are installed on dedicated interfaces
  8. which have address-translation enabled.
  9. Author:
  10. Abolade Gbadegesin (aboladeg) 20-Mar-1998
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. //
  16. // FORWARD DECLARATIONS
  17. //
  18. VOID
  19. NatpCreateProxyArpCallback(
  20. ULONG Address,
  21. ULONG Mask,
  22. PVOID Context
  23. );
  24. VOID
  25. NatpDeleteProxyArpCallback(
  26. ULONG Address,
  27. ULONG Mask,
  28. PVOID Context
  29. );
  30. VOID
  31. NatpCreateProxyArpCallback(
  32. ULONG Address,
  33. ULONG Mask,
  34. PVOID Context
  35. )
  36. /*++
  37. Routine Description:
  38. This routine is invoked to remove a proxy-ARP entry.
  39. Arguments:
  40. Address - the address to remove
  41. Mask - the mask associated with 'Address'
  42. Context - context-field holding the entry's interface
  43. Return Value:
  44. none.
  45. --*/
  46. {
  47. ULONG Error;
  48. DEFINE_MIB_BUFFER(Info, MIB_PROXYARP, Entry);
  49. PROFILE("NatpCreateProxyArpCallback");
  50. //
  51. // Install an entry for the range, unless the host-portion is 1 bit wide,
  52. // in which case the range consists only of an all-zeroes and all-ones host.
  53. // The stack will refuse to answer ARP queries for either one,
  54. // so adding such a range would be a waste.
  55. //
  56. Info->dwId = PROXY_ARP;
  57. if (~Mask != 1) {
  58. Entry->dwAddress = (Address & Mask);
  59. Entry->dwMask = Mask;
  60. Entry->dwIfIndex = ((PNAT_INTERFACE)Context)->Index;
  61. Error =
  62. NatSupportFunctions.MIBEntryCreate(
  63. IPRTRMGR_PID,
  64. MIB_INFO_SIZE(MIB_PROXYARP),
  65. Info
  66. );
  67. if (Error) {
  68. CHAR MaskString[16];
  69. lstrcpyA(MaskString, INET_NTOA(Mask));
  70. NhTrace(
  71. TRACE_FLAG_NAT,
  72. "NatpCreateProxyArpCallback: error %d adding %s/%s",
  73. Error, INET_NTOA(Address), MaskString
  74. );
  75. NhInformationLog(
  76. IP_NAT_LOG_UPDATE_ARP_FAILED,
  77. Error,
  78. "%I%I",
  79. Address,
  80. Mask
  81. );
  82. }
  83. }
  84. //
  85. // If the mask is not all-ones, also install entries for the all-zeroes
  86. // and all-ones host-portions of the range; otherwise IP will refuse
  87. // to answer ARP queries for these.
  88. //
  89. if (~Mask) {
  90. Entry->dwAddress = (Address & Mask);
  91. Entry->dwMask = 0xffffffff;
  92. Entry->dwIfIndex = ((PNAT_INTERFACE)Context)->Index;
  93. NatSupportFunctions.MIBEntryCreate(
  94. IPRTRMGR_PID,
  95. MIB_INFO_SIZE(MIB_PROXYARP),
  96. Info
  97. );
  98. Entry->dwAddress = (Address | ~Mask);
  99. Entry->dwMask = 0xffffffff;
  100. Entry->dwIfIndex = ((PNAT_INTERFACE)Context)->Index;
  101. NatSupportFunctions.MIBEntryCreate(
  102. IPRTRMGR_PID,
  103. MIB_INFO_SIZE(MIB_PROXYARP),
  104. Info
  105. );
  106. }
  107. } // NatpCreateProxyArpCallback
  108. VOID
  109. NatpDeleteProxyArpCallback(
  110. ULONG Address,
  111. ULONG Mask,
  112. PVOID Context
  113. )
  114. /*++
  115. Routine Description:
  116. This routine is invoked to remove a proxy-ARP entry.
  117. Arguments:
  118. Address - the address to remove
  119. Mask - the mask associated with 'Address'
  120. Context - context-field holding the entry's interface
  121. Return Value:
  122. none.
  123. --*/
  124. {
  125. BYTE Buffer[FIELD_OFFSET(MIB_OPAQUE_QUERY, rgdwVarIndex) + 3*sizeof(DWORD)];
  126. ULONG Error;
  127. PMIB_OPAQUE_QUERY Query = (PMIB_OPAQUE_QUERY)Buffer;
  128. PROFILE("NatpDeleteProxyArpCallback");
  129. Query->dwVarId = PROXY_ARP;
  130. Query->rgdwVarIndex[0] = (Address & Mask);
  131. Query->rgdwVarIndex[1] = Mask;
  132. Query->rgdwVarIndex[2] = ((PNAT_INTERFACE)Context)->Index;
  133. Error =
  134. NatSupportFunctions.MIBEntryDelete(
  135. IPRTRMGR_PID,
  136. MIB_INFO_SIZE(MIB_PROXYARP),
  137. Buffer
  138. );
  139. if (Error) {
  140. CHAR MaskString[16];
  141. lstrcpyA(MaskString, INET_NTOA(Mask));
  142. NhTrace(
  143. TRACE_FLAG_NAT,
  144. "NatpDeleteProxyArpCallback: error %d deleting %s/%s",
  145. Error, INET_NTOA(Address), MaskString
  146. );
  147. NhInformationLog(
  148. IP_NAT_LOG_UPDATE_ARP_FAILED,
  149. Error,
  150. "%I%I",
  151. Address,
  152. Mask
  153. );
  154. }
  155. //
  156. // If the mask is not all-ones, also remove the entries for the all-zeroes
  157. // and all-ones host-portions of the range.
  158. //
  159. if (~Mask) {
  160. Query->rgdwVarIndex[0] = (Address & Mask);
  161. Query->rgdwVarIndex[1] = 0xffffffff;
  162. Query->rgdwVarIndex[2] = ((PNAT_INTERFACE)Context)->Index;
  163. NatSupportFunctions.MIBEntryDelete(
  164. IPRTRMGR_PID,
  165. MIB_INFO_SIZE(MIB_PROXYARP),
  166. Buffer
  167. );
  168. Query->rgdwVarIndex[0] = (Address | ~Mask);
  169. Query->rgdwVarIndex[1] = 0xffffffff;
  170. Query->rgdwVarIndex[2] = ((PNAT_INTERFACE)Context)->Index;
  171. NatSupportFunctions.MIBEntryDelete(
  172. IPRTRMGR_PID,
  173. MIB_INFO_SIZE(MIB_PROXYARP),
  174. Buffer
  175. );
  176. }
  177. } // NatpDeleteProxyArpCallback
  178. VOID
  179. NatUpdateProxyArp(
  180. PNAT_INTERFACE Interfacep,
  181. BOOLEAN CreateEntries
  182. )
  183. /*++
  184. Routine Description:
  185. This routine is invoked to install or remove the proxy-ARP entries
  186. corresponding to the address-ranges configured on the given interface.
  187. Arguments:
  188. Interfacep - the interface on which to operate
  189. CreateEntries - TRUE to install entries, FALSE to remove
  190. Return Value:
  191. none.
  192. Environment:
  193. Invoked with the interface list locked by the caller.
  194. --*/
  195. {
  196. ULONG Count;
  197. ULONG Error;
  198. ULONG i;
  199. PIP_NAT_ADDRESS_RANGE Range;
  200. PROFILE("NatUpdateProxyArp");
  201. if (!Interfacep->Info ||
  202. !NatSupportFunctions.MIBEntryCreate ||
  203. !NatSupportFunctions.MIBEntryDelete
  204. ) {
  205. return;
  206. }
  207. //
  208. // Locate the address-ranges, if any
  209. //
  210. Error =
  211. MprInfoBlockFind(
  212. &Interfacep->Info->Header,
  213. IP_NAT_ADDRESS_RANGE_TYPE,
  214. NULL,
  215. &Count,
  216. (PUCHAR*)&Range
  217. );
  218. if (Error || NULL == Range) { return; }
  219. //
  220. // Now go through the ranges, decomposing each one
  221. //
  222. for (i = 0; i < Count; i++) {
  223. DecomposeRange(
  224. Range[i].StartAddress,
  225. Range[i].EndAddress,
  226. MostGeneralMask(Range[i].StartAddress, Range[i].EndAddress),
  227. CreateEntries
  228. ? NatpCreateProxyArpCallback : NatpDeleteProxyArpCallback,
  229. Interfacep
  230. );
  231. }
  232. } // NatUpdateProxyArp