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.

452 lines
8.3 KiB

  1. #include"precomp.h"
  2. DWORD
  3. VerifyAddresses(
  4. ADDR Addr,
  5. BOOL bAcceptMe,
  6. BOOL bIsDesAddr
  7. )
  8. {
  9. DWORD dwError = 0;
  10. BOOL bIsValid = FALSE;
  11. switch (Addr.AddrType) {
  12. case IP_ADDR_UNIQUE:
  13. bIsValid = bIsValidIPAddress(
  14. ntohl(Addr.uIpAddr),
  15. bAcceptMe,
  16. bIsDesAddr
  17. );
  18. if (!bIsValid) {
  19. dwError = ERROR_INVALID_PARAMETER;
  20. BAIL_ON_WIN32_ERROR(dwError);
  21. }
  22. break;
  23. case IP_ADDR_SUBNET:
  24. dwError = VerifySubNetAddress(
  25. ntohl(Addr.uIpAddr),
  26. ntohl(Addr.uSubNetMask),
  27. bIsDesAddr
  28. );
  29. BAIL_ON_WIN32_ERROR(dwError);
  30. break;
  31. case IP_ADDR_INTERFACE:
  32. if (Addr.uIpAddr) {
  33. dwError = ERROR_INVALID_PARAMETER;
  34. BAIL_ON_WIN32_ERROR(dwError);
  35. }
  36. break;
  37. default:
  38. dwError = ERROR_INVALID_PARAMETER;
  39. BAIL_ON_WIN32_ERROR(dwError);
  40. break;
  41. }
  42. error:
  43. return (dwError);
  44. }
  45. BOOL
  46. EqualAddresses(
  47. IN ADDR OldAddr,
  48. IN ADDR NewAddr
  49. )
  50. {
  51. BOOL bMatches = FALSE;
  52. if (OldAddr.AddrType == NewAddr.AddrType) {
  53. switch(OldAddr.AddrType) {
  54. case IP_ADDR_UNIQUE:
  55. if (OldAddr.uIpAddr == NewAddr.uIpAddr) {
  56. bMatches = TRUE;
  57. }
  58. break;
  59. case IP_ADDR_SUBNET:
  60. if ((OldAddr.uIpAddr == NewAddr.uIpAddr) &&
  61. (OldAddr.uSubNetMask == NewAddr.uSubNetMask)) {
  62. bMatches = TRUE;
  63. }
  64. break;
  65. case IP_ADDR_INTERFACE:
  66. if (!memcmp(
  67. &OldAddr.gInterfaceID,
  68. &NewAddr.gInterfaceID,
  69. sizeof(GUID)) &&
  70. (OldAddr.uIpAddr == NewAddr.uIpAddr)) {
  71. bMatches = TRUE;
  72. }
  73. break;
  74. }
  75. }
  76. return (bMatches);
  77. }
  78. VOID
  79. CopyAddresses(
  80. IN ADDR InAddr,
  81. OUT PADDR pOutAddr
  82. )
  83. {
  84. pOutAddr->AddrType = InAddr.AddrType;
  85. switch (InAddr.AddrType) {
  86. case IP_ADDR_UNIQUE:
  87. pOutAddr->uIpAddr = InAddr.uIpAddr;
  88. pOutAddr->uSubNetMask = IP_ADDRESS_MASK_NONE;
  89. memset(&pOutAddr->gInterfaceID, 0, sizeof(GUID));
  90. break;
  91. case IP_ADDR_SUBNET:
  92. pOutAddr->uIpAddr = InAddr.uIpAddr;
  93. pOutAddr->uSubNetMask = InAddr.uSubNetMask;
  94. memset(&pOutAddr->gInterfaceID, 0, sizeof(GUID));
  95. break;
  96. case IP_ADDR_INTERFACE:
  97. pOutAddr->uIpAddr = InAddr.uIpAddr;
  98. pOutAddr->uSubNetMask = IP_ADDRESS_MASK_NONE;
  99. memcpy(
  100. &pOutAddr->gInterfaceID,
  101. &InAddr.gInterfaceID,
  102. sizeof(GUID)
  103. );
  104. break;
  105. }
  106. }
  107. BOOL
  108. AddressesConflict(
  109. ADDR SrcAddr,
  110. ADDR DesAddr
  111. )
  112. {
  113. if ((SrcAddr.AddrType == IP_ADDR_UNIQUE) &&
  114. (DesAddr.AddrType == IP_ADDR_UNIQUE)) {
  115. if (SrcAddr.uIpAddr == DesAddr.uIpAddr) {
  116. return (TRUE);
  117. }
  118. }
  119. if ((SrcAddr.AddrType == IP_ADDR_INTERFACE) &&
  120. (DesAddr.AddrType == IP_ADDR_INTERFACE)) {
  121. return (TRUE);
  122. }
  123. return (FALSE);
  124. }
  125. VOID
  126. FreeAddresses(
  127. ADDR Addr
  128. )
  129. {
  130. switch (Addr.AddrType) {
  131. case (IP_ADDR_UNIQUE):
  132. case (IP_ADDR_SUBNET):
  133. case (IP_ADDR_INTERFACE):
  134. break;
  135. }
  136. }
  137. DWORD
  138. VerifySubNetAddress(
  139. ULONG uSubNetAddr,
  140. ULONG uSubNetMask,
  141. BOOL bIsDesAddr
  142. )
  143. {
  144. DWORD dwError = 0;
  145. BOOL bIsValid = FALSE;
  146. if (uSubNetAddr == SUBNET_ADDRESS_ANY) {
  147. if (uSubNetMask != SUBNET_MASK_ANY) {
  148. dwError = ERROR_INVALID_PARAMETER;
  149. BAIL_ON_WIN32_ERROR(dwError);
  150. }
  151. }
  152. else {
  153. bIsValid = bIsValidSubnet(
  154. uSubNetAddr,
  155. uSubNetMask,
  156. bIsDesAddr
  157. );
  158. if (!bIsValid) {
  159. dwError = ERROR_INVALID_PARAMETER;
  160. BAIL_ON_WIN32_ERROR(dwError);
  161. }
  162. }
  163. error:
  164. return (dwError);
  165. }
  166. BOOL
  167. bIsValidIPMask(
  168. ULONG uMask
  169. )
  170. {
  171. BOOL bValidMask = FALSE;
  172. ULONG uTestMask = 0;
  173. //
  174. // Mask must be contiguous bits.
  175. //
  176. for (uTestMask = 0xFFFFFFFF; uTestMask; uTestMask <<= 1) {
  177. if (uTestMask == uMask) {
  178. bValidMask = TRUE;
  179. break;
  180. }
  181. }
  182. return (bValidMask);
  183. }
  184. BOOL
  185. bIsValidIPAddress(
  186. ULONG uIpAddr,
  187. BOOL bAcceptMe,
  188. BOOL bIsDesAddr
  189. )
  190. {
  191. ULONG uHostMask = IN_CLASSA_HOST; // Default host mask.
  192. //
  193. // Accept the address if its "me".
  194. //
  195. if (bAcceptMe) {
  196. if (uIpAddr == IP_ADDRESS_ME) {
  197. return TRUE;
  198. }
  199. }
  200. //
  201. // Reject if its a multicast address and is not the
  202. // destination address.
  203. //
  204. if (IN_CLASSD(uIpAddr)) {
  205. if (bIsDesAddr) {
  206. return TRUE;
  207. }
  208. else {
  209. return FALSE;
  210. }
  211. }
  212. //
  213. // Reject if its a Class E address.
  214. //
  215. if (IN_CLASSE(uIpAddr)) {
  216. return FALSE;
  217. }
  218. //
  219. // Reject if the first octet is zero.
  220. //
  221. if (!(IN_CLASSA_NET & uIpAddr)) {
  222. return FALSE;
  223. }
  224. //
  225. // Use default mask based on Class when none is provided.
  226. //
  227. if (IN_CLASSA(uIpAddr)) {
  228. uHostMask = IN_CLASSA_HOST;
  229. }
  230. else if (IN_CLASSB(uIpAddr)) {
  231. uHostMask = IN_CLASSB_HOST;
  232. }
  233. else if (IN_CLASSC(uIpAddr)) {
  234. uHostMask = IN_CLASSC_HOST;
  235. }
  236. //
  237. // Accept address when host portion is non-zero.
  238. //
  239. if (uHostMask & uIpAddr) {
  240. return TRUE;
  241. }
  242. return FALSE;
  243. }
  244. BOOL
  245. bIsValidSubnet(
  246. ULONG uIpAddr,
  247. ULONG uMask,
  248. BOOL bIsDesAddr
  249. )
  250. {
  251. ULONG uHostMask = 0;
  252. //
  253. // Reject if its a multicast address and is not the
  254. // destination address.
  255. //
  256. if (IN_CLASSD(uIpAddr)) {
  257. if (!bIsDesAddr) {
  258. return FALSE;
  259. }
  260. }
  261. //
  262. // Reject if its a Class E address.
  263. //
  264. if (IN_CLASSE(uIpAddr)) {
  265. return FALSE;
  266. }
  267. //
  268. // Reject if the first octet is zero.
  269. //
  270. if (!(IN_CLASSA_NET & uIpAddr)) {
  271. return FALSE;
  272. }
  273. //
  274. // If the mask is invalid then return.
  275. //
  276. if (!bIsValidIPMask(uMask)) {
  277. return FALSE;
  278. }
  279. //
  280. // Use the provided subnet mask to generate the host mask.
  281. //
  282. uHostMask = 0xFFFFFFFF ^ uMask;
  283. //
  284. // Validate the address and the mask.
  285. //
  286. if (IN_CLASSA(uIpAddr)) {
  287. if (IN_CLASSA_NET > uMask) {
  288. return FALSE;
  289. }
  290. }
  291. else if (IN_CLASSB(uIpAddr)) {
  292. if (IN_CLASSB_NET > uMask) {
  293. return FALSE;
  294. }
  295. }
  296. else if (IN_CLASSC(uIpAddr)) {
  297. if (IN_CLASSC_NET > uMask) {
  298. //
  299. // Superset of Class C Subnet Address.
  300. //
  301. return TRUE;
  302. }
  303. }
  304. //
  305. // Accept address only when the host portion is zero, network
  306. // portion is non-zero and first octet is non-zero.
  307. //
  308. if (!(uHostMask & uIpAddr) &&
  309. (uMask & uIpAddr) &&
  310. (IN_CLASSA_NET & uIpAddr)) {
  311. return TRUE;
  312. }
  313. return FALSE;
  314. }
  315. BOOL
  316. MatchAddresses(
  317. ADDR AddrToMatch,
  318. ADDR AddrTemplate
  319. )
  320. {
  321. switch (AddrTemplate.AddrType) {
  322. case IP_ADDR_UNIQUE:
  323. if ((AddrToMatch.uIpAddr & AddrToMatch.uSubNetMask) !=
  324. (AddrTemplate.uIpAddr & AddrToMatch.uSubNetMask)) {
  325. return (FALSE);
  326. }
  327. break;
  328. case IP_ADDR_SUBNET:
  329. if ((AddrToMatch.uIpAddr & AddrToMatch.uSubNetMask) !=
  330. ((AddrTemplate.uIpAddr & AddrTemplate.uSubNetMask)
  331. & AddrToMatch.uSubNetMask)) {
  332. return (FALSE);
  333. }
  334. break;
  335. case IP_ADDR_INTERFACE:
  336. if (memcmp(
  337. &AddrToMatch.gInterfaceID,
  338. &AddrTemplate.gInterfaceID,
  339. sizeof(GUID))) {
  340. return (FALSE);
  341. }
  342. break;
  343. }
  344. return (TRUE);
  345. }
  346. DWORD
  347. ApplyMulticastFilterValidation(
  348. ADDR Addr,
  349. BOOL bCreateMirror
  350. )
  351. {
  352. DWORD dwError = 0;
  353. if (((Addr.AddrType == IP_ADDR_UNIQUE) ||
  354. (Addr.AddrType == IP_ADDR_SUBNET)) &&
  355. (IN_CLASSD(ntohl(Addr.uIpAddr))) &&
  356. bCreateMirror) {
  357. dwError = ERROR_INVALID_PARAMETER;
  358. BAIL_ON_WIN32_ERROR(dwError);
  359. }
  360. error:
  361. return (dwError);
  362. }