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.

3418 lines
90 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. routing\netsh\ip\iphandle.c
  5. Abstract:
  6. Fns to get command options
  7. Revision History:
  8. Anand Mahalingam 7/10/98 Created
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. #undef EXTRA_DEBUG
  13. #define SHOW_IF_FILTER 0
  14. #define SHOW_INTERFACE 1
  15. #define SHOW_PERSISTENTROUTE 2
  16. extern ULONG g_ulNumTopCmds;
  17. extern ULONG g_ulNumGroups;
  18. extern CMD_GROUP_ENTRY g_IpCmdGroups[];
  19. extern CMD_ENTRY g_IpCmds[];
  20. DWORD
  21. PreHandleCommand(
  22. IN LPWSTR *ppwcArguments,
  23. IN DWORD dwCurrentIndex,
  24. IN DWORD dwArgCount,
  25. IN TAG_TYPE *pttTags,
  26. IN DWORD dwTagCount,
  27. IN DWORD dwMinArgs,
  28. IN DWORD dwMaxArgs,
  29. OUT DWORD *pdwTagType
  30. )
  31. {
  32. ZeroMemory(pdwTagType, sizeof(DWORD) * dwMaxArgs);
  33. return PreprocessCommand(g_hModule,
  34. ppwcArguments,
  35. dwCurrentIndex,
  36. dwArgCount,
  37. pttTags,
  38. dwTagCount,
  39. dwMinArgs,
  40. dwMaxArgs,
  41. pdwTagType);
  42. }
  43. DWORD
  44. HandleIpUpdate(
  45. IN LPCWSTR pwszMachine,
  46. IN OUT LPWSTR *ppwcArguments,
  47. IN DWORD dwCurrentIndex,
  48. IN DWORD dwArgCount,
  49. IN DWORD dwFlags,
  50. IN LPCVOID pvData,
  51. OUT BOOL *pbDone
  52. )
  53. /*++
  54. Routine Description:
  55. Updates IP autostatic routes on an interface
  56. Arguments:
  57. Return Value:
  58. NO_ERROR
  59. --*/
  60. {
  61. TAG_TYPE rgTags[] = {TOKEN_NAME, TRUE,FALSE};
  62. DWORD dwErr, dwSize, dwTagType = -1;
  63. WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN+1];
  64. if (dwArgCount != 3)
  65. {
  66. //
  67. // Need the name of the interface
  68. //
  69. return ERROR_INVALID_SYNTAX;
  70. }
  71. dwErr = MatchTagsInCmdLine(g_hModule,
  72. ppwcArguments,
  73. dwCurrentIndex,
  74. dwArgCount,
  75. rgTags,
  76. sizeof(rgTags)/sizeof(TAG_TYPE),
  77. &dwTagType);
  78. if(dwErr isnot NO_ERROR)
  79. {
  80. if(dwErr is ERROR_INVALID_OPTION_TAG)
  81. {
  82. return ERROR_INVALID_SYNTAX;
  83. }
  84. return dwErr;
  85. }
  86. if(dwTagType isnot 0)
  87. {
  88. return ERROR_INVALID_SYNTAX;
  89. }
  90. dwSize = sizeof(rgwcIfName);
  91. IpmontrGetIfNameFromFriendlyName(ppwcArguments[dwCurrentIndex],
  92. rgwcIfName,
  93. &dwSize);
  94. dwErr = UpdateAutoStaticRoutes(rgwcIfName);
  95. return dwErr;
  96. }
  97. // (almost) borrowed from netsh\if\utils.c
  98. // compares dwAddress against all valid masks (all 33 of them!) till a match
  99. BOOL ValidMask(DWORD dwAddress)
  100. {
  101. DWORD i, dwMask;
  102. dwAddress = ntohl(dwAddress); // dwAddress is in network byte order
  103. for (i=0, dwMask=0; i<33; (dwMask = ((dwMask>>1) + 0x80000000)), i++)
  104. {
  105. if (dwAddress == dwMask)
  106. return TRUE;
  107. }
  108. return FALSE;
  109. }
  110. DWORD
  111. IpAddDelIfFilter(
  112. PWCHAR *ppwcArguments,
  113. DWORD dwCurrentIndex,
  114. DWORD dwArgCount,
  115. BOOL bAdd
  116. )
  117. /*++
  118. Routine Description:
  119. Gets options for add/del interface filters
  120. Arguments:
  121. ppwcArguments - Argument array
  122. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  123. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  124. bAdd - To add or to delete
  125. Return Value:
  126. NO_ERROR
  127. --*/
  128. {
  129. FILTER_INFO fi;
  130. DWORD dwBitVector = 0, dwNumParsed = 0;
  131. DWORD dwErr = NO_ERROR,dwRes;
  132. PDWORD pdwTagType;
  133. DWORD dwNumOpt, dwStatus = (DWORD) -1;
  134. DWORD dwNumTags = 11, dwNumArg, i, j, dwFilterType;
  135. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  136. BOOL bTags = FALSE, bOkay = TRUE;
  137. TAG_TYPE pttTags[] = {{TOKEN_NAME,TRUE,FALSE},
  138. {TOKEN_FILTER_TYPE,TRUE,FALSE},
  139. {TOKEN_SOURCE_ADDRESS,TRUE,FALSE},
  140. {TOKEN_SOURCE_MASK,TRUE,FALSE},
  141. {TOKEN_DEST_ADDRESS,TRUE,FALSE},
  142. {TOKEN_DEST_MASK,TRUE,FALSE},
  143. {TOKEN_PROTOCOL,TRUE,FALSE},
  144. {TOKEN_SOURCE_PORT,TRUE,FALSE},
  145. {TOKEN_DEST_PORT,TRUE,FALSE},
  146. {TOKEN_TYPE,TRUE,FALSE},
  147. {TOKEN_CODE,TRUE,FALSE}};
  148. if (dwCurrentIndex >= dwArgCount)
  149. {
  150. //
  151. // No arguments specified
  152. //
  153. return ERROR_SHOW_USAGE;
  154. }
  155. ZeroMemory(&fi, sizeof(fi));
  156. dwNumArg = dwArgCount - dwCurrentIndex;
  157. pdwTagType = HeapAlloc(GetProcessHeap(),
  158. 0,
  159. dwNumArg * sizeof(DWORD));
  160. if (pdwTagType is NULL)
  161. {
  162. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  163. return ERROR_NOT_ENOUGH_MEMORY;
  164. }
  165. dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments,
  166. dwCurrentIndex,
  167. dwArgCount,
  168. pttTags,
  169. dwNumTags,
  170. pdwTagType);
  171. if (dwErr isnot NO_ERROR)
  172. {
  173. if (dwErr is ERROR_INVALID_OPTION_TAG)
  174. {
  175. dwErr = ERROR_INVALID_SYNTAX; // show usage
  176. }
  177. HeapFree(GetProcessHeap(),0,pdwTagType);
  178. return dwErr;
  179. }
  180. bTags = TRUE;
  181. for ( i = 0; i < dwNumArg; i++)
  182. {
  183. switch (pdwTagType[i])
  184. {
  185. case 0 :
  186. {
  187. GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  188. wszIfName,
  189. sizeof(wszIfName),
  190. &dwNumParsed);
  191. // no filters allowed on INTERNAL/LOOPBACK interfaces
  192. if (!_wcsicmp(wszIfName, L"internal") or
  193. !_wcsicmp(wszIfName, L"loopback"))
  194. {
  195. DisplayMessage(g_hModule,
  196. MSG_IP_BAD_INTERFACE_TYPE,
  197. wszIfName);
  198. dwErr = ERROR_INVALID_PARAMETER;
  199. i = dwNumArg;
  200. }
  201. break;
  202. }
  203. case 1:
  204. {
  205. TOKEN_VALUE rgEnums[] =
  206. {{TOKEN_VALUE_INPUT, IP_IN_FILTER_INFO},
  207. {TOKEN_VALUE_OUTPUT, IP_OUT_FILTER_INFO},
  208. {TOKEN_VALUE_DIAL, IP_DEMAND_DIAL_FILTER_INFO}};
  209. //
  210. // Tag FILTERTYPE
  211. //
  212. dwErr = MatchEnumTag(g_hModule,
  213. ppwcArguments[i + dwCurrentIndex],
  214. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  215. rgEnums,
  216. &dwRes);
  217. if(dwErr != NO_ERROR)
  218. {
  219. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  220. pttTags[pdwTagType[i]].pwszTag,
  221. ppwcArguments[i + dwCurrentIndex]);
  222. DisplayMessage( g_hModule,
  223. MSG_IP_BAD_OPTION_ENUMERATION,
  224. pttTags[pdwTagType[i]].pwszTag );
  225. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  226. {
  227. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  228. }
  229. i = dwNumArg;
  230. dwErr = NO_ERROR;
  231. bOkay = FALSE;
  232. break;
  233. }
  234. dwFilterType = dwRes;
  235. break;
  236. }
  237. case 2:
  238. {
  239. dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex], &fi.dwSrcAddr);
  240. if(dwErr is ERROR_INVALID_PARAMETER)
  241. {
  242. DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR,
  243. ppwcArguments[i + dwCurrentIndex]);
  244. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  245. pttTags[pdwTagType[i]].pwszTag,
  246. ppwcArguments[i + dwCurrentIndex]);
  247. dwErr = ERROR_INVALID_PARAMETER;
  248. i = dwNumArg;
  249. break;
  250. }
  251. //
  252. // Get the src mask too.
  253. //
  254. if (pdwTagType[i+1] != 3)
  255. {
  256. //
  257. // Addr Mask pair not present
  258. //
  259. dwErr = ERROR_INVALID_SYNTAX;
  260. i = dwNumArg;
  261. break;
  262. }
  263. dwErr = GetIpAddress(ppwcArguments[i + 1 + dwCurrentIndex],
  264. &fi.dwSrcMask);
  265. if ((dwErr is ERROR_INVALID_PARAMETER) or
  266. (!ValidMask(fi.dwSrcMask)) or
  267. ((fi.dwSrcAddr & fi.dwSrcMask) isnot fi.dwSrcAddr))
  268. {
  269. DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR,
  270. ppwcArguments[i + 1 + dwCurrentIndex]);
  271. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  272. pttTags[pdwTagType[i + 1]].pwszTag,
  273. ppwcArguments[i + dwCurrentIndex + 1]);
  274. dwErr = ERROR_INVALID_PARAMETER;
  275. i = dwNumArg;
  276. break;
  277. }
  278. i++;
  279. break;
  280. }
  281. case 4 :
  282. {
  283. dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex],
  284. &fi.dwDstAddr);
  285. if(dwErr is ERROR_INVALID_PARAMETER)
  286. {
  287. DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR,
  288. ppwcArguments[i + dwCurrentIndex]);
  289. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  290. pttTags[pdwTagType[i]].pwszTag,
  291. ppwcArguments[i + dwCurrentIndex]);
  292. dwErr = ERROR_INVALID_PARAMETER;
  293. i = dwNumArg;
  294. break;
  295. }
  296. //
  297. // Get the dst mask too.
  298. //
  299. if (pdwTagType[i+1] != 5)
  300. {
  301. //
  302. // Addr Mask pair not present
  303. //
  304. dwErr = ERROR_INVALID_SYNTAX;
  305. i = dwNumArg;
  306. break;
  307. }
  308. dwErr = GetIpAddress(ppwcArguments[i + 1 + dwCurrentIndex],
  309. &fi.dwDstMask);
  310. if ((dwErr is ERROR_INVALID_PARAMETER) or
  311. (!ValidMask(fi.dwDstMask)) or
  312. ((fi.dwDstAddr & fi.dwDstMask) isnot fi.dwDstAddr))
  313. {
  314. DisplayMessage(g_hModule, MSG_IP_BAD_IP_ADDR,
  315. ppwcArguments[i + 1 + dwCurrentIndex]);
  316. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  317. pttTags[pdwTagType[i + 1]].pwszTag,
  318. ppwcArguments[i + 1 + dwCurrentIndex]);
  319. dwErr = ERROR_INVALID_PARAMETER;
  320. i = dwNumArg;
  321. break;
  322. }
  323. i++;
  324. break;
  325. }
  326. case 6:
  327. {
  328. TOKEN_VALUE rgEnums[] =
  329. {
  330. {TOKEN_VALUE_ANY, FILTER_PROTO_ANY},
  331. {TOKEN_VALUE_TCP, FILTER_PROTO_TCP},
  332. {TOKEN_VALUE_TCP_ESTAB, FILTER_PROTO_TCP},
  333. {TOKEN_VALUE_UDP, FILTER_PROTO_UDP},
  334. {TOKEN_VALUE_ICMP, FILTER_PROTO_ICMP}
  335. };
  336. if (MatchEnumTag(g_hModule,
  337. ppwcArguments[i + dwCurrentIndex],
  338. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  339. rgEnums,
  340. &dwRes) != NO_ERROR)
  341. {
  342. //
  343. // In this case see if its a valid value
  344. //
  345. dwRes = wcstoul(ppwcArguments[i + dwCurrentIndex],
  346. NULL,
  347. 10);
  348. if((dwRes < 1) ||
  349. (dwRes > 255))
  350. {
  351. DispTokenErrMsg(g_hModule,
  352. MSG_IP_BAD_OPTION_VALUE,
  353. pttTags[pdwTagType[i]].pwszTag,
  354. ppwcArguments[i + dwCurrentIndex]);
  355. DisplayMessage( g_hModule,
  356. MSG_IP_BAD_OPTION_ENUMERATION,
  357. pttTags[pdwTagType[i]].pwszTag );
  358. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  359. {
  360. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  361. }
  362. i = dwNumArg;
  363. dwErr = NO_ERROR;
  364. bOkay = FALSE;
  365. break;
  366. }
  367. }
  368. fi.dwProtocol = dwRes;
  369. switch (fi.dwProtocol)
  370. {
  371. case FILTER_PROTO_ANY :
  372. //
  373. // We are done
  374. //
  375. fi.wSrcPort = fi.wDstPort = 0;
  376. break;
  377. case FILTER_PROTO_TCP :
  378. // TCP and TCP_ESTABLISHED have same protocol number
  379. if (!MatchToken(ppwcArguments[i + dwCurrentIndex],
  380. TOKEN_VALUE_TCP))
  381. {
  382. fi.fLateBound |= TCP_ESTABLISHED_FLAG;
  383. }
  384. // continue processing as we could for UDP...
  385. case FILTER_PROTO_UDP :
  386. //
  387. // Get the src and dst ports too
  388. //
  389. if (i + 2 >= dwNumArg)
  390. {
  391. dwErr = ERROR_INVALID_SYNTAX;
  392. i = dwNumArg;
  393. break;
  394. }
  395. if (bTags &&
  396. (pdwTagType[i+1] != 7 || pdwTagType[i+2] != 8))
  397. {
  398. dwErr = ERROR_INVALID_SYNTAX;
  399. i = dwNumArg;
  400. break;
  401. }
  402. fi.wSrcPort =
  403. htons((WORD)wcstoul(ppwcArguments[i + 1 + dwCurrentIndex],
  404. NULL,
  405. 10));
  406. fi.wDstPort =
  407. htons((WORD)wcstoul(ppwcArguments[i + 2 + dwCurrentIndex],
  408. NULL,
  409. 10));
  410. i += 2;
  411. break;
  412. case FILTER_PROTO_ICMP :
  413. //
  414. // Get the src and dst ports too
  415. //
  416. if (i + 2 >= dwNumArg)
  417. {
  418. dwErr = ERROR_INVALID_SYNTAX;
  419. i = dwNumArg;
  420. break;
  421. }
  422. // src and dest ports acted upon as type and code
  423. if (bTags &&
  424. (pdwTagType[i+1] != 7 || pdwTagType[i+2] != 8) &&
  425. (pdwTagType[i+1] != 9 || pdwTagType[i+2] != 10))
  426. {
  427. dwErr = ERROR_INVALID_SYNTAX;
  428. i = dwNumArg;
  429. break;
  430. }
  431. fi.wSrcPort = (BYTE)wcstoul(ppwcArguments[i + 1 + dwCurrentIndex], NULL, 10);
  432. fi.wDstPort = (BYTE)wcstoul(ppwcArguments[i + 2 + dwCurrentIndex], NULL, 10);
  433. i += 2;
  434. break;
  435. default:
  436. {
  437. //
  438. // any 'other' protocol
  439. //
  440. fi.wSrcPort = fi.wDstPort = 0;
  441. break;
  442. }
  443. }
  444. break;
  445. }
  446. default:
  447. {
  448. i = dwNumArg;
  449. dwErr = ERROR_INVALID_SYNTAX;
  450. break;
  451. }
  452. }
  453. }
  454. HeapFree(GetProcessHeap(), 0, pdwTagType);
  455. switch(dwErr)
  456. {
  457. case NO_ERROR :
  458. break;
  459. default:
  460. return dwErr;
  461. }
  462. if (!bOkay)
  463. {
  464. return NO_ERROR;
  465. }
  466. //
  467. // Make sure all parameters are present
  468. //
  469. if ( !pttTags[0].bPresent ||
  470. !pttTags[1].bPresent ||
  471. !pttTags[2].bPresent ||
  472. !pttTags[3].bPresent ||
  473. !pttTags[4].bPresent ||
  474. !pttTags[5].bPresent ||
  475. !pttTags[6].bPresent )
  476. {
  477. DisplayMessage(g_hModule, MSG_CANT_FIND_EOPT);
  478. return ERROR_INVALID_SYNTAX;
  479. }
  480. dwErr = AddDelFilterInfo(fi,
  481. wszIfName,
  482. dwFilterType,
  483. bAdd);
  484. return dwErr;
  485. }
  486. DWORD
  487. HandleIpAddIfFilter(
  488. IN LPCWSTR pwszMachine,
  489. IN OUT LPWSTR *ppwcArguments,
  490. IN DWORD dwCurrentIndex,
  491. IN DWORD dwArgCount,
  492. IN DWORD dwFlags,
  493. IN LPCVOID pvData,
  494. OUT BOOL *pbDone
  495. )
  496. /*++
  497. Routine Description:
  498. Gets options for add interface filters
  499. Arguments:
  500. ppwcArguments - Argument array
  501. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  502. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  503. Return Value:
  504. NO_ERROR
  505. --*/
  506. {
  507. return IpAddDelIfFilter(ppwcArguments,
  508. dwCurrentIndex,
  509. dwArgCount,
  510. TRUE);
  511. }
  512. DWORD
  513. HandleIpDelIfFilter(
  514. IN LPCWSTR pwszMachine,
  515. IN OUT LPWSTR *ppwcArguments,
  516. IN DWORD dwCurrentIndex,
  517. IN DWORD dwArgCount,
  518. IN DWORD dwFlags,
  519. IN LPCVOID pvData,
  520. OUT BOOL *pbDone
  521. )
  522. /*++
  523. Routine Description:
  524. Gets options for del interface filters
  525. Arguments:
  526. ppwcArguments - Argument array
  527. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  528. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  529. Return Value:
  530. NO_ERROR
  531. --*/
  532. {
  533. return IpAddDelIfFilter(ppwcArguments,
  534. dwCurrentIndex,
  535. dwArgCount,
  536. FALSE);
  537. }
  538. DWORD
  539. IpAddSetDelRtmRoute(
  540. PWCHAR *ppwcArguments,
  541. DWORD dwCurrentIndex,
  542. DWORD dwArgCount,
  543. DWORD dwCommand
  544. )
  545. /*++
  546. Routine Description:
  547. Gets options for add/del routes over interfaces.
  548. These operations are performed directly to RTM
  549. and do not involve the registry. As persistence
  550. is not involved, we need the router to be running.
  551. Arguments:
  552. ppwcArguments - Argument array
  553. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  554. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  555. dwCommand - To add, set, or delete
  556. Return Value:
  557. NO_ERROR
  558. --*/
  559. {
  560. INTERFACE_ROUTE_INFO route;
  561. DWORD dwNumParsed, dwErr, dwRes;
  562. DWORD dwNumOpt, dwStatus = (DWORD) -1;
  563. DWORD dwNumArg, i;
  564. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  565. TAG_TYPE pttTags[] = {{TOKEN_DEST,TRUE,FALSE},
  566. {TOKEN_MASK,FALSE,FALSE},
  567. {TOKEN_NAMEINDEX,FALSE,FALSE},
  568. {TOKEN_NHOP,FALSE,FALSE},
  569. {TOKEN_PREFERENCE,FALSE,FALSE},
  570. {TOKEN_METRIC,FALSE,FALSE},
  571. {TOKEN_VIEW,FALSE,FALSE}};
  572. enum idx {DEST, MASK, NAMEINDEX, NHOP, PREFERENCE, METRIC, VIEW};
  573. DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  574. DWORD dwMaxArgs;
  575. DWORD dwIfClass;
  576. DWORD dwFlags;
  577. PINTERFACE_ROUTE_INFO pTable = NULL;
  578. //
  579. // We can add non persistent routes only if router is running
  580. //
  581. CHECK_ROUTER_RUNNING();
  582. ZeroMemory(&route,
  583. sizeof(route));
  584. route.dwRtInfoProto = PROTO_IP_NETMGMT; // default proto
  585. route.dwRtInfoPreference = 0; // default preference = protocol default
  586. route.dwRtInfoMetric1 = 1; // default metric
  587. route.dwRtInfoMetric2 = MIB_IPROUTE_METRIC_UNUSED;
  588. route.dwRtInfoMetric3 = MIB_IPROUTE_METRIC_UNUSED;
  589. route.dwRtInfoViewSet = RTM_VIEW_MASK_UCAST | RTM_VIEW_MASK_MCAST;
  590. // Do generic processing
  591. dwErr = PreHandleCommand( ppwcArguments,
  592. dwCurrentIndex,
  593. dwArgCount,
  594. pttTags,
  595. sizeof(pttTags)/sizeof(TAG_TYPE),
  596. 1,
  597. sizeof(pttTags)/sizeof(TAG_TYPE),
  598. pdwTagType );
  599. if (dwErr)
  600. {
  601. return dwErr;
  602. }
  603. dwNumArg = dwArgCount - dwCurrentIndex;
  604. //
  605. // At this point, the arg array contains only values (either because
  606. // the tags werent present, or because that info has now been split out)
  607. // So we go through each of the each of the arguments, look up its tag
  608. // type in the tag array, switch on the type of tag it is and then
  609. // process accordingly.
  610. //
  611. for (i = 0; i < dwNumArg; i++)
  612. {
  613. switch (pdwTagType[i])
  614. {
  615. case DEST: // DEST
  616. {
  617. dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex],
  618. &route.dwRtInfoDest,
  619. &route.dwRtInfoMask);
  620. break;
  621. }
  622. case MASK: // MASK
  623. {
  624. dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex],
  625. &route.dwRtInfoMask);
  626. break;
  627. }
  628. case NAMEINDEX : // INDEX or NAME
  629. {
  630. //
  631. // If it starts with '0x', this is a hex index
  632. //
  633. if ((ppwcArguments[i + dwCurrentIndex][0] == L'0') &&
  634. (ppwcArguments[i + dwCurrentIndex][1] == L'x'))
  635. {
  636. route.dwRtInfoIfIndex =
  637. wcstoul(ppwcArguments[i + dwCurrentIndex],
  638. NULL,
  639. 16);
  640. }
  641. else
  642. {
  643. route.dwRtInfoIfIndex =
  644. wcstoul(ppwcArguments[i + dwCurrentIndex],
  645. NULL,
  646. 10);
  647. }
  648. if (route.dwRtInfoIfIndex == 0)
  649. {
  650. GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  651. wszIfName,
  652. sizeof(wszIfName),
  653. &dwNumParsed);
  654. if (!dwNumParsed)
  655. {
  656. DisplayMessage(g_hModule, EMSG_CANT_MATCH_NAME);
  657. return ERROR_INVALID_PARAMETER;
  658. }
  659. }
  660. break;
  661. }
  662. case NHOP: // NHOP
  663. {
  664. dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex],
  665. &route.dwRtInfoNextHop);
  666. break;
  667. }
  668. case PREFERENCE:
  669. {
  670. route.dwRtInfoPreference =
  671. wcstoul(ppwcArguments[i + dwCurrentIndex],
  672. NULL,
  673. 10);
  674. break;
  675. }
  676. case METRIC: // METRIC
  677. {
  678. route.dwRtInfoMetric1 =
  679. wcstoul(ppwcArguments[i + dwCurrentIndex],
  680. NULL,
  681. 10);
  682. break;
  683. }
  684. case VIEW:
  685. {
  686. TOKEN_VALUE rgMaskEnums[] = {
  687. { TOKEN_VALUE_UNICAST, RTM_VIEW_MASK_UCAST },
  688. { TOKEN_VALUE_MULTICAST, RTM_VIEW_MASK_MCAST },
  689. { TOKEN_VALUE_BOTH, RTM_VIEW_MASK_UCAST
  690. |RTM_VIEW_MASK_MCAST } };
  691. dwErr = MatchEnumTag( g_hModule,
  692. ppwcArguments[i + dwCurrentIndex],
  693. sizeof(rgMaskEnums)/sizeof(TOKEN_VALUE),
  694. rgMaskEnums,
  695. &route.dwRtInfoViewSet);
  696. if (dwErr isnot NO_ERROR)
  697. {
  698. DispTokenErrMsg( g_hModule,
  699. MSG_IP_BAD_OPTION_VALUE,
  700. pttTags[pdwTagType[i]].pwszTag,
  701. ppwcArguments[i + dwCurrentIndex] );
  702. i = dwArgCount;
  703. return ERROR_INVALID_PARAMETER;
  704. }
  705. break;
  706. }
  707. }
  708. }
  709. if (dwErr)
  710. {
  711. return dwErr;
  712. }
  713. if (route.dwRtInfoDest & ~route.dwRtInfoMask)
  714. {
  715. // Mask contains bits not in address
  716. DisplayMessage(g_hModule, EMSG_PREFIX_ERROR);
  717. return ERROR_INVALID_PARAMETER;
  718. }
  719. if (!pttTags[NAMEINDEX].bPresent)
  720. {
  721. //
  722. // Neither NAME nor INDEX - adding with a nexthop
  723. //
  724. PMIB_IPADDRTABLE AddrTable;
  725. PMIB_IPADDRROW AddrEntry;
  726. MIB_OPAQUE_QUERY Query;
  727. PMIB_OPAQUE_INFO Info;
  728. DWORD dwQuerySize;
  729. DWORD dwEntrySize;
  730. INT iFirstMatch;
  731. UINT i;
  732. if (!pttTags[NHOP].bPresent)
  733. {
  734. DisplayMessage(g_hModule, EMSG_CANT_FIND_NAME_OR_NHOP);
  735. return ERROR_INVALID_SYNTAX;
  736. }
  737. //
  738. // Search for the interface that matches nexthop
  739. //
  740. dwQuerySize = sizeof(MIB_OPAQUE_QUERY) - sizeof(DWORD);
  741. Query.dwVarId = IP_ADDRTABLE;
  742. dwErr = MibGet(PID_IP,
  743. IPRTRMGR_PID,
  744. (PVOID) &Query,
  745. dwQuerySize,
  746. (PVOID *) &Info,
  747. &dwEntrySize);
  748. if (dwErr != NO_ERROR)
  749. {
  750. DisplayMessage(g_hModule, MSG_IP_DIM_ERROR, dwErr);
  751. return ERROR_SUPPRESS_OUTPUT;
  752. }
  753. if (Info is NULL)
  754. {
  755. DisplayMessage(g_hModule, EMSG_CANT_FIND_INDEX);
  756. return ERROR_INVALID_PARAMETER;
  757. }
  758. AddrTable = (PMIB_IPADDRTABLE)Info->rgbyData;
  759. iFirstMatch = -1;
  760. for (i = 0; i < AddrTable->dwNumEntries; i++)
  761. {
  762. AddrEntry = &AddrTable->table[i];
  763. if ((route.dwRtInfoNextHop & AddrEntry->dwMask) ==
  764. (AddrEntry->dwAddr & AddrEntry->dwMask))
  765. {
  766. if (iFirstMatch != -1)
  767. {
  768. //
  769. // We already matched an interface
  770. // [Ambiguous next hop description]
  771. //
  772. MprAdminMIBBufferFree((PVOID)Info);
  773. DisplayMessage(g_hModule, EMSG_AMBIGUOUS_INDEX_FROM_NHOP);
  774. return ERROR_INVALID_PARAMETER;
  775. }
  776. iFirstMatch = i;
  777. }
  778. }
  779. if (iFirstMatch == -1)
  780. {
  781. //
  782. // Could not find the direct nexthop
  783. //
  784. MprAdminMIBBufferFree((PVOID)Info);
  785. DisplayMessage(g_hModule, EMSG_CANT_FIND_INDEX);
  786. return ERROR_INVALID_PARAMETER;
  787. }
  788. //
  789. // Found the interface used to reach nexthop
  790. //
  791. route.dwRtInfoIfIndex = AddrTable->table[iFirstMatch].dwIndex;
  792. MprAdminMIBBufferFree((PVOID)Info);
  793. }
  794. if (route.dwRtInfoIfIndex)
  795. {
  796. //
  797. // Check if this index has a public exported name
  798. //
  799. GetGuidFromIfIndex(g_hMIBServer,
  800. route.dwRtInfoIfIndex,
  801. wszIfName,
  802. MAX_INTERFACE_NAME_LEN);
  803. //
  804. // We proceed and see if we can still add/set/del
  805. //
  806. }
  807. if (wszIfName[0] != L'\0')
  808. {
  809. //
  810. // NAME specified, or derived from INDEX above
  811. //
  812. dwErr = GetInterfaceClass(wszIfName, &dwIfClass);
  813. //
  814. // If we get an error, we will skip remaining
  815. // checks which will be performed by iprtrmgr
  816. //
  817. if (dwErr == NO_ERROR)
  818. {
  819. if (dwIfClass is IFCLASS_LOOPBACK)
  820. {
  821. return ERROR_INVALID_SYNTAX;
  822. }
  823. if (!pttTags[NHOP].bPresent)
  824. {
  825. // Make sure interface is p2p
  826. if (dwIfClass isnot IFCLASS_P2P)
  827. {
  828. DisplayMessage(g_hModule, EMSG_NEED_NHOP);
  829. return ERROR_INVALID_PARAMETER;
  830. }
  831. }
  832. }
  833. }
  834. //
  835. // If it is a set, we should not overwrite things not specified
  836. //
  837. dwFlags = ALL_FIELDS_SPECIFIED;
  838. if (dwCommand == SET_COMMAND)
  839. {
  840. if (!pttTags[PREFERENCE].bPresent) dwFlags |= PREF_NOT_SPECIFIED;
  841. if (!pttTags[METRIC].bPresent) dwFlags |= METRIC_NOT_SPECIFIED;
  842. if (!pttTags[VIEW].bPresent) dwFlags |= VIEW_NOT_SPECIFIED;
  843. }
  844. return AddSetDelRtmRouteInfo(&route, wszIfName, dwCommand, dwFlags);
  845. }
  846. DWORD
  847. HandleIpAddRtmRoute(
  848. IN LPCWSTR pwszMachine,
  849. IN OUT LPWSTR *ppwcArguments,
  850. IN DWORD dwCurrentIndex,
  851. IN DWORD dwArgCount,
  852. IN DWORD dwFlags,
  853. IN LPCVOID pvData,
  854. OUT BOOL *pbDone
  855. )
  856. {
  857. return IpAddSetDelRtmRoute(ppwcArguments,
  858. dwCurrentIndex,
  859. dwArgCount,
  860. ADD_COMMAND);
  861. }
  862. DWORD
  863. HandleIpDelRtmRoute(
  864. IN LPCWSTR pwszMachine,
  865. IN OUT LPWSTR *ppwcArguments,
  866. IN DWORD dwCurrentIndex,
  867. IN DWORD dwArgCount,
  868. IN DWORD dwFlags,
  869. IN LPCVOID pvData,
  870. OUT BOOL *pbDone
  871. )
  872. {
  873. return IpAddSetDelRtmRoute(ppwcArguments,
  874. dwCurrentIndex,
  875. dwArgCount,
  876. DELETE_COMMAND);
  877. }
  878. DWORD
  879. HandleIpSetRtmRoute(
  880. IN LPCWSTR pwszMachine,
  881. IN OUT LPWSTR *ppwcArguments,
  882. IN DWORD dwCurrentIndex,
  883. IN DWORD dwArgCount,
  884. IN DWORD dwFlags,
  885. IN LPCVOID pvData,
  886. OUT BOOL *pbDone
  887. )
  888. {
  889. return IpAddSetDelRtmRoute(ppwcArguments,
  890. dwCurrentIndex,
  891. dwArgCount,
  892. SET_COMMAND);
  893. }
  894. DWORD
  895. IpAddSetDelPersistentRoute(
  896. PWCHAR *ppwcArguments,
  897. DWORD dwCurrentIndex,
  898. DWORD dwArgCount,
  899. DWORD dwCommand
  900. )
  901. /*++
  902. Routine Description:
  903. Gets options for add/del routes over interfaces.
  904. These operations are performed directly to the
  905. registry and so these routes are persistent. If
  906. the router is running, they go into the RTM too.
  907. Arguments:
  908. ppwcArguments - Argument array
  909. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  910. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  911. dwCommand - To add, set, or delete
  912. Return Value:
  913. NO_ERROR
  914. --*/
  915. {
  916. INTERFACE_ROUTE_INFO route;
  917. DWORD dwNumParsed, dwErr, dwRes;
  918. DWORD dwNumOpt, dwStatus = (DWORD) -1;
  919. DWORD dwNumArg, i;
  920. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  921. TAG_TYPE pttTags[] = {{TOKEN_DEST,TRUE,FALSE},
  922. {TOKEN_MASK,FALSE,FALSE},
  923. {TOKEN_NAME,FALSE,FALSE},
  924. {TOKEN_NHOP,FALSE,FALSE},
  925. {TOKEN_PROTOCOL,FALSE,FALSE},
  926. {TOKEN_PREFERENCE,FALSE,FALSE},
  927. {TOKEN_METRIC,FALSE,FALSE},
  928. {TOKEN_VIEW,FALSE,FALSE}};
  929. enum idx {DEST, MASK, NAME, NHOP, PROTO, PREFERENCE, METRIC, VIEW};
  930. DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  931. DWORD dwMaxArgs;
  932. DWORD dwIfClass;
  933. DWORD dwFlags;
  934. PINTERFACE_ROUTE_INFO pTable = NULL;
  935. ZeroMemory(&route,
  936. sizeof(route));
  937. route.dwRtInfoProto = PROTO_IP_NT_STATIC_NON_DOD; // default proto
  938. route.dwRtInfoPreference = 0; // default preference = protocol default
  939. route.dwRtInfoMetric1 = 1; // default metric
  940. route.dwRtInfoMetric2 = MIB_IPROUTE_METRIC_UNUSED;
  941. route.dwRtInfoMetric3 = MIB_IPROUTE_METRIC_UNUSED;
  942. route.dwRtInfoViewSet = RTM_VIEW_MASK_UCAST | RTM_VIEW_MASK_MCAST;
  943. // Do generic processing
  944. dwErr = PreHandleCommand( ppwcArguments,
  945. dwCurrentIndex,
  946. dwArgCount,
  947. pttTags,
  948. sizeof(pttTags)/sizeof(TAG_TYPE),
  949. 1,
  950. sizeof(pttTags)/sizeof(TAG_TYPE),
  951. pdwTagType );
  952. if (dwErr)
  953. {
  954. return dwErr;
  955. }
  956. dwNumArg = dwArgCount - dwCurrentIndex;
  957. //
  958. // At this point, the arg array contains only values (either because
  959. // the tags werent present, or because that info has now been split out)
  960. // So we go through each of the each of the arguments, look up its tag
  961. // type in the tag array, switch on the type of tag it is and then
  962. // process accordingly.
  963. //
  964. for (i = 0; i < dwNumArg; i++)
  965. {
  966. switch (pdwTagType[i])
  967. {
  968. case DEST: // DEST
  969. {
  970. dwErr = GetIpPrefix(ppwcArguments[i + dwCurrentIndex],
  971. &route.dwRtInfoDest,
  972. &route.dwRtInfoMask);
  973. break;
  974. }
  975. case MASK: // MASK
  976. {
  977. dwErr = GetIpMask(ppwcArguments[i + dwCurrentIndex],
  978. &route.dwRtInfoMask);
  979. break;
  980. }
  981. case NAME : // NAME
  982. {
  983. GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  984. wszIfName,
  985. sizeof(wszIfName),
  986. &dwNumParsed);
  987. break;
  988. }
  989. case NHOP: // NHOP
  990. {
  991. dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex],
  992. &route.dwRtInfoNextHop);
  993. break;
  994. }
  995. case PROTO : // PROTO
  996. {
  997. TOKEN_VALUE rgEnums[] =
  998. {/*{TOKEN_VALUE_AUTOSTATIC, PROTO_IP_NT_AUTOSTATIC},*/
  999. {TOKEN_VALUE_STATIC, PROTO_IP_NT_STATIC},
  1000. {TOKEN_VALUE_NONDOD, PROTO_IP_NT_STATIC_NON_DOD}};
  1001. dwErr = MatchEnumTag(g_hModule,
  1002. ppwcArguments[i + dwCurrentIndex],
  1003. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1004. rgEnums,
  1005. &dwRes);
  1006. if (dwErr != NO_ERROR)
  1007. {
  1008. DispTokenErrMsg(g_hModule,
  1009. MSG_IP_BAD_OPTION_VALUE,
  1010. pttTags[pdwTagType[i]].pwszTag,
  1011. ppwcArguments[i + dwCurrentIndex]);
  1012. DisplayMessage( g_hModule,
  1013. MSG_IP_BAD_OPTION_ENUMERATION,
  1014. pttTags[pdwTagType[i]].pwszTag );
  1015. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  1016. {
  1017. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  1018. }
  1019. return NO_ERROR;
  1020. }
  1021. route.dwRtInfoProto = dwRes;
  1022. break;
  1023. }
  1024. case PREFERENCE:
  1025. {
  1026. route.dwRtInfoPreference =
  1027. wcstoul(ppwcArguments[i + dwCurrentIndex],
  1028. NULL,
  1029. 10);
  1030. break;
  1031. }
  1032. case METRIC:
  1033. {
  1034. route.dwRtInfoMetric1 =
  1035. wcstoul(ppwcArguments[i + dwCurrentIndex],
  1036. NULL,
  1037. 10);
  1038. break;
  1039. }
  1040. case VIEW:
  1041. {
  1042. TOKEN_VALUE rgMaskEnums[] = {
  1043. { TOKEN_VALUE_UNICAST, RTM_VIEW_MASK_UCAST },
  1044. { TOKEN_VALUE_MULTICAST, RTM_VIEW_MASK_MCAST },
  1045. { TOKEN_VALUE_BOTH, RTM_VIEW_MASK_UCAST
  1046. |RTM_VIEW_MASK_MCAST } };
  1047. dwErr = MatchEnumTag( g_hModule,
  1048. ppwcArguments[i + dwCurrentIndex],
  1049. sizeof(rgMaskEnums)/sizeof(TOKEN_VALUE),
  1050. rgMaskEnums,
  1051. &route.dwRtInfoViewSet);
  1052. if (dwErr isnot NO_ERROR)
  1053. {
  1054. DispTokenErrMsg( g_hModule,
  1055. MSG_IP_BAD_OPTION_VALUE,
  1056. pttTags[pdwTagType[i]].pwszTag,
  1057. ppwcArguments[i + dwCurrentIndex] );
  1058. i = dwArgCount;
  1059. return ERROR_INVALID_PARAMETER;
  1060. }
  1061. break;
  1062. }
  1063. }
  1064. }
  1065. if (dwErr)
  1066. {
  1067. return dwErr;
  1068. }
  1069. if (route.dwRtInfoDest & ~route.dwRtInfoMask)
  1070. {
  1071. // Mask contains bits not in address
  1072. DisplayMessage(g_hModule, EMSG_PREFIX_ERROR);
  1073. return ERROR_INVALID_PARAMETER;
  1074. }
  1075. if (!pttTags[NAME].bPresent)
  1076. {
  1077. // Need if name to add persistent route
  1078. DisplayMessage(g_hModule, EMSG_CANT_FIND_NAME);
  1079. return ERROR_INVALID_SYNTAX;
  1080. }
  1081. dwErr = GetInterfaceClass(wszIfName, &dwIfClass);
  1082. if (dwErr)
  1083. {
  1084. DisplayMessage(g_hModule, EMSG_CANT_GET_IF_INFO,
  1085. wszIfName,
  1086. dwErr);
  1087. return ERROR_INVALID_PARAMETER;
  1088. }
  1089. if (dwIfClass is IFCLASS_LOOPBACK)
  1090. {
  1091. return ERROR_INVALID_SYNTAX;
  1092. }
  1093. if (!pttTags[NHOP].bPresent)
  1094. {
  1095. // Make sure interface is p2p
  1096. if (dwIfClass isnot IFCLASS_P2P)
  1097. {
  1098. DisplayMessage(g_hModule, EMSG_NEED_NHOP);
  1099. return ERROR_INVALID_PARAMETER;
  1100. }
  1101. }
  1102. if (dwIfClass is IFCLASS_P2P)
  1103. {
  1104. if (!pttTags[PROTO].bPresent)
  1105. {
  1106. // if not explicitly specified, change protocol to static
  1107. route.dwRtInfoProto = PROTO_IP_NT_STATIC; // default proto
  1108. }
  1109. }
  1110. else
  1111. {
  1112. // make sure we didn't try to set static on a non-P2P interface
  1113. if (route.dwRtInfoProto is PROTO_IP_NT_STATIC)
  1114. {
  1115. return ERROR_INVALID_PARAMETER;
  1116. }
  1117. }
  1118. //
  1119. // If it is a set, we should not overwrite things not specified
  1120. //
  1121. dwFlags = ALL_FIELDS_SPECIFIED;
  1122. if (dwCommand == SET_COMMAND)
  1123. {
  1124. if (!pttTags[PREFERENCE].bPresent) dwFlags |= PREF_NOT_SPECIFIED;
  1125. if (!pttTags[METRIC].bPresent) dwFlags |= METRIC_NOT_SPECIFIED;
  1126. if (!pttTags[VIEW].bPresent) dwFlags |= VIEW_NOT_SPECIFIED;
  1127. }
  1128. return AddSetDelPersistentRouteInfo(&route, wszIfName, dwCommand, dwFlags);
  1129. }
  1130. DWORD
  1131. HandleIpAddPersistentRoute(
  1132. IN LPCWSTR pwszMachine,
  1133. IN OUT LPWSTR *ppwcArguments,
  1134. IN DWORD dwCurrentIndex,
  1135. IN DWORD dwArgCount,
  1136. IN DWORD dwFlags,
  1137. IN LPCVOID pvData,
  1138. OUT BOOL *pbDone
  1139. )
  1140. {
  1141. return IpAddSetDelPersistentRoute(ppwcArguments,
  1142. dwCurrentIndex,
  1143. dwArgCount,
  1144. ADD_COMMAND);
  1145. }
  1146. DWORD
  1147. HandleIpDelPersistentRoute(
  1148. IN LPCWSTR pwszMachine,
  1149. IN OUT LPWSTR *ppwcArguments,
  1150. IN DWORD dwCurrentIndex,
  1151. IN DWORD dwArgCount,
  1152. IN DWORD dwFlags,
  1153. IN LPCVOID pvData,
  1154. OUT BOOL *pbDone
  1155. )
  1156. {
  1157. return IpAddSetDelPersistentRoute(ppwcArguments,
  1158. dwCurrentIndex,
  1159. dwArgCount,
  1160. DELETE_COMMAND);
  1161. }
  1162. DWORD
  1163. HandleIpSetPersistentRoute(
  1164. IN LPCWSTR pwszMachine,
  1165. IN OUT LPWSTR *ppwcArguments,
  1166. IN DWORD dwCurrentIndex,
  1167. IN DWORD dwArgCount,
  1168. IN DWORD dwFlags,
  1169. IN LPCVOID pvData,
  1170. OUT BOOL *pbDone
  1171. )
  1172. {
  1173. return IpAddSetDelPersistentRoute(ppwcArguments,
  1174. dwCurrentIndex,
  1175. dwArgCount,
  1176. SET_COMMAND);
  1177. }
  1178. DWORD
  1179. HandleIpAddRoutePref(
  1180. IN LPCWSTR pwszMachine,
  1181. IN OUT LPWSTR *ppwcArguments,
  1182. IN DWORD dwCurrentIndex,
  1183. IN DWORD dwArgCount,
  1184. IN DWORD dwFlags,
  1185. IN LPCVOID pvData,
  1186. OUT BOOL *pbDone
  1187. )
  1188. /*++
  1189. Routine Description:
  1190. Gets options for adding route preferences
  1191. Arguments:
  1192. ppwcArguments - Argument array
  1193. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1194. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1195. Return Value:
  1196. NO_ERROR
  1197. --*/
  1198. {
  1199. PPROTOCOL_METRIC ppm;
  1200. DWORD dwBitVector = 0, dwNumPref,dwPrefIndex;
  1201. DWORD dwErr = NO_ERROR,dwRes;
  1202. PDWORD pdwTagType;
  1203. DWORD dwNumTags = 2, dwNumArg, i, dwAddr;
  1204. TAG_TYPE pttTags[] = {{TOKEN_PROTOCOL, TRUE,FALSE},
  1205. {TOKEN_PREF_LEVEL, TRUE,FALSE}};
  1206. if (dwCurrentIndex >= dwArgCount)
  1207. {
  1208. //
  1209. // No arguments specified
  1210. //
  1211. return ERROR_SHOW_USAGE;
  1212. }
  1213. dwNumArg = dwArgCount - dwCurrentIndex;
  1214. pdwTagType = HeapAlloc(GetProcessHeap(),
  1215. 0,
  1216. dwNumArg * sizeof(DWORD));
  1217. if (pdwTagType is NULL)
  1218. {
  1219. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1220. return ERROR_NOT_ENOUGH_MEMORY;
  1221. }
  1222. dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments,
  1223. dwCurrentIndex,
  1224. dwArgCount,
  1225. pttTags,
  1226. dwNumTags,
  1227. pdwTagType);
  1228. if (dwErr isnot NO_ERROR)
  1229. {
  1230. HeapFree(GetProcessHeap(),0,pdwTagType);
  1231. if (dwErr is ERROR_INVALID_OPTION_TAG)
  1232. {
  1233. dwErr = ERROR_INVALID_SYNTAX; // show usage
  1234. }
  1235. return dwErr;
  1236. }
  1237. dwNumPref = dwNumArg / 2 + dwNumArg % 2;
  1238. ppm = HeapAlloc(GetProcessHeap(),
  1239. 0,
  1240. dwNumPref * sizeof(PROTOCOL_METRIC));
  1241. if (ppm is NULL)
  1242. {
  1243. HeapFree(GetProcessHeap(),0,pdwTagType);
  1244. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1245. return ERROR_NOT_ENOUGH_MEMORY;
  1246. }
  1247. for ( i = 0, dwPrefIndex = 0; i < dwNumArg; i++)
  1248. {
  1249. switch (pdwTagType[i])
  1250. {
  1251. case 0:
  1252. {
  1253. //
  1254. // TAG = PROTOCOL
  1255. //
  1256. dwRes = MatchRoutingProtoTag(ppwcArguments[i + dwCurrentIndex]);
  1257. if (dwRes == (DWORD) -1)
  1258. {
  1259. DispTokenErrMsg(g_hModule,
  1260. MSG_IP_BAD_OPTION_VALUE,
  1261. pttTags[pdwTagType[i]].pwszTag,
  1262. ppwcArguments[i + dwCurrentIndex]);
  1263. i = dwNumArg;
  1264. dwErr = ERROR_INVALID_PARAMETER;
  1265. break;
  1266. }
  1267. ppm[dwPrefIndex].dwProtocolId = dwRes;
  1268. //
  1269. // Get the metric too
  1270. //
  1271. if (pdwTagType[i+1] == 1)
  1272. {
  1273. ppm[dwPrefIndex].dwMetric =
  1274. wcstoul(ppwcArguments[i + 1 +dwCurrentIndex],NULL,10);
  1275. if (ppm[dwPrefIndex].dwMetric==0
  1276. && wcscmp(ppwcArguments[i + 1 +dwCurrentIndex], L"0")!=0)
  1277. {
  1278. dwErr = ERROR_INVALID_SYNTAX;
  1279. i = dwNumArg;
  1280. break;
  1281. }
  1282. i++;
  1283. dwPrefIndex++;
  1284. }
  1285. else
  1286. {
  1287. //
  1288. // the range is not an addr mask pair.
  1289. // So ignore the addr (i.e. don't increment dwRangeIndex)
  1290. //
  1291. dwErr = ERROR_INVALID_SYNTAX;
  1292. i = dwNumArg;
  1293. break;
  1294. }
  1295. break;
  1296. }
  1297. default :
  1298. {
  1299. i = dwNumArg;
  1300. dwErr = ERROR_INVALID_SYNTAX;
  1301. break;
  1302. }
  1303. }
  1304. }
  1305. HeapFree(GetProcessHeap(), 0, pdwTagType);
  1306. switch(dwErr)
  1307. {
  1308. case NO_ERROR :
  1309. break;
  1310. default:
  1311. return dwErr;
  1312. }
  1313. if (dwPrefIndex)
  1314. {
  1315. //
  1316. // Add route pref
  1317. //
  1318. dwRes = AddDeleteRoutePrefLevel(ppm,
  1319. dwPrefIndex,
  1320. TRUE);
  1321. }
  1322. HeapFree(GetProcessHeap(), 0, ppm);
  1323. return dwErr;
  1324. }
  1325. DWORD
  1326. HandleIpDelRoutePref(
  1327. IN LPCWSTR pwszMachine,
  1328. IN OUT LPWSTR *ppwcArguments,
  1329. IN DWORD dwCurrentIndex,
  1330. IN DWORD dwArgCount,
  1331. IN DWORD dwFlags,
  1332. IN LPCVOID pvData,
  1333. OUT BOOL *pbDone
  1334. )
  1335. /*++
  1336. Routine Description:
  1337. Gets options for deleting route preferences
  1338. Arguments:
  1339. ppwcArguments - Argument array
  1340. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1341. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1342. Return Value:
  1343. NO_ERROR
  1344. --*/
  1345. {
  1346. PPROTOCOL_METRIC ppm;
  1347. DWORD dwBitVector = 0, dwNumPref,dwPrefIndex;
  1348. DWORD dwErr = NO_ERROR,dwRes;
  1349. TAG_TYPE pttTags[] = {{TOKEN_PROTOCOL,TRUE,FALSE}};
  1350. PDWORD pdwTagType;
  1351. DWORD dwNumTags = 1, dwNumArg, i, dwAddr;
  1352. if (dwCurrentIndex >= dwArgCount)
  1353. {
  1354. //
  1355. // No arguments specified
  1356. //
  1357. return ERROR_SHOW_USAGE;
  1358. }
  1359. dwNumArg = dwArgCount - dwCurrentIndex;
  1360. pdwTagType = HeapAlloc(GetProcessHeap(),
  1361. 0,
  1362. dwNumArg * sizeof(DWORD));
  1363. if (pdwTagType is NULL)
  1364. {
  1365. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1366. return ERROR_NOT_ENOUGH_MEMORY;
  1367. }
  1368. dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments,
  1369. dwCurrentIndex,
  1370. dwArgCount,
  1371. pttTags,
  1372. dwNumTags,
  1373. pdwTagType);
  1374. if (dwErr isnot NO_ERROR)
  1375. {
  1376. HeapFree(GetProcessHeap(),0,pdwTagType);
  1377. if (dwErr is ERROR_INVALID_OPTION_TAG)
  1378. {
  1379. dwErr = ERROR_INVALID_SYNTAX; // show usage
  1380. }
  1381. return dwErr;
  1382. }
  1383. dwNumPref = dwNumArg;
  1384. ppm = HeapAlloc(GetProcessHeap(),
  1385. 0,
  1386. dwNumPref * sizeof(PROTOCOL_METRIC));
  1387. if (ppm is NULL)
  1388. {
  1389. HeapFree(GetProcessHeap(),0,pdwTagType);
  1390. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1391. return ERROR_NOT_ENOUGH_MEMORY;
  1392. }
  1393. for ( i = 0, dwPrefIndex = 0; i < dwNumArg; i++)
  1394. {
  1395. switch (pdwTagType[i])
  1396. {
  1397. case 0:
  1398. {
  1399. //
  1400. // TAG = PROTOCOL
  1401. //
  1402. dwRes = MatchRoutingProtoTag(ppwcArguments[i + dwCurrentIndex]);
  1403. if (dwRes == (DWORD) -1)
  1404. {
  1405. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1406. pttTags[pdwTagType[i]].pwszTag,
  1407. ppwcArguments[i + dwCurrentIndex]);
  1408. i = dwNumArg;
  1409. dwErr = ERROR_INVALID_PARAMETER;
  1410. break;
  1411. }
  1412. ppm[dwPrefIndex++].dwProtocolId = dwRes;
  1413. break;
  1414. }
  1415. default :
  1416. {
  1417. i = dwNumArg;
  1418. dwErr = ERROR_INVALID_SYNTAX;
  1419. break;
  1420. }
  1421. }
  1422. }
  1423. HeapFree(GetProcessHeap(), 0, pdwTagType);
  1424. switch(dwErr)
  1425. {
  1426. case NO_ERROR :
  1427. break;
  1428. default:
  1429. return dwErr;
  1430. }
  1431. if (dwPrefIndex)
  1432. {
  1433. //
  1434. // Add route pref
  1435. //
  1436. dwRes = AddDeleteRoutePrefLevel(ppm,
  1437. dwPrefIndex,
  1438. FALSE);
  1439. }
  1440. HeapFree(GetProcessHeap(), 0, ppm);
  1441. return dwErr;
  1442. }
  1443. DWORD
  1444. HandleIpSetRoutePref(
  1445. IN LPCWSTR pwszMachine,
  1446. IN OUT LPWSTR *ppwcArguments,
  1447. IN DWORD dwCurrentIndex,
  1448. IN DWORD dwArgCount,
  1449. IN DWORD dwFlags,
  1450. IN LPCVOID pvData,
  1451. OUT BOOL *pbDone
  1452. )
  1453. /*++
  1454. Routine Description:
  1455. Gets options for setting route preferences
  1456. Arguments:
  1457. ppwcArguments - Argument array
  1458. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1459. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1460. Return Value:
  1461. NO_ERROR
  1462. --*/
  1463. {
  1464. PROTOCOL_METRIC pm;
  1465. DWORD dwBitVector = 0, dwNumPref,dwPrefIndex;
  1466. DWORD dwErr = NO_ERROR,dwRes;
  1467. TAG_TYPE pttTags[] = {{TOKEN_PROTOCOL, TRUE,FALSE},
  1468. {TOKEN_PREF_LEVEL, TRUE,FALSE}};
  1469. PDWORD pdwTagType;
  1470. DWORD dwNumTags = 2, dwNumArg, i, dwAddr;
  1471. if (dwCurrentIndex >= dwArgCount)
  1472. {
  1473. //
  1474. // No arguments specified
  1475. //
  1476. return ERROR_SHOW_USAGE;
  1477. }
  1478. dwNumArg = dwArgCount - dwCurrentIndex;
  1479. pdwTagType = HeapAlloc(GetProcessHeap(),
  1480. 0,
  1481. dwNumArg * sizeof(DWORD));
  1482. if (pdwTagType is NULL)
  1483. {
  1484. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1485. return ERROR_NOT_ENOUGH_MEMORY;
  1486. }
  1487. dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments,
  1488. dwCurrentIndex,
  1489. dwArgCount,
  1490. pttTags,
  1491. dwNumTags,
  1492. pdwTagType);
  1493. if (dwErr isnot NO_ERROR)
  1494. {
  1495. HeapFree(GetProcessHeap(),0,pdwTagType);
  1496. if (dwErr is ERROR_INVALID_OPTION_TAG)
  1497. {
  1498. return ERROR_INVALID_SYNTAX; // show usage
  1499. }
  1500. return dwErr;
  1501. }
  1502. for ( i = 0, dwPrefIndex = 0; i < dwNumArg; i++)
  1503. {
  1504. switch (pdwTagType[i])
  1505. {
  1506. case 0: // PROTOCOL
  1507. dwRes = MatchRoutingProtoTag(ppwcArguments[i + dwCurrentIndex]);
  1508. if (dwRes == (DWORD) -1)
  1509. {
  1510. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1511. pttTags[pdwTagType[i]].pwszTag,
  1512. ppwcArguments[i + dwCurrentIndex]);
  1513. i = dwNumArg;
  1514. dwErr = ERROR_INVALID_PARAMETER;
  1515. break;
  1516. }
  1517. pm.dwProtocolId = dwRes;
  1518. //
  1519. // Get the metric too
  1520. //
  1521. if (pdwTagType[i+1] == 1)
  1522. {
  1523. pm.dwMetric =
  1524. wcstoul(ppwcArguments[i + 1 +dwCurrentIndex],NULL,10);
  1525. if (pm.dwMetric==0
  1526. && wcscmp(ppwcArguments[i + 1 +dwCurrentIndex], L"0")!=0)
  1527. {
  1528. dwErr = ERROR_INVALID_SYNTAX;
  1529. i = dwNumArg;
  1530. break;
  1531. }
  1532. i++;
  1533. dwPrefIndex++;
  1534. }
  1535. else
  1536. {
  1537. dwErr = ERROR_INVALID_SYNTAX;
  1538. i = dwNumArg;
  1539. break;
  1540. }
  1541. break;
  1542. default :
  1543. i = dwNumArg;
  1544. dwErr = ERROR_INVALID_SYNTAX;
  1545. break;
  1546. }
  1547. }
  1548. HeapFree(GetProcessHeap(), 0, pdwTagType);
  1549. switch(dwErr)
  1550. {
  1551. case NO_ERROR :
  1552. break;
  1553. default:
  1554. return dwErr;
  1555. }
  1556. dwErr = SetRoutePrefLevel(pm);
  1557. return dwErr;
  1558. }
  1559. DWORD
  1560. HandleIpSetLogLevel(
  1561. IN LPCWSTR pwszMachine,
  1562. IN OUT LPWSTR *ppwcArguments,
  1563. IN DWORD dwCurrentIndex,
  1564. IN DWORD dwArgCount,
  1565. IN DWORD dwFlags,
  1566. IN LPCVOID pvData,
  1567. OUT BOOL *pbDone
  1568. )
  1569. /*++
  1570. Routine Description:
  1571. Gets options for setting global parameter namely logging level
  1572. Arguments:
  1573. ppwcArguments - Argument array
  1574. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1575. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1576. Return Value:
  1577. NO_ERROR
  1578. --*/
  1579. {
  1580. DWORD dwErr = NO_ERROR;
  1581. TAG_TYPE pttTags[] = {{TOKEN_LOG_LEVEL,TRUE,FALSE}};
  1582. PDWORD pdwTagType;
  1583. DWORD dwNumTags = 1, dwNumArg, i, dwAddr;
  1584. DWORD dwLoggingLevel = (DWORD) -1;
  1585. BOOL bOkay = TRUE;
  1586. if (dwCurrentIndex >= dwArgCount)
  1587. {
  1588. //
  1589. // No arguments specified
  1590. //
  1591. return ERROR_SHOW_USAGE;
  1592. }
  1593. dwNumArg = dwArgCount - dwCurrentIndex;
  1594. pdwTagType = HeapAlloc(GetProcessHeap(),
  1595. 0,
  1596. dwNumArg * sizeof(DWORD));
  1597. if (pdwTagType is NULL)
  1598. {
  1599. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1600. return ERROR_NOT_ENOUGH_MEMORY;
  1601. }
  1602. dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments,
  1603. dwCurrentIndex,
  1604. dwArgCount,
  1605. pttTags,
  1606. dwNumTags,
  1607. pdwTagType);
  1608. if (dwErr isnot NO_ERROR)
  1609. {
  1610. HeapFree(GetProcessHeap(),0,pdwTagType);
  1611. if (dwErr is ERROR_INVALID_OPTION_TAG)
  1612. {
  1613. return ERROR_INVALID_SYNTAX;
  1614. }
  1615. return dwErr;
  1616. }
  1617. for ( i = 0; i < dwNumArg; i++)
  1618. {
  1619. switch (pdwTagType[i])
  1620. {
  1621. case 0: // LOGLEVEL
  1622. {
  1623. TOKEN_VALUE rgEnums[] =
  1624. {{TOKEN_VALUE_NONE, IPRTR_LOGGING_NONE},
  1625. {TOKEN_VALUE_ERROR, IPRTR_LOGGING_ERROR},
  1626. {TOKEN_VALUE_WARN, IPRTR_LOGGING_WARN},
  1627. {TOKEN_VALUE_INFO, IPRTR_LOGGING_INFO}};
  1628. dwErr = MatchEnumTag(g_hModule,
  1629. ppwcArguments[i + dwCurrentIndex],
  1630. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1631. rgEnums,
  1632. &dwLoggingLevel);
  1633. if (dwErr != NO_ERROR)
  1634. {
  1635. DispTokenErrMsg(g_hModule,
  1636. MSG_IP_BAD_OPTION_VALUE,
  1637. pttTags[pdwTagType[i]].pwszTag,
  1638. ppwcArguments[i + dwCurrentIndex]);
  1639. DisplayMessage( g_hModule,
  1640. MSG_IP_BAD_OPTION_ENUMERATION,
  1641. pttTags[pdwTagType[i]].pwszTag );
  1642. for (i=0; i<4; i++)
  1643. {
  1644. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  1645. }
  1646. i = dwNumArg;
  1647. dwErr = NO_ERROR;
  1648. bOkay = FALSE;
  1649. break;
  1650. }
  1651. break;
  1652. }
  1653. default :
  1654. {
  1655. i = dwNumArg;
  1656. dwErr = ERROR_INVALID_SYNTAX;
  1657. break;
  1658. }
  1659. }
  1660. }
  1661. HeapFree(GetProcessHeap(), 0, pdwTagType);
  1662. switch(dwErr)
  1663. {
  1664. case NO_ERROR :
  1665. break;
  1666. default:
  1667. return dwErr;
  1668. }
  1669. if (!bOkay)
  1670. {
  1671. return NO_ERROR;
  1672. }
  1673. dwErr = SetGlobalConfigInfo(dwLoggingLevel);
  1674. return dwErr;
  1675. }
  1676. DWORD
  1677. HandleIpSetIfFilter(
  1678. IN LPCWSTR pwszMachine,
  1679. IN OUT LPWSTR *ppwcArguments,
  1680. IN DWORD dwCurrentIndex,
  1681. IN DWORD dwArgCount,
  1682. IN DWORD dwFlags,
  1683. IN LPCVOID pvData,
  1684. OUT BOOL *pbDone
  1685. )
  1686. /*++
  1687. Routine Description:
  1688. Gets options for setting interface filter parameters
  1689. Arguments:
  1690. ppwcArguments - Argument array
  1691. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1692. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1693. Return Value:
  1694. NO_ERROR
  1695. --*/
  1696. {
  1697. DWORD dwNumParsed = 0;
  1698. DWORD dwErr = NO_ERROR,dwRes;
  1699. TAG_TYPE pttTags[] = {{TOKEN_NAME,TRUE,FALSE},
  1700. {TOKEN_FILTER_TYPE,FALSE,FALSE},
  1701. {TOKEN_ACTION,FALSE,FALSE},
  1702. {TOKEN_FRAGCHECK,FALSE,FALSE}};
  1703. PDWORD pdwTagType;
  1704. DWORD dwNumOpt;
  1705. DWORD dwNumTags = 4, dwNumArg, i, j;
  1706. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  1707. DWORD dwFilterType, dwAction;
  1708. BOOL bFragCheck, bOkay = TRUE;
  1709. if (dwCurrentIndex >= dwArgCount)
  1710. {
  1711. //
  1712. // No arguments specified
  1713. //
  1714. return ERROR_SHOW_USAGE;
  1715. }
  1716. dwNumArg = dwArgCount - dwCurrentIndex;
  1717. pdwTagType = HeapAlloc(GetProcessHeap(),
  1718. 0,
  1719. dwNumArg * sizeof(DWORD));
  1720. if (pdwTagType is NULL)
  1721. {
  1722. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  1723. return ERROR_NOT_ENOUGH_MEMORY;
  1724. }
  1725. dwErr = MatchTagsInCmdLine(g_hModule, ppwcArguments,
  1726. dwCurrentIndex,
  1727. dwArgCount,
  1728. pttTags,
  1729. dwNumTags,
  1730. pdwTagType);
  1731. if (dwErr isnot NO_ERROR)
  1732. {
  1733. HeapFree(GetProcessHeap(),0,pdwTagType);
  1734. if (dwErr is ERROR_INVALID_OPTION_TAG)
  1735. {
  1736. return ERROR_INVALID_SYNTAX; // show usage
  1737. }
  1738. return dwErr;
  1739. }
  1740. for ( i = 0; i < dwNumArg; i++)
  1741. {
  1742. switch (pdwTagType[i])
  1743. {
  1744. case 0 :
  1745. {
  1746. GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  1747. wszIfName,
  1748. sizeof(wszIfName),
  1749. &dwNumParsed);
  1750. // no filters allowed on INTERNAL/LOOPBACK interfaces
  1751. if (!_wcsicmp(wszIfName, L"internal") or
  1752. !_wcsicmp(wszIfName, L"loopback"))
  1753. {
  1754. DisplayMessage(g_hModule,
  1755. MSG_IP_BAD_INTERFACE_TYPE,
  1756. wszIfName);
  1757. dwErr = ERROR_INVALID_PARAMETER;
  1758. i = dwNumArg;
  1759. }
  1760. break;
  1761. }
  1762. case 1:
  1763. {
  1764. TOKEN_VALUE rgEnums[] =
  1765. {{TOKEN_VALUE_INPUT, IP_IN_FILTER_INFO},
  1766. {TOKEN_VALUE_OUTPUT, IP_OUT_FILTER_INFO},
  1767. {TOKEN_VALUE_DIAL, IP_DEMAND_DIAL_FILTER_INFO}};
  1768. //
  1769. // Tag TYPE
  1770. //
  1771. dwErr = MatchEnumTag(g_hModule,
  1772. ppwcArguments[i + dwCurrentIndex],
  1773. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1774. rgEnums,
  1775. &dwFilterType);
  1776. if (dwErr != NO_ERROR)
  1777. {
  1778. DispTokenErrMsg(g_hModule, MSG_IP_BAD_OPTION_VALUE,
  1779. pttTags[pdwTagType[i]].pwszTag,
  1780. ppwcArguments[i + dwCurrentIndex]);
  1781. DisplayMessage( g_hModule,
  1782. MSG_IP_BAD_OPTION_ENUMERATION,
  1783. pttTags[pdwTagType[i]].pwszTag );
  1784. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  1785. {
  1786. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  1787. }
  1788. i = dwNumArg;
  1789. bOkay = FALSE;
  1790. dwErr = NO_ERROR;
  1791. break;
  1792. }
  1793. break;
  1794. }
  1795. case 2:
  1796. {
  1797. TOKEN_VALUE rgEnums[] =
  1798. {{TOKEN_VALUE_DROP, PF_ACTION_DROP},
  1799. {TOKEN_VALUE_FORWARD, PF_ACTION_FORWARD}};
  1800. //
  1801. // Tag ACTION
  1802. //
  1803. dwErr = MatchEnumTag(g_hModule,
  1804. ppwcArguments[i + dwCurrentIndex],
  1805. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1806. rgEnums,
  1807. &dwAction);
  1808. if (dwErr != NO_ERROR)
  1809. {
  1810. DispTokenErrMsg(g_hModule,
  1811. MSG_IP_BAD_OPTION_VALUE,
  1812. pttTags[pdwTagType[i]].pwszTag,
  1813. ppwcArguments[i + dwCurrentIndex]);
  1814. DisplayMessage( g_hModule,
  1815. MSG_IP_BAD_OPTION_ENUMERATION,
  1816. pttTags[pdwTagType[i]].pwszTag );
  1817. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  1818. {
  1819. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  1820. }
  1821. i = dwNumArg;
  1822. dwErr = NO_ERROR;
  1823. bOkay = FALSE;
  1824. break;
  1825. }
  1826. break;
  1827. }
  1828. case 3:
  1829. {
  1830. TOKEN_VALUE rgEnums[] =
  1831. {{TOKEN_VALUE_ENABLE, TRUE},
  1832. {TOKEN_VALUE_DISABLE, FALSE}};
  1833. //
  1834. // TAG = FRAGCHK
  1835. //
  1836. dwErr = MatchEnumTag(g_hModule,
  1837. ppwcArguments[i + dwCurrentIndex],
  1838. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1839. rgEnums,
  1840. &dwRes);
  1841. if (dwErr != NO_ERROR)
  1842. {
  1843. DispTokenErrMsg(g_hModule,
  1844. MSG_IP_BAD_OPTION_VALUE,
  1845. pttTags[pdwTagType[i]].pwszTag,
  1846. ppwcArguments[i + dwCurrentIndex]);
  1847. DisplayMessage( g_hModule,
  1848. MSG_IP_BAD_OPTION_ENUMERATION,
  1849. pttTags[pdwTagType[i]].pwszTag );
  1850. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  1851. {
  1852. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  1853. }
  1854. i = dwNumArg;
  1855. dwErr = NO_ERROR;
  1856. bOkay = FALSE;
  1857. break;
  1858. }
  1859. bFragCheck = (dwRes) ? TRUE : FALSE;
  1860. break;
  1861. }
  1862. default:
  1863. {
  1864. i = dwNumArg;
  1865. dwErr = ERROR_INVALID_SYNTAX;
  1866. break;
  1867. }
  1868. }
  1869. }
  1870. HeapFree(GetProcessHeap(), 0, pdwTagType);
  1871. switch(dwErr)
  1872. {
  1873. case NO_ERROR :
  1874. break;
  1875. default:
  1876. return dwErr;
  1877. }
  1878. if (!bOkay)
  1879. {
  1880. return NO_ERROR;
  1881. }
  1882. if (!pttTags[0].bPresent ||
  1883. (pttTags[1].bPresent & !pttTags[2].bPresent) ||
  1884. (!pttTags[1].bPresent & pttTags[2].bPresent))
  1885. {
  1886. return ERROR_INVALID_SYNTAX; // show usage
  1887. }
  1888. if (pttTags[3].bPresent)
  1889. {
  1890. dwErr = SetFragCheckInfo(wszIfName, bFragCheck);
  1891. }
  1892. if (dwErr isnot NO_ERROR)
  1893. {
  1894. return dwErr;
  1895. }
  1896. if (pttTags[1].bPresent)
  1897. {
  1898. dwErr = SetFilterInfo(wszIfName, dwFilterType, dwAction);
  1899. }
  1900. return dwErr;
  1901. }
  1902. DWORD
  1903. IpAddSetDelInterface(
  1904. PWCHAR *ppwcArguments,
  1905. DWORD dwCurrentIndex,
  1906. DWORD dwArgCount,
  1907. DWORD dwAction
  1908. )
  1909. /*++
  1910. Routine Description:
  1911. Gets options for setting interface parameters
  1912. Arguments:
  1913. ppwcArguments - Argument array
  1914. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  1915. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  1916. Return Value:
  1917. NO_ERROR
  1918. --*/
  1919. {
  1920. DWORD dwBitVector = 0, dwNumParsed = 0;
  1921. DWORD dwErr = NO_ERROR, dwRes;
  1922. TAG_TYPE pttTags[] = {
  1923. {TOKEN_NAME, TRUE, FALSE},
  1924. {TOKEN_STATUS, FALSE,FALSE}};
  1925. BOOL bOkay = TRUE;
  1926. DWORD pdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  1927. DWORD dwNumOpt, dwStatus = (DWORD) -1;
  1928. DWORD dwNumTags = 2, dwNumArg, i, j;
  1929. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  1930. DWORD dwMaxArgs = (dwAction is DELETE_COMMAND)? 1
  1931. : sizeof(pttTags)/sizeof(TAG_TYPE);
  1932. // Do generic processing
  1933. dwErr = PreHandleCommand( ppwcArguments,
  1934. dwCurrentIndex,
  1935. dwArgCount,
  1936. pttTags,
  1937. sizeof(pttTags)/sizeof(TAG_TYPE),
  1938. 1,
  1939. dwMaxArgs,
  1940. pdwTagType );
  1941. if (dwErr)
  1942. {
  1943. return dwErr;
  1944. }
  1945. dwNumArg = dwArgCount - dwCurrentIndex;
  1946. for (i=0; i<dwNumArg; i++)
  1947. {
  1948. switch (pdwTagType[i])
  1949. {
  1950. case 0: // NAME
  1951. {
  1952. GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  1953. wszIfName,
  1954. sizeof(wszIfName),
  1955. &dwNumParsed);
  1956. break;
  1957. }
  1958. case 1: // STATE
  1959. {
  1960. TOKEN_VALUE rgEnums[] =
  1961. {{TOKEN_VALUE_ENABLE, IF_ADMIN_STATUS_UP},
  1962. {TOKEN_VALUE_DISABLE, IF_ADMIN_STATUS_DOWN}};
  1963. dwErr = MatchEnumTag(g_hModule,
  1964. ppwcArguments[i + dwCurrentIndex],
  1965. sizeof(rgEnums)/sizeof(TOKEN_VALUE),
  1966. rgEnums,
  1967. &dwStatus);
  1968. if (dwErr isnot NO_ERROR)
  1969. {
  1970. DispTokenErrMsg(g_hModule,
  1971. MSG_IP_BAD_OPTION_VALUE,
  1972. pttTags[pdwTagType[i]].pwszTag,
  1973. ppwcArguments[i + dwCurrentIndex]);
  1974. DisplayMessage( g_hModule,
  1975. MSG_IP_BAD_OPTION_ENUMERATION,
  1976. pttTags[pdwTagType[i]].pwszTag );
  1977. for (i=0; i<sizeof(rgEnums)/sizeof(TOKEN_VALUE); i++)
  1978. {
  1979. DisplayMessageT( L" %1!s!\n", rgEnums[i].pwszToken );
  1980. }
  1981. i = dwNumArg;
  1982. dwErr = NO_ERROR;
  1983. bOkay = FALSE;
  1984. break;
  1985. }
  1986. break;
  1987. }
  1988. }
  1989. }
  1990. if (!bOkay)
  1991. {
  1992. return NO_ERROR;
  1993. }
  1994. if (dwAction is DELETE_COMMAND)
  1995. {
  1996. dwErr = DeleteInterfaceInfo(wszIfName);
  1997. if (dwErr isnot NO_ERROR)
  1998. {
  1999. return dwErr;
  2000. }
  2001. return ERROR_OKAY;
  2002. }
  2003. if (dwStatus is IF_ADMIN_STATUS_DOWN)
  2004. {
  2005. DWORD dwIfType;
  2006. // Make sure we support disabling this interface
  2007. dwErr = GetInterfaceInfo(wszIfName, NULL, NULL, &dwIfType);
  2008. if (dwErr == NO_ERROR)
  2009. {
  2010. if (dwIfType isnot ROUTER_IF_TYPE_DEDICATED)
  2011. {
  2012. DisplayMessage( g_hModule, MSG_IP_CANT_DISABLE_INTERFACE );
  2013. return ERROR_SUPPRESS_OUTPUT;
  2014. }
  2015. }
  2016. }
  2017. if (dwAction is ADD_COMMAND)
  2018. {
  2019. dwErr = AddInterfaceInfo(wszIfName);
  2020. }
  2021. dwErr = UpdateInterfaceStatusInfo(dwAction,
  2022. wszIfName,
  2023. dwStatus);
  2024. if (dwErr isnot NO_ERROR)
  2025. {
  2026. return dwErr;
  2027. }
  2028. return ERROR_OKAY;
  2029. }
  2030. DWORD
  2031. HandleIpAddInterface(
  2032. IN LPCWSTR pwszMachine,
  2033. IN OUT LPWSTR *ppwcArguments,
  2034. IN DWORD dwCurrentIndex,
  2035. IN DWORD dwArgCount,
  2036. IN DWORD dwFlags,
  2037. IN LPCVOID pvData,
  2038. OUT BOOL *pbDone
  2039. )
  2040. {
  2041. return IpAddSetDelInterface( ppwcArguments,
  2042. dwCurrentIndex,
  2043. dwArgCount,
  2044. ADD_COMMAND);
  2045. }
  2046. DWORD
  2047. HandleIpSetInterface(
  2048. IN LPCWSTR pwszMachine,
  2049. IN OUT LPWSTR *ppwcArguments,
  2050. IN DWORD dwCurrentIndex,
  2051. IN DWORD dwArgCount,
  2052. IN DWORD dwFlags,
  2053. IN LPCVOID pvData,
  2054. OUT BOOL *pbDone
  2055. )
  2056. {
  2057. return IpAddSetDelInterface( ppwcArguments,
  2058. dwCurrentIndex,
  2059. dwArgCount,
  2060. SET_COMMAND );
  2061. }
  2062. DWORD
  2063. HandleIpDelInterface(
  2064. IN LPCWSTR pwszMachine,
  2065. IN OUT LPWSTR *ppwcArguments,
  2066. IN DWORD dwCurrentIndex,
  2067. IN DWORD dwArgCount,
  2068. IN DWORD dwFlags,
  2069. IN LPCVOID pvData,
  2070. OUT BOOL *pbDone
  2071. )
  2072. {
  2073. return IpAddSetDelInterface( ppwcArguments,
  2074. dwCurrentIndex,
  2075. dwArgCount,
  2076. DELETE_COMMAND);
  2077. }
  2078. DWORD
  2079. HandleIpShowRoutePref(
  2080. IN LPCWSTR pwszMachine,
  2081. IN OUT LPWSTR *ppwcArguments,
  2082. IN DWORD dwCurrentIndex,
  2083. IN DWORD dwArgCount,
  2084. IN DWORD dwFlags,
  2085. IN LPCVOID pvData,
  2086. OUT BOOL *pbDone
  2087. )
  2088. /*++
  2089. Routine Description:
  2090. Arguments:
  2091. ppwcArguments - Argument array
  2092. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2093. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2094. Return Value:
  2095. NO_ERROR
  2096. --*/
  2097. {
  2098. //
  2099. // No options expected
  2100. //
  2101. return ShowRoutePref(NULL);
  2102. }
  2103. DWORD
  2104. HandleIpShowLogLevel(
  2105. IN LPCWSTR pwszMachine,
  2106. IN OUT LPWSTR *ppwcArguments,
  2107. IN DWORD dwCurrentIndex,
  2108. IN DWORD dwArgCount,
  2109. IN DWORD dwFlags,
  2110. IN LPCVOID pvData,
  2111. OUT BOOL *pbDone
  2112. )
  2113. /*++
  2114. Routine Description:
  2115. Arguments:
  2116. ppwcArguments - Argument array
  2117. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2118. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2119. Return Value:
  2120. NO_ERROR
  2121. --*/
  2122. {
  2123. //
  2124. // No options expected
  2125. //
  2126. if (dwCurrentIndex != dwArgCount)
  2127. {
  2128. return ERROR_SHOW_USAGE;
  2129. }
  2130. return ShowIpGlobal(NULL);
  2131. }
  2132. DWORD
  2133. HandleIpShowProtocol(
  2134. IN LPCWSTR pwszMachine,
  2135. IN OUT LPWSTR *ppwcArguments,
  2136. IN DWORD dwCurrentIndex,
  2137. IN DWORD dwArgCount,
  2138. IN DWORD dwFlags,
  2139. IN LPCVOID pvData,
  2140. OUT BOOL *pbDone
  2141. )
  2142. /*++
  2143. Routine Description:
  2144. Arguments:
  2145. ppwcArguments - Argument array
  2146. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2147. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2148. Return Value:
  2149. NO_ERROR
  2150. --*/
  2151. {
  2152. //
  2153. // No options expected
  2154. //
  2155. return ShowIpProtocol();
  2156. }
  2157. DWORD
  2158. IpShowSingleInterfaceInfo(
  2159. IN LPCWSTR pwszInterfaceName,
  2160. IN DWORD dwInfoType,
  2161. IN DWORD dwFormat,
  2162. IN OUT PDWORD pdwNumRows
  2163. )
  2164. {
  2165. switch(dwInfoType)
  2166. {
  2167. case SHOW_IF_FILTER:
  2168. {
  2169. return ShowIpIfFilter(NULL, dwFormat, pwszInterfaceName, pdwNumRows);
  2170. }
  2171. case SHOW_INTERFACE:
  2172. {
  2173. return ShowIpInterface(dwFormat, pwszInterfaceName, pdwNumRows);
  2174. }
  2175. case SHOW_PERSISTENTROUTE:
  2176. {
  2177. return ShowIpPersistentRoute(NULL, pwszInterfaceName, pdwNumRows);
  2178. }
  2179. default:
  2180. {
  2181. return ERROR_INVALID_PARAMETER;
  2182. }
  2183. }
  2184. }
  2185. DWORD
  2186. IpShowInterfaceInfo(
  2187. PWCHAR *ppwcArguments,
  2188. DWORD dwCurrentIndex,
  2189. DWORD dwArgCount,
  2190. DWORD dwInfoType
  2191. )
  2192. /*++
  2193. Routine Description:
  2194. Gets options for showing various interface information
  2195. Arguments:
  2196. ppwcArguments - Argument array
  2197. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2198. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2199. dwInfoType - The type of info to display
  2200. Return Value:
  2201. NO_ERROR
  2202. --*/
  2203. {
  2204. DWORD dwErr, dwTotal;
  2205. TAG_TYPE pttTags[] = {{TOKEN_NAME,FALSE,FALSE}};
  2206. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  2207. DWORD rgdwTagType[sizeof(pttTags)/sizeof(TAG_TYPE)];
  2208. DWORD dwCount, i, j, dwNumOpt;
  2209. DWORD dwNumTags = 1, dwNumArg, dwNumParsed;
  2210. DWORD dwSize, dwRes, dwNumRows = 0;
  2211. PMPR_INTERFACE_0 pmi0;
  2212. // Do generic processing
  2213. dwErr = PreHandleCommand( ppwcArguments,
  2214. dwCurrentIndex,
  2215. dwArgCount,
  2216. pttTags,
  2217. sizeof(pttTags)/sizeof(TAG_TYPE),
  2218. 0,
  2219. 1,
  2220. rgdwTagType );
  2221. if (dwErr isnot NO_ERROR)
  2222. {
  2223. return dwErr;
  2224. }
  2225. // If interface specified, show info for specified interface only.
  2226. for (i=0; i<dwArgCount-dwCurrentIndex; i++)
  2227. {
  2228. switch (rgdwTagType[i])
  2229. {
  2230. case 0: // NAME
  2231. {
  2232. GetInterfaceName( ppwcArguments[i + dwCurrentIndex],
  2233. wszInterfaceName,
  2234. sizeof(wszInterfaceName),
  2235. &dwNumParsed);
  2236. dwErr = IpShowSingleInterfaceInfo(wszInterfaceName,
  2237. dwInfoType,
  2238. FORMAT_VERBOSE,
  2239. &dwNumRows);
  2240. if (!dwNumRows)
  2241. {
  2242. DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
  2243. }
  2244. return dwErr;
  2245. }
  2246. }
  2247. }
  2248. // No Interface specified. Enumerate interfaces and show
  2249. // info for each interface.
  2250. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
  2251. if (dwErr isnot NO_ERROR)
  2252. {
  2253. return dwErr;
  2254. }
  2255. for (i=0; i<dwCount && dwErr is NO_ERROR; i++)
  2256. {
  2257. dwErr = IpShowSingleInterfaceInfo( pmi0[i].wszInterfaceName,
  2258. dwInfoType,
  2259. FORMAT_TABLE,
  2260. &dwNumRows );
  2261. if (dwErr is ERROR_NO_SUCH_INTERFACE)
  2262. {
  2263. dwErr = NO_ERROR;
  2264. }
  2265. }
  2266. if (!dwNumRows)
  2267. {
  2268. DisplayMessage( g_hModule, MSG_IP_NO_ENTRIES );
  2269. }
  2270. return dwErr;
  2271. }
  2272. DWORD
  2273. HandleIpShowIfFilter(
  2274. IN LPCWSTR pwszMachine,
  2275. IN OUT LPWSTR *ppwcArguments,
  2276. IN DWORD dwCurrentIndex,
  2277. IN DWORD dwArgCount,
  2278. IN DWORD dwFlags,
  2279. IN LPCVOID pvData,
  2280. OUT BOOL *pbDone
  2281. )
  2282. /*++
  2283. Routine Description:
  2284. Arguments:
  2285. ppwcArguments - Argument array
  2286. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2287. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2288. Return Value:
  2289. NO_ERROR
  2290. --*/
  2291. {
  2292. return IpShowInterfaceInfo(ppwcArguments,
  2293. dwCurrentIndex,
  2294. dwArgCount,
  2295. SHOW_IF_FILTER);
  2296. }
  2297. DWORD
  2298. HandleIpShowInterface(
  2299. IN LPCWSTR pwszMachine,
  2300. IN OUT LPWSTR *ppwcArguments,
  2301. IN DWORD dwCurrentIndex,
  2302. IN DWORD dwArgCount,
  2303. IN DWORD dwFlags,
  2304. IN LPCVOID pvData,
  2305. OUT BOOL *pbDone
  2306. )
  2307. /*++
  2308. Routine Description:
  2309. Arguments:
  2310. ppwcArguments - Argument array
  2311. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2312. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2313. Return Value:
  2314. NO_ERROR
  2315. --*/
  2316. {
  2317. return IpShowInterfaceInfo(ppwcArguments,
  2318. dwCurrentIndex,
  2319. dwArgCount,
  2320. SHOW_INTERFACE);
  2321. }
  2322. DWORD
  2323. HandleIpShowPersistentRoute(
  2324. IN LPCWSTR pwszMachine,
  2325. IN OUT LPWSTR *ppwcArguments,
  2326. IN DWORD dwCurrentIndex,
  2327. IN DWORD dwArgCount,
  2328. IN DWORD dwFlags,
  2329. IN LPCVOID pvData,
  2330. OUT BOOL *pbDone
  2331. )
  2332. /*++
  2333. Routine Description:
  2334. Handler for show ip route. We just call the main interface info display
  2335. handler
  2336. Arguments:
  2337. ppwcArguments - Argument array
  2338. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2339. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2340. Return Value:
  2341. NO_ERROR
  2342. --*/
  2343. {
  2344. if (IsRouterRunning())
  2345. {
  2346. DisplayMessage(g_hModule, MSG_IP_PERSISTENT_ROUTER);
  2347. }
  2348. else
  2349. {
  2350. DisplayMessage(g_hModule, MSG_IP_PERSISTENT_CONFIG);
  2351. }
  2352. return IpShowInterfaceInfo(ppwcArguments,
  2353. dwCurrentIndex,
  2354. dwArgCount,
  2355. SHOW_PERSISTENTROUTE);
  2356. }
  2357. DWORD
  2358. HandleIpAddIpIpTunnel(
  2359. IN LPCWSTR pwszMachine,
  2360. IN OUT LPWSTR *ppwcArguments,
  2361. IN DWORD dwCurrentIndex,
  2362. IN DWORD dwArgCount,
  2363. IN DWORD dwFlags,
  2364. IN LPCVOID pvData,
  2365. OUT BOOL *pbDone
  2366. )
  2367. /*++
  2368. Routine Description:
  2369. Arguments:
  2370. ppwcArguments - Argument array
  2371. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2372. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2373. Return Value:
  2374. NO_ERROR
  2375. --*/
  2376. {
  2377. return IpAddSetIpIpTunnel(ppwcArguments,
  2378. dwCurrentIndex,
  2379. dwArgCount,
  2380. TRUE);
  2381. }
  2382. DWORD
  2383. HandleIpSetIpIpTunnel(
  2384. IN LPCWSTR pwszMachine,
  2385. IN OUT LPWSTR *ppwcArguments,
  2386. IN DWORD dwCurrentIndex,
  2387. IN DWORD dwArgCount,
  2388. IN DWORD dwFlags,
  2389. IN LPCVOID pvData,
  2390. OUT BOOL *pbDone
  2391. )
  2392. /*++
  2393. Routine Description:
  2394. Arguments:
  2395. ppwcArguments - Argument array
  2396. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is the first arg
  2397. dwArgCount - ppwcArguments[dwArgCount - 1] is the last arg
  2398. Return Value:
  2399. NO_ERROR
  2400. --*/
  2401. {
  2402. return IpAddSetIpIpTunnel(ppwcArguments,
  2403. dwCurrentIndex,
  2404. dwArgCount,
  2405. FALSE);
  2406. }
  2407. DWORD
  2408. IpAddSetIpIpTunnel(
  2409. PWCHAR *ppwcArguments,
  2410. DWORD dwCurrentIndex,
  2411. DWORD dwArgCount,
  2412. BOOL bAdd
  2413. )
  2414. {
  2415. DWORD dwNumArgs, dwErr, dwNumParsed;
  2416. TAG_TYPE rgTags[] = {{TOKEN_NAME, TRUE, FALSE},
  2417. {TOKEN_LOCALADDR, TRUE, FALSE},
  2418. {TOKEN_REMADDR, TRUE, FALSE},
  2419. {TOKEN_TTL, FALSE,FALSE}};
  2420. WCHAR rgwcIfName[MAX_INTERFACE_NAME_LEN + 1];
  2421. DWORD rgdwTagType[sizeof(rgTags)/sizeof(TAG_TYPE)];
  2422. ULONG i;
  2423. PWCHAR pwszIfName;
  2424. IPINIP_CONFIG_INFO ConfigInfo;
  2425. dwNumArgs = dwArgCount - dwCurrentIndex;
  2426. if((dwCurrentIndex > dwArgCount) or
  2427. (dwNumArgs isnot 4))
  2428. {
  2429. //
  2430. // No arguments specified
  2431. //
  2432. return ERROR_SHOW_USAGE;
  2433. }
  2434. dwErr = MatchTagsInCmdLine(g_hModule,
  2435. ppwcArguments,
  2436. dwCurrentIndex,
  2437. dwArgCount,
  2438. rgTags,
  2439. sizeof(rgTags)/sizeof(TAG_TYPE),
  2440. rgdwTagType);
  2441. if (dwErr isnot NO_ERROR)
  2442. {
  2443. if (dwErr is ERROR_INVALID_OPTION_TAG)
  2444. {
  2445. return ERROR_INVALID_SYNTAX;
  2446. }
  2447. return dwErr;
  2448. }
  2449. for(i = 0; i < dwNumArgs; i ++)
  2450. {
  2451. switch (rgdwTagType[i])
  2452. {
  2453. case 0 : // NAME
  2454. {
  2455. dwErr = GetInterfaceName(ppwcArguments[i + dwCurrentIndex],
  2456. rgwcIfName,
  2457. sizeof(rgwcIfName),
  2458. &dwNumParsed);
  2459. if(bAdd)
  2460. {
  2461. if(dwErr is NO_ERROR)
  2462. {
  2463. return ERROR_OBJECT_ALREADY_EXISTS;
  2464. }
  2465. pwszIfName = ppwcArguments[i + dwCurrentIndex];
  2466. }
  2467. else
  2468. {
  2469. if(dwErr isnot NO_ERROR)
  2470. {
  2471. return dwErr;
  2472. }
  2473. pwszIfName = rgwcIfName;
  2474. }
  2475. break;
  2476. }
  2477. case 1:
  2478. {
  2479. //
  2480. // Tag for localaddr
  2481. //
  2482. dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex],
  2483. &ConfigInfo.dwLocalAddress);
  2484. break;
  2485. }
  2486. case 2:
  2487. {
  2488. //
  2489. // Tag for remoteaddr
  2490. //
  2491. dwErr = GetIpAddress(ppwcArguments[i + dwCurrentIndex],
  2492. &ConfigInfo.dwRemoteAddress);
  2493. break;
  2494. }
  2495. case 3:
  2496. {
  2497. //
  2498. // Tag for ttl
  2499. //
  2500. ConfigInfo.byTtl =
  2501. LOBYTE(LOWORD(wcstoul(ppwcArguments[i + dwCurrentIndex],
  2502. NULL,
  2503. 10)));
  2504. break;
  2505. }
  2506. default:
  2507. {
  2508. i = dwNumArgs;
  2509. dwErr = ERROR_INVALID_SYNTAX;
  2510. break;
  2511. }
  2512. }
  2513. }
  2514. switch(dwErr)
  2515. {
  2516. case NO_ERROR:
  2517. {
  2518. break;
  2519. }
  2520. default:
  2521. {
  2522. return dwErr;
  2523. }
  2524. }
  2525. for(i = 0; i < dwNumArgs; i++)
  2526. {
  2527. if(!rgTags[i].bPresent)
  2528. {
  2529. DisplayMessage(g_hModule,
  2530. MSG_CANT_FIND_EOPT);
  2531. return ERROR_INVALID_SYNTAX;
  2532. }
  2533. }
  2534. dwErr = AddSetIpIpTunnelInfo(pwszIfName,
  2535. &ConfigInfo);
  2536. return dwErr;
  2537. }
  2538. DWORD
  2539. IpDump(
  2540. IN LPCWSTR pwszRouter,
  2541. IN LPWSTR *ppwcArguments,
  2542. IN DWORD dwArgCount,
  2543. IN LPCVOID pvData
  2544. )
  2545. {
  2546. DumpIpInformation((HANDLE)-1);
  2547. return NO_ERROR;
  2548. }
  2549. #if 0
  2550. DWORD
  2551. HandleIpInstall(
  2552. PWCHAR pwszMachine,
  2553. PWCHAR *ppwcArguments,
  2554. DWORD dwCurrentIndex,
  2555. DWORD dwArgCount,
  2556. DWORD dwFlags,
  2557. PVOID pvData,
  2558. BOOL *pbDone
  2559. )
  2560. {
  2561. // XXX DLLPath, ProtocolId
  2562. // XXX set default info here
  2563. // global info block (what is this?)
  2564. // protocol priority block (no need?)
  2565. // multicast boundaries block (no need)
  2566. return NO_ERROR;
  2567. }
  2568. DWORD
  2569. HandleIpUninstall(
  2570. PWCHAR pwszMachine,
  2571. PWCHAR *ppwcArguments,
  2572. DWORD dwCurrentIndex,
  2573. DWORD dwArgCount,
  2574. DWORD dwFlags,
  2575. PVOID pvData,
  2576. BOOL *pbDone
  2577. )
  2578. {
  2579. PMPR_INTERFACE_0 pmi0;
  2580. DWORD dwCount, dwTotal, i, dwErr;
  2581. // Remove global info
  2582. // XXX
  2583. // Remove interface info
  2584. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
  2585. if (dwErr is NO_ERROR)
  2586. {
  2587. for (i=0; i<dwCount; i++)
  2588. {
  2589. DeleteInterfaceInfo(pmi0[i].wszInterfaceName);
  2590. }
  2591. }
  2592. return NO_ERROR;
  2593. }
  2594. #endif
  2595. DWORD
  2596. HandleIpReset(
  2597. IN LPCWSTR pwszMachine,
  2598. IN OUT LPWSTR *ppwcArguments,
  2599. IN DWORD dwCurrentIndex,
  2600. IN DWORD dwArgCount,
  2601. IN DWORD dwFlags,
  2602. IN LPCVOID pvData,
  2603. OUT BOOL *pbDone
  2604. )
  2605. {
  2606. PMPR_INTERFACE_0 pmi0;
  2607. DWORD dwCount, dwTotal, i, dwErr, dwSize, dwBlkSize;
  2608. DWORD dwNumProtocols;
  2609. GLOBAL_INFO gi;
  2610. PPRIORITY_INFO pPriInfo;
  2611. PPROTOCOL_METRIC pProtocolMetrics;
  2612. RTR_INFO_BLOCK_HEADER *pInfoHdr;
  2613. RTR_INFO_BLOCK_HEADER *pLocalInfoHdr;
  2614. PROTOCOL_METRIC defaultProtocolMetrics[] =
  2615. {
  2616. {PROTO_IP_LOCAL, 1},
  2617. {PROTO_IP_NT_STATIC, 3},
  2618. {PROTO_IP_NT_STATIC_NON_DOD, 5},
  2619. {PROTO_IP_NT_AUTOSTATIC, 7},
  2620. {PROTO_IP_NETMGMT, 10},
  2621. {PROTO_IP_OSPF, 110},
  2622. {PROTO_IP_RIP, 120}
  2623. };
  2624. PROTOCOL_METRIC defaultProtocolMetricsNT4[] =
  2625. {
  2626. {PROTO_IP_LOCAL, 1},
  2627. {PROTO_IP_NETMGMT, 2},
  2628. {PROTO_IP_OSPF, 3},
  2629. {PROTO_IP_RIP, 4},
  2630. {PROTO_IP_IGMP, 5}
  2631. };
  2632. // delete all blocks except the IP_GLOBAL_INFO
  2633. dwErr = ValidateGlobalInfo(&pInfoHdr);
  2634. if (dwErr is NO_ERROR)
  2635. {
  2636. // Copy to a local buffer just in case the APIs modify it as we go
  2637. dwSize = sizeof(RTR_INFO_BLOCK_HEADER) * pInfoHdr->TocEntriesCount;
  2638. pLocalInfoHdr = MALLOC(dwSize);
  2639. if (pLocalInfoHdr is NULL)
  2640. {
  2641. return ERROR_NOT_ENOUGH_MEMORY;
  2642. }
  2643. memcpy(pLocalInfoHdr, pInfoHdr, dwSize);
  2644. // Set Global and RoutePref info
  2645. {
  2646. dwBlkSize = sizeof(GLOBAL_INFO);
  2647. dwCount = 1;
  2648. gi.bFilteringOn = FALSE;
  2649. gi.dwLoggingLevel = IPRTR_LOGGING_ERROR;
  2650. dwErr = IpmontrSetInfoBlockInGlobalInfo(IP_GLOBAL_INFO,
  2651. (PBYTE) &gi,
  2652. dwBlkSize,
  2653. dwCount);
  2654. }
  2655. {
  2656. // Based on the router version, calculate the number
  2657. // of protocols etc.
  2658. // TODO: currently assuming >=NT5. Should find out the router
  2659. // version somehow
  2660. dwNumProtocols =
  2661. sizeof(defaultProtocolMetrics)/sizeof(PROTOCOL_METRIC);
  2662. pProtocolMetrics = defaultProtocolMetrics;
  2663. dwBlkSize = SIZEOF_PRIORITY_INFO(dwNumProtocols);
  2664. dwCount = 1;
  2665. // Allocate buffer to hold the Priority Information
  2666. pPriInfo = MALLOC(dwBlkSize);
  2667. if (pPriInfo is NULL)
  2668. {
  2669. return ERROR_NOT_ENOUGH_MEMORY;
  2670. }
  2671. pPriInfo->dwNumProtocols = dwNumProtocols;
  2672. memcpy(
  2673. pPriInfo->ppmProtocolMetric,
  2674. pProtocolMetrics,
  2675. dwNumProtocols * sizeof(PROTOCOL_METRIC));
  2676. dwErr = IpmontrSetInfoBlockInGlobalInfo(IP_PROT_PRIORITY_INFO,
  2677. (PBYTE) pPriInfo,
  2678. dwBlkSize,
  2679. dwCount);
  2680. FREE(pPriInfo);
  2681. }
  2682. for (i=0; i<pLocalInfoHdr->TocEntriesCount; i++)
  2683. {
  2684. switch (pLocalInfoHdr->TocEntry[i].InfoType)
  2685. {
  2686. case IP_GLOBAL_INFO:
  2687. case IP_PROT_PRIORITY_INFO:
  2688. // already done
  2689. break;
  2690. default:
  2691. IpmontrDeleteInfoBlockFromGlobalInfo(
  2692. pLocalInfoHdr->TocEntry[i].InfoType );
  2693. break;
  2694. }
  2695. }
  2696. FREE(pLocalInfoHdr);
  2697. }
  2698. // Delete all interface info
  2699. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0, &dwCount, &dwTotal);
  2700. if (dwErr is NO_ERROR)
  2701. {
  2702. for (i=0; i<dwCount; i++)
  2703. {
  2704. DeleteInterfaceInfo(pmi0[i].wszInterfaceName);
  2705. }
  2706. }
  2707. return NO_ERROR;
  2708. }