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.

767 lines
19 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. routing\monitor2\ip\utils.c
  5. Abstract:
  6. Utility functions
  7. Revision History:
  8. Anand Mahalingam 7/10/98 Created
  9. --*/
  10. #include "precomp.h"
  11. #pragma hdrstop
  12. DWORD
  13. GetMibTagToken(
  14. IN LPWSTR *ppwcArguments,
  15. IN DWORD dwArgCount,
  16. IN DWORD dwNumIndices,
  17. OUT PDWORD pdwRR,
  18. OUT PBOOL pbIndex,
  19. OUT PDWORD pdwIndex
  20. )
  21. /*++
  22. Routine Description:
  23. Looks for indices and refresh rate arguments in the command. If index
  24. tag is present, it would be of the form index= index1 index2 ....
  25. The index= is removed by this function. So is rr= if it is there in
  26. the command. If pdwRR is 0 then, no refresh sought.
  27. Arguments:
  28. ppwcArguments - The argument array. Each argument has tag=value form
  29. dwCurrentIndex - ppwcArguments[dwCurrentIndex] is first arg.
  30. dwArgCount - ppwcArguments[dwArgCount - 1] is last arg.
  31. pttTagToken - Array of tag token ids that are allowed in the args
  32. dwNumTags - Size of pttTagToken
  33. pdwOut - Array identifying the type of each argument.
  34. Return Value:
  35. NO_ERROR, ERROR_INVALID_PARAMETER, ERROR_INVALID_OPTION_TAG
  36. --*/
  37. {
  38. DWORD i;
  39. BOOL bTag;
  40. if (dwArgCount is 0)
  41. {
  42. *pdwRR = 0;
  43. *pbIndex = FALSE;
  44. return NO_ERROR;
  45. }
  46. if (dwArgCount < dwNumIndices)
  47. {
  48. //
  49. // No index
  50. //
  51. *pbIndex = FALSE;
  52. if (dwArgCount > 1)
  53. {
  54. *pdwRR = 0;
  55. return ERROR_INVALID_PARAMETER;
  56. }
  57. //
  58. // No Index specified. Make sure refresh rate is specified
  59. // with tag.
  60. //
  61. if (_wcsnicmp(ppwcArguments[0],L"RR=",3) == 0)
  62. {
  63. //
  64. // get the refresh rate
  65. //
  66. *pdwRR = wcstoul(&ppwcArguments[0][3], NULL, 10);
  67. }
  68. else
  69. {
  70. return ERROR_INVALID_PARAMETER;
  71. }
  72. }
  73. else
  74. {
  75. //
  76. // Check for index tag
  77. //
  78. if (_wcsnicmp(ppwcArguments[0],L"INDEX=",6) == 0)
  79. {
  80. *pbIndex = TRUE;
  81. *pdwIndex = 0;
  82. //
  83. // remove tag and see if refresh rate is specified
  84. //
  85. wcscpy(ppwcArguments[0], &ppwcArguments[0][6]);
  86. if (dwArgCount > dwNumIndices)
  87. {
  88. //
  89. // Make sure that argument has RR tag
  90. //
  91. if (_wcsnicmp(ppwcArguments[dwNumIndices],L"RR=",3) == 0)
  92. {
  93. //
  94. // get the refresh rate
  95. //
  96. *pdwRR = wcstoul(&ppwcArguments[dwNumIndices][3], NULL , 10);
  97. }
  98. else
  99. {
  100. return ERROR_INVALID_PARAMETER;
  101. }
  102. }
  103. else
  104. {
  105. //
  106. // No refresh rate specified
  107. //
  108. *pdwRR = 0;
  109. return NO_ERROR;
  110. }
  111. }
  112. else
  113. {
  114. //
  115. // Not index tag, See if it has an RR tag
  116. //
  117. if (_wcsnicmp(ppwcArguments[0],L"RR=",3) == 0)
  118. {
  119. //
  120. // get the refresh rate
  121. //
  122. *pdwRR = wcstoul(&ppwcArguments[0][3], NULL , 10);
  123. //
  124. // See if the index follows
  125. //
  126. if (dwArgCount > dwNumIndices)
  127. {
  128. if (dwArgCount > 1)
  129. {
  130. if (_wcsnicmp(ppwcArguments[1],L"INDEX=",6) == 0)
  131. {
  132. wcscpy(ppwcArguments[1], &ppwcArguments[1][6]);
  133. *pbIndex = TRUE;
  134. *pdwIndex = 1;
  135. return NO_ERROR;
  136. }
  137. else
  138. {
  139. *pdwRR = 0;
  140. return ERROR_INVALID_PARAMETER;
  141. }
  142. }
  143. else
  144. {
  145. return NO_ERROR;
  146. }
  147. }
  148. }
  149. //
  150. // No RR Tag either
  151. //
  152. else if (dwArgCount > dwNumIndices)
  153. {
  154. //
  155. // Assume ppwcArguments[dwNumIndices] is the refresh rate
  156. //
  157. *pdwRR = wcstoul(ppwcArguments[dwNumIndices], NULL , 10);
  158. if (dwNumIndices != 0)
  159. {
  160. *pbIndex = TRUE;
  161. *pdwIndex = 0;
  162. }
  163. }
  164. else
  165. {
  166. //
  167. // only index present with no tag
  168. //
  169. *pbIndex = TRUE;
  170. *pdwIndex = 0;
  171. }
  172. }
  173. }
  174. return NO_ERROR;
  175. }
  176. DWORD
  177. GetIpPrefix(
  178. IN LPCWSTR ppwcArg,
  179. OUT PIPV4_ADDRESS pipAddress,
  180. OUT PIPV4_ADDRESS pipMask
  181. )
  182. {
  183. CHAR pszIpAddr[ADDR_LENGTH+1], *p;
  184. DWORD dwDots;
  185. // Accept "default" as a special case
  186. if (MatchToken( ppwcArg, TOKEN_DEFAULT))
  187. {
  188. *pipAddress = *pipMask = 0;
  189. return NO_ERROR;
  190. }
  191. // Make sure all characters are legal [/0-9.]
  192. if (ppwcArg[ wcsspn(ppwcArg, L"/0123456789.") ])
  193. {
  194. return ERROR_INVALID_PARAMETER;
  195. }
  196. WideCharToMultiByte(GetConsoleOutputCP(),
  197. 0,
  198. ppwcArg,
  199. -1,
  200. pszIpAddr,
  201. ADDR_LENGTH,
  202. NULL,
  203. NULL);
  204. pszIpAddr[ADDR_LENGTH] = '\0';
  205. p = strchr( pszIpAddr, '/' );
  206. if (p)
  207. {
  208. ULONG ulLen = (atoi(p+1));
  209. *pipMask = (ulLen)? htonl(~0 << (32 - ulLen)) : 0;
  210. *p = 0;
  211. }
  212. else
  213. {
  214. *pipMask = ~0;
  215. }
  216. // If less than three dots were specified, append .0 until there are
  217. for (dwDots=0, p=strchr(pszIpAddr, '.'); p; dwDots++,p=strchr(p+1,'.'));
  218. while (dwDots < 3) {
  219. strcat(pszIpAddr, ".0");
  220. dwDots++;
  221. }
  222. *pipAddress = (DWORD) inet_addr(pszIpAddr);
  223. return NO_ERROR;
  224. }
  225. DWORD
  226. GetIpMask(
  227. IN LPCWSTR ppwcArg,
  228. OUT PIPV4_ADDRESS pipAddress
  229. )
  230. /*++
  231. Routine Description:
  232. Gets the ip address from the string.
  233. Arguments:
  234. pwszIpAddr - Ip address string
  235. pipAddress - IP address
  236. Return Value:
  237. NO_ERROR, ERROR_INVALID_PARAMETER
  238. --*/
  239. {
  240. CHAR pszIpAddr[ADDR_LENGTH+1];
  241. // Make sure all characters are legal [/0-9.]
  242. if (ppwcArg[ wcsspn(ppwcArg, L"/0123456789.") ])
  243. {
  244. return ERROR_INVALID_PARAMETER;
  245. }
  246. WideCharToMultiByte(GetConsoleOutputCP(),
  247. 0,
  248. ppwcArg,
  249. -1,
  250. pszIpAddr,
  251. ADDR_LENGTH,
  252. NULL,
  253. NULL);
  254. pszIpAddr[ADDR_LENGTH] = '\0';
  255. if (pszIpAddr[0] is '/')
  256. {
  257. ULONG ulLen = (atoi(pszIpAddr+1));
  258. *pipAddress = (ulLen)? htonl(~0 << (32 - ulLen)) : 0;
  259. }
  260. else
  261. {
  262. *pipAddress = (DWORD) inet_addr(pszIpAddr);
  263. }
  264. return NO_ERROR;
  265. }
  266. DWORD
  267. GetIpAddress(
  268. IN LPCWSTR pwszArgument,
  269. OUT PIPV4_ADDRESS pipAddress
  270. )
  271. /*++
  272. Routine Description
  273. Gets the ip address from the string.
  274. Arguments
  275. pwszArgument argument specifing an ip address
  276. pipAddress ip address
  277. Return Value
  278. NO_ERROR if success
  279. Failure code o/w
  280. --*/
  281. {
  282. CHAR pszAddress[ADDR_LENGTH + 1];
  283. DWORD dwAddress = 0;
  284. PCHAR pcNext = NULL;
  285. ULONG ulCount = 0;
  286. // ensure all characters are legal [0-9.]
  287. if (pwszArgument[wcsspn(pwszArgument, L"0123456789.")])
  288. return ERROR_INVALID_PARAMETER;
  289. // convert to an ansi string
  290. sprintf(pszAddress, "%S", pwszArgument);
  291. // ensure there are 3 '.' (periods)
  292. for (pcNext = pszAddress, ulCount = 0; *pcNext != '\0'; pcNext++)
  293. if (*pcNext is '.')
  294. ulCount++;
  295. if (ulCount != 3)
  296. return ERROR_INVALID_PARAMETER;
  297. dwAddress = (DWORD) inet_addr(pszAddress);
  298. // return an error if dwAddress is INADDR_NONE (255.255.255.255)
  299. // and the address specified isn't 255.255.255.255 (INADDR_NONE)
  300. if ((dwAddress is INADDR_NONE) and
  301. strcmp(pszAddress, "255.255.255.255"))
  302. return ERROR_INVALID_PARAMETER;
  303. *pipAddress = dwAddress;
  304. return NO_ERROR;
  305. }
  306. BYTE
  307. MaskToMaskLen(
  308. IPV4_ADDRESS dwMask
  309. )
  310. {
  311. register int i;
  312. dwMask = ntohl(dwMask);
  313. for (i=0; i<32 && !(dwMask & (1<<i)); i++);
  314. return 32-i;
  315. }
  316. VOID
  317. MakeAddressStringW(
  318. OUT LPWSTR pwcPrefixStr,
  319. IN IPV4_ADDRESS ipAddr
  320. )
  321. {
  322. swprintf( pwcPrefixStr,
  323. L"%d.%d.%d.%d",
  324. PRINT_IPADDR(ipAddr) );
  325. }
  326. VOID
  327. MakePrefixStringW(
  328. OUT LPWSTR pwcPrefixStr,
  329. IN IPV4_ADDRESS ipAddr,
  330. IN IPV4_ADDRESS ipMask
  331. )
  332. {
  333. swprintf( pwcPrefixStr,
  334. L"%d.%d.%d.%d/%d",
  335. PRINT_IPADDR(ipAddr),
  336. MaskToMaskLen(ipMask) );
  337. }
  338. DWORD
  339. GetIfIndexFromGuid(
  340. IN MIB_SERVER_HANDLE hMibServer,
  341. IN LPCWSTR pwszGuid,
  342. OUT PDWORD pdwIfIndex
  343. )
  344. {
  345. MIB_OPAQUE_QUERY Query;
  346. PMIB_IFTABLE pIfTable;
  347. DWORD dwErr, dwOutEntrySize;
  348. PMIB_OPAQUE_INFO pRpcInfo;
  349. DWORD dwCount, i;
  350. Query.dwVarId = IF_TABLE;
  351. Query.rgdwVarIndex[0] = 0;
  352. dwErr = MibGet( PID_IP,
  353. IPRTRMGR_PID,
  354. (PVOID) &Query,
  355. sizeof(Query),
  356. (PVOID *) &pRpcInfo,
  357. &dwOutEntrySize );
  358. if (dwErr isnot NO_ERROR)
  359. {
  360. return dwErr;
  361. }
  362. pIfTable = (PMIB_IFTABLE)(pRpcInfo->rgbyData);
  363. dwCount = pIfTable->dwNumEntries;
  364. *pdwIfIndex = 0;
  365. for (i=0; i<dwCount; i++)
  366. {
  367. if (!wcscmp(pIfTable->table[i].wszName, pwszGuid))
  368. {
  369. *pdwIfIndex = pIfTable->table[i].dwIndex;
  370. break;
  371. }
  372. }
  373. MprAdminMIBBufferFree( (PVOID) pRpcInfo );
  374. return NO_ERROR;
  375. }
  376. DWORD
  377. GetGuidFromIfIndex(
  378. IN MIB_SERVER_HANDLE hMibServer,
  379. IN DWORD dwIfIndex,
  380. OUT LPWSTR pwszBuffer,
  381. IN DWORD dwBufferSize
  382. )
  383. {
  384. MIB_OPAQUE_QUERY Query;
  385. PMIB_IFROW pIfRow;
  386. DWORD dwErr, dwOutEntrySize;
  387. PMIB_OPAQUE_INFO pRpcInfo;
  388. Query.dwVarId = IF_ROW;
  389. Query.rgdwVarIndex[0] = dwIfIndex;
  390. dwErr = MibGet( PID_IP,
  391. IPRTRMGR_PID,
  392. (PVOID) &Query,
  393. sizeof(Query),
  394. (PVOID *) &pRpcInfo,
  395. &dwOutEntrySize );
  396. if (dwErr isnot NO_ERROR)
  397. {
  398. return dwErr;
  399. }
  400. pIfRow = (PMIB_IFROW)(pRpcInfo->rgbyData);
  401. wcscpy( pwszBuffer, pIfRow->wszName );
  402. MprAdminMIBBufferFree( (PVOID) pRpcInfo );
  403. return NO_ERROR;
  404. }
  405. DWORD
  406. IpmontrGetFriendlyNameFromIfIndex(
  407. IN MIB_SERVER_HANDLE hMibServer,
  408. IN DWORD dwIfIndex,
  409. OUT LPWSTR pwszBuffer,
  410. IN DWORD dwBufferSize
  411. )
  412. /*++
  413. Routine Description:
  414. Gets friendly Interface name from Interface index
  415. Arguments:
  416. hMibServer - Handle to the MIB server
  417. dwIfIndex - Interface index
  418. pwszBuffer - Buffer that will be holding the friendly interface name
  419. dwBufferSize - Size (in Bytes) of the pwszBuffer
  420. --*/
  421. {
  422. WCHAR wszGuid[MAX_INTERFACE_NAME_LEN + 1];
  423. DWORD dwErr, BufLen;
  424. BufLen = sizeof(wszGuid);
  425. dwErr = GetGuidFromIfIndex(hMibServer, dwIfIndex, wszGuid, BufLen);
  426. if (dwErr isnot NO_ERROR)
  427. {
  428. return dwErr;
  429. }
  430. return IpmontrGetFriendlyNameFromIfName( wszGuid, pwszBuffer, &dwBufferSize );
  431. }
  432. DWORD
  433. IpmontrGetIfIndexFromFriendlyName(
  434. IN MIB_SERVER_HANDLE hMibServer,
  435. IN LPCWSTR pwszFriendlyName,
  436. OUT PDWORD pdwIfIndex
  437. )
  438. {
  439. WCHAR wszGuid[MAX_INTERFACE_NAME_LEN + 1];
  440. DWORD dwErr, dwSize = sizeof(wszGuid);
  441. dwErr = IpmontrGetIfNameFromFriendlyName( pwszFriendlyName,
  442. wszGuid,
  443. &dwSize );
  444. if (dwErr isnot NO_ERROR)
  445. {
  446. return dwErr;
  447. }
  448. return GetIfIndexFromGuid( hMibServer, wszGuid, pdwIfIndex );
  449. }
  450. DWORD
  451. IpmontrGetFriendlyNameFromIfName(
  452. IN LPCWSTR pwszName,
  453. OUT LPWSTR pwszBuffer,
  454. IN PDWORD pdwBufSize
  455. )
  456. /*++
  457. Description:
  458. Defines function to map a guid interface name to an unique descriptive
  459. name describing that interface.
  460. Arguments:
  461. pwszName - Buffer holding a Guid Interface Name
  462. pwszBuffer - Buffer to hold the Friendly Name
  463. pdwBufferSize - pointer to the Size (in Bytes) of the pwszBuffer
  464. --*/
  465. {
  466. return NsGetFriendlyNameFromIfName( g_hMprConfig,
  467. pwszName,
  468. pwszBuffer,
  469. pdwBufSize );
  470. }
  471. DWORD
  472. IpmontrGetIfNameFromFriendlyName(
  473. IN LPCWSTR pwszName,
  474. OUT LPWSTR pwszBuffer,
  475. IN PDWORD pdwBufSize
  476. )
  477. /*++
  478. Description:
  479. Defines function to map a friendly interface name to a guid interface
  480. name.
  481. Arguments:
  482. pwszName - Buffer holding a Friendly Interface Name
  483. pwszBuffer - Buffer to hold Guid Interface Name
  484. pdwBufferSize - pointer to the Size (in Bytes) of the pwszBuffer
  485. Returns:
  486. NO_ERROR, ERROR_NO_SUCH_INTERFACE
  487. --*/
  488. {
  489. return NsGetIfNameFromFriendlyName( g_hMprConfig,
  490. pwszName,
  491. pwszBuffer,
  492. pdwBufSize );
  493. }
  494. #ifdef KSL_IPINIP
  495. DWORD
  496. IpmontrCreateInterface(
  497. IN LPCWSTR pwszMachineName,
  498. IN LPCWSTR pwszInterfaceName,
  499. IN DWORD dwLocalAddress,
  500. IN DWORD dwRemoteAddress,
  501. IN BYTE byTtl
  502. )
  503. /*++
  504. Description: TODO This function is really really really ugly and does
  505. not belong in Netsh. There needs to be a system API to do this,
  506. but there isn't one right now so we have to workaround it by copying
  507. all this crud here. This code is stolen from netsh\if\routerdb.c
  508. RtrInterfaceAddIpip() which is also really really really ugly.
  509. --*/
  510. {
  511. DWORD dwErr = ERROR_CAN_NOT_COMPLETE;
  512. GUID Guid;
  513. GUID *pGuid = &Guid;
  514. MPR_IPINIP_INTERFACE_0 NameInfo;
  515. MPR_INTERFACE_0 IfInfo;
  516. HANDLE hIfCfg;
  517. HANDLE hIfAdmin;
  518. IPINIP_CONFIG_INFO info;
  519. // Initialize
  520. //
  521. ZeroMemory(&IfInfo, sizeof(IfInfo));
  522. IfInfo.fEnabled = TRUE;
  523. IfInfo.dwIfType = ROUTER_IF_TYPE_TUNNEL1;
  524. wcscpy(IfInfo.wszInterfaceName, pwszInterfaceName);
  525. info.dwLocalAddress = dwLocalAddress;
  526. info.dwRemoteAddress = dwRemoteAddress;
  527. info.byTtl = byTtl;
  528. dwErr = AddSetIpIpTunnelInfo(pwszInterfaceName, &info);
  529. if(dwErr isnot NO_ERROR)
  530. {
  531. //
  532. // Tear down the mapping
  533. //
  534. MprSetupIpInIpInterfaceFriendlyNameDelete(NULL, pGuid);
  535. }
  536. return dwErr;
  537. }
  538. DWORD
  539. IpmontrDeleteInterface(
  540. IN LPCWSTR pwszMachineName,
  541. IN LPCWSTR pwszInterfaceName
  542. )
  543. /*++
  544. Description: TODO This function is really really really ugly and does
  545. not belong in Netsh. There needs to be a system API to do this,
  546. but there isn't one right now so we have to workaround it by copying
  547. all this crud here. This code is stolen from netsh\if\routerdb.c
  548. RtrInterfaceDelete() which is also really really really ugly.
  549. Called by: HandleMsdpDeletePeer()
  550. --*/
  551. {
  552. DWORD dwErr = ERROR_CAN_NOT_COMPLETE;
  553. DWORD dwSize;
  554. HANDLE hIfCfg, hIfAdmin;
  555. GUID Guid;
  556. MPR_INTERFACE_0 *pIfInfo;
  557. do {
  558. dwErr = MprConfigInterfaceGetHandle(g_hMprConfig,
  559. (LPWSTR)pwszInterfaceName,
  560. &hIfCfg);
  561. if(dwErr isnot NO_ERROR)
  562. {
  563. break;
  564. }
  565. dwErr = MprConfigInterfaceGetInfo(g_hMprConfig,
  566. hIfCfg,
  567. 0,
  568. (PBYTE *)&pIfInfo,
  569. &dwSize);
  570. if(dwErr isnot NO_ERROR)
  571. {
  572. break;
  573. }
  574. if(pIfInfo->dwIfType isnot ROUTER_IF_TYPE_TUNNEL1)
  575. {
  576. MprConfigBufferFree(pIfInfo);
  577. dwErr = ERROR_INVALID_PARAMETER;
  578. break;
  579. }
  580. #ifdef KSL_IPINIP
  581. dwErr = MprConfigInterfaceDelete(g_hMprConfig,
  582. hIfCfg);
  583. MprConfigBufferFree(pIfInfo);
  584. if(dwErr isnot NO_ERROR)
  585. {
  586. break;
  587. }
  588. dwErr = ConvertStringToGuid(pwszInterfaceName,
  589. (USHORT)(wcslen(pwszInterfaceName) * sizeof(WCHAR)),
  590. &Guid);
  591. if(dwErr isnot NO_ERROR)
  592. {
  593. break;
  594. }
  595. dwErr = MprSetupIpInIpInterfaceFriendlyNameDelete((LPWSTR)pwszMachineName,
  596. &Guid);
  597. if(IsRouterRunning())
  598. {
  599. dwErr = MprAdminInterfaceGetHandle(g_hMprAdmin,
  600. (LPWSTR)pwszInterfaceName,
  601. &hIfAdmin,
  602. FALSE);
  603. if(dwErr isnot NO_ERROR)
  604. {
  605. break;
  606. }
  607. dwErr = MprAdminInterfaceDelete(g_hMprAdmin,
  608. hIfAdmin);
  609. }
  610. #endif //KSL_IPINIP
  611. } while (FALSE);
  612. return dwErr;
  613. }
  614. #endif //KSL_IPINIP