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.

951 lines
23 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. routing\netsh\ip\route.c
  5. --*/
  6. #include "precomp.h"
  7. #pragma hdrstop
  8. DWORD
  9. AddSetDelRtmRouteInfo(
  10. IN PINTERFACE_ROUTE_INFO pRoute,
  11. IN LPCWSTR pwszIfName,
  12. IN DWORD dwCommand,
  13. IN DWORD dwFlags
  14. )
  15. /*++
  16. Routine Description:
  17. Adds/deletes normal (read as non persistant)
  18. routes on interfaces.
  19. Arguments:
  20. pRoute - route to add/set/delete
  21. pwszIfName - Interface Name
  22. dwCommand - Add, set, or delete
  23. Return Value:
  24. NO_ERROR
  25. --*/
  26. {
  27. ULONG dwOutEntrySize;
  28. DWORD dwRes, i;
  29. PMIB_IPDESTTABLE lpTable;
  30. PMIB_IPDESTROW pEntry = NULL;
  31. MIB_OPAQUE_QUERY QueryBuff[3]; // more than enough
  32. MIB_OPAQUE_QUERY *pQuery = QueryBuff;
  33. PMIB_OPAQUE_INFO pInfo;
  34. DEFINE_MIB_BUFFER(pRouteInfo, MIB_IPDESTROW, pRouteRow);
  35. if (!pRoute->dwRtInfoIfIndex)
  36. {
  37. //
  38. // Get the interface index from friendly name
  39. //
  40. dwRes = IpmontrGetIfIndexFromFriendlyName(g_hMIBServer,
  41. pwszIfName,
  42. &pRoute->dwRtInfoIfIndex);
  43. if (dwRes != NO_ERROR)
  44. {
  45. return dwRes;
  46. }
  47. //
  48. // The interface probably is disconnected
  49. //
  50. if (pRoute->dwRtInfoIfIndex == 0)
  51. {
  52. DisplayMessage(g_hModule, EMSG_INTERFACE_INVALID_OR_DISC);
  53. return ERROR_INVALID_PARAMETER;
  54. }
  55. }
  56. //
  57. // Use MprAdmin api to add, del or set entry
  58. //
  59. switch(dwCommand)
  60. {
  61. case ADD_COMMAND:
  62. case SET_COMMAND:
  63. //
  64. // Does this route already exist in the router ?
  65. //
  66. // Get all this protocol routes on dest
  67. pQuery->dwVarId = ROUTE_MATCHING;
  68. pQuery->rgdwVarIndex[0] = pRoute->dwRtInfoDest;
  69. pQuery->rgdwVarIndex[1] = pRoute->dwRtInfoMask;
  70. pQuery->rgdwVarIndex[2] = RTM_VIEW_MASK_ANY;
  71. pQuery->rgdwVarIndex[3] = pRoute->dwRtInfoProto;
  72. pInfo = NULL;
  73. dwRes = MibGet(PID_IP,
  74. IPRTRMGR_PID,
  75. (PVOID) pQuery,
  76. sizeof(MIB_OPAQUE_QUERY) + 3 * sizeof(DWORD),
  77. (PVOID *) &pInfo,
  78. &dwOutEntrySize);
  79. if ( dwRes isnot NO_ERROR )
  80. {
  81. DisplayMessage(g_hModule, MSG_IP_DIM_ERROR, dwRes );
  82. return dwRes;
  83. }
  84. if ( pInfo isnot NULL )
  85. {
  86. //
  87. // Search for a matching route
  88. //
  89. BOOL bFound = FALSE;
  90. lpTable = (PMIB_IPDESTTABLE)(pInfo->rgbyData);
  91. for (i=0; i<lpTable->dwNumEntries; i++)
  92. {
  93. pEntry = &lpTable->table[i];
  94. if ((pEntry->dwForwardIfIndex == pRoute->dwRtInfoIfIndex) &&
  95. (pEntry->dwForwardNextHop == pRoute->dwRtInfoNextHop))
  96. {
  97. bFound = TRUE;
  98. break;
  99. }
  100. }
  101. if (!bFound)
  102. pEntry = NULL;
  103. if (i == lpTable->dwNumEntries)
  104. {
  105. //
  106. // No matching route found - quit if set
  107. //
  108. if (dwCommand == SET_COMMAND)
  109. {
  110. MprAdminMIBBufferFree((PVOID)pInfo);
  111. return ERROR_NOT_FOUND;
  112. }
  113. }
  114. else
  115. {
  116. //
  117. // A matching route found - quit if add
  118. //
  119. if (dwCommand == ADD_COMMAND)
  120. {
  121. MprAdminMIBBufferFree((PVOID)pInfo);
  122. return ERROR_OBJECT_ALREADY_EXISTS;
  123. }
  124. }
  125. }
  126. else
  127. {
  128. //
  129. // No matching routes found - quit if set
  130. //
  131. if (dwCommand == SET_COMMAND)
  132. {
  133. return ERROR_NOT_FOUND;
  134. }
  135. }
  136. //
  137. // Convert the route to a ip route row format
  138. //
  139. pRouteInfo->dwId = ROUTE_MATCHING;
  140. pRouteRow->dwForwardDest = pRoute->dwRtInfoDest;
  141. pRouteRow->dwForwardMask = pRoute->dwRtInfoMask;
  142. pRouteRow->dwForwardPolicy = 0;
  143. pRouteRow->dwForwardNextHop = pRoute->dwRtInfoNextHop;
  144. pRouteRow->dwForwardIfIndex = pRoute->dwRtInfoIfIndex;
  145. pRouteRow->dwForwardType = 0;
  146. pRouteRow->dwForwardProto = pRoute->dwRtInfoProto;
  147. pRouteRow->dwForwardAge = INFINITE;
  148. pRouteRow->dwForwardNextHopAS = 0;
  149. pRouteRow->dwForwardMetric1 = pRoute->dwRtInfoMetric1;
  150. pRouteRow->dwForwardMetric2 = pRoute->dwRtInfoMetric2;
  151. pRouteRow->dwForwardMetric3 = pRoute->dwRtInfoMetric3;
  152. pRouteRow->dwForwardMetric4 = MIB_IPROUTE_METRIC_UNUSED;
  153. pRouteRow->dwForwardMetric5 = MIB_IPROUTE_METRIC_UNUSED;
  154. pRouteRow->dwForwardPreference = pRoute->dwRtInfoPreference;
  155. pRouteRow->dwForwardViewSet = pRoute->dwRtInfoViewSet;
  156. if (dwCommand == ADD_COMMAND)
  157. {
  158. dwRes = MprAdminMIBEntryCreate(g_hMIBServer,
  159. PID_IP,
  160. IPRTRMGR_PID,
  161. (PVOID)pRouteInfo,
  162. MIB_INFO_SIZE(MIB_IPDESTROW));
  163. }
  164. else
  165. {
  166. if ((dwFlags & FIELDS_NOT_SPECIFIED) && pEntry)
  167. {
  168. //
  169. // Get the old preference, metric, or view
  170. //
  171. if (dwFlags & PREF_NOT_SPECIFIED)
  172. {
  173. pRouteRow->dwForwardPreference = pEntry->dwForwardPreference;
  174. }
  175. if (dwFlags & METRIC_NOT_SPECIFIED)
  176. {
  177. pRouteRow->dwForwardMetric1 = pEntry->dwForwardMetric1;
  178. }
  179. if (dwFlags & VIEW_NOT_SPECIFIED)
  180. {
  181. pRouteRow->dwForwardViewSet = pEntry->dwForwardViewSet;
  182. }
  183. }
  184. dwRes = MprAdminMIBEntrySet(g_hMIBServer,
  185. PID_IP,
  186. IPRTRMGR_PID,
  187. (PVOID)pRouteInfo,
  188. MIB_INFO_SIZE(MIB_IPDESTROW));
  189. }
  190. // Free the old route information obtained
  191. if (pInfo)
  192. {
  193. MprAdminMIBBufferFree((PVOID)pInfo);
  194. }
  195. break;
  196. case DELETE_COMMAND:
  197. {
  198. DWORD rgdwInfo[6];
  199. PMIB_OPAQUE_QUERY pIndex = (PMIB_OPAQUE_QUERY)rgdwInfo;
  200. pIndex->dwVarId = ROUTE_MATCHING;
  201. pIndex->rgdwVarIndex[0] = pRoute->dwRtInfoDest;
  202. pIndex->rgdwVarIndex[1] = pRoute->dwRtInfoMask;
  203. pIndex->rgdwVarIndex[2] = pRoute->dwRtInfoIfIndex;
  204. pIndex->rgdwVarIndex[3] = pRoute->dwRtInfoNextHop;
  205. pIndex->rgdwVarIndex[4] = pRoute->dwRtInfoProto;
  206. dwRes = MprAdminMIBEntryDelete(g_hMIBServer,
  207. PID_IP,
  208. IPRTRMGR_PID,
  209. (PVOID)pIndex,
  210. sizeof(rgdwInfo));
  211. break;
  212. }
  213. default:
  214. dwRes = ERROR_INVALID_PARAMETER;
  215. }
  216. return dwRes;
  217. }
  218. DWORD
  219. AddSetDelPersistentRouteInfo(
  220. IN PINTERFACE_ROUTE_INFO pRoute,
  221. IN LPCWSTR pwszIfName,
  222. IN DWORD dwCommand,
  223. IN DWORD dwFlags
  224. )
  225. /*++
  226. Routine Description:
  227. Adds/deletes persitant routes on interfaces.
  228. Arguments:
  229. route - route to add/set/delete
  230. pwszIfName - Interface Name
  231. dwCommand - Add, set, or delete
  232. Return Value:
  233. ERROR_OKAY
  234. --*/
  235. {
  236. DWORD dwRes;
  237. PINTERFACE_ROUTE_INFO pOldTable, pNewTable;
  238. DWORD dwIfType, dwSize, dwCount;
  239. pNewTable = NULL;
  240. do
  241. {
  242. dwRes = IpmontrGetInfoBlockFromInterfaceInfo(pwszIfName,
  243. IP_ROUTE_INFO,
  244. (PBYTE *) &pOldTable,
  245. &dwSize,
  246. &dwCount,
  247. &dwIfType);
  248. if((dwRes is ERROR_NOT_FOUND) &&
  249. dwCommand is ADD_COMMAND)
  250. {
  251. //
  252. // No route info but we are asked to add
  253. //
  254. pOldTable = NULL;
  255. dwRes = NO_ERROR;
  256. dwCount = 0;
  257. }
  258. if(dwRes isnot NO_ERROR)
  259. {
  260. break;
  261. }
  262. //
  263. // These take the old table and return a new one in its stead
  264. //
  265. switch(dwCommand)
  266. {
  267. case ADD_COMMAND:
  268. dwRes = AddRoute(pOldTable,
  269. pRoute,
  270. dwIfType,
  271. &dwCount,
  272. &pNewTable);
  273. break;
  274. case DELETE_COMMAND:
  275. dwRes = DeleteRoute(pOldTable,
  276. pRoute,
  277. dwIfType,
  278. &dwCount,
  279. &pNewTable);
  280. break;
  281. case SET_COMMAND:
  282. dwRes = SetRoute(pOldTable,
  283. pRoute,
  284. dwIfType,
  285. dwFlags,
  286. &dwCount);
  287. pNewTable = pOldTable;
  288. pOldTable = NULL;
  289. break;
  290. }
  291. if(dwRes != NO_ERROR)
  292. {
  293. break;
  294. }
  295. //
  296. // Set the new info back
  297. //
  298. dwRes = IpmontrSetInfoBlockInInterfaceInfo(pwszIfName,
  299. IP_ROUTE_INFO,
  300. (PBYTE)pNewTable,
  301. sizeof(INTERFACE_ROUTE_INFO),
  302. dwCount);
  303. if(dwRes != NO_ERROR)
  304. {
  305. break;
  306. }
  307. pNewTable = NULL;
  308. } while ( FALSE );
  309. if(pOldTable)
  310. {
  311. FREE_BUFFER(pOldTable);
  312. }
  313. if(pNewTable)
  314. {
  315. HeapFree(GetProcessHeap(),
  316. 0,
  317. pNewTable);
  318. pNewTable = NULL;
  319. }
  320. switch(dwRes)
  321. {
  322. case NO_ERROR:
  323. {
  324. dwRes = ERROR_OKAY;
  325. break;
  326. }
  327. case ERROR_NOT_FOUND:
  328. {
  329. WCHAR wszBuffer[MAX_INTERFACE_NAME_LEN+1];
  330. DWORD dwSizeTemp = sizeof(wszBuffer);
  331. IpmontrGetFriendlyNameFromIfName( pwszIfName, wszBuffer, &dwSizeTemp);
  332. DisplayMessage(g_hModule, EMSG_IP_NO_ROUTE_INFO, wszBuffer);
  333. dwRes = ERROR_SUPPRESS_OUTPUT;
  334. break;
  335. }
  336. case ERROR_NOT_ENOUGH_MEMORY:
  337. {
  338. DisplayMessage(g_hModule, MSG_IP_NOT_ENOUGH_MEMORY);
  339. dwRes = ERROR_SUPPRESS_OUTPUT;
  340. break;
  341. }
  342. }
  343. return dwRes;
  344. }
  345. DWORD
  346. SetRoute(
  347. IN PINTERFACE_ROUTE_INFO pTable,
  348. IN PINTERFACE_ROUTE_INFO pRoute,
  349. IN DWORD dwIfType,
  350. IN DWORD dwFlags,
  351. IN OUT PDWORD pdwCount
  352. )
  353. {
  354. ULONG ulIndex, i;
  355. //
  356. // If the count is 0, the function will return false
  357. // and we will error out
  358. //
  359. if(!IsRoutePresent(pTable,
  360. pRoute,
  361. dwIfType,
  362. *pdwCount,
  363. &ulIndex))
  364. {
  365. return ERROR_NOT_FOUND;
  366. }
  367. if (dwFlags & FIELDS_NOT_SPECIFIED)
  368. {
  369. //
  370. // Preserve the old values if not specified
  371. //
  372. if (dwFlags & PREF_NOT_SPECIFIED)
  373. {
  374. pRoute->dwRtInfoPreference = pTable[ulIndex].dwRtInfoPreference;
  375. }
  376. if (dwFlags & METRIC_NOT_SPECIFIED)
  377. {
  378. pRoute->dwRtInfoMetric1 = pTable[ulIndex].dwRtInfoMetric1;
  379. }
  380. if (dwFlags & VIEW_NOT_SPECIFIED)
  381. {
  382. pRoute->dwRtInfoViewSet = pTable[ulIndex].dwRtInfoViewSet;
  383. }
  384. }
  385. pTable[ulIndex] = *pRoute;
  386. return NO_ERROR;
  387. }
  388. DWORD
  389. AddRoute(
  390. IN PINTERFACE_ROUTE_INFO pOldTable,
  391. IN PINTERFACE_ROUTE_INFO pRoute,
  392. IN DWORD dwIfType,
  393. IN OUT PDWORD pdwCount,
  394. OUT INTERFACE_ROUTE_INFO **ppNewTable
  395. )
  396. /*++
  397. Routine Description:
  398. Adds a route to the current info
  399. Arguments:
  400. Return Value:
  401. NO_ERROR
  402. --*/
  403. {
  404. ULONG ulIndex, i;
  405. if(IsRoutePresent(pOldTable,
  406. pRoute,
  407. dwIfType,
  408. *pdwCount,
  409. &ulIndex))
  410. {
  411. return ERROR_OBJECT_ALREADY_EXISTS;
  412. }
  413. //
  414. // Just create a block with size n + 1
  415. //
  416. *ppNewTable = HeapAlloc(GetProcessHeap(),
  417. 0,
  418. ((*pdwCount) + 1) * sizeof(INTERFACE_ROUTE_INFO));
  419. if(*ppNewTable is NULL)
  420. {
  421. return ERROR_NOT_ENOUGH_MEMORY;
  422. }
  423. for(i = 0; i < *pdwCount; i++)
  424. {
  425. //
  426. // structure copy
  427. //
  428. (*ppNewTable)[i] = pOldTable[i];
  429. }
  430. //
  431. // copy the new route
  432. //
  433. (*ppNewTable)[i] = *pRoute;
  434. *pdwCount += 1;
  435. return NO_ERROR;
  436. }
  437. DWORD
  438. DeleteRoute(
  439. IN PINTERFACE_ROUTE_INFO pOldTable,
  440. IN PINTERFACE_ROUTE_INFO pRoute,
  441. IN DWORD dwIfType,
  442. IN OUT PDWORD pdwCount,
  443. OUT INTERFACE_ROUTE_INFO **ppNewTable
  444. )
  445. /*++
  446. Routine Description:
  447. Deletes a route from an interface
  448. Arguments:
  449. Return Value:
  450. NO_ERROR
  451. --*/
  452. {
  453. ULONG ulIndex, i, j;
  454. //
  455. // If the count is 0, the function will return false
  456. // and we will error out
  457. //
  458. if(!IsRoutePresent(pOldTable,
  459. pRoute,
  460. dwIfType,
  461. *pdwCount,
  462. &ulIndex))
  463. {
  464. return ERROR_NOT_FOUND;
  465. }
  466. //
  467. // If the count is 1
  468. //
  469. *pdwCount -= 1;
  470. if(*pdwCount is 0)
  471. {
  472. *ppNewTable = NULL;
  473. return NO_ERROR;
  474. }
  475. //
  476. // delete the route
  477. //
  478. *ppNewTable = HeapAlloc(GetProcessHeap(),
  479. 0,
  480. (*pdwCount) * sizeof(INTERFACE_ROUTE_INFO));
  481. if(*ppNewTable is NULL)
  482. {
  483. return ERROR_NOT_ENOUGH_MEMORY;
  484. }
  485. i = j = 0;
  486. while(i <= *pdwCount)
  487. {
  488. if(i == ulIndex)
  489. {
  490. i++;
  491. continue;
  492. }
  493. //
  494. // structure copy
  495. //
  496. (*ppNewTable)[j] = pOldTable[i];
  497. i++;
  498. j++;
  499. }
  500. return NO_ERROR;
  501. }
  502. BOOL
  503. IsRoutePresent(
  504. IN PINTERFACE_ROUTE_INFO pTable,
  505. IN PINTERFACE_ROUTE_INFO pRoute,
  506. IN DWORD dwIfType,
  507. IN ULONG ulCount,
  508. OUT PULONG pulIndex
  509. )
  510. /*++
  511. Routine Description:
  512. Checks to see if interface is already present
  513. Arguments:
  514. Return Value:
  515. NO_ERROR
  516. --*/
  517. {
  518. ULONG i;
  519. BOOL bDontMatchNHop;
  520. if((dwIfType is ROUTER_IF_TYPE_DEDICATED) or
  521. (dwIfType is ROUTER_IF_TYPE_INTERNAL))
  522. {
  523. bDontMatchNHop = FALSE;
  524. }
  525. else
  526. {
  527. bDontMatchNHop = TRUE;
  528. }
  529. // Do this check just to keep the prefix checker happy
  530. if (pTable is NULL)
  531. {
  532. return FALSE;
  533. }
  534. for(i = 0; i < ulCount; i++)
  535. {
  536. if((pTable[i].dwRtInfoDest is pRoute->dwRtInfoDest) and
  537. (pTable[i].dwRtInfoMask is pRoute->dwRtInfoMask) and
  538. #if 0
  539. (pTable[i].dwRtInfoProto is pRoute->dwRtInfoProto) and
  540. #endif
  541. (bDontMatchNHop or
  542. (pTable[i].dwRtInfoNextHop is pRoute->dwRtInfoNextHop)))
  543. {
  544. *pulIndex = i;
  545. return TRUE;
  546. }
  547. }
  548. return FALSE;
  549. }
  550. DWORD
  551. ShowIpPersistentRoute(
  552. IN HANDLE hFile, OPTIONAL
  553. IN LPCWSTR pwszIfName,
  554. IN OUT PDWORD pdwNumRows
  555. )
  556. /*++
  557. Routine Description:
  558. Show the static (persistent) routes on the interface
  559. Arguments:
  560. pwszIfName - Interface name
  561. Return Value:
  562. NO_ERROR
  563. --*/
  564. {
  565. PINTERFACE_ROUTE_INFO pRoutes;
  566. DWORD dwErr, dwBlkSize, dwCount, dwIfType, dwNumParsed, i;
  567. DWORD dwIfClass;
  568. WCHAR wszNextHop[ADDR_LENGTH + 1];
  569. WCHAR wszIfDesc[MAX_INTERFACE_NAME_LEN + 1];
  570. PWCHAR pwszProto, pwszToken, pwszQuoted;
  571. WCHAR wszViews[3];
  572. dwErr = GetInterfaceDescription(pwszIfName,
  573. wszIfDesc,
  574. &dwNumParsed);
  575. if (!dwNumParsed)
  576. {
  577. wcscpy(wszIfDesc, pwszIfName);
  578. }
  579. //
  580. // Retrieve the routes
  581. //
  582. dwErr = IpmontrGetInfoBlockFromInterfaceInfo(pwszIfName,
  583. IP_ROUTE_INFO,
  584. (PBYTE *) &pRoutes,
  585. &dwBlkSize,
  586. &dwCount,
  587. &dwIfType);
  588. //
  589. // If no IP_ROUTE_INFO block is found for this interface,
  590. // don't print anything and return NO_ERROR
  591. //
  592. if (dwErr == ERROR_NOT_FOUND)
  593. {
  594. return NO_ERROR;
  595. }
  596. if (dwErr != NO_ERROR)
  597. {
  598. return dwErr;
  599. }
  600. if((pRoutes == NULL) ||
  601. (dwCount == 0))
  602. {
  603. return NO_ERROR;
  604. }
  605. dwErr = GetInterfaceClass(pwszIfName, &dwIfClass);
  606. if (dwErr != NO_ERROR)
  607. {
  608. DisplayMessage(g_hModule, EMSG_CANT_GET_IF_INFO,
  609. wszIfDesc,
  610. dwErr);
  611. return dwErr;
  612. }
  613. if(hFile == NULL)
  614. {
  615. if (*pdwNumRows is 0)
  616. {
  617. DisplayMessage(g_hModule, MSG_RTR_ROUTE_HDR);
  618. }
  619. pwszQuoted = NULL;
  620. }
  621. else
  622. {
  623. pwszQuoted = MakeQuotedString(wszIfDesc);
  624. }
  625. for(i = 0; i < dwCount; i++)
  626. {
  627. wszViews[0] = (pRoutes[i].dwRtInfoViewSet & RTM_VIEW_MASK_UCAST)? 'U':' ';
  628. wszViews[1] = (pRoutes[i].dwRtInfoViewSet & RTM_VIEW_MASK_MCAST)? 'M':' ';
  629. wszViews[2] = '\0';
  630. switch(pRoutes[i].dwRtInfoProto)
  631. {
  632. case PROTO_IP_NT_AUTOSTATIC:
  633. {
  634. pwszProto = MakeString(g_hModule, STRING_NT_AUTOSTATIC);
  635. pwszToken = TOKEN_VALUE_AUTOSTATIC;
  636. break;
  637. }
  638. case PROTO_IP_NT_STATIC:
  639. {
  640. pwszProto = MakeString(g_hModule, STRING_STATIC);
  641. pwszToken = TOKEN_VALUE_STATIC;
  642. break;
  643. }
  644. case PROTO_IP_NT_STATIC_NON_DOD:
  645. {
  646. pwszProto = MakeString(g_hModule, STRING_NONDOD);
  647. pwszToken = TOKEN_VALUE_NONDOD;
  648. break;
  649. }
  650. default:
  651. {
  652. pwszProto = MakeString(g_hModule, STRING_PROTO_UNKNOWN);
  653. pwszToken = NULL;
  654. break;
  655. }
  656. }
  657. MakeUnicodeIpAddr(wszNextHop,
  658. inet_ntoa(*((struct in_addr *)&(pRoutes[i].dwRtInfoNextHop))));
  659. if(hFile)
  660. {
  661. if(pwszToken)
  662. {
  663. WCHAR wszMask[ADDR_LENGTH + 1], wszDest[ADDR_LENGTH + 1];
  664. PWCHAR pwszView = NULL;
  665. MakeUnicodeIpAddr(wszDest,
  666. inet_ntoa(*((struct in_addr *)&(pRoutes[i].dwRtInfoDest))));
  667. MakeUnicodeIpAddr(wszMask,
  668. inet_ntoa(*((struct in_addr *)&(pRoutes[i].dwRtInfoMask))));
  669. switch (pRoutes[i].dwRtInfoViewSet)
  670. {
  671. case RTM_VIEW_MASK_UCAST: pwszView=TOKEN_VALUE_UNICAST ; break;
  672. case RTM_VIEW_MASK_MCAST: pwszView=TOKEN_VALUE_MULTICAST; break;
  673. case RTM_VIEW_MASK_UCAST
  674. |RTM_VIEW_MASK_MCAST: pwszView=TOKEN_VALUE_BOTH; break;
  675. }
  676. if (pwszView)
  677. {
  678. if ( dwIfClass == IFCLASS_P2P ) {
  679. DisplayMessageT( DMP_IP_ADDSET_P2P_PERSISTENTROUTE,
  680. wszDest,
  681. wszMask,
  682. pwszQuoted,
  683. pwszToken,
  684. pRoutes[i].dwRtInfoPreference,
  685. pRoutes[i].dwRtInfoMetric1,
  686. pwszView );
  687. }
  688. else {
  689. DisplayMessageT( DMP_IP_ADDSET_PERSISTENTROUTE,
  690. wszDest,
  691. wszMask,
  692. pwszQuoted,
  693. wszNextHop,
  694. pwszToken,
  695. pRoutes[i].dwRtInfoPreference,
  696. pRoutes[i].dwRtInfoMetric1,
  697. pwszView );
  698. }
  699. }
  700. }
  701. }
  702. else
  703. {
  704. WCHAR wcszBuffer[80];
  705. MakePrefixStringW( wcszBuffer,
  706. pRoutes[i].dwRtInfoDest,
  707. pRoutes[i].dwRtInfoMask );
  708. DisplayMessage(g_hModule,
  709. MSG_RTR_ROUTE_INFO,
  710. wcszBuffer,
  711. pwszProto,
  712. pRoutes[i].dwRtInfoPreference,
  713. pRoutes[i].dwRtInfoMetric1,
  714. wszNextHop,
  715. wszViews,
  716. wszIfDesc);
  717. (*pdwNumRows)++;
  718. }
  719. FreeString(pwszProto);
  720. }
  721. if(pwszQuoted)
  722. {
  723. FreeQuotedString(pwszQuoted);
  724. }
  725. HeapFree(GetProcessHeap(),
  726. 0,
  727. pRoutes);
  728. return NO_ERROR;
  729. }