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.

4693 lines
121 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. qosopt.c
  5. Abstract:
  6. Fns to parse QOS commands
  7. Revision History:
  8. --*/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. //
  12. // Install, Uninstall Handlers
  13. //
  14. DWORD
  15. HandleQosInstall(
  16. PWCHAR pwszMachine,
  17. PTCHAR *pptcArguments,
  18. DWORD dwCurrentIndex,
  19. DWORD dwArgCount,
  20. DWORD dwFlags,
  21. MIB_SERVER_HANDLE hMibServer,
  22. BOOL *pbDone
  23. )
  24. /*++
  25. Routine Description:
  26. Gets options for adding QOS global info
  27. Arguments:
  28. pptcArguments - Argument array
  29. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  30. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  31. Return Value:
  32. NO_ERROR or Error Code
  33. --*/
  34. {
  35. PBYTE pbInfoBlk;
  36. DWORD dwSize, dwErr;
  37. //
  38. // No options expected for add command.
  39. //
  40. if (dwCurrentIndex != dwArgCount)
  41. {
  42. //
  43. // No arguments specified
  44. //
  45. return ERROR_INVALID_SYNTAX;
  46. }
  47. pbInfoBlk = NULL;
  48. do
  49. {
  50. dwErr = MakeQosGlobalInfo( &pbInfoBlk, &dwSize);
  51. if (dwErr != NO_ERROR)
  52. {
  53. break;
  54. }
  55. //
  56. // Add Qos to global block
  57. //
  58. dwErr = IpmontrSetInfoBlockInGlobalInfo(MS_IP_QOSMGR,
  59. pbInfoBlk,
  60. dwSize,
  61. 1);
  62. if (dwErr == NO_ERROR)
  63. {
  64. UpdateAllInterfaceConfigs();
  65. }
  66. }
  67. while (FALSE);
  68. HEAP_FREE_NOT_NULL(pbInfoBlk);
  69. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  70. }
  71. DWORD
  72. HandleQosUninstall(
  73. PWCHAR pwszMachine,
  74. PTCHAR *pptcArguments,
  75. DWORD dwCurrentIndex,
  76. DWORD dwArgCount,
  77. DWORD dwFlags,
  78. MIB_SERVER_HANDLE hMibServer,
  79. BOOL *pbDone
  80. )
  81. /*++
  82. Routine Description:
  83. Gets options for deleting QOS global info
  84. Arguments:
  85. pptcArguments - Argument array
  86. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  87. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  88. Return Value:
  89. NO_ERROR or Error Code
  90. --*/
  91. {
  92. DWORD dwErr;
  93. //
  94. // No options expected for add command.
  95. //
  96. if (dwCurrentIndex != dwArgCount)
  97. {
  98. //
  99. // No arguments specified
  100. //
  101. return ERROR_INVALID_SYNTAX;
  102. }
  103. dwErr = IpmontrDeleteProtocol(MS_IP_QOSMGR);
  104. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  105. }
  106. //
  107. // Add, Del, Show Child Helpers
  108. //
  109. //
  110. // Set and Show Global Handlers
  111. //
  112. DWORD
  113. HandleQosSetGlobal(
  114. PWCHAR pwszMachine,
  115. PTCHAR *pptcArguments,
  116. DWORD dwCurrentIndex,
  117. DWORD dwArgCount,
  118. DWORD dwFlags,
  119. MIB_SERVER_HANDLE hMibServer,
  120. BOOL *pbDone
  121. )
  122. /*++
  123. Routine Description:
  124. Gets options for setting QOS global info
  125. Arguments:
  126. pptcArguments - Argument array
  127. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  128. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  129. Return Value:
  130. NO_ERROR or Error Code
  131. --*/
  132. {
  133. DWORD dwBitVector;
  134. DWORD dwErr, dwRes;
  135. DWORD dwNumArg, i, j;
  136. IPQOS_GLOBAL_CONFIG igcGlobalCfg;
  137. TAG_TYPE pttTags[] = {{TOKEN_OPT_LOG_LEVEL,FALSE,FALSE}};
  138. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  139. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  140. //
  141. // parse command arguements
  142. //
  143. dwErr = PreprocessCommand(
  144. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  145. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  146. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  147. );
  148. if ( dwErr != NO_ERROR )
  149. {
  150. return dwErr;
  151. }
  152. dwNumArg = dwArgCount - dwCurrentIndex;
  153. dwBitVector = 0;
  154. for ( i = 0; i < dwNumArg; i++)
  155. {
  156. switch (pdwTagType[i])
  157. {
  158. case 0 :
  159. {
  160. //
  161. // Tag LOGLEVEL
  162. //
  163. TOKEN_VALUE rgEnums[] =
  164. {{TOKEN_OPT_VALUE_NONE, IPQOS_LOGGING_NONE},
  165. {TOKEN_OPT_VALUE_ERROR, IPQOS_LOGGING_ERROR},
  166. {TOKEN_OPT_VALUE_WARN, IPQOS_LOGGING_WARN},
  167. {TOKEN_OPT_VALUE_INFO, IPQOS_LOGGING_INFO}};
  168. GET_ENUM_TAG_VALUE();
  169. igcGlobalCfg.LoggingLevel = dwRes;
  170. dwBitVector |= QOS_LOG_MASK;
  171. break;
  172. }
  173. default:
  174. {
  175. i = dwNumArg;
  176. dwErr = ERROR_INVALID_SYNTAX;
  177. break;
  178. }
  179. }
  180. }
  181. if (dwErr == NO_ERROR)
  182. {
  183. if (dwBitVector)
  184. {
  185. dwErr = UpdateQosGlobalConfig(&igcGlobalCfg,
  186. dwBitVector);
  187. }
  188. }
  189. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  190. }
  191. DWORD
  192. HandleQosShowGlobal(
  193. PWCHAR pwszMachine,
  194. PTCHAR *pptcArguments,
  195. DWORD dwCurrentIndex,
  196. DWORD dwArgCount,
  197. DWORD dwFlags,
  198. MIB_SERVER_HANDLE hMibServer,
  199. BOOL *pbDone
  200. )
  201. /*++
  202. Routine Description:
  203. Gets options for showing QOS global info
  204. Arguments:
  205. pptcArguments - Argument array
  206. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  207. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  208. Return Value:
  209. NO_ERROR
  210. --*/
  211. {
  212. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  213. //
  214. // Does not expect any arguments. If any are specified, report error.
  215. //
  216. if (dwCurrentIndex != dwArgCount)
  217. {
  218. return ERROR_INVALID_SYNTAX;
  219. }
  220. return ShowQosGlobalInfo(NULL);
  221. }
  222. //
  223. // Add, Del, Set, Show If Handlers
  224. //
  225. DWORD
  226. HandleQosAddIf(
  227. PWCHAR pwszMachine,
  228. PTCHAR *pptcArguments,
  229. DWORD dwCurrentIndex,
  230. DWORD dwArgCount,
  231. DWORD dwFlags,
  232. MIB_SERVER_HANDLE hMibServer,
  233. BOOL *pbDone
  234. )
  235. /*++
  236. Routine Description:
  237. Gets options for add interface
  238. Arguments:
  239. pptcArguments - Argument array
  240. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  241. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  242. Return Value:
  243. dwErr
  244. --*/
  245. {
  246. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  247. DWORD dwErr, dwIfType, dwBlkSize, dwBitVector = 0, dwCount;
  248. IPQOS_IF_CONFIG ChangeCfg;
  249. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  250. //
  251. // get optional parameters that are also being set
  252. //
  253. ZeroMemory(&ChangeCfg, sizeof(IPQOS_IF_CONFIG));
  254. dwErr = GetQosSetIfOpt(pptcArguments,
  255. dwCurrentIndex,
  256. dwArgCount,
  257. wszInterfaceName,
  258. sizeof(wszInterfaceName),
  259. &ChangeCfg,
  260. &dwBitVector,
  261. ADD_FLAG
  262. );
  263. if (dwErr != NO_ERROR)
  264. {
  265. return dwErr;
  266. }
  267. do
  268. {
  269. //
  270. // make sure that the interface does not already exist in the config
  271. //
  272. {
  273. PIPQOS_IF_CONFIG pTmpCfg;
  274. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(wszInterfaceName,
  275. MS_IP_QOSMGR,
  276. (PBYTE *) &pTmpCfg,
  277. &dwBlkSize,
  278. &dwCount,
  279. &dwIfType);
  280. if (dwErr is NO_ERROR && pTmpCfg != NULL)
  281. {
  282. HEAP_FREE(pTmpCfg);
  283. DisplayMessage(g_hModule, EMSG_INTERFACE_EXISTS,
  284. wszInterfaceName);
  285. return ERROR_SUPPRESS_OUTPUT;
  286. }
  287. }
  288. //
  289. // check if Qos global info is set. else add Qos global info
  290. //
  291. {
  292. PIPQOS_GLOBAL_CONFIG pGlobalConfig = NULL;
  293. DWORD dwBlkSize, dwCount;
  294. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  295. (PBYTE *) &pGlobalConfig,
  296. &dwBlkSize,
  297. &dwCount);
  298. HEAP_FREE_NOT_NULL(pGlobalConfig);
  299. if ((dwErr is ERROR_NOT_FOUND) || (dwBlkSize == 0))
  300. {
  301. // create qos global info
  302. dwErr = HandleQosInstall(pwszMachine,
  303. NULL,
  304. 0,
  305. 0,
  306. dwFlags,
  307. hMibServer,
  308. pbDone);
  309. }
  310. if (dwErr != NO_ERROR)
  311. {
  312. break;
  313. }
  314. }
  315. //
  316. // set the interface info
  317. //
  318. dwErr = UpdateQosInterfaceConfig(wszInterfaceName,
  319. &ChangeCfg,
  320. dwBitVector,
  321. ADD_FLAG);
  322. }
  323. while (FALSE);
  324. // no error message
  325. return (dwErr == NO_ERROR) ? ERROR_OKAY: dwErr;
  326. }
  327. DWORD
  328. HandleQosDelIf(
  329. PWCHAR pwszMachine,
  330. PTCHAR *pptcArguments,
  331. DWORD dwCurrentIndex,
  332. DWORD dwArgCount,
  333. DWORD dwFlags,
  334. MIB_SERVER_HANDLE hMibServer,
  335. BOOL *pbDone
  336. )
  337. /*++
  338. Routine Description:
  339. Gets options for del interface
  340. Arguments:
  341. pptcArguments - Argument array
  342. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  343. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  344. Return Value:
  345. NO_ERROR
  346. --*/
  347. {
  348. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  349. DWORD dwErr, dwIfType, dwBlkSize, dwBitVector = 0, dwCount;
  350. IPQOS_IF_CONFIG ChangeCfg; //will not be used
  351. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  352. //
  353. // get interface name.
  354. //
  355. ZeroMemory( &ChangeCfg, sizeof(IPQOS_IF_CONFIG) );
  356. dwErr = GetQosSetIfOpt(pptcArguments,
  357. dwCurrentIndex,
  358. dwArgCount,
  359. wszInterfaceName,
  360. sizeof(wszInterfaceName),
  361. &ChangeCfg,
  362. &dwBitVector,
  363. ADD_FLAG
  364. );
  365. if (dwErr != NO_ERROR)
  366. {
  367. return dwErr;
  368. }
  369. //
  370. // make sure that no other option is set.
  371. //
  372. if (dwBitVector)
  373. {
  374. return ERROR_INVALID_SYNTAX;
  375. }
  376. //
  377. // delete interface info
  378. //
  379. dwErr = IpmontrDeleteInfoBlockFromInterfaceInfo(wszInterfaceName,
  380. MS_IP_QOSMGR);
  381. return (dwErr == NO_ERROR) ? ERROR_OKAY: dwErr;
  382. }
  383. DWORD
  384. HandleQosSetIf(
  385. PWCHAR pwszMachine,
  386. PTCHAR *pptcArguments,
  387. DWORD dwCurrentIndex,
  388. DWORD dwArgCount,
  389. DWORD dwFlags,
  390. MIB_SERVER_HANDLE hMibServer,
  391. BOOL *pbDone
  392. )
  393. /*++
  394. Routine Description:
  395. Gets options for set interface
  396. Arguments:
  397. pptcArguments - Argument array
  398. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  399. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  400. Return Value:
  401. NO_ERROR
  402. --*/
  403. {
  404. IPQOS_IF_CONFIG ChangeCfg; //no variable parts can be set
  405. DWORD dwBitVector = 0,
  406. dwErr = NO_ERROR;
  407. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  408. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  409. //
  410. // get the optional interface parameters
  411. //
  412. ZeroMemory( &ChangeCfg, sizeof(IPQOS_IF_CONFIG) );
  413. dwErr = GetQosSetIfOpt(pptcArguments,
  414. dwCurrentIndex,
  415. dwArgCount,
  416. wszIfName,
  417. sizeof(wszIfName),
  418. &ChangeCfg,
  419. &dwBitVector,
  420. SET_FLAG
  421. );
  422. if (dwErr != NO_ERROR)
  423. {
  424. return dwErr;
  425. }
  426. if (dwBitVector)
  427. {
  428. //
  429. // Call UpdateInterfaceCfg
  430. //
  431. dwErr = UpdateQosInterfaceConfig(wszIfName,
  432. &ChangeCfg,
  433. dwBitVector,
  434. SET_FLAG);
  435. }
  436. return (dwErr == NO_ERROR) ? ERROR_OKAY: dwErr;
  437. }
  438. DWORD
  439. HandleQosShowIf(
  440. PWCHAR pwszMachine,
  441. PTCHAR *pptcArguments,
  442. DWORD dwCurrentIndex,
  443. DWORD dwArgCount,
  444. DWORD dwFlags,
  445. MIB_SERVER_HANDLE hMibServer,
  446. BOOL *pbDone
  447. )
  448. /*++
  449. Routine Description:
  450. Gets options for showing QOS interface info
  451. Arguments:
  452. pptcArguments - Argument array
  453. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  454. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  455. Return Value:
  456. NO_ERROR
  457. --*/
  458. {
  459. DWORD i, j, dwErr = NO_ERROR, dwNumOpt;
  460. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  461. DWORD dwNumArg,
  462. dwBufferSize = sizeof(wszInterfaceName);
  463. DWORD dwSize, dwRes;
  464. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,FALSE,FALSE}};
  465. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  466. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  467. if (dwCurrentIndex == dwArgCount) {
  468. dwErr = ShowQosAllInterfaceInfo( NULL ) ;
  469. return dwErr;
  470. }
  471. //
  472. // Parse command line
  473. //
  474. dwErr = PreprocessCommand(
  475. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  476. pttTags, NUM_TAGS_IN_TABLE(pttTags),
  477. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  478. );
  479. if ( dwErr != NO_ERROR )
  480. {
  481. return dwErr;
  482. }
  483. dwNumArg = dwArgCount - dwCurrentIndex;
  484. for ( i = 0; i < dwNumArg; i++)
  485. {
  486. switch (pdwTagType[i])
  487. {
  488. case 0 :
  489. IpmontrGetIfNameFromFriendlyName(pptcArguments[i + dwCurrentIndex],
  490. wszInterfaceName,&dwBufferSize);
  491. break;
  492. default:
  493. i = dwNumArg;
  494. dwErr = ERROR_INVALID_SYNTAX;
  495. break;
  496. }
  497. }
  498. if (dwErr == NO_ERROR)
  499. {
  500. dwErr = ShowQosInterfaceInfo(NULL, wszInterfaceName);
  501. }
  502. return dwErr;
  503. }
  504. //
  505. // Dump Handlers
  506. //
  507. DWORD
  508. DumpQosInformation (
  509. HANDLE hFile
  510. )
  511. /*++
  512. Routine Description:
  513. Dumps Qos information to a text file
  514. Arguments:
  515. Return Value:
  516. NO_ERROR
  517. --*/
  518. {
  519. //DisplayMessageT( DMP_QOS_HEADER );
  520. DisplayMessage(g_hModule, MSG_QOS_HEADER);
  521. DisplayMessageT( DMP_QOS_PUSHD );
  522. DisplayMessageT( DMP_QOS_UNINSTALL );
  523. //DisplayMessageT(DMP_QOS_GLOBAL_HEADER) ;
  524. //
  525. // dump qos global information
  526. //
  527. ShowQosGlobalInfo( hFile ) ;
  528. //
  529. // dump flowspecs at the end
  530. // of the global information
  531. //
  532. ShowQosFlowspecs(hFile, NULL);
  533. //
  534. // dump qos objects that occur
  535. // at the end of flowspec info
  536. //
  537. ShowQosObjects(hFile,
  538. NULL,
  539. QOS_OBJECT_END_OF_LIST);
  540. //DisplayMessageT(DMP_QOS_GLOBAL_FOOTER);
  541. //
  542. // dump qos config for all interfaces
  543. //
  544. ShowQosAllInterfaceInfo( hFile );
  545. DisplayMessageT( DMP_POPD );
  546. //DisplayMessageT( DMP_QOS_FOOTER );
  547. DisplayMessage( g_hModule, MSG_QOS_FOOTER );
  548. return NO_ERROR ;
  549. }
  550. DWORD
  551. QosDump(
  552. PWCHAR pwszMachine,
  553. WCHAR **ppwcArguments,
  554. DWORD dwArgCount,
  555. PVOID pvData
  556. )
  557. {
  558. return DumpQosInformation((HANDLE) -1);
  559. }
  560. //
  561. // Help Handlers
  562. //
  563. //
  564. // Flowspec Add, Del, Set Handlers
  565. //
  566. DWORD
  567. HandleQosAddFlowspec(
  568. PWCHAR pwszMachine,
  569. PTCHAR *pptcArguments,
  570. DWORD dwCurrentIndex,
  571. DWORD dwArgCount,
  572. DWORD dwFlags,
  573. MIB_SERVER_HANDLE hMibServer,
  574. BOOL *pbDone
  575. )
  576. /*++
  577. Routine Description:
  578. Gets options for adding flowspecs to the
  579. global info.
  580. Arguments:
  581. pptcArguments - Argument array
  582. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  583. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  584. Return Value:
  585. NO_ERROR
  586. --*/
  587. {
  588. return GetQosAddDelFlowspecOpt(pptcArguments,
  589. dwCurrentIndex,
  590. dwArgCount,
  591. TRUE);
  592. }
  593. DWORD
  594. HandleQosDelFlowspec(
  595. PWCHAR pwszMachine,
  596. PTCHAR *pptcArguments,
  597. DWORD dwCurrentIndex,
  598. DWORD dwArgCount,
  599. DWORD dwFlags,
  600. MIB_SERVER_HANDLE hMibServer,
  601. BOOL *pbDone
  602. )
  603. /*++
  604. Routine Description:
  605. Gets options for deleting flowspecs from the
  606. global info.
  607. Arguments:
  608. pptcArguments - Argument array
  609. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  610. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  611. Return Value:
  612. NO_ERROR
  613. --*/
  614. {
  615. return GetQosAddDelFlowspecOpt(pptcArguments,
  616. dwCurrentIndex,
  617. dwArgCount,
  618. FALSE);
  619. }
  620. DWORD
  621. HandleQosShowFlowspec(
  622. PWCHAR pwszMachine,
  623. PTCHAR *pptcArguments,
  624. DWORD dwCurrentIndex,
  625. DWORD dwArgCount,
  626. DWORD dwFlags,
  627. MIB_SERVER_HANDLE hMibServer,
  628. BOOL *pbDone
  629. )
  630. /*++
  631. Routine Description:
  632. Gets options for showing flowspecs in the
  633. global info.
  634. Arguments:
  635. None
  636. Return Value:
  637. None
  638. --*/
  639. {
  640. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,FALSE,FALSE}};
  641. PTCHAR pszFlowspec;
  642. DWORD dwNumOpt, dwRes;
  643. DWORD dwNumArg, i, j;
  644. DWORD dwTagType, dwErr;
  645. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  646. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  647. if (dwCurrentIndex == dwArgCount)
  648. {
  649. //
  650. // No arguments - show all flowspecs
  651. //
  652. pszFlowspec = NULL;
  653. }
  654. else {
  655. //
  656. // Get name of the flowspec to show
  657. //
  658. dwErr = PreprocessCommand(
  659. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  660. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  661. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  662. );
  663. if ( dwErr != NO_ERROR )
  664. {
  665. return dwErr;
  666. }
  667. dwNumArg = dwArgCount - dwCurrentIndex;
  668. if (dwNumArg != 1)
  669. {
  670. return ERROR_INVALID_SYNTAX;
  671. }
  672. pszFlowspec = pptcArguments[dwCurrentIndex];
  673. }
  674. return ShowQosFlowspecs(NULL, pszFlowspec);
  675. }
  676. //
  677. // DsRule Add, Del, Show Handlers
  678. //
  679. DWORD
  680. HandleQosAddDsRule(
  681. PWCHAR pwszMachine,
  682. PTCHAR *pptcArguments,
  683. DWORD dwCurrentIndex,
  684. DWORD dwArgCount,
  685. DWORD dwFlags,
  686. MIB_SERVER_HANDLE hMibServer,
  687. BOOL *pbDone
  688. )
  689. /*++
  690. Routine Description:
  691. Gets options for adding diffserv rules to the
  692. diffserv maps in global info. If the diffserv
  693. map in not already present, a new one will be
  694. created when adding the first rule.
  695. Arguments:
  696. pptcArguments - Argument array
  697. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  698. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  699. Return Value:
  700. NO_ERROR
  701. --*/
  702. {
  703. return GetQosAddDelDsRuleOpt(pptcArguments,
  704. dwCurrentIndex,
  705. dwArgCount,
  706. TRUE);
  707. }
  708. DWORD
  709. HandleQosDelDsRule(
  710. PWCHAR pwszMachine,
  711. PTCHAR *pptcArguments,
  712. DWORD dwCurrentIndex,
  713. DWORD dwArgCount,
  714. DWORD dwFlags,
  715. MIB_SERVER_HANDLE hMibServer,
  716. BOOL *pbDone
  717. )
  718. /*++
  719. Routine Description:
  720. Gets options for deleting diffserv ruless from
  721. an existing diffserv map in the global info. If
  722. this is the last diffserv rule in the diffserv
  723. map, the diffserv map is removed from the global
  724. info.
  725. Arguments:
  726. pptcArguments - Argument array
  727. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  728. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  729. Return Value:
  730. NO_ERROR
  731. --*/
  732. {
  733. return GetQosAddDelDsRuleOpt(pptcArguments,
  734. dwCurrentIndex,
  735. dwArgCount,
  736. FALSE);
  737. }
  738. DWORD
  739. HandleQosShowDsMap(
  740. PWCHAR pwszMachine,
  741. PTCHAR *pptcArguments,
  742. DWORD dwCurrentIndex,
  743. DWORD dwArgCount,
  744. DWORD dwFlags,
  745. MIB_SERVER_HANDLE hMibServer,
  746. BOOL *pbDone
  747. )
  748. /*++
  749. Routine Description:
  750. Gets options for showing diffserv maps
  751. in the global info.
  752. Arguments:
  753. None
  754. Return Value:
  755. None
  756. --*/
  757. {
  758. return HandleQosShowGenericQosObject(QOS_OBJECT_DIFFSERV,
  759. pptcArguments,
  760. dwCurrentIndex,
  761. dwArgCount,
  762. pbDone);
  763. }
  764. //
  765. // Flow Add, Del, Set Handlers
  766. //
  767. DWORD
  768. HandleQosAddFlowOnIf(
  769. PWCHAR pwszMachine,
  770. PTCHAR *pptcArguments,
  771. DWORD dwCurrentIndex,
  772. DWORD dwArgCount,
  773. DWORD dwFlags,
  774. MIB_SERVER_HANDLE hMibServer,
  775. BOOL *pbDone
  776. )
  777. /*++
  778. Routine Description:
  779. Gets options for adding flows on an interface
  780. Arguments:
  781. pptcArguments - Argument array
  782. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  783. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  784. Return Value:
  785. NO_ERROR
  786. --*/
  787. {
  788. return GetQosAddDelIfFlowOpt(pptcArguments,
  789. dwCurrentIndex,
  790. dwArgCount,
  791. TRUE);
  792. }
  793. DWORD
  794. HandleQosDelFlowOnIf(
  795. PWCHAR pwszMachine,
  796. PTCHAR *pptcArguments,
  797. DWORD dwCurrentIndex,
  798. DWORD dwArgCount,
  799. DWORD dwFlags,
  800. MIB_SERVER_HANDLE hMibServer,
  801. BOOL *pbDone
  802. )
  803. /*++
  804. Routine Description:
  805. Gets options for deleting flows on an interface
  806. Arguments:
  807. pptcArguments - Argument array
  808. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  809. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  810. Return Value:
  811. NO_ERROR
  812. --*/
  813. {
  814. return GetQosAddDelIfFlowOpt(pptcArguments,
  815. dwCurrentIndex,
  816. dwArgCount,
  817. FALSE);
  818. }
  819. DWORD
  820. HandleQosShowFlowOnIf(
  821. PWCHAR pwszMachine,
  822. PTCHAR *pptcArguments,
  823. DWORD dwCurrentIndex,
  824. DWORD dwArgCount,
  825. DWORD dwFlags,
  826. MIB_SERVER_HANDLE hMibServer,
  827. BOOL *pbDone
  828. )
  829. /*++
  830. Routine Description:
  831. Arguments:
  832. None
  833. Return Value:
  834. None
  835. --*/
  836. {
  837. WCHAR wszInterfaceName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  838. DWORD dwBufferSize = sizeof(wszInterfaceName);
  839. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,FALSE,FALSE},
  840. {TOKEN_OPT_FLOW_NAME,FALSE,FALSE}};
  841. PTCHAR pszIfName;
  842. PTCHAR pszFlow;
  843. DWORD dwNumOpt, dwRes;
  844. DWORD dwNumArg, i, j;
  845. DWORD dwErr;
  846. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  847. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  848. pszIfName = pszFlow = NULL;
  849. if (dwCurrentIndex == dwArgCount)
  850. {
  851. //
  852. // No arguments - show all flows on all interfaces
  853. //
  854. dwErr = NO_ERROR;
  855. }
  856. else {
  857. //
  858. // Get name of the flow to show
  859. //
  860. dwErr = PreprocessCommand(
  861. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  862. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  863. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  864. );
  865. if ( dwErr != NO_ERROR )
  866. {
  867. return dwErr;
  868. }
  869. dwNumArg = dwArgCount - dwCurrentIndex;
  870. for ( i = 0; i < dwNumArg; i++ )
  871. {
  872. switch (pdwTagType[i])
  873. {
  874. case 0: // Interfacename
  875. IpmontrGetIfNameFromFriendlyName(pptcArguments[i + dwCurrentIndex],
  876. wszInterfaceName,
  877. &dwBufferSize);
  878. pszIfName = wszInterfaceName;
  879. break;
  880. case 1: // Flowname
  881. pszFlow = pptcArguments[dwCurrentIndex + i];
  882. break;
  883. default:
  884. i = dwNumArg;
  885. dwErr = ERROR_INVALID_SYNTAX;
  886. break;
  887. }
  888. }
  889. }
  890. if (dwErr == NO_ERROR)
  891. {
  892. dwErr = ShowQosFlows(NULL, pszIfName, pszFlow);
  893. }
  894. return dwErr;
  895. }
  896. //
  897. // FlowspecOnFlow Add, Del Handlers
  898. //
  899. DWORD
  900. HandleQosAddFlowspecOnIfFlow(
  901. PWCHAR pwszMachine,
  902. PTCHAR *pptcArguments,
  903. DWORD dwCurrentIndex,
  904. DWORD dwArgCount,
  905. DWORD dwFlags,
  906. MIB_SERVER_HANDLE hMibServer,
  907. BOOL *pbDone
  908. )
  909. /*++
  910. Routine Description:
  911. Arguments:
  912. None
  913. Return Value:
  914. None
  915. --*/
  916. {
  917. return GetQosAddDelFlowspecOnFlowOpt(pptcArguments,
  918. dwCurrentIndex,
  919. dwArgCount,
  920. TRUE);
  921. }
  922. DWORD
  923. HandleQosDelFlowspecOnIfFlow(
  924. PWCHAR pwszMachine,
  925. PTCHAR *pptcArguments,
  926. DWORD dwCurrentIndex,
  927. DWORD dwArgCount,
  928. DWORD dwFlags,
  929. MIB_SERVER_HANDLE hMibServer,
  930. BOOL *pbDone
  931. )
  932. /*++
  933. Routine Description:
  934. Arguments:
  935. None
  936. Return Value:
  937. None
  938. --*/
  939. {
  940. return GetQosAddDelFlowspecOnFlowOpt(pptcArguments,
  941. dwCurrentIndex,
  942. dwArgCount,
  943. FALSE);
  944. }
  945. //
  946. // QosObject Del, Show Handlers
  947. //
  948. DWORD
  949. HandleQosDelQosObject(
  950. PWCHAR pwszMachine,
  951. PTCHAR *pptcArguments,
  952. DWORD dwCurrentIndex,
  953. DWORD dwArgCount,
  954. DWORD dwFlags,
  955. MIB_SERVER_HANDLE hMibServer,
  956. BOOL *pbDone
  957. )
  958. /*++
  959. Routine Description:
  960. Gets options for deleting qos objects
  961. in the global info.
  962. Arguments:
  963. None
  964. Return Value:
  965. None
  966. --*/
  967. {
  968. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,TRUE,FALSE}};
  969. PWCHAR pwszQosObject;
  970. DWORD dwNumArg;
  971. DWORD dwErr;
  972. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  973. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  974. //
  975. // parse command arguements
  976. //
  977. dwErr = PreprocessCommand(
  978. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  979. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  980. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  981. );
  982. if ( dwErr != NO_ERROR )
  983. {
  984. return dwErr;
  985. }
  986. dwNumArg = dwArgCount - dwCurrentIndex;
  987. if (dwNumArg != 1)
  988. {
  989. return ERROR_INVALID_SYNTAX;
  990. }
  991. //
  992. // Get name of the qosobject to delete
  993. //
  994. pwszQosObject = pptcArguments[dwCurrentIndex];
  995. return GetQosAddDelQosObject(pwszQosObject, NULL, FALSE);
  996. }
  997. DWORD
  998. HandleQosShowQosObject(
  999. PWCHAR pwszMachine,
  1000. PTCHAR *pptcArguments,
  1001. DWORD dwCurrentIndex,
  1002. DWORD dwArgCount,
  1003. DWORD dwFlags,
  1004. MIB_SERVER_HANDLE hMibServer,
  1005. BOOL *pbDone
  1006. )
  1007. /*++
  1008. Routine Description:
  1009. Gets options for showing qos objects
  1010. in the global info.
  1011. Arguments:
  1012. None
  1013. Return Value:
  1014. None
  1015. --*/
  1016. {
  1017. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,FALSE,FALSE},
  1018. {TOKEN_OPT_QOSOBJECT_TYPE,FALSE,FALSE}};
  1019. PTCHAR pszQosObject;
  1020. ULONG dwObjectType;
  1021. DWORD dwNumOpt, dwRes;
  1022. DWORD dwNumArg, i, j;
  1023. DWORD dwTagType, dwErr;
  1024. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  1025. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  1026. // Init type to indicate a "generic" object
  1027. dwObjectType = QOS_OBJECT_END_OF_LIST;
  1028. pszQosObject = NULL;
  1029. if (dwCurrentIndex < dwArgCount)
  1030. {
  1031. //
  1032. // Get name of the qosobject to show
  1033. //
  1034. dwErr = PreprocessCommand(
  1035. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  1036. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  1037. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  1038. );
  1039. if ( dwErr != NO_ERROR )
  1040. {
  1041. return dwErr;
  1042. }
  1043. dwNumArg = dwArgCount - dwCurrentIndex;
  1044. for (i = 0; i < dwNumArg; i++)
  1045. {
  1046. switch (pdwTagType[i])
  1047. {
  1048. case 0 :
  1049. // QOS OBJECT NAME
  1050. pszQosObject = pptcArguments[i + dwCurrentIndex];
  1051. break;
  1052. case 1 :
  1053. {
  1054. // QOS OBJECT TYPE
  1055. TOKEN_VALUE rgEnums[] =
  1056. {{TOKEN_OPT_QOSOBJECT_DIFFSERV, QOS_OBJECT_DIFFSERV},
  1057. {TOKEN_OPT_QOSOBJECT_SD_MODE, QOS_OBJECT_SD_MODE}};
  1058. GET_ENUM_TAG_VALUE();
  1059. dwObjectType = dwRes;
  1060. break;
  1061. }
  1062. default:
  1063. i = dwNumArg;
  1064. dwErr = ERROR_INVALID_SYNTAX;
  1065. break;
  1066. }
  1067. }
  1068. if (dwErr != NO_ERROR)
  1069. {
  1070. return dwErr;
  1071. }
  1072. }
  1073. return ShowQosObjects(NULL, pszQosObject, dwObjectType);
  1074. }
  1075. DWORD
  1076. HandleQosShowGenericQosObject(
  1077. DWORD dwQosObjectType,
  1078. PTCHAR *pptcArguments,
  1079. DWORD dwCurrentIndex,
  1080. DWORD dwArgCount,
  1081. BOOL *pbDone
  1082. )
  1083. /*++
  1084. Routine Description:
  1085. Gets options for showing qos objects
  1086. in the global info.
  1087. Arguments:
  1088. None
  1089. Return Value:
  1090. None
  1091. --*/
  1092. {
  1093. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,FALSE,FALSE}};
  1094. PTCHAR pszQosObject;
  1095. DWORD dwNumArg;
  1096. DWORD dwTagType, dwErr;
  1097. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  1098. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  1099. pszQosObject = NULL;
  1100. if (dwCurrentIndex < dwArgCount)
  1101. {
  1102. //
  1103. // Get name of the qosobject to show
  1104. //
  1105. dwErr = PreprocessCommand(
  1106. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  1107. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  1108. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  1109. );
  1110. if ( dwErr != NO_ERROR )
  1111. {
  1112. return dwErr;
  1113. }
  1114. dwNumArg = dwArgCount - dwCurrentIndex;
  1115. if (dwNumArg != 1)
  1116. {
  1117. return ERROR_INVALID_SYNTAX;
  1118. }
  1119. pszQosObject = pptcArguments[dwCurrentIndex];
  1120. }
  1121. return ShowQosObjects(NULL, pszQosObject, dwQosObjectType);
  1122. }
  1123. //
  1124. // SDMode Add, Del, Show Handlers
  1125. //
  1126. DWORD
  1127. HandleQosAddSdMode(
  1128. PWCHAR pwszMachine,
  1129. PTCHAR *pptcArguments,
  1130. DWORD dwCurrentIndex,
  1131. DWORD dwArgCount,
  1132. DWORD dwFlags,
  1133. MIB_SERVER_HANDLE hMibServer,
  1134. BOOL *pbDone
  1135. )
  1136. /*++
  1137. Routine Description:
  1138. Gets options for adding shape modes
  1139. to the global info.
  1140. Arguments:
  1141. None
  1142. Return Value:
  1143. None
  1144. --*/
  1145. {
  1146. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,TRUE,FALSE},
  1147. {TOKEN_OPT_SHAPING_MODE,TRUE,FALSE}};
  1148. QOS_SD_MODE qsdMode;
  1149. PTCHAR pszSdMode;
  1150. DWORD dwSdMode, dwNumArg, i, j, dwErr, dwRes;
  1151. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  1152. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  1153. //
  1154. // parse command arguements
  1155. //
  1156. dwErr = PreprocessCommand(
  1157. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  1158. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  1159. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  1160. );
  1161. if ( dwErr != NO_ERROR )
  1162. {
  1163. return dwErr;
  1164. }
  1165. // Init to -1 to indicate value not filled in
  1166. dwSdMode = -1;
  1167. dwNumArg = dwArgCount - dwCurrentIndex;
  1168. //
  1169. // Process the arguments now
  1170. //
  1171. for (i = 0; i < dwNumArg; i++)
  1172. {
  1173. switch (pdwTagType[i])
  1174. {
  1175. case 0 :
  1176. // SDMODE_NAME
  1177. pszSdMode = pptcArguments[i + dwCurrentIndex];
  1178. break;
  1179. case 1:
  1180. {
  1181. // SHAPING
  1182. TOKEN_VALUE rgEnums[] =
  1183. {{TOKEN_OPT_SDMODE_BORROW, TC_NONCONF_BORROW},
  1184. {TOKEN_OPT_SDMODE_SHAPE, TC_NONCONF_SHAPE},
  1185. {TOKEN_OPT_SDMODE_DISCARD, TC_NONCONF_DISCARD},
  1186. {TOKEN_OPT_SDMODE_BORROW_PLUS, TC_NONCONF_BORROW_PLUS}};
  1187. GET_ENUM_TAG_VALUE();
  1188. dwSdMode = dwRes;
  1189. break;
  1190. }
  1191. default:
  1192. {
  1193. i = dwNumArg;
  1194. dwErr = ERROR_INVALID_SYNTAX;
  1195. break;
  1196. }
  1197. }
  1198. }
  1199. if (dwErr == NO_ERROR)
  1200. {
  1201. #if 0
  1202. // interface name should be present
  1203. // and also the shaping mode value
  1204. if ((!pttTags[0].bPresent) ||
  1205. (!pttTags[1].bPresent))
  1206. {
  1207. dwErr = ERROR_INVALID_SYNTAX;
  1208. break;
  1209. }
  1210. #endif
  1211. // Create a new QOS object with inp
  1212. qsdMode.ObjectHdr.ObjectType = QOS_OBJECT_SD_MODE ;
  1213. qsdMode.ObjectHdr.ObjectLength = sizeof(QOS_SD_MODE);
  1214. qsdMode.ShapeDiscardMode = dwSdMode;
  1215. dwErr = GetQosAddDelQosObject(pszSdMode,
  1216. (QOS_OBJECT_HDR *)&qsdMode,
  1217. TRUE);
  1218. }
  1219. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  1220. }
  1221. DWORD
  1222. HandleQosShowSdMode(
  1223. PWCHAR pwszMachine,
  1224. PTCHAR *pptcArguments,
  1225. DWORD dwCurrentIndex,
  1226. DWORD dwArgCount,
  1227. DWORD dwFlags,
  1228. MIB_SERVER_HANDLE hMibServer,
  1229. BOOL *pbDone
  1230. )
  1231. /*++
  1232. Routine Description:
  1233. Gets options for showing shape modes
  1234. in the global info.
  1235. Arguments:
  1236. None
  1237. Return Value:
  1238. None
  1239. --*/
  1240. {
  1241. return HandleQosShowGenericQosObject(QOS_OBJECT_SD_MODE,
  1242. pptcArguments,
  1243. dwCurrentIndex,
  1244. dwArgCount,
  1245. pbDone);
  1246. }
  1247. //
  1248. // QosObjectOnFlow Add, Del Handlers
  1249. //
  1250. DWORD
  1251. HandleQosAddQosObjectOnIfFlow(
  1252. PWCHAR pwszMachine,
  1253. PTCHAR *pptcArguments,
  1254. DWORD dwCurrentIndex,
  1255. DWORD dwArgCount,
  1256. DWORD dwFlags,
  1257. MIB_SERVER_HANDLE hMibServer,
  1258. BOOL *pbDone
  1259. )
  1260. /*++
  1261. Routine Description:
  1262. Arguments:
  1263. None
  1264. Return Value:
  1265. None
  1266. --*/
  1267. {
  1268. return GetQosAddDelQosObjectOnFlowOpt(pptcArguments,
  1269. dwCurrentIndex,
  1270. dwArgCount,
  1271. TRUE);
  1272. }
  1273. DWORD
  1274. HandleQosDelQosObjectOnIfFlow(
  1275. PWCHAR pwszMachine,
  1276. PTCHAR *pptcArguments,
  1277. DWORD dwCurrentIndex,
  1278. DWORD dwArgCount,
  1279. DWORD dwFlags,
  1280. MIB_SERVER_HANDLE hMibServer,
  1281. BOOL *pbDone
  1282. )
  1283. /*++
  1284. Routine Description:
  1285. Arguments:
  1286. None
  1287. Return Value:
  1288. None
  1289. --*/
  1290. {
  1291. return GetQosAddDelQosObjectOnFlowOpt(pptcArguments,
  1292. dwCurrentIndex,
  1293. dwArgCount,
  1294. FALSE);
  1295. }
  1296. //
  1297. // Filter Add, Del, Set Handlers
  1298. //
  1299. DWORD
  1300. HandleQosAttachFilterToFlow(
  1301. PWCHAR pwszMachine,
  1302. PTCHAR *pptcArguments,
  1303. DWORD dwCurrentIndex,
  1304. DWORD dwArgCount,
  1305. DWORD dwFlags,
  1306. MIB_SERVER_HANDLE hMibServer,
  1307. BOOL *pbDone
  1308. )
  1309. /*++
  1310. Routine Description:
  1311. Arguments:
  1312. None
  1313. Return Value:
  1314. None
  1315. --*/
  1316. {
  1317. return ERROR_NOT_SUPPORTED;
  1318. }
  1319. DWORD
  1320. HandleQosDetachFilterFromFlow(
  1321. PWCHAR pwszMachine,
  1322. PTCHAR *pptcArguments,
  1323. DWORD dwCurrentIndex,
  1324. DWORD dwArgCount,
  1325. DWORD dwFlags,
  1326. MIB_SERVER_HANDLE hMibServer,
  1327. BOOL *pbDone
  1328. )
  1329. /*++
  1330. Routine Description:
  1331. Arguments:
  1332. None
  1333. Return Value:
  1334. None
  1335. --*/
  1336. {
  1337. return ERROR_NOT_SUPPORTED;
  1338. }
  1339. DWORD
  1340. HandleQosModifyFilterOnFlow(
  1341. PWCHAR pwszMachine,
  1342. PTCHAR *pptcArguments,
  1343. DWORD dwCurrentIndex,
  1344. DWORD dwArgCount,
  1345. DWORD dwFlags,
  1346. MIB_SERVER_HANDLE hMibServer,
  1347. BOOL *pbDone
  1348. )
  1349. /*++
  1350. Routine Description:
  1351. Arguments:
  1352. None
  1353. Return Value:
  1354. None
  1355. --*/
  1356. {
  1357. return ERROR_NOT_SUPPORTED;
  1358. }
  1359. DWORD
  1360. HandleQosShowFilterOnFlow(
  1361. PWCHAR pwszMachine,
  1362. PTCHAR *pptcArguments,
  1363. DWORD dwCurrentIndex,
  1364. DWORD dwArgCount,
  1365. DWORD dwFlags,
  1366. MIB_SERVER_HANDLE hMibServer,
  1367. BOOL *pbDone
  1368. )
  1369. /*++
  1370. Routine Description:
  1371. Arguments:
  1372. None
  1373. Return Value:
  1374. None
  1375. --*/
  1376. {
  1377. return ERROR_NOT_SUPPORTED;
  1378. }
  1379. //
  1380. // If Helper functions
  1381. //
  1382. DWORD
  1383. GetQosSetIfOpt(
  1384. IN PTCHAR *pptcArguments,
  1385. IN DWORD dwCurrentIndex,
  1386. IN DWORD dwArgCount,
  1387. IN PWCHAR wszIfName,
  1388. IN DWORD dwSizeOfwszIfName,
  1389. OUT PIPQOS_IF_CONFIG pChangeCfg,
  1390. OUT DWORD *pdwBitVector,
  1391. IN BOOL bAddSet
  1392. )
  1393. /*++
  1394. Routine Description:
  1395. Gets options for set interface, add interface
  1396. Arguments:
  1397. pptcArguments - Argument array
  1398. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  1399. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  1400. wszIfName - Interface name.
  1401. dwSizeOfwszIfName-Size of the wszIfName buffer
  1402. pChangeCfg - The config containing changes values
  1403. pdwBitVector - Bit vector specifying what values have changed
  1404. bAddSet - Called when If entry is being created or set
  1405. Return Value:
  1406. NO_ERROR
  1407. --*/
  1408. {
  1409. DWORD dwErr = NO_ERROR,dwRes;
  1410. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,TRUE,FALSE},
  1411. {TOKEN_OPT_IF_STATE,FALSE,FALSE}};
  1412. DWORD dwNumOpt;
  1413. DWORD dwNumArg, i, j;
  1414. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  1415. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  1416. //
  1417. // parse command arguements
  1418. //
  1419. dwErr = PreprocessCommand(
  1420. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  1421. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  1422. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  1423. );
  1424. if ( dwErr != NO_ERROR )
  1425. {
  1426. return dwErr;
  1427. }
  1428. dwNumArg = dwArgCount - dwCurrentIndex;
  1429. for ( i = 0; i < dwNumArg; i++)
  1430. {
  1431. switch (pdwTagType[i])
  1432. {
  1433. case 0 :
  1434. {
  1435. //
  1436. // INTERFACE_NAME
  1437. //
  1438. IpmontrGetIfNameFromFriendlyName(pptcArguments[i + dwCurrentIndex],
  1439. wszIfName,&dwSizeOfwszIfName);
  1440. break;
  1441. }
  1442. case 1:
  1443. {
  1444. //
  1445. // STATE
  1446. //
  1447. TOKEN_VALUE rgEnums[] =
  1448. {{TOKEN_OPT_VALUE_DISABLE, IPQOS_STATE_DISABLED},
  1449. {TOKEN_OPT_VALUE_ENABLE, IPQOS_STATE_ENABLED}};
  1450. GET_ENUM_TAG_VALUE();
  1451. pChangeCfg->QosState = dwRes;
  1452. *pdwBitVector |= QOS_IF_STATE_MASK;
  1453. break;
  1454. }
  1455. default:
  1456. {
  1457. i = dwNumArg;
  1458. dwErr = ERROR_INVALID_SYNTAX;
  1459. break;
  1460. }
  1461. }
  1462. }
  1463. #if 0
  1464. // interface name should be present
  1465. if (!pttTags[0].bPresent)
  1466. {
  1467. dwErr = ERROR_INVALID_SYNTAX;
  1468. }
  1469. #endif
  1470. return dwErr;
  1471. }
  1472. //
  1473. // Flow Helper functions
  1474. //
  1475. DWORD
  1476. GetQosAddDelIfFlowOpt(
  1477. PTCHAR *pptcArguments,
  1478. DWORD dwCurrentIndex,
  1479. DWORD dwArgCount,
  1480. BOOL bAdd
  1481. )
  1482. /*++
  1483. Routine Description:
  1484. Gets options for add/del/set(modify) flows
  1485. Arguments:
  1486. pptcArguments - Argument array
  1487. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  1488. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  1489. bAdd - Adding or deleting flows
  1490. Return Value:
  1491. NO_ERROR
  1492. --*/
  1493. {
  1494. PIPQOS_IF_CONFIG piicSrc = NULL, piicDst = NULL;
  1495. DWORD dwBlkSize, dwNewBlkSize, dwQosCount;
  1496. DWORD i, j, dwErr = NO_ERROR, dwNumOpt;
  1497. DWORD dwSkip, dwOffset, dwSize, dwBitVector = 0;
  1498. DWORD dwIfType;
  1499. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  1500. DWORD dwBufferSize = sizeof(wszIfName);
  1501. PIPQOS_IF_FLOW pNextFlow, pDestFlow;
  1502. PWCHAR pwszFlowName;
  1503. DWORD dwNumArg;
  1504. PUCHAR pFlow;
  1505. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,TRUE,FALSE},
  1506. {TOKEN_OPT_FLOW_NAME,TRUE,FALSE}};
  1507. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  1508. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  1509. //
  1510. // parse command arguements
  1511. //
  1512. dwErr = PreprocessCommand(
  1513. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  1514. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  1515. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  1516. );
  1517. if ( dwErr != NO_ERROR )
  1518. {
  1519. return dwErr;
  1520. }
  1521. dwNumArg = dwArgCount - dwCurrentIndex;
  1522. for ( i = 0; i < dwNumArg; i++ )
  1523. {
  1524. switch (pdwTagType[i])
  1525. {
  1526. case 0:
  1527. /* Get interface name for the flow */
  1528. IpmontrGetIfNameFromFriendlyName(pptcArguments[i + dwCurrentIndex],
  1529. wszIfName, &dwBufferSize);
  1530. break;
  1531. case 1:
  1532. /* Get the flow name for the flow */
  1533. pwszFlowName = pptcArguments[i + dwCurrentIndex];
  1534. break;
  1535. default:
  1536. i = dwNumArg;
  1537. dwErr = ERROR_INVALID_SYNTAX;
  1538. break;
  1539. }
  1540. }
  1541. do
  1542. {
  1543. if (dwErr != NO_ERROR)
  1544. {
  1545. break;
  1546. }
  1547. #if 0
  1548. // interface and flow names should be present
  1549. if ((!pttTags[0].bPresent) || (!pttTags[1].bPresent))
  1550. {
  1551. dwErr = ERROR_INVALID_SYNTAX;
  1552. break;
  1553. }
  1554. #endif
  1555. //
  1556. // Get the interface info and check if flow already exists
  1557. //
  1558. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(wszIfName,
  1559. MS_IP_QOSMGR,
  1560. (PBYTE *) &piicSrc,
  1561. &dwBlkSize,
  1562. &dwQosCount,
  1563. &dwIfType);
  1564. if (dwErr != NO_ERROR)
  1565. {
  1566. break;
  1567. }
  1568. if ( piicSrc == NULL )
  1569. {
  1570. dwErr = ERROR_INVALID_PARAMETER;
  1571. break;
  1572. }
  1573. pNextFlow = (PIPQOS_IF_FLOW)((PUCHAR)piicSrc + sizeof(IPQOS_IF_CONFIG));
  1574. for (j = 0; j < piicSrc->NumFlows; j++)
  1575. {
  1576. if (!_wcsicmp(pNextFlow->FlowName, pwszFlowName))
  1577. {
  1578. break;
  1579. }
  1580. pNextFlow = (PIPQOS_IF_FLOW)
  1581. ((PUCHAR) pNextFlow + pNextFlow->FlowSize);
  1582. }
  1583. if (bAdd)
  1584. {
  1585. if (j < piicSrc->NumFlows)
  1586. {
  1587. //
  1588. // We already have a flow by this name
  1589. //
  1590. DisplayMessage(g_hModule,
  1591. MSG_FLOW_ALREADY_EXISTS,
  1592. pwszFlowName);
  1593. dwErr = ERROR_SUPPRESS_OUTPUT;
  1594. break;
  1595. }
  1596. }
  1597. else
  1598. {
  1599. if (j == piicSrc->NumFlows)
  1600. {
  1601. //
  1602. // We do not have a flow by this name
  1603. //
  1604. DisplayMessage(g_hModule,
  1605. MSG_FLOW_NOT_FOUND,
  1606. pwszFlowName);
  1607. dwErr = ERROR_SUPPRESS_OUTPUT;
  1608. break;
  1609. }
  1610. // Flow was found at 'pNextFlow' position
  1611. }
  1612. if (bAdd)
  1613. {
  1614. //
  1615. // We have a new flow definition - update config
  1616. //
  1617. dwNewBlkSize = dwBlkSize + sizeof(IPQOS_IF_FLOW);
  1618. piicDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  1619. if (!piicDst)
  1620. {
  1621. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1622. break;
  1623. }
  1624. // Copy all the existing flows to the new config
  1625. memcpy(piicDst, piicSrc, dwBlkSize);
  1626. //
  1627. // Stick the new flow as the last flow in array
  1628. //
  1629. pDestFlow = (PIPQOS_IF_FLOW)((PUCHAR) piicDst + dwBlkSize);
  1630. wcscpy(pDestFlow->FlowName, pwszFlowName);
  1631. pDestFlow->FlowSize = sizeof(IPQOS_IF_FLOW);
  1632. pDestFlow->FlowDesc.SendingFlowspecName[0] = L'\0';
  1633. pDestFlow->FlowDesc.RecvingFlowspecName[0] = L'\0';
  1634. pDestFlow->FlowDesc.NumTcObjects = 0;
  1635. piicDst->NumFlows++;
  1636. }
  1637. else
  1638. {
  1639. //
  1640. // We have to del old flowspec defn - update config
  1641. //
  1642. dwNewBlkSize = dwBlkSize - pNextFlow->FlowSize;
  1643. piicDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  1644. if (!piicDst)
  1645. {
  1646. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1647. break;
  1648. }
  1649. dwOffset = (PUCHAR)pNextFlow - (PUCHAR)piicSrc;
  1650. // Copy the all the flowspecs that occur before
  1651. memcpy(piicDst, piicSrc, dwOffset);
  1652. // Copy the rest of the flowspecs as they are
  1653. dwSkip = dwOffset + pNextFlow->FlowSize;
  1654. memcpy((PUCHAR) piicDst + dwOffset,
  1655. (PUCHAR) piicSrc + dwSkip,
  1656. dwBlkSize - dwSkip);
  1657. piicDst->NumFlows--;
  1658. }
  1659. // Update the interface config by setting new info
  1660. dwErr = IpmontrSetInfoBlockInInterfaceInfo(wszIfName,
  1661. MS_IP_QOSMGR,
  1662. (PBYTE) piicDst,
  1663. dwNewBlkSize,
  1664. dwQosCount);
  1665. }
  1666. while (FALSE);
  1667. HEAP_FREE_NOT_NULL(piicSrc);
  1668. HEAP_FREE_NOT_NULL(piicDst);
  1669. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  1670. }
  1671. DWORD
  1672. ShowQosFlows(
  1673. IN HANDLE hFile,
  1674. IN PWCHAR pwszIfGuid,
  1675. IN PWCHAR wszFlowName
  1676. )
  1677. {
  1678. PMPR_INTERFACE_0 pmi0;
  1679. DWORD dwErr, dwCount, dwTotal, i;
  1680. if (pwszIfGuid)
  1681. {
  1682. return ShowQosFlowsOnIf(hFile, pwszIfGuid, wszFlowName);
  1683. }
  1684. else
  1685. {
  1686. //
  1687. // Enumerate all interfaces applicable to QOS
  1688. //
  1689. dwErr = IpmontrInterfaceEnum((PBYTE *) &pmi0,
  1690. &dwCount,
  1691. &dwTotal);
  1692. if(dwErr != NO_ERROR)
  1693. {
  1694. return dwErr;
  1695. }
  1696. for(i = 0; i < dwCount; i++)
  1697. {
  1698. ShowQosFlowsOnIf(hFile,
  1699. pmi0[i].wszInterfaceName,
  1700. wszFlowName);
  1701. }
  1702. }
  1703. return NO_ERROR;
  1704. }
  1705. DWORD
  1706. ShowQosFlowsOnIf(
  1707. IN HANDLE hFile,
  1708. IN PWCHAR pwszIfGuid,
  1709. IN PWCHAR wszFlowName
  1710. )
  1711. {
  1712. WCHAR wszInterfaceName[ MAX_INTERFACE_NAME_LEN + 1 ] = L"\0";
  1713. DWORD dwBufferSize = sizeof(wszInterfaceName);
  1714. PWCHAR pwszFriendlyIfName = NULL;
  1715. PIPQOS_IF_CONFIG piicSrc;
  1716. DWORD dwBlkSize,dwQosCount;
  1717. DWORD dwIfType, dwErr, j, k;
  1718. PIPQOS_IF_FLOW pNextFlow;
  1719. PWCHAR pwszFlowName = NULL;
  1720. PWCHAR pwszNextObject, pwszObjectName = NULL;
  1721. PWCHAR pwszSendingFlowspec, pwszRecvingFlowspec;
  1722. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(pwszIfGuid,
  1723. MS_IP_QOSMGR,
  1724. (PBYTE *) &piicSrc,
  1725. &dwBlkSize,
  1726. &dwQosCount,
  1727. &dwIfType);
  1728. if (dwErr != NO_ERROR)
  1729. {
  1730. return dwErr;
  1731. }
  1732. if ( piicSrc == NULL )
  1733. {
  1734. return ERROR_INVALID_PARAMETER;
  1735. }
  1736. //
  1737. // Get friendly name for interface
  1738. //
  1739. dwErr = IpmontrGetFriendlyNameFromIfName(pwszIfGuid,
  1740. wszInterfaceName,
  1741. &dwBufferSize);
  1742. if ( dwErr != NO_ERROR )
  1743. {
  1744. return dwErr;
  1745. }
  1746. pwszFriendlyIfName = MakeQuotedString( wszInterfaceName );
  1747. if ( pwszFriendlyIfName == NULL )
  1748. {
  1749. return ERROR_NOT_ENOUGH_MEMORY;
  1750. }
  1751. pNextFlow = (PIPQOS_IF_FLOW)((PUCHAR)piicSrc + sizeof(IPQOS_IF_CONFIG));
  1752. for (j = 0; j < piicSrc->NumFlows; j++)
  1753. {
  1754. if ((!wszFlowName) ||
  1755. (!_wcsicmp(pNextFlow->FlowName, wszFlowName)))
  1756. {
  1757. //
  1758. // Print or dump the flow now
  1759. //
  1760. pwszFlowName = MakeQuotedString(pNextFlow->FlowName);
  1761. if (pwszFlowName == NULL)
  1762. {
  1763. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1764. break;
  1765. }
  1766. // Print or dump flowspecs
  1767. pwszSendingFlowspec =
  1768. MakeQuotedString(pNextFlow->FlowDesc.SendingFlowspecName);
  1769. pwszRecvingFlowspec =
  1770. MakeQuotedString(pNextFlow->FlowDesc.RecvingFlowspecName);
  1771. if (hFile)
  1772. {
  1773. DisplayMessageT(DMP_QOS_DELETE_FLOW,
  1774. pwszFriendlyIfName,
  1775. pwszFlowName);
  1776. DisplayMessageT(DMP_QOS_ADD_FLOW,
  1777. pwszFriendlyIfName,
  1778. pwszFlowName);
  1779. if (!_wcsicmp(pwszSendingFlowspec, pwszRecvingFlowspec))
  1780. {
  1781. if (pNextFlow->FlowDesc.SendingFlowspecName[0])
  1782. {
  1783. DisplayMessageT(DMP_QOS_ADD_FLOWSPEC_ON_FLOW_BI,
  1784. pwszFriendlyIfName,
  1785. pwszFlowName,
  1786. pwszSendingFlowspec);
  1787. }
  1788. }
  1789. else
  1790. {
  1791. if (pNextFlow->FlowDesc.RecvingFlowspecName[0])
  1792. {
  1793. DisplayMessageT(DMP_QOS_ADD_FLOWSPEC_ON_FLOW_IN,
  1794. pwszFriendlyIfName,
  1795. pwszFlowName,
  1796. pwszRecvingFlowspec);
  1797. }
  1798. if (pNextFlow->FlowDesc.SendingFlowspecName[0])
  1799. {
  1800. DisplayMessageT(DMP_QOS_ADD_FLOWSPEC_ON_FLOW_OUT,
  1801. pwszFriendlyIfName,
  1802. pwszFlowName,
  1803. pwszSendingFlowspec);
  1804. }
  1805. }
  1806. }
  1807. else
  1808. {
  1809. DisplayMessage(g_hModule, MSG_QOS_FLOW_INFO,
  1810. pwszFlowName,
  1811. pwszFriendlyIfName,
  1812. pwszRecvingFlowspec,
  1813. pwszSendingFlowspec,
  1814. pNextFlow->FlowDesc.NumTcObjects);
  1815. }
  1816. // Print or dump qos objects
  1817. pwszNextObject =
  1818. (PWCHAR) ((PUCHAR) pNextFlow + sizeof(IPQOS_IF_FLOW));
  1819. for (k = 0; k < pNextFlow->FlowDesc.NumTcObjects; k++)
  1820. {
  1821. pwszObjectName = MakeQuotedString(pwszNextObject);
  1822. if ( pwszObjectName == NULL )
  1823. {
  1824. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  1825. break;
  1826. }
  1827. if (hFile)
  1828. {
  1829. DisplayMessageT(DMP_QOS_ADD_QOSOBJECT_ON_FLOW,
  1830. pwszFriendlyIfName,
  1831. pwszFlowName,
  1832. pwszObjectName);
  1833. }
  1834. else
  1835. {
  1836. DisplayMessage(g_hModule, MSG_QOS_QOSOBJECT_INFO,
  1837. k,
  1838. pwszObjectName);
  1839. }
  1840. pwszNextObject += MAX_STRING_LENGTH;
  1841. FreeQuotedString(pwszObjectName);
  1842. }
  1843. if ( pwszFlowName )
  1844. {
  1845. FreeQuotedString( pwszFlowName );
  1846. pwszFlowName = NULL;
  1847. }
  1848. //
  1849. // If we matched flow, then done
  1850. //
  1851. if ((wszFlowName) || (dwErr != NO_ERROR))
  1852. {
  1853. break;
  1854. }
  1855. }
  1856. pNextFlow = (PIPQOS_IF_FLOW)
  1857. ((PUCHAR) pNextFlow + pNextFlow->FlowSize);
  1858. }
  1859. if ( pwszFriendlyIfName )
  1860. {
  1861. FreeQuotedString( pwszFriendlyIfName );
  1862. }
  1863. if (dwErr == NO_ERROR)
  1864. {
  1865. if ((wszFlowName) && (j == piicSrc->NumFlows))
  1866. {
  1867. // We didnt find the flow we are looking for
  1868. DisplayMessage(g_hModule,
  1869. MSG_FLOW_NOT_FOUND,
  1870. wszFlowName);
  1871. return ERROR_SUPPRESS_OUTPUT;
  1872. }
  1873. }
  1874. return dwErr;
  1875. }
  1876. //
  1877. // DsRule, DsMap Helpers
  1878. //
  1879. DWORD
  1880. GetQosAddDelDsRuleOpt(
  1881. PTCHAR *pptcArguments,
  1882. DWORD dwCurrentIndex,
  1883. DWORD dwArgCount,
  1884. BOOL bAdd
  1885. )
  1886. {
  1887. DWORD dwErr = NO_ERROR;
  1888. TAG_TYPE pttTags[] = {
  1889. {TOKEN_OPT_NAME,TRUE,FALSE},
  1890. {TOKEN_OPT_INBOUND_DS_FIELD,TRUE,FALSE},
  1891. {TOKEN_OPT_CONF_OUTBOUND_DS_FIELD,FALSE,FALSE},
  1892. {TOKEN_OPT_NONCONF_OUTBOUND_DS_FIELD,FALSE,FALSE},
  1893. {TOKEN_OPT_CONF_USER_PRIORITY,FALSE,FALSE},
  1894. {TOKEN_OPT_NONCONF_USER_PRIORITY,FALSE,FALSE}};
  1895. PIPQOS_NAMED_QOSOBJECT pThisQosObject, pNextQosObject;
  1896. PVOID pBuffer;
  1897. PTCHAR pszDsMap;
  1898. QOS_DIFFSERV *pDsMap;
  1899. QOS_DIFFSERV_RULE dsRule, *pDsRule, *pNextDsRule;
  1900. PIPQOS_GLOBAL_CONFIG pigcSrc = NULL, pigcDst = NULL;
  1901. DWORD dwBlkSize, dwNewBlkSize, dwQosCount;
  1902. DWORD dwNumOpt, dwRes;
  1903. DWORD dwNumArg, i, j;
  1904. DWORD dwSkip, dwOffset;
  1905. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  1906. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  1907. //
  1908. // parse command arguements
  1909. //
  1910. dwErr = PreprocessCommand(
  1911. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  1912. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  1913. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  1914. );
  1915. if ( dwErr != NO_ERROR )
  1916. {
  1917. return dwErr;
  1918. }
  1919. dwNumArg = dwArgCount - dwCurrentIndex;
  1920. //
  1921. // We need all params for add and atleast
  1922. // the dsmap name n dsrule num for delete
  1923. //
  1924. if (( bAdd && (dwNumArg != 6)) ||
  1925. (!bAdd && (dwNumArg != 2)))
  1926. {
  1927. return ERROR_INVALID_SYNTAX;
  1928. }
  1929. pDsRule = &dsRule;
  1930. //
  1931. // Initialize the diffserv rule definition
  1932. //
  1933. memset(pDsRule, 0, sizeof(QOS_DIFFSERV_RULE));
  1934. //
  1935. // Process the arguments now
  1936. //
  1937. for ( i = 0; i < dwNumArg; i++)
  1938. {
  1939. // All params except the first are uchar vals
  1940. if ( pdwTagType[i] > 0)
  1941. {
  1942. // What if this is not a valid ULONG ? '0' will not do...
  1943. dwRes = _tcstoul(pptcArguments[i + dwCurrentIndex],NULL,10);
  1944. }
  1945. switch (pdwTagType[i])
  1946. {
  1947. case 0:
  1948. //
  1949. // DSMAP Name: See if we already have the name
  1950. //
  1951. pszDsMap = pptcArguments[i + dwCurrentIndex];
  1952. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  1953. (PBYTE *) &pigcSrc,
  1954. &dwBlkSize,
  1955. &dwQosCount);
  1956. if (dwErr != NO_ERROR)
  1957. {
  1958. break;
  1959. }
  1960. if ( pigcSrc == NULL )
  1961. {
  1962. dwErr = ERROR_INVALID_PARAMETER;
  1963. break;
  1964. }
  1965. dwOffset = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr);
  1966. pThisQosObject = NULL;
  1967. pNextQosObject =
  1968. (PIPQOS_NAMED_QOSOBJECT)((PUCHAR) pigcSrc
  1969. + sizeof(IPQOS_GLOBAL_CONFIG)
  1970. + (pigcSrc->NumFlowspecs *
  1971. sizeof(IPQOS_NAMED_FLOWSPEC)));
  1972. for (j = 0; j < pigcSrc->NumQosObjects; j++)
  1973. {
  1974. if (!_wcsicmp(pNextQosObject->QosObjectName,
  1975. pszDsMap))
  1976. {
  1977. break;
  1978. }
  1979. pNextQosObject =
  1980. (PIPQOS_NAMED_QOSOBJECT)
  1981. ((PUCHAR) pNextQosObject +
  1982. dwOffset +
  1983. pNextQosObject->QosObjectHdr.ObjectLength);
  1984. }
  1985. if (j < pigcSrc->NumQosObjects)
  1986. {
  1987. //
  1988. // You cannot add/del dsrules from a non dsmap
  1989. //
  1990. if (pNextQosObject->QosObjectHdr.ObjectType !=
  1991. QOS_OBJECT_DIFFSERV)
  1992. {
  1993. i = dwNumArg;
  1994. dwErr = ERROR_INVALID_FUNCTION;
  1995. break;
  1996. }
  1997. }
  1998. if (bAdd)
  1999. {
  2000. if (j < pigcSrc->NumQosObjects)
  2001. {
  2002. // Remember QOS object you are interested in
  2003. pThisQosObject = pNextQosObject;
  2004. }
  2005. }
  2006. else
  2007. {
  2008. if (j == pigcSrc->NumQosObjects)
  2009. {
  2010. //
  2011. // We do not have a qos object by this name
  2012. //
  2013. DisplayMessage(g_hModule,
  2014. MSG_QOSOBJECT_NOT_FOUND,
  2015. pszDsMap);
  2016. i = dwNumArg;
  2017. dwErr = ERROR_SUPPRESS_OUTPUT;
  2018. break;
  2019. }
  2020. // Remember QOS object you are interested in
  2021. pThisQosObject = pNextQosObject;
  2022. }
  2023. break;
  2024. case 1:
  2025. // INBOUND_DS
  2026. pDsRule->InboundDSField = (UCHAR) dwRes;
  2027. break;
  2028. case 2:
  2029. // CONF_OUTBOUND_DS
  2030. pDsRule->ConformingOutboundDSField = (UCHAR) dwRes;
  2031. break;
  2032. case 3:
  2033. // NONCONF_OUTBOUND_DS
  2034. pDsRule->NonConformingOutboundDSField = (UCHAR) dwRes;
  2035. break;
  2036. case 4:
  2037. // CONF_USER_PRIOTITY
  2038. pDsRule->ConformingUserPriority = (UCHAR) dwRes;
  2039. break;
  2040. case 5:
  2041. // NONCONF_USER_PRIOTITY
  2042. pDsRule->NonConformingUserPriority = (UCHAR) dwRes;
  2043. break;
  2044. default:
  2045. {
  2046. i = dwNumArg;
  2047. dwErr = ERROR_INVALID_SYNTAX;
  2048. break;
  2049. }
  2050. }
  2051. }
  2052. do
  2053. {
  2054. if (dwErr != NO_ERROR)
  2055. {
  2056. break;
  2057. }
  2058. #if 0
  2059. //
  2060. // interface name should be present
  2061. // and the ds rule id (inbound ds)
  2062. //
  2063. if ((!pttTags[0].bPresent) ||
  2064. (!pttTags[1].bPresent))
  2065. {
  2066. dwErr = ERROR_INVALID_SYNTAX;
  2067. break;
  2068. }
  2069. #endif
  2070. //
  2071. // and the test of the info for add
  2072. //
  2073. if (bAdd)
  2074. {
  2075. if ((!pttTags[2].bPresent) ||
  2076. (!pttTags[3].bPresent) ||
  2077. (!pttTags[4].bPresent) ||
  2078. (!pttTags[5].bPresent))
  2079. {
  2080. dwErr = ERROR_INVALID_SYNTAX;
  2081. break;
  2082. }
  2083. }
  2084. #if 1
  2085. //
  2086. // BUGBUG: Adding and deleting DS rules will cause
  2087. // the corresponding map to be updated, but will
  2088. // this result in getting dependent flows changed?
  2089. //
  2090. #endif
  2091. if (bAdd)
  2092. {
  2093. if (pThisQosObject)
  2094. {
  2095. //
  2096. // Check if this dsrule is already present
  2097. //
  2098. pDsMap = (QOS_DIFFSERV *) &pThisQosObject->QosObjectHdr;
  2099. pNextDsRule = (QOS_DIFFSERV_RULE *)&pDsMap->DiffservRule[0];
  2100. for (j = 0; j < pDsMap->DSFieldCount; j++)
  2101. {
  2102. if (pNextDsRule->InboundDSField ==
  2103. pDsRule->InboundDSField)
  2104. {
  2105. break;
  2106. }
  2107. pNextDsRule++;
  2108. }
  2109. dwOffset = (PUCHAR)pNextDsRule - (PUCHAR)pigcSrc;
  2110. if (j < pDsMap->DSFieldCount)
  2111. {
  2112. //
  2113. // Update existing DS rule with info
  2114. //
  2115. *pNextDsRule = *pDsRule;
  2116. dwSkip = 0;
  2117. pBuffer = NULL;
  2118. }
  2119. else
  2120. {
  2121. //
  2122. // Initialize new DS rule for new rule info
  2123. //
  2124. dwSkip = sizeof(QOS_DIFFSERV_RULE);
  2125. pNextDsRule = HeapAlloc(GetProcessHeap(),
  2126. 0,
  2127. dwSkip);
  2128. if (pNextDsRule == NULL)
  2129. {
  2130. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2131. break;
  2132. }
  2133. *pNextDsRule = *pDsRule;
  2134. //
  2135. // Update num of dfsrv rules in src buff
  2136. // so that dst copy results in new value
  2137. //
  2138. pDsMap->DSFieldCount++;
  2139. pDsMap->ObjectHdr.ObjectLength +=sizeof(QOS_DIFFSERV_RULE);
  2140. pBuffer = pNextDsRule;
  2141. }
  2142. }
  2143. else
  2144. {
  2145. //
  2146. // Initialize a new DS map to hold the rule
  2147. //
  2148. dwSkip = sizeof(IPQOS_NAMED_QOSOBJECT) +
  2149. sizeof(ULONG) + // this for DSFieldCount
  2150. sizeof(QOS_DIFFSERV_RULE);
  2151. dwOffset = (PUCHAR) pNextQosObject - (PUCHAR) pigcSrc;
  2152. pThisQosObject = HeapAlloc(GetProcessHeap(),
  2153. 0,
  2154. dwSkip);
  2155. if (pThisQosObject == NULL)
  2156. {
  2157. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2158. break;
  2159. }
  2160. wcscpy(pThisQosObject->QosObjectName, pszDsMap);
  2161. pDsMap = (QOS_DIFFSERV *) &pThisQosObject->QosObjectHdr;
  2162. pDsMap->ObjectHdr.ObjectType = QOS_OBJECT_DIFFSERV;
  2163. pDsMap->ObjectHdr.ObjectLength =
  2164. dwSkip - FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr);
  2165. pDsMap->DSFieldCount = 1;
  2166. pNextDsRule =
  2167. (QOS_DIFFSERV_RULE *) &pDsMap->DiffservRule[0];
  2168. *pNextDsRule = *pDsRule;
  2169. //
  2170. // Update num of qos objects in src buff
  2171. // so that dst copy results in new value
  2172. //
  2173. pigcSrc->NumQosObjects++;
  2174. pBuffer = pThisQosObject;
  2175. }
  2176. dwNewBlkSize = dwBlkSize + dwSkip;
  2177. pigcDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  2178. if (!pigcDst)
  2179. {
  2180. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2181. break;
  2182. }
  2183. // Copy the all the info that occurs before
  2184. memcpy(pigcDst, pigcSrc, dwOffset);
  2185. // Copy the new information after dwOffset
  2186. memcpy((PUCHAR) pigcDst + dwOffset,
  2187. pBuffer,
  2188. dwSkip);
  2189. // Copy the rest of the info as it is
  2190. memcpy((PUCHAR) pigcDst + dwOffset + dwSkip,
  2191. (PUCHAR) pigcSrc + dwOffset,
  2192. dwBlkSize - dwOffset);
  2193. HEAP_FREE_NOT_NULL(pBuffer);
  2194. }
  2195. else
  2196. {
  2197. //
  2198. // Check if this dsrule is already present
  2199. //
  2200. pDsMap = (QOS_DIFFSERV *) &pThisQosObject->QosObjectHdr;
  2201. pNextDsRule = (QOS_DIFFSERV_RULE *)&pDsMap->DiffservRule[0];
  2202. for (j = 0; j < pDsMap->DSFieldCount; j++)
  2203. {
  2204. if (pNextDsRule->InboundDSField ==
  2205. pDsRule->InboundDSField)
  2206. {
  2207. break;
  2208. }
  2209. pNextDsRule++;
  2210. }
  2211. if (j == pDsMap->DSFieldCount)
  2212. {
  2213. // Did not find DS rule in the DS map
  2214. DisplayMessage(g_hModule,
  2215. MSG_DSRULE_NOT_FOUND,
  2216. pszDsMap,
  2217. pDsRule->InboundDSField);
  2218. dwErr = ERROR_SUPPRESS_OUTPUT;
  2219. break;
  2220. }
  2221. if (pDsMap->DSFieldCount == 1)
  2222. {
  2223. // Last DS rule in the DS map
  2224. dwOffset = (PUCHAR)pThisQosObject - (PUCHAR)pigcSrc;
  2225. dwSkip = sizeof(IPQOS_NAMED_QOSOBJECT) +
  2226. sizeof(ULONG) + // this for DSFieldCount
  2227. sizeof(QOS_DIFFSERV_RULE);
  2228. //
  2229. // Update num of qos objects in src buff
  2230. // so that dst copy results in new value
  2231. //
  2232. pigcSrc->NumQosObjects--;
  2233. }
  2234. else
  2235. {
  2236. // More than 1 rule in DS map
  2237. dwOffset = (PUCHAR)pNextDsRule - (PUCHAR)pigcSrc;
  2238. dwSkip = sizeof(QOS_DIFFSERV_RULE);
  2239. //
  2240. // Update num of dfsrv rules in src buff
  2241. // so that dst copy results in new value
  2242. //
  2243. pDsMap->DSFieldCount--;
  2244. pDsMap->ObjectHdr.ObjectLength -= sizeof(QOS_DIFFSERV_RULE);
  2245. }
  2246. dwNewBlkSize = dwBlkSize - dwSkip;
  2247. pigcDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  2248. if (!pigcDst)
  2249. {
  2250. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2251. break;
  2252. }
  2253. // Copy the all the info that occurs before
  2254. memcpy(pigcDst, pigcSrc, dwOffset);
  2255. // Copy the rest of the info as it is
  2256. dwOffset += dwSkip;
  2257. memcpy((PUCHAR) pigcDst + dwOffset - dwSkip,
  2258. (PUCHAR) pigcSrc + dwOffset,
  2259. dwBlkSize - dwOffset);
  2260. }
  2261. // Update the global config by setting new info
  2262. dwErr = IpmontrSetInfoBlockInGlobalInfo(MS_IP_QOSMGR,
  2263. (PBYTE) pigcDst,
  2264. dwNewBlkSize,
  2265. dwQosCount);
  2266. if (dwErr == NO_ERROR)
  2267. {
  2268. UpdateAllInterfaceConfigs();
  2269. }
  2270. }
  2271. while (FALSE);
  2272. HEAP_FREE_NOT_NULL(pigcSrc);
  2273. HEAP_FREE_NOT_NULL(pigcDst);
  2274. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  2275. }
  2276. DWORD
  2277. ShowQosDsMap(
  2278. IN HANDLE hFile,
  2279. IN PWCHAR wszDsMapName,
  2280. IN QOS_OBJECT_HDR *pQosObject
  2281. )
  2282. {
  2283. QOS_DIFFSERV_RULE *pDsRule;
  2284. QOS_DIFFSERV *pDsMap;
  2285. PWCHAR pwszDsMapName;
  2286. DWORD dwErr, k;
  2287. pDsMap = (QOS_DIFFSERV *) pQosObject;
  2288. //
  2289. // Print or dump the dsmap now
  2290. //
  2291. do
  2292. {
  2293. pwszDsMapName = MakeQuotedString(wszDsMapName);
  2294. if (pwszDsMapName == NULL)
  2295. {
  2296. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2297. break;
  2298. }
  2299. if (hFile)
  2300. {
  2301. DisplayMessageT(DMP_QOS_DSMAP_HEADER);
  2302. }
  2303. else
  2304. {
  2305. DisplayMessage(g_hModule, MSG_QOS_DSMAP_INFO,
  2306. pwszDsMapName,
  2307. pDsMap->DSFieldCount);
  2308. }
  2309. //
  2310. // Print each DS rule in the map
  2311. //
  2312. pDsRule = (QOS_DIFFSERV_RULE *) &pDsMap->DiffservRule[0];
  2313. for (k = 0; k < pDsMap->DSFieldCount; k++)
  2314. {
  2315. if (hFile)
  2316. {
  2317. DisplayMessageT(DMP_QOS_DELETE_DSRULE,
  2318. pwszDsMapName,
  2319. pDsRule->InboundDSField);
  2320. DisplayMessageT(DMP_QOS_ADD_DSRULE,
  2321. pwszDsMapName,
  2322. pDsRule->InboundDSField,
  2323. pDsRule->ConformingOutboundDSField,
  2324. pDsRule->NonConformingOutboundDSField,
  2325. pDsRule->ConformingUserPriority,
  2326. pDsRule->NonConformingUserPriority);
  2327. }
  2328. else
  2329. {
  2330. DisplayMessage(g_hModule, MSG_QOS_DSRULE_INFO,
  2331. pwszDsMapName,
  2332. k,
  2333. pDsRule->InboundDSField,
  2334. pDsRule->ConformingOutboundDSField,
  2335. pDsRule->NonConformingOutboundDSField,
  2336. pDsRule->ConformingUserPriority,
  2337. pDsRule->NonConformingUserPriority);
  2338. }
  2339. pDsRule++;
  2340. }
  2341. if (hFile)
  2342. {
  2343. DisplayMessageT(DMP_QOS_DSMAP_FOOTER);
  2344. }
  2345. if ( pwszDsMapName )
  2346. {
  2347. FreeQuotedString( pwszDsMapName );
  2348. }
  2349. return NO_ERROR;
  2350. }
  2351. while (FALSE);
  2352. return dwErr;
  2353. }
  2354. //
  2355. // SD Mode Helpers
  2356. //
  2357. DWORD
  2358. ShowQosSdMode(
  2359. IN HANDLE hFile,
  2360. IN PWCHAR wszSdModeName,
  2361. IN QOS_OBJECT_HDR *pQosObject
  2362. )
  2363. {
  2364. QOS_SD_MODE *pSdMode;
  2365. PWCHAR pwszSdModeName;
  2366. DWORD dwErr, k;
  2367. PTCHAR ptszSdMode = NULL;
  2368. VALUE_TOKEN vtSdMode1[] =
  2369. {TC_NONCONF_BORROW,TOKEN_OPT_SDMODE_BORROW,
  2370. TC_NONCONF_SHAPE,TOKEN_OPT_SDMODE_SHAPE,
  2371. TC_NONCONF_DISCARD,TOKEN_OPT_SDMODE_DISCARD,
  2372. TC_NONCONF_BORROW_PLUS,TOKEN_OPT_SDMODE_BORROW_PLUS};
  2373. VALUE_STRING vtSdMode2[] =
  2374. {TC_NONCONF_BORROW,STRING_SDMODE_BORROW,
  2375. TC_NONCONF_SHAPE,STRING_SDMODE_SHAPE,
  2376. TC_NONCONF_DISCARD,STRING_SDMODE_DISCARD,
  2377. TC_NONCONF_BORROW_PLUS,STRING_SDMODE_BORROW_PLUS};
  2378. pSdMode = (QOS_SD_MODE *)pQosObject;
  2379. //
  2380. // Print or dump the sdmode now
  2381. //
  2382. do
  2383. {
  2384. pwszSdModeName = MakeQuotedString(wszSdModeName);
  2385. if (pwszSdModeName == NULL)
  2386. {
  2387. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2388. break;
  2389. }
  2390. //
  2391. // Get service type of flowspec
  2392. //
  2393. GetAltDisplayString(g_hModule, hFile,
  2394. pSdMode->ShapeDiscardMode,
  2395. vtSdMode1,
  2396. vtSdMode2,
  2397. NUM_VALUES_IN_TABLE(vtSdMode1),
  2398. &ptszSdMode);
  2399. if ( ptszSdMode == NULL )
  2400. {
  2401. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2402. break;
  2403. }
  2404. if (hFile)
  2405. {
  2406. DisplayMessageT(DMP_QOS_DEL_SDMODE,
  2407. pwszSdModeName);
  2408. DisplayMessageT(DMP_QOS_ADD_SDMODE,
  2409. pwszSdModeName,
  2410. ptszSdMode);
  2411. }
  2412. else
  2413. {
  2414. DisplayMessage(g_hModule, MSG_QOS_SDMODE_INFO,
  2415. pwszSdModeName,
  2416. ptszSdMode);
  2417. }
  2418. FREE_STRING_NOT_NULL ( ptszSdMode );
  2419. if ( pwszSdModeName )
  2420. {
  2421. FreeQuotedString( pwszSdModeName );
  2422. }
  2423. return NO_ERROR;
  2424. }
  2425. while (FALSE);
  2426. return dwErr;
  2427. }
  2428. //
  2429. // Qos Object Helpers
  2430. //
  2431. DWORD
  2432. GetQosAddDelQosObject(
  2433. IN PWCHAR pwszQosObjectName,
  2434. IN QOS_OBJECT_HDR *pQosObject,
  2435. IN BOOL bAdd
  2436. )
  2437. {
  2438. PIPQOS_NAMED_QOSOBJECT pNextQosObject;
  2439. PIPQOS_GLOBAL_CONFIG pigcSrc = NULL, pigcDst = NULL;
  2440. DWORD dwBlkSize, dwNewBlkSize, dwQosCount;
  2441. DWORD dwErr, dwSize, dwSkip, dwOffset, j;
  2442. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  2443. (PBYTE *) &pigcSrc,
  2444. &dwBlkSize,
  2445. &dwQosCount);
  2446. if (dwErr != NO_ERROR)
  2447. {
  2448. return dwErr;
  2449. }
  2450. if (pigcSrc == NULL)
  2451. {
  2452. return ERROR_INVALID_PARAMETER;
  2453. }
  2454. dwOffset = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr);
  2455. //
  2456. // Search for a QOS Object with this name
  2457. //
  2458. pNextQosObject = (PIPQOS_NAMED_QOSOBJECT)((PUCHAR) pigcSrc
  2459. + sizeof(IPQOS_GLOBAL_CONFIG)
  2460. + (pigcSrc->NumFlowspecs *
  2461. sizeof(IPQOS_NAMED_FLOWSPEC)));
  2462. for (j = 0; j < pigcSrc->NumQosObjects; j++)
  2463. {
  2464. if (!_wcsicmp(pNextQosObject->QosObjectName,
  2465. pwszQosObjectName))
  2466. {
  2467. break;
  2468. }
  2469. pNextQosObject = (PIPQOS_NAMED_QOSOBJECT)
  2470. ((PUCHAR) pNextQosObject +
  2471. dwOffset +
  2472. pNextQosObject->QosObjectHdr.ObjectLength);
  2473. }
  2474. do
  2475. {
  2476. if (bAdd)
  2477. {
  2478. dwSize = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr) +
  2479. pQosObject->ObjectLength;
  2480. dwSkip = 0;
  2481. if (j < pigcSrc->NumQosObjects)
  2482. {
  2483. //
  2484. // Do (not) allow overwriting qos objects
  2485. //
  2486. #if NO_UPDATE
  2487. //
  2488. // We already have a qos object by this name
  2489. //
  2490. DisplayMessage(g_hModule,
  2491. MSG_QOSOBJECT_ALREADY_EXISTS,
  2492. pwszQosObjectName);
  2493. dwErr = ERROR_SUPPRESS_OUTPUT;
  2494. break;
  2495. #endif
  2496. // Get the existing size of the qos object
  2497. dwSkip = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr) +
  2498. pNextQosObject->QosObjectHdr.ObjectLength;
  2499. }
  2500. else
  2501. {
  2502. //
  2503. // Update num of qos objects in src buff
  2504. // so that dst copy results in new value
  2505. //
  2506. pigcSrc->NumQosObjects++;
  2507. }
  2508. dwOffset = (PUCHAR) pNextQosObject - (PUCHAR) pigcSrc;
  2509. dwNewBlkSize = dwBlkSize + dwSize - dwSkip;
  2510. pigcDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  2511. if (!pigcDst)
  2512. {
  2513. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2514. break;
  2515. }
  2516. // Copy the all the info that occurs before
  2517. memcpy(pigcDst, pigcSrc, dwOffset);
  2518. // Copy the new information after dwOffset
  2519. // Copy the name of the qos object first
  2520. wcscpy((PWCHAR)((PUCHAR) pigcDst + dwOffset),
  2521. pwszQosObjectName);
  2522. // Copy the rest of the input information
  2523. memcpy((PUCHAR) pigcDst + dwOffset + MAX_WSTR_LENGTH,
  2524. (PUCHAR) pQosObject,
  2525. pQosObject->ObjectLength);
  2526. // Copy the rest of the info as it is
  2527. memcpy((PUCHAR) pigcDst + (dwOffset + dwSize),
  2528. (PUCHAR) pigcSrc + (dwOffset + dwSkip),
  2529. dwBlkSize - (dwOffset + dwSkip));
  2530. }
  2531. else
  2532. {
  2533. #if 1
  2534. //
  2535. // BUGBUG: What if there are dependent flows ?
  2536. //
  2537. #endif
  2538. if (j == pigcSrc->NumQosObjects)
  2539. {
  2540. //
  2541. // We do not have a qos object by this name
  2542. //
  2543. DisplayMessage(g_hModule,
  2544. MSG_QOSOBJECT_NOT_FOUND,
  2545. pwszQosObjectName);
  2546. dwErr = ERROR_SUPPRESS_OUTPUT;
  2547. break;
  2548. }
  2549. //
  2550. // Update num of qos objects in src buff
  2551. // so that dst copy results in new value
  2552. //
  2553. pigcSrc->NumQosObjects--;
  2554. dwOffset = (PUCHAR)pNextQosObject - (PUCHAR)pigcSrc;
  2555. dwSkip = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr) +
  2556. pNextQosObject->QosObjectHdr.ObjectLength;
  2557. dwNewBlkSize = dwBlkSize - dwSkip;
  2558. pigcDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  2559. if (!pigcDst)
  2560. {
  2561. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2562. break;
  2563. }
  2564. // Copy the all the info that occurs before
  2565. memcpy(pigcDst, pigcSrc, dwOffset);
  2566. // Copy the rest of the info as it is
  2567. dwOffset += dwSkip;
  2568. memcpy((PUCHAR) pigcDst + dwOffset - dwSkip,
  2569. (PUCHAR) pigcSrc + dwOffset,
  2570. dwBlkSize - dwOffset);
  2571. }
  2572. // Update the global config by setting new info
  2573. dwErr = IpmontrSetInfoBlockInGlobalInfo(MS_IP_QOSMGR,
  2574. (PBYTE) pigcDst,
  2575. dwNewBlkSize,
  2576. dwQosCount);
  2577. if (dwErr == NO_ERROR)
  2578. {
  2579. UpdateAllInterfaceConfigs();
  2580. }
  2581. }
  2582. while (FALSE);
  2583. HEAP_FREE_NOT_NULL(pigcSrc);
  2584. HEAP_FREE_NOT_NULL(pigcDst);
  2585. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  2586. }
  2587. DWORD
  2588. ShowQosObjects(
  2589. IN HANDLE hFile,
  2590. IN PWCHAR wszQosObjectName,
  2591. IN ULONG dwQosObjectType
  2592. )
  2593. {
  2594. PIPQOS_NAMED_QOSOBJECT pNextQosObject;
  2595. PIPQOS_GLOBAL_CONFIG pigcSrc;
  2596. PSHOW_QOS_OBJECT pfnShowQosObject;
  2597. DWORD dwBlkSize,dwQosCount;
  2598. DWORD dwOffset;
  2599. DWORD dwErr, j;
  2600. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  2601. (PBYTE *) &pigcSrc,
  2602. &dwBlkSize,
  2603. &dwQosCount);
  2604. if (dwErr != NO_ERROR)
  2605. {
  2606. return dwErr;
  2607. }
  2608. if ( pigcSrc == NULL )
  2609. {
  2610. return ERROR_INVALID_PARAMETER;
  2611. }
  2612. dwOffset = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr);
  2613. pNextQosObject = (PIPQOS_NAMED_QOSOBJECT)((PUCHAR) pigcSrc
  2614. + sizeof(IPQOS_GLOBAL_CONFIG)
  2615. + (pigcSrc->NumFlowspecs *
  2616. sizeof(IPQOS_NAMED_FLOWSPEC)));
  2617. for (j = 0; j < pigcSrc->NumQosObjects; j++)
  2618. {
  2619. if ((dwQosObjectType == QOS_OBJECT_END_OF_LIST) ||
  2620. (dwQosObjectType == pNextQosObject->QosObjectHdr.ObjectType))
  2621. {
  2622. if ((!wszQosObjectName) ||
  2623. (!_wcsicmp(pNextQosObject->QosObjectName, wszQosObjectName)))
  2624. {
  2625. switch (pNextQosObject->QosObjectHdr.ObjectType)
  2626. {
  2627. case QOS_OBJECT_DIFFSERV:
  2628. pfnShowQosObject = ShowQosDsMap;
  2629. break;
  2630. case QOS_OBJECT_SD_MODE:
  2631. pfnShowQosObject = ShowQosSdMode;
  2632. break;
  2633. default:
  2634. pfnShowQosObject = ShowQosGenObj;
  2635. }
  2636. pfnShowQosObject(hFile,
  2637. pNextQosObject->QosObjectName,
  2638. &pNextQosObject->QosObjectHdr);
  2639. //
  2640. // If we matched the qos object name, then done
  2641. //
  2642. if (wszQosObjectName)
  2643. {
  2644. break;
  2645. }
  2646. }
  2647. }
  2648. pNextQosObject = (PIPQOS_NAMED_QOSOBJECT)
  2649. ((PUCHAR) pNextQosObject +
  2650. dwOffset +
  2651. pNextQosObject->QosObjectHdr.ObjectLength);
  2652. }
  2653. if (dwErr == NO_ERROR)
  2654. {
  2655. if ((wszQosObjectName) && (j == pigcSrc->NumQosObjects))
  2656. {
  2657. // We didnt find the qos object we are looking for
  2658. DisplayMessage(g_hModule,
  2659. MSG_QOSOBJECT_NOT_FOUND,
  2660. wszQosObjectName);
  2661. dwErr = ERROR_SUPPRESS_OUTPUT;
  2662. }
  2663. }
  2664. HEAP_FREE(pigcSrc);
  2665. return dwErr;
  2666. }
  2667. DWORD
  2668. ShowQosGenObj(
  2669. IN HANDLE hFile,
  2670. IN PWCHAR wszGenObjName,
  2671. IN QOS_OBJECT_HDR *pQosObject
  2672. )
  2673. {
  2674. // We can print a general description from name and size
  2675. return NO_ERROR;
  2676. }
  2677. DWORD
  2678. GetQosAddDelQosObjectOnFlowOpt(
  2679. PTCHAR *pptcArguments,
  2680. DWORD dwCurrentIndex,
  2681. DWORD dwArgCount,
  2682. BOOL bAdd
  2683. )
  2684. /*++
  2685. Routine Description:
  2686. Gets options for attach and detach QOS objects
  2687. from flows.
  2688. Arguments:
  2689. pptcArguments - Argument array
  2690. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  2691. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  2692. bAdd - Adding or deleting flows
  2693. Return Value:
  2694. NO_ERROR
  2695. --*/
  2696. {
  2697. PIPQOS_GLOBAL_CONFIG pigcSrc = NULL;
  2698. PIPQOS_IF_CONFIG piicSrc = NULL, piicDst = NULL;
  2699. DWORD dwBlkSize, dwNewBlkSize, dwQosCount;
  2700. DWORD dwBlkSize1, dwQosCount1;
  2701. DWORD i, j, k, l;
  2702. DWORD dwErr = NO_ERROR, dwNumOpt;
  2703. DWORD dwRes;
  2704. DWORD dwSkip, dwOffset, dwSize, dwBitVector = 0;
  2705. DWORD dwIfType;
  2706. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  2707. PIPQOS_NAMED_QOSOBJECT pNamedQosObject, pNextQosObject;
  2708. PIPQOS_IF_FLOW pNextFlow, pDestFlow;
  2709. PWCHAR pwszFlowName, pwszQosObject, pwszNextObject;
  2710. DWORD dwNumArg,
  2711. dwBufferSize = sizeof(wszIfName);
  2712. PUCHAR pFlow;
  2713. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,TRUE,FALSE},
  2714. {TOKEN_OPT_FLOW_NAME,TRUE,FALSE},
  2715. {TOKEN_OPT_QOSOBJECT,TRUE,FALSE}};
  2716. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  2717. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  2718. //
  2719. // parse command arguements
  2720. //
  2721. dwErr = PreprocessCommand(
  2722. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  2723. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  2724. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  2725. );
  2726. if ( dwErr != NO_ERROR )
  2727. {
  2728. return dwErr;
  2729. }
  2730. dwNumArg = dwArgCount - dwCurrentIndex;
  2731. for ( i = 0; i < dwNumArg; i++ )
  2732. {
  2733. switch (pdwTagType[i])
  2734. {
  2735. case 0:
  2736. // INTERFACE NAME
  2737. IpmontrGetIfNameFromFriendlyName( pptcArguments[i + dwCurrentIndex],
  2738. wszIfName,&dwBufferSize);
  2739. break;
  2740. case 1:
  2741. // FLOW NAME
  2742. pwszFlowName = pptcArguments[i + dwCurrentIndex];
  2743. break;
  2744. case 2:
  2745. // QOSOBJECT NAME
  2746. pwszQosObject = pptcArguments[i + dwCurrentIndex];
  2747. break;
  2748. default:
  2749. i = dwNumArg;
  2750. dwErr = ERROR_INVALID_SYNTAX;
  2751. break;
  2752. }
  2753. }
  2754. do
  2755. {
  2756. if (dwErr != NO_ERROR)
  2757. {
  2758. break;
  2759. }
  2760. #if 0
  2761. // interface, flow, qosobject names should be present
  2762. if ((!pttTags[0].bPresent) ||
  2763. (!pttTags[1].bPresent) ||
  2764. (!pttTags[2].bPresent))
  2765. {
  2766. dwErr = ERROR_INVALID_SYNTAX;
  2767. break;
  2768. }
  2769. #endif
  2770. //
  2771. // Get the interface info and check if flow already exists
  2772. //
  2773. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(wszIfName,
  2774. MS_IP_QOSMGR,
  2775. (PBYTE *) &piicSrc,
  2776. &dwBlkSize,
  2777. &dwQosCount,
  2778. &dwIfType);
  2779. if (dwErr != NO_ERROR)
  2780. {
  2781. break;
  2782. }
  2783. if ( piicSrc == NULL )
  2784. {
  2785. dwErr = ERROR_INVALID_PARAMETER;
  2786. break;
  2787. }
  2788. pNextFlow = (PIPQOS_IF_FLOW)((PUCHAR)piicSrc + sizeof(IPQOS_IF_CONFIG));
  2789. for (j = 0; j < piicSrc->NumFlows; j++)
  2790. {
  2791. if (!_wcsicmp(pNextFlow->FlowName, pwszFlowName))
  2792. {
  2793. break;
  2794. }
  2795. pNextFlow = (PIPQOS_IF_FLOW)
  2796. ((PUCHAR) pNextFlow + pNextFlow->FlowSize);
  2797. }
  2798. if (j == piicSrc->NumFlows)
  2799. {
  2800. //
  2801. // We do not have a flow by this name
  2802. //
  2803. DisplayMessage(g_hModule,
  2804. MSG_FLOW_NOT_FOUND,
  2805. pwszFlowName);
  2806. i = dwNumArg;
  2807. dwErr = ERROR_SUPPRESS_OUTPUT;
  2808. break;
  2809. }
  2810. // Flow was found at 'pNextFlow' position
  2811. //
  2812. // Search for a QOS object by this name
  2813. //
  2814. pwszNextObject =
  2815. (PWCHAR) ((PUCHAR) pNextFlow + sizeof(IPQOS_IF_FLOW));
  2816. for (k = 0; k < pNextFlow->FlowDesc.NumTcObjects; k++)
  2817. {
  2818. if (!_wcsicmp(pwszNextObject, pwszQosObject))
  2819. {
  2820. break;
  2821. }
  2822. pwszNextObject += MAX_STRING_LENGTH;
  2823. }
  2824. if (!bAdd)
  2825. {
  2826. //
  2827. // Make sure that the flow has the named qosobject
  2828. //
  2829. if (k == pNextFlow->FlowDesc.NumTcObjects)
  2830. {
  2831. DisplayMessage(g_hModule,
  2832. MSG_QOSOBJECT_NOT_FOUND,
  2833. pwszQosObject);
  2834. dwErr = ERROR_SUPPRESS_OUTPUT;
  2835. break;
  2836. }
  2837. //
  2838. // Update number of qos objects in src buff
  2839. // so that copy to dest results in new value
  2840. //
  2841. pNextFlow->FlowSize -= MAX_WSTR_LENGTH;
  2842. pNextFlow->FlowDesc.NumTcObjects--;
  2843. //
  2844. // Delete the association of the qosobject & flow
  2845. //
  2846. dwNewBlkSize = dwBlkSize - MAX_WSTR_LENGTH;
  2847. piicDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  2848. if (!piicDst)
  2849. {
  2850. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2851. break;
  2852. }
  2853. dwOffset = (PUCHAR)pwszNextObject - (PUCHAR)piicSrc;
  2854. // Copy the all the objects that occur before
  2855. memcpy(piicDst, piicSrc, dwOffset);
  2856. // Copy the rest of the obj names as they are
  2857. dwSkip = dwOffset + MAX_WSTR_LENGTH;
  2858. memcpy((PUCHAR) piicDst + dwOffset,
  2859. (PUCHAR) piicSrc + dwSkip,
  2860. dwBlkSize - dwSkip);
  2861. }
  2862. else
  2863. {
  2864. //
  2865. // Does the flow already have this QOS object ?
  2866. //
  2867. if (k < pNextFlow->FlowDesc.NumTcObjects)
  2868. {
  2869. DisplayMessage(g_hModule,
  2870. MSG_QOSOBJECT_ALREADY_EXISTS,
  2871. pwszQosObject);
  2872. dwErr = ERROR_SUPPRESS_OUTPUT;
  2873. break;
  2874. }
  2875. //
  2876. // Make sure that qosobject is actually defined
  2877. //
  2878. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  2879. (PBYTE *) &pigcSrc,
  2880. &dwBlkSize1,
  2881. &dwQosCount1);
  2882. if (dwErr != NO_ERROR)
  2883. {
  2884. break;
  2885. }
  2886. if ( pigcSrc == NULL )
  2887. {
  2888. dwErr = ERROR_INVALID_PARAMETER;
  2889. break;
  2890. }
  2891. dwOffset = FIELD_OFFSET(IPQOS_NAMED_QOSOBJECT, QosObjectHdr);
  2892. pNextQosObject =
  2893. (PIPQOS_NAMED_QOSOBJECT)((PUCHAR) pigcSrc
  2894. + sizeof(IPQOS_GLOBAL_CONFIG)
  2895. + (pigcSrc->NumFlowspecs *
  2896. sizeof(IPQOS_NAMED_FLOWSPEC)));
  2897. for (l = 0; l < pigcSrc->NumQosObjects; l++)
  2898. {
  2899. if (!_wcsicmp(pNextQosObject->QosObjectName,
  2900. pwszQosObject))
  2901. {
  2902. break;
  2903. }
  2904. pNextQosObject = (PIPQOS_NAMED_QOSOBJECT)
  2905. ((PUCHAR) pNextQosObject +
  2906. dwOffset +
  2907. pNextQosObject->QosObjectHdr.ObjectLength);
  2908. }
  2909. if (l == pigcSrc->NumQosObjects)
  2910. {
  2911. //
  2912. // We do not have a qos object by this name
  2913. //
  2914. DisplayMessage(g_hModule,
  2915. MSG_QOSOBJECT_NOT_FOUND,
  2916. pwszQosObject);
  2917. dwErr = ERROR_SUPPRESS_OUTPUT;
  2918. break;
  2919. }
  2920. //
  2921. // Update number of qos objects in src buff
  2922. // so that copy to dest results in new value
  2923. //
  2924. pNextFlow->FlowSize += MAX_WSTR_LENGTH;
  2925. pNextFlow->FlowDesc.NumTcObjects++;
  2926. //
  2927. // Create the association of the qosobject & flow
  2928. //
  2929. dwNewBlkSize = dwBlkSize + MAX_WSTR_LENGTH;
  2930. piicDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  2931. if (!piicDst)
  2932. {
  2933. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  2934. break;
  2935. }
  2936. dwOffset = (PUCHAR)pwszNextObject - (PUCHAR)piicSrc;
  2937. // Copy the all the objects that occur before
  2938. memcpy(piicDst, piicSrc, dwOffset);
  2939. // Copy the new association at the end of flow
  2940. wcscpy((PWCHAR)((PUCHAR) piicDst + dwOffset),
  2941. pwszQosObject);
  2942. // Copy the rest of the obj names as they are
  2943. dwSkip = dwOffset + MAX_WSTR_LENGTH;
  2944. memcpy((PUCHAR) piicDst + dwSkip,
  2945. (PUCHAR) piicSrc + dwOffset,
  2946. dwBlkSize - dwOffset);
  2947. }
  2948. // Update the interface config by setting new info
  2949. dwErr = IpmontrSetInfoBlockInInterfaceInfo(wszIfName,
  2950. MS_IP_QOSMGR,
  2951. (PBYTE) piicDst,
  2952. dwNewBlkSize,
  2953. dwQosCount);
  2954. }
  2955. while (FALSE);
  2956. HEAP_FREE_NOT_NULL(piicSrc);
  2957. HEAP_FREE_NOT_NULL(pigcSrc);
  2958. HEAP_FREE_NOT_NULL(piicDst);
  2959. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  2960. }
  2961. //
  2962. // Flowspec Helpers
  2963. //
  2964. DWORD
  2965. GetQosAddDelFlowspecOpt(
  2966. PTCHAR *pptcArguments,
  2967. DWORD dwCurrentIndex,
  2968. DWORD dwArgCount,
  2969. BOOL bAdd
  2970. )
  2971. {
  2972. DWORD dwErr = NO_ERROR;
  2973. TAG_TYPE pttTags[] = {
  2974. {TOKEN_OPT_NAME,TRUE,FALSE},
  2975. {TOKEN_OPT_SERVICE_TYPE,FALSE,FALSE},
  2976. {TOKEN_OPT_TOKEN_RATE,FALSE,FALSE},
  2977. {TOKEN_OPT_TOKEN_BUCKET_SIZE,FALSE,FALSE},
  2978. {TOKEN_OPT_PEAK_BANDWIDTH,FALSE,FALSE},
  2979. {TOKEN_OPT_LATENCY,FALSE,FALSE},
  2980. {TOKEN_OPT_DELAY_VARIATION,FALSE,FALSE},
  2981. {TOKEN_OPT_MAX_SDU_SIZE,FALSE,FALSE},
  2982. {TOKEN_OPT_MIN_POLICED_SIZE,FALSE,FALSE}};
  2983. PIPQOS_NAMED_FLOWSPEC pNamedFlowspec, pNextFlowspec;
  2984. FLOWSPEC fsFlowspec, *pFlowspec;
  2985. PIPQOS_GLOBAL_CONFIG pigcSrc = NULL, pigcDst = NULL;
  2986. DWORD dwBlkSize, dwNewBlkSize, dwQosCount;
  2987. PTCHAR pszFlowspec;
  2988. DWORD dwNumOpt, dwRes;
  2989. DWORD dwNumArg, i, j;
  2990. DWORD dwSkip, dwOffset;
  2991. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  2992. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  2993. //
  2994. // parse command arguements
  2995. //
  2996. dwErr = PreprocessCommand(
  2997. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  2998. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  2999. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  3000. );
  3001. if ( dwErr != NO_ERROR )
  3002. {
  3003. return dwErr;
  3004. }
  3005. dwNumArg = dwArgCount - dwCurrentIndex;
  3006. //
  3007. // We need only the name for delete
  3008. //
  3009. if (!bAdd && (dwNumArg != 1))
  3010. {
  3011. return ERROR_INVALID_SYNTAX;
  3012. }
  3013. pFlowspec = &fsFlowspec;
  3014. if (bAdd)
  3015. {
  3016. //
  3017. // Initialize the flowspec definition
  3018. //
  3019. memset(pFlowspec, QOS_NOT_SPECIFIED, sizeof(FLOWSPEC));
  3020. }
  3021. //
  3022. // Process the arguments now
  3023. //
  3024. for ( i = 0; i < dwNumArg; i++)
  3025. {
  3026. // Only an flowspec name is allowed at delete
  3027. if ((!bAdd) && (pdwTagType[i] != 0))
  3028. {
  3029. dwErr = ERROR_INVALID_SYNTAX;
  3030. break;
  3031. }
  3032. // All params except the first 2 are ulong vals
  3033. if ( pdwTagType[i] > 1)
  3034. {
  3035. // What if this is not a valid ULONG ? '0' will not do...
  3036. dwRes = _tcstoul(pptcArguments[i + dwCurrentIndex],NULL,10);
  3037. }
  3038. switch (pdwTagType[i])
  3039. {
  3040. case 0 :
  3041. {
  3042. //
  3043. // FLOWSPEC_NAME : See if we already have the name
  3044. //
  3045. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  3046. (PBYTE *) &pigcSrc,
  3047. &dwBlkSize,
  3048. &dwQosCount);
  3049. if (dwErr != NO_ERROR)
  3050. {
  3051. break;
  3052. }
  3053. if ( pigcSrc == NULL )
  3054. {
  3055. dwErr = ERROR_INVALID_PARAMETER;
  3056. break;
  3057. }
  3058. pNextFlowspec = (PIPQOS_NAMED_FLOWSPEC)
  3059. ((PUCHAR) pigcSrc + sizeof(IPQOS_GLOBAL_CONFIG));
  3060. for (j = 0; j < pigcSrc->NumFlowspecs; j++)
  3061. {
  3062. if (!_wcsicmp(pNextFlowspec->FlowspecName,
  3063. pptcArguments[i + dwCurrentIndex]))
  3064. {
  3065. break;
  3066. }
  3067. pNextFlowspec++;
  3068. }
  3069. if (bAdd)
  3070. {
  3071. //
  3072. // Do (not) allow overwriting existing flowspecs
  3073. //
  3074. #if NO_UPDATE
  3075. if (j < pigcSrc->NumFlowspecs)
  3076. {
  3077. //
  3078. // We already have a flowspec by this name
  3079. //
  3080. DisplayMessage(g_hModule,
  3081. MSG_FLOWSPEC_ALREADY_EXISTS,
  3082. pptcArguments[i + dwCurrentIndex]);
  3083. i = dwNumArg;
  3084. dwErr = ERROR_SUPPRESS_OUTPUT;
  3085. break;
  3086. }
  3087. #endif
  3088. pszFlowspec = pptcArguments[i + dwCurrentIndex];
  3089. }
  3090. else
  3091. {
  3092. if (j == pigcSrc->NumFlowspecs)
  3093. {
  3094. //
  3095. // We do not have a flowspec by this name
  3096. //
  3097. DisplayMessage(g_hModule,
  3098. MSG_FLOWSPEC_NOT_FOUND,
  3099. pptcArguments[i + dwCurrentIndex]);
  3100. i = dwNumArg;
  3101. dwErr = ERROR_SUPPRESS_OUTPUT;
  3102. break;
  3103. }
  3104. }
  3105. break;
  3106. }
  3107. case 1:
  3108. {
  3109. //
  3110. // SERVICE_TYPE
  3111. //
  3112. TOKEN_VALUE rgEnums[] =
  3113. {{TOKEN_OPT_SERVICE_BESTEFFORT, SERVICETYPE_BESTEFFORT},
  3114. {TOKEN_OPT_SERVICE_CONTROLLEDLOAD,SERVICETYPE_CONTROLLEDLOAD},
  3115. {TOKEN_OPT_SERVICE_GUARANTEED, SERVICETYPE_GUARANTEED},
  3116. {TOKEN_OPT_SERVICE_QUALITATIVE, SERVICETYPE_QUALITATIVE}};
  3117. GET_ENUM_TAG_VALUE();
  3118. pFlowspec->ServiceType = dwRes;
  3119. break;
  3120. }
  3121. case 2:
  3122. {
  3123. //
  3124. // TOKEN_RATE
  3125. //
  3126. pFlowspec->TokenRate = dwRes;
  3127. break;
  3128. }
  3129. case 3:
  3130. {
  3131. //
  3132. // TOKEN_BUCKET_SIZE
  3133. //
  3134. pFlowspec->TokenBucketSize = dwRes;
  3135. break;
  3136. }
  3137. case 4:
  3138. {
  3139. //
  3140. // PEAK_BANDWIDTH
  3141. //
  3142. pFlowspec->PeakBandwidth = dwRes;
  3143. break;
  3144. }
  3145. case 5:
  3146. {
  3147. //
  3148. // LATENCY
  3149. //
  3150. pFlowspec->Latency = dwRes;
  3151. break;
  3152. }
  3153. case 6:
  3154. {
  3155. //
  3156. // DELAY_VARIATION
  3157. //
  3158. pFlowspec->DelayVariation = dwRes;
  3159. break;
  3160. }
  3161. case 7:
  3162. {
  3163. //
  3164. // MAX_SDU_SIZE
  3165. //
  3166. pFlowspec->MaxSduSize = dwRes;
  3167. break;
  3168. }
  3169. case 8:
  3170. {
  3171. //
  3172. // MIN_POLICED_SIZE
  3173. //
  3174. pFlowspec->MinimumPolicedSize = dwRes;
  3175. break;
  3176. }
  3177. default:
  3178. {
  3179. i = dwNumArg;
  3180. dwErr = ERROR_INVALID_SYNTAX;
  3181. break;
  3182. }
  3183. }
  3184. }
  3185. do
  3186. {
  3187. if (dwErr != NO_ERROR)
  3188. {
  3189. break;
  3190. }
  3191. #if 0
  3192. // interface name should be present
  3193. if (!pttTags[0].bPresent)
  3194. {
  3195. dwErr = ERROR_INVALID_SYNTAX;
  3196. break;
  3197. }
  3198. #endif
  3199. // if add, service type should be present
  3200. if (bAdd && (!pttTags[1].bPresent))
  3201. {
  3202. dwErr = ERROR_INVALID_SYNTAX;
  3203. break;
  3204. }
  3205. if (bAdd)
  3206. {
  3207. //
  3208. // We have a new flowspec definition - update config
  3209. //
  3210. dwNewBlkSize = dwBlkSize;
  3211. if (j == pigcSrc->NumFlowspecs)
  3212. {
  3213. // We do not already have a flowspec by this name
  3214. dwNewBlkSize += sizeof(IPQOS_NAMED_FLOWSPEC);
  3215. }
  3216. pigcDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  3217. if (!pigcDst)
  3218. {
  3219. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  3220. break;
  3221. }
  3222. dwOffset = (PUCHAR)pNextFlowspec - (PUCHAR) pigcSrc;
  3223. // Copy all existing flowspecs to the new config
  3224. memcpy(pigcDst, pigcSrc, dwOffset);
  3225. // Stick new flowspec at the next flowspec in list
  3226. pNamedFlowspec =
  3227. (PIPQOS_NAMED_FLOWSPEC)((PUCHAR)pigcDst + dwOffset);
  3228. wcscpy(pNamedFlowspec->FlowspecName, pszFlowspec);
  3229. pNamedFlowspec->FlowspecDesc = fsFlowspec;
  3230. // Copy rest of the interface config information
  3231. dwSkip = dwOffset;
  3232. if (j == pigcSrc->NumFlowspecs)
  3233. {
  3234. pigcDst->NumFlowspecs++;
  3235. }
  3236. else
  3237. {
  3238. // We are overwriting an existing flowspec
  3239. dwSkip += sizeof(IPQOS_NAMED_FLOWSPEC);
  3240. }
  3241. memcpy((PUCHAR)pigcDst + dwOffset + sizeof(IPQOS_NAMED_FLOWSPEC),
  3242. (PUCHAR)pigcSrc + dwSkip,
  3243. dwBlkSize - dwSkip);
  3244. }
  3245. else
  3246. {
  3247. #if 1
  3248. //
  3249. // BUGBUG: What if there are dependent flows present ?
  3250. //
  3251. #endif
  3252. //
  3253. // We have to del old flowspec defn - update config
  3254. //
  3255. dwNewBlkSize = dwBlkSize - sizeof(IPQOS_NAMED_FLOWSPEC);
  3256. pigcDst = HeapAlloc(GetProcessHeap(),0,dwNewBlkSize);
  3257. if (!pigcDst)
  3258. {
  3259. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  3260. break;
  3261. }
  3262. dwOffset = (PUCHAR)pNextFlowspec - (PUCHAR)pigcSrc;
  3263. // Copy the all the flowspecs that occur before
  3264. memcpy(pigcDst, pigcSrc, dwOffset);
  3265. // Copy the rest of the flowspecs as they are
  3266. dwSkip = dwOffset + sizeof(IPQOS_NAMED_FLOWSPEC);
  3267. memcpy((PUCHAR) pigcDst + dwOffset,
  3268. (PUCHAR) pigcSrc + dwSkip,
  3269. dwBlkSize - dwSkip);
  3270. pigcDst->NumFlowspecs--;
  3271. }
  3272. // Update the global config by setting new info
  3273. dwErr = IpmontrSetInfoBlockInGlobalInfo(MS_IP_QOSMGR,
  3274. (PBYTE) pigcDst,
  3275. dwNewBlkSize,
  3276. dwQosCount);
  3277. if (dwErr == NO_ERROR)
  3278. {
  3279. UpdateAllInterfaceConfigs();
  3280. }
  3281. }
  3282. while (FALSE);
  3283. HEAP_FREE_NOT_NULL(pigcSrc);
  3284. HEAP_FREE_NOT_NULL(pigcDst);
  3285. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  3286. }
  3287. DWORD
  3288. ShowQosFlowspecs(
  3289. IN HANDLE hFile,
  3290. IN PWCHAR wszFlowspecName
  3291. )
  3292. {
  3293. PIPQOS_GLOBAL_CONFIG pigcSrc;
  3294. DWORD dwBlkSize,dwQosCount;
  3295. DWORD dwErr, j;
  3296. PIPQOS_NAMED_FLOWSPEC pNextFlowspec;
  3297. FLOWSPEC *pFlowspec;
  3298. PWCHAR pwszFlowspecName = NULL;
  3299. PTCHAR ptszServiceType = NULL;
  3300. VALUE_TOKEN vtServiceType1[] =
  3301. {SERVICETYPE_BESTEFFORT,TOKEN_OPT_SERVICE_BESTEFFORT,
  3302. SERVICETYPE_CONTROLLEDLOAD,TOKEN_OPT_SERVICE_CONTROLLEDLOAD,
  3303. SERVICETYPE_GUARANTEED,TOKEN_OPT_SERVICE_GUARANTEED,
  3304. SERVICETYPE_QUALITATIVE,TOKEN_OPT_SERVICE_QUALITATIVE};
  3305. VALUE_STRING vtServiceType2[] =
  3306. {SERVICETYPE_BESTEFFORT,STRING_SERVICE_BESTEFFORT,
  3307. SERVICETYPE_CONTROLLEDLOAD,STRING_SERVICE_CONTROLLEDLOAD,
  3308. SERVICETYPE_GUARANTEED,STRING_SERVICE_GUARANTEED,
  3309. SERVICETYPE_QUALITATIVE,STRING_SERVICE_QUALITATIVE};
  3310. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  3311. (PBYTE *) &pigcSrc,
  3312. &dwBlkSize,
  3313. &dwQosCount);
  3314. if (dwErr != NO_ERROR)
  3315. {
  3316. return dwErr;
  3317. }
  3318. if ( pigcSrc == NULL )
  3319. {
  3320. return ERROR_INVALID_PARAMETER;
  3321. }
  3322. pNextFlowspec = (PIPQOS_NAMED_FLOWSPEC) ((PUCHAR) pigcSrc +
  3323. sizeof(IPQOS_GLOBAL_CONFIG));
  3324. for (j = 0; j < pigcSrc->NumFlowspecs; j++)
  3325. {
  3326. if ((!wszFlowspecName) ||
  3327. (!_wcsicmp(pNextFlowspec->FlowspecName, wszFlowspecName)))
  3328. {
  3329. pFlowspec = &pNextFlowspec->FlowspecDesc;
  3330. //
  3331. // Print or dump the flowspec now
  3332. //
  3333. pwszFlowspecName =
  3334. MakeQuotedString(pNextFlowspec->FlowspecName);
  3335. if (pwszFlowspecName == NULL)
  3336. {
  3337. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  3338. break;
  3339. }
  3340. //
  3341. // Get service type of flowspec
  3342. //
  3343. GetAltDisplayString(g_hModule, hFile,
  3344. pFlowspec->ServiceType,
  3345. vtServiceType1,
  3346. vtServiceType2,
  3347. NUM_VALUES_IN_TABLE(vtServiceType1),
  3348. &ptszServiceType);
  3349. if ( ptszServiceType == NULL )
  3350. {
  3351. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  3352. break;
  3353. }
  3354. if (hFile)
  3355. {
  3356. DisplayMessageT(DMP_QOS_DELETE_FLOWSPEC,
  3357. pwszFlowspecName);
  3358. DisplayMessageT(DMP_QOS_ADD_FLOWSPEC,
  3359. pwszFlowspecName,
  3360. ptszServiceType,
  3361. pFlowspec->TokenRate,
  3362. pFlowspec->TokenBucketSize,
  3363. pFlowspec->PeakBandwidth,
  3364. pFlowspec->Latency,
  3365. pFlowspec->DelayVariation,
  3366. pFlowspec->MaxSduSize,
  3367. pFlowspec->MinimumPolicedSize);
  3368. }
  3369. else
  3370. {
  3371. DisplayMessage(g_hModule, MSG_QOS_FLOWSPEC_INFO,
  3372. pwszFlowspecName,
  3373. ptszServiceType,
  3374. pFlowspec->TokenRate,
  3375. pFlowspec->TokenBucketSize,
  3376. pFlowspec->PeakBandwidth,
  3377. pFlowspec->Latency,
  3378. pFlowspec->DelayVariation,
  3379. pFlowspec->MaxSduSize,
  3380. pFlowspec->MinimumPolicedSize);
  3381. }
  3382. FREE_STRING_NOT_NULL( ptszServiceType ) ;
  3383. if ( pwszFlowspecName )
  3384. {
  3385. FreeQuotedString( pwszFlowspecName );
  3386. pwszFlowspecName = NULL;
  3387. }
  3388. //
  3389. // If we matched flowspec, then done
  3390. //
  3391. if (wszFlowspecName)
  3392. {
  3393. break;
  3394. }
  3395. }
  3396. // Advance to the next flowspec in the list
  3397. pNextFlowspec++;
  3398. }
  3399. if (dwErr == NO_ERROR)
  3400. {
  3401. if ((wszFlowspecName) && (j == pigcSrc->NumFlowspecs))
  3402. {
  3403. // We didnt find the flowspec we are looking for
  3404. DisplayMessage(g_hModule,
  3405. MSG_FLOWSPEC_NOT_FOUND,
  3406. wszFlowspecName);
  3407. dwErr = ERROR_SUPPRESS_OUTPUT;
  3408. }
  3409. }
  3410. HEAP_FREE(pigcSrc);
  3411. return dwErr;
  3412. }
  3413. DWORD
  3414. GetQosAddDelFlowspecOnFlowOpt(
  3415. PTCHAR *pptcArguments,
  3416. DWORD dwCurrentIndex,
  3417. DWORD dwArgCount,
  3418. BOOL bAdd
  3419. )
  3420. /*++
  3421. Routine Description:
  3422. Gets options for attaching and detaching
  3423. flowspecs on flows.
  3424. Arguments:
  3425. pptcArguments - Argument array
  3426. dwCurrentIndex - pptcArguments[dwCurrentIndex] is the first arg
  3427. dwArgCount - pptcArguments[dwArgCount - 1] is the last arg
  3428. bAdd - Adding or deleting flows
  3429. Return Value:
  3430. NO_ERROR
  3431. --*/
  3432. {
  3433. PIPQOS_GLOBAL_CONFIG pigcSrc = NULL;
  3434. PIPQOS_IF_CONFIG piicSrc = NULL;
  3435. DWORD dwBlkSize, dwQosCount;
  3436. DWORD dwBlkSize1, dwQosCount1;
  3437. DWORD i, j, dwErr = NO_ERROR, dwNumOpt;
  3438. DWORD dwRes;
  3439. DWORD dwSkip, dwOffset, dwSize, dwBitVector = 0;
  3440. DWORD dwIfType, dwDirection;
  3441. WCHAR wszIfName[MAX_INTERFACE_NAME_LEN + 1] = L"\0";
  3442. PIPQOS_NAMED_FLOWSPEC pNamedFlowspec, pNextFlowspec;
  3443. PIPQOS_IF_FLOW pNextFlow, pDestFlow;
  3444. PWCHAR pwszFlowName, pwszFlowspec;
  3445. DWORD dwNumArg,
  3446. dwBufferSize = sizeof(wszIfName);
  3447. PUCHAR pFlow;
  3448. TAG_TYPE pttTags[] = {{TOKEN_OPT_NAME,TRUE,FALSE},
  3449. {TOKEN_OPT_FLOW_NAME,TRUE,FALSE},
  3450. {TOKEN_OPT_FLOWSPEC,TRUE,FALSE},
  3451. {TOKEN_OPT_DIRECTION, FALSE, FALSE}};
  3452. DWORD pdwTagType[NUM_TAGS_IN_TABLE(pttTags)];
  3453. VERIFY_INSTALLED(MS_IP_QOSMGR, STRING_PROTO_QOS_MANAGER);
  3454. //
  3455. // parse command arguements
  3456. //
  3457. dwErr = PreprocessCommand(
  3458. g_hModule, pptcArguments, dwCurrentIndex, dwArgCount,
  3459. pttTags, sizeof(pttTags)/sizeof(TAG_TYPE),
  3460. 1, NUM_TAGS_IN_TABLE(pttTags), pdwTagType
  3461. );
  3462. if ( dwErr != NO_ERROR )
  3463. {
  3464. return dwErr;
  3465. }
  3466. dwNumArg = dwArgCount - dwCurrentIndex;
  3467. dwDirection = DIRECTION_BIDIRECTIONAL;
  3468. for ( i = 0; i < dwNumArg; i++ )
  3469. {
  3470. switch (pdwTagType[i])
  3471. {
  3472. case 0:
  3473. // INTERFACE NAME
  3474. IpmontrGetIfNameFromFriendlyName( pptcArguments[i + dwCurrentIndex],
  3475. wszIfName,&dwBufferSize);
  3476. break;
  3477. case 1:
  3478. // FLOW NAME
  3479. pwszFlowName = pptcArguments[i + dwCurrentIndex];
  3480. break;
  3481. case 2:
  3482. // FLOWSPEC NAME
  3483. pwszFlowspec = pptcArguments[i + dwCurrentIndex];
  3484. break;
  3485. case 3:
  3486. {
  3487. // DIRECTION
  3488. TOKEN_VALUE rgEnums[] =
  3489. {{TOKEN_OPT_DIRECTION_INBOUND, DIRECTION_INBOUND},
  3490. {TOKEN_OPT_DIRECTION_OUTBOUND, DIRECTION_OUTBOUND},
  3491. {TOKEN_OPT_DIRECTION_BIDIRECTIONAL, DIRECTION_BIDIRECTIONAL}};
  3492. GET_ENUM_TAG_VALUE();
  3493. dwDirection = dwRes;
  3494. break;
  3495. }
  3496. default:
  3497. i = dwNumArg;
  3498. dwErr = ERROR_INVALID_SYNTAX;
  3499. break;
  3500. }
  3501. }
  3502. do
  3503. {
  3504. if (dwErr != NO_ERROR)
  3505. {
  3506. break;
  3507. }
  3508. #if 0
  3509. // interface, flow, flowspec names should be present
  3510. if ((!pttTags[0].bPresent) ||
  3511. (!pttTags[1].bPresent) ||
  3512. (!pttTags[2].bPresent))
  3513. {
  3514. dwErr = ERROR_INVALID_SYNTAX;
  3515. break;
  3516. }
  3517. #endif
  3518. //
  3519. // Get the interface info and check if flow already exists
  3520. //
  3521. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(wszIfName,
  3522. MS_IP_QOSMGR,
  3523. (PBYTE *) &piicSrc,
  3524. &dwBlkSize,
  3525. &dwQosCount,
  3526. &dwIfType);
  3527. if (dwErr != NO_ERROR)
  3528. {
  3529. break;
  3530. }
  3531. if ( piicSrc == NULL )
  3532. {
  3533. dwErr = ERROR_INVALID_PARAMETER;
  3534. break;
  3535. }
  3536. pNextFlow = (PIPQOS_IF_FLOW)((PUCHAR)piicSrc + sizeof(IPQOS_IF_CONFIG));
  3537. for (j = 0; j < piicSrc->NumFlows; j++)
  3538. {
  3539. if (!_wcsicmp(pNextFlow->FlowName, pwszFlowName))
  3540. {
  3541. break;
  3542. }
  3543. pNextFlow = (PIPQOS_IF_FLOW)
  3544. ((PUCHAR) pNextFlow + pNextFlow->FlowSize);
  3545. }
  3546. if (j == piicSrc->NumFlows)
  3547. {
  3548. //
  3549. // We do not have a flow by this name
  3550. //
  3551. DisplayMessage(g_hModule,
  3552. MSG_FLOW_NOT_FOUND,
  3553. pwszFlowName);
  3554. i = dwNumArg;
  3555. dwErr = ERROR_SUPPRESS_OUTPUT;
  3556. break;
  3557. }
  3558. // Flow was found at 'pNextFlow' position
  3559. if (!bAdd)
  3560. {
  3561. //
  3562. // Make sure that the flow has the named flowspec
  3563. //
  3564. if (dwDirection & DIRECTION_INBOUND)
  3565. {
  3566. if (_wcsicmp(pNextFlow->FlowDesc.RecvingFlowspecName,
  3567. pwszFlowspec))
  3568. {
  3569. DisplayMessage(g_hModule,
  3570. MSG_FLOWSPEC_NOT_FOUND,
  3571. pwszFlowspec);
  3572. dwErr = ERROR_SUPPRESS_OUTPUT;
  3573. break;
  3574. }
  3575. }
  3576. if (dwDirection & DIRECTION_OUTBOUND)
  3577. {
  3578. if (_wcsicmp(pNextFlow->FlowDesc.SendingFlowspecName,
  3579. pwszFlowspec))
  3580. {
  3581. DisplayMessage(g_hModule,
  3582. MSG_FLOWSPEC_NOT_FOUND,
  3583. pwszFlowspec);
  3584. dwErr = ERROR_SUPPRESS_OUTPUT;
  3585. break;
  3586. }
  3587. }
  3588. //
  3589. // Delete the association of the flowspec & flow
  3590. //
  3591. if (dwDirection & DIRECTION_INBOUND)
  3592. {
  3593. pNextFlow->FlowDesc.RecvingFlowspecName[0] = L'\0';
  3594. }
  3595. if (dwDirection & DIRECTION_OUTBOUND)
  3596. {
  3597. pNextFlow->FlowDesc.SendingFlowspecName[0] = L'\0';
  3598. }
  3599. }
  3600. else
  3601. {
  3602. //
  3603. // Make sure that the flowspec is actually defined
  3604. //
  3605. dwErr = IpmontrGetInfoBlockFromGlobalInfo(MS_IP_QOSMGR,
  3606. (PBYTE *) &pigcSrc,
  3607. &dwBlkSize1,
  3608. &dwQosCount1);
  3609. if (dwErr != NO_ERROR)
  3610. {
  3611. break;
  3612. }
  3613. if ( pigcSrc == NULL )
  3614. {
  3615. dwErr = ERROR_INVALID_PARAMETER;
  3616. break;
  3617. }
  3618. pNextFlowspec = (PIPQOS_NAMED_FLOWSPEC)
  3619. ((PUCHAR) pigcSrc + sizeof(IPQOS_GLOBAL_CONFIG));
  3620. for (j = 0; j < pigcSrc->NumFlowspecs; j++)
  3621. {
  3622. if (!_wcsicmp(pNextFlowspec->FlowspecName,
  3623. pwszFlowspec))
  3624. {
  3625. break;
  3626. }
  3627. pNextFlowspec++;
  3628. }
  3629. if (j == pigcSrc->NumFlowspecs)
  3630. {
  3631. //
  3632. // We do not have a flowspec by this name
  3633. //
  3634. DisplayMessage(g_hModule,
  3635. MSG_FLOWSPEC_NOT_FOUND,
  3636. pwszFlowspec);
  3637. dwErr = ERROR_SUPPRESS_OUTPUT;
  3638. break;
  3639. }
  3640. //
  3641. // Create the association of the flowspec & flow
  3642. //
  3643. if (dwDirection & DIRECTION_INBOUND)
  3644. {
  3645. wcscpy(pNextFlow->FlowDesc.RecvingFlowspecName,
  3646. pwszFlowspec);
  3647. }
  3648. if (dwDirection & DIRECTION_OUTBOUND)
  3649. {
  3650. wcscpy(pNextFlow->FlowDesc.SendingFlowspecName,
  3651. pwszFlowspec);
  3652. }
  3653. }
  3654. // Update the interface config by setting new info
  3655. dwErr = IpmontrSetInfoBlockInInterfaceInfo(wszIfName,
  3656. MS_IP_QOSMGR,
  3657. (PBYTE) piicSrc,
  3658. dwBlkSize,
  3659. dwQosCount);
  3660. }
  3661. while (FALSE);
  3662. HEAP_FREE_NOT_NULL(pigcSrc);
  3663. HEAP_FREE_NOT_NULL(piicSrc);
  3664. return (dwErr == NO_ERROR) ? ERROR_OKAY : dwErr;
  3665. }