Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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