Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

583 lines
13 KiB

  1. #include "inc.h"
  2. CMD_ENTRY g_rgMainCmdTable[] =
  3. {
  4. {TOKEN_ROUTE, HandleRoute},
  5. {TOKEN_ADDRESS, HandleAddress},
  6. {TOKEN_INTERFACE, HandleInterface},
  7. {TOKEN_ARP, HandleArp},
  8. };
  9. HMODULE g_hModule;
  10. DWORD
  11. _cdecl
  12. wmain(
  13. int argc,
  14. wchar_t *argv[]
  15. )
  16. /*++
  17. Routine Description
  18. Locks
  19. Arguments
  20. Return Value
  21. --*/
  22. {
  23. LONG lIndex;
  24. setlocale(LC_ALL,
  25. "");
  26. if(argc < 2)
  27. {
  28. DisplayMessage(HMSG_IPKERN_USAGE);
  29. return ERROR;
  30. }
  31. g_hModule = GetModuleHandle(NULL);
  32. if(g_hModule is NULL)
  33. {
  34. return GetLastError();
  35. }
  36. lIndex = ParseCommand(g_rgMainCmdTable,
  37. sizeof(g_rgMainCmdTable)/sizeof(CMD_ENTRY),
  38. argv[1]);
  39. if(lIndex is -1)
  40. {
  41. DisplayMessage(HMSG_IPKERN_USAGE);
  42. return ERROR_INVALID_PARAMETER;
  43. }
  44. g_rgMainCmdTable[lIndex].pfnHandler(argc - 1,
  45. &argv[1]);
  46. return NO_ERROR;
  47. }
  48. BOOL
  49. MatchToken(
  50. IN PWCHAR pwszToken,
  51. IN DWORD dwTokenId
  52. )
  53. {
  54. WCHAR pwszTemp[MAX_TOKEN_LENGTH] = L"\0";
  55. if(!LoadStringW(g_hModule,
  56. dwTokenId,
  57. pwszTemp,
  58. MAX_TOKEN_LENGTH))
  59. {
  60. return FALSE;
  61. }
  62. if(!_wcsicmp(pwszToken, pwszTemp))
  63. {
  64. return TRUE;
  65. }
  66. return FALSE;
  67. }
  68. LONG
  69. ParseCommand(
  70. PCMD_ENTRY pCmdTable,
  71. LONG lNumEntries,
  72. PWCHAR pwszFirstArg
  73. )
  74. {
  75. LONG i;
  76. for(i = 0; i < lNumEntries; i++)
  77. {
  78. if(MatchToken(pwszFirstArg,
  79. pCmdTable[i].dwTokenId))
  80. {
  81. return i;
  82. }
  83. }
  84. return -1;
  85. }
  86. DWORD
  87. DisplayMessage(
  88. DWORD dwMsgId,
  89. ...
  90. )
  91. {
  92. DWORD dwMsglen = 0;
  93. PWCHAR pwszOutput;
  94. va_list arglist;
  95. WCHAR rgwcInput[MAX_MSG_LENGTH];
  96. pwszOutput = NULL;
  97. do
  98. {
  99. va_start(arglist, dwMsgId);
  100. if(!LoadStringW(g_hModule,
  101. dwMsgId,
  102. rgwcInput,
  103. MAX_MSG_LENGTH))
  104. {
  105. break;
  106. }
  107. dwMsglen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
  108. rgwcInput,
  109. 0,
  110. 0L,
  111. (PWCHAR)&pwszOutput,
  112. 0,
  113. &arglist);
  114. if(dwMsglen is 0)
  115. {
  116. break;
  117. }
  118. wprintf( L"%s", pwszOutput );
  119. }while(FALSE);
  120. if(pwszOutput)
  121. {
  122. LocalFree(pwszOutput);
  123. }
  124. return dwMsglen;
  125. }
  126. PWCHAR
  127. MakeString(
  128. DWORD dwMsgId,
  129. ...
  130. )
  131. {
  132. DWORD dwMsglen;
  133. PWCHAR pwszOutput;
  134. va_list arglist;
  135. WCHAR rgwcInput[MAX_MSG_LENGTH];
  136. pwszOutput = NULL;
  137. do
  138. {
  139. va_start(arglist,
  140. dwMsgId);
  141. if(!LoadStringW(g_hModule,
  142. dwMsgId,
  143. rgwcInput,
  144. MAX_MSG_LENGTH))
  145. {
  146. break;
  147. }
  148. FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_STRING,
  149. rgwcInput,
  150. 0,
  151. 0L, // Default country ID.
  152. (PWCHAR)&pwszOutput,
  153. 0,
  154. &arglist);
  155. }while(FALSE);
  156. return pwszOutput;
  157. }
  158. VOID
  159. FreeString(
  160. PWCHAR pwszString
  161. )
  162. {
  163. LocalFree(pwszString);
  164. }
  165. //
  166. // This preinitialized array defines the strings to be used.
  167. // The index of each row corresponds to the value for a byte
  168. // in an IP address. The first three bytes of each row are the
  169. // char/string value for the byte, and the fourth byte in each row is
  170. // the length of the string required for the byte. This approach
  171. // allows a fast implementation with no jumps.
  172. //
  173. static const WCHAR NToUWCharStrings[][4] =
  174. {
  175. L'0', L'x', L'x', 1,
  176. L'1', L'x', L'x', 1,
  177. L'2', L'x', L'x', 1,
  178. L'3', L'x', L'x', 1,
  179. L'4', L'x', L'x', 1,
  180. L'5', L'x', L'x', 1,
  181. L'6', L'x', L'x', 1,
  182. L'7', L'x', L'x', 1,
  183. L'8', L'x', L'x', 1,
  184. L'9', L'x', L'x', 1,
  185. L'1', L'0', L'x', 2,
  186. L'1', L'1', L'x', 2,
  187. L'1', L'2', L'x', 2,
  188. L'1', L'3', L'x', 2,
  189. L'1', L'4', L'x', 2,
  190. L'1', L'5', L'x', 2,
  191. L'1', L'6', L'x', 2,
  192. L'1', L'7', L'x', 2,
  193. L'1', L'8', L'x', 2,
  194. L'1', L'9', L'x', 2,
  195. L'2', L'0', L'x', 2,
  196. L'2', L'1', L'x', 2,
  197. L'2', L'2', L'x', 2,
  198. L'2', L'3', L'x', 2,
  199. L'2', L'4', L'x', 2,
  200. L'2', L'5', L'x', 2,
  201. L'2', L'6', L'x', 2,
  202. L'2', L'7', L'x', 2,
  203. L'2', L'8', L'x', 2,
  204. L'2', L'9', L'x', 2,
  205. L'3', L'0', L'x', 2,
  206. L'3', L'1', L'x', 2,
  207. L'3', L'2', L'x', 2,
  208. L'3', L'3', L'x', 2,
  209. L'3', L'4', L'x', 2,
  210. L'3', L'5', L'x', 2,
  211. L'3', L'6', L'x', 2,
  212. L'3', L'7', L'x', 2,
  213. L'3', L'8', L'x', 2,
  214. L'3', L'9', L'x', 2,
  215. L'4', L'0', L'x', 2,
  216. L'4', L'1', L'x', 2,
  217. L'4', L'2', L'x', 2,
  218. L'4', L'3', L'x', 2,
  219. L'4', L'4', L'x', 2,
  220. L'4', L'5', L'x', 2,
  221. L'4', L'6', L'x', 2,
  222. L'4', L'7', L'x', 2,
  223. L'4', L'8', L'x', 2,
  224. L'4', L'9', L'x', 2,
  225. L'5', L'0', L'x', 2,
  226. L'5', L'1', L'x', 2,
  227. L'5', L'2', L'x', 2,
  228. L'5', L'3', L'x', 2,
  229. L'5', L'4', L'x', 2,
  230. L'5', L'5', L'x', 2,
  231. L'5', L'6', L'x', 2,
  232. L'5', L'7', L'x', 2,
  233. L'5', L'8', L'x', 2,
  234. L'5', L'9', L'x', 2,
  235. L'6', L'0', L'x', 2,
  236. L'6', L'1', L'x', 2,
  237. L'6', L'2', L'x', 2,
  238. L'6', L'3', L'x', 2,
  239. L'6', L'4', L'x', 2,
  240. L'6', L'5', L'x', 2,
  241. L'6', L'6', L'x', 2,
  242. L'6', L'7', L'x', 2,
  243. L'6', L'8', L'x', 2,
  244. L'6', L'9', L'x', 2,
  245. L'7', L'0', L'x', 2,
  246. L'7', L'1', L'x', 2,
  247. L'7', L'2', L'x', 2,
  248. L'7', L'3', L'x', 2,
  249. L'7', L'4', L'x', 2,
  250. L'7', L'5', L'x', 2,
  251. L'7', L'6', L'x', 2,
  252. L'7', L'7', L'x', 2,
  253. L'7', L'8', L'x', 2,
  254. L'7', L'9', L'x', 2,
  255. L'8', L'0', L'x', 2,
  256. L'8', L'1', L'x', 2,
  257. L'8', L'2', L'x', 2,
  258. L'8', L'3', L'x', 2,
  259. L'8', L'4', L'x', 2,
  260. L'8', L'5', L'x', 2,
  261. L'8', L'6', L'x', 2,
  262. L'8', L'7', L'x', 2,
  263. L'8', L'8', L'x', 2,
  264. L'8', L'9', L'x', 2,
  265. L'9', L'0', L'x', 2,
  266. L'9', L'1', L'x', 2,
  267. L'9', L'2', L'x', 2,
  268. L'9', L'3', L'x', 2,
  269. L'9', L'4', L'x', 2,
  270. L'9', L'5', L'x', 2,
  271. L'9', L'6', L'x', 2,
  272. L'9', L'7', L'x', 2,
  273. L'9', L'8', L'x', 2,
  274. L'9', L'9', L'x', 2,
  275. L'1', L'0', L'0', 3,
  276. L'1', L'0', L'1', 3,
  277. L'1', L'0', L'2', 3,
  278. L'1', L'0', L'3', 3,
  279. L'1', L'0', L'4', 3,
  280. L'1', L'0', L'5', 3,
  281. L'1', L'0', L'6', 3,
  282. L'1', L'0', L'7', 3,
  283. L'1', L'0', L'8', 3,
  284. L'1', L'0', L'9', 3,
  285. L'1', L'1', L'0', 3,
  286. L'1', L'1', L'1', 3,
  287. L'1', L'1', L'2', 3,
  288. L'1', L'1', L'3', 3,
  289. L'1', L'1', L'4', 3,
  290. L'1', L'1', L'5', 3,
  291. L'1', L'1', L'6', 3,
  292. L'1', L'1', L'7', 3,
  293. L'1', L'1', L'8', 3,
  294. L'1', L'1', L'9', 3,
  295. L'1', L'2', L'0', 3,
  296. L'1', L'2', L'1', 3,
  297. L'1', L'2', L'2', 3,
  298. L'1', L'2', L'3', 3,
  299. L'1', L'2', L'4', 3,
  300. L'1', L'2', L'5', 3,
  301. L'1', L'2', L'6', 3,
  302. L'1', L'2', L'7', 3,
  303. L'1', L'2', L'8', 3,
  304. L'1', L'2', L'9', 3,
  305. L'1', L'3', L'0', 3,
  306. L'1', L'3', L'1', 3,
  307. L'1', L'3', L'2', 3,
  308. L'1', L'3', L'3', 3,
  309. L'1', L'3', L'4', 3,
  310. L'1', L'3', L'5', 3,
  311. L'1', L'3', L'6', 3,
  312. L'1', L'3', L'7', 3,
  313. L'1', L'3', L'8', 3,
  314. L'1', L'3', L'9', 3,
  315. L'1', L'4', L'0', 3,
  316. L'1', L'4', L'1', 3,
  317. L'1', L'4', L'2', 3,
  318. L'1', L'4', L'3', 3,
  319. L'1', L'4', L'4', 3,
  320. L'1', L'4', L'5', 3,
  321. L'1', L'4', L'6', 3,
  322. L'1', L'4', L'7', 3,
  323. L'1', L'4', L'8', 3,
  324. L'1', L'4', L'9', 3,
  325. L'1', L'5', L'0', 3,
  326. L'1', L'5', L'1', 3,
  327. L'1', L'5', L'2', 3,
  328. L'1', L'5', L'3', 3,
  329. L'1', L'5', L'4', 3,
  330. L'1', L'5', L'5', 3,
  331. L'1', L'5', L'6', 3,
  332. L'1', L'5', L'7', 3,
  333. L'1', L'5', L'8', 3,
  334. L'1', L'5', L'9', 3,
  335. L'1', L'6', L'0', 3,
  336. L'1', L'6', L'1', 3,
  337. L'1', L'6', L'2', 3,
  338. L'1', L'6', L'3', 3,
  339. L'1', L'6', L'4', 3,
  340. L'1', L'6', L'5', 3,
  341. L'1', L'6', L'6', 3,
  342. L'1', L'6', L'7', 3,
  343. L'1', L'6', L'8', 3,
  344. L'1', L'6', L'9', 3,
  345. L'1', L'7', L'0', 3,
  346. L'1', L'7', L'1', 3,
  347. L'1', L'7', L'2', 3,
  348. L'1', L'7', L'3', 3,
  349. L'1', L'7', L'4', 3,
  350. L'1', L'7', L'5', 3,
  351. L'1', L'7', L'6', 3,
  352. L'1', L'7', L'7', 3,
  353. L'1', L'7', L'8', 3,
  354. L'1', L'7', L'9', 3,
  355. L'1', L'8', L'0', 3,
  356. L'1', L'8', L'1', 3,
  357. L'1', L'8', L'2', 3,
  358. L'1', L'8', L'3', 3,
  359. L'1', L'8', L'4', 3,
  360. L'1', L'8', L'5', 3,
  361. L'1', L'8', L'6', 3,
  362. L'1', L'8', L'7', 3,
  363. L'1', L'8', L'8', 3,
  364. L'1', L'8', L'9', 3,
  365. L'1', L'9', L'0', 3,
  366. L'1', L'9', L'1', 3,
  367. L'1', L'9', L'2', 3,
  368. L'1', L'9', L'3', 3,
  369. L'1', L'9', L'4', 3,
  370. L'1', L'9', L'5', 3,
  371. L'1', L'9', L'6', 3,
  372. L'1', L'9', L'7', 3,
  373. L'1', L'9', L'8', 3,
  374. L'1', L'9', L'9', 3,
  375. L'2', L'0', L'0', 3,
  376. L'2', L'0', L'1', 3,
  377. L'2', L'0', L'2', 3,
  378. L'2', L'0', L'3', 3,
  379. L'2', L'0', L'4', 3,
  380. L'2', L'0', L'5', 3,
  381. L'2', L'0', L'6', 3,
  382. L'2', L'0', L'7', 3,
  383. L'2', L'0', L'8', 3,
  384. L'2', L'0', L'9', 3,
  385. L'2', L'1', L'0', 3,
  386. L'2', L'1', L'1', 3,
  387. L'2', L'1', L'2', 3,
  388. L'2', L'1', L'3', 3,
  389. L'2', L'1', L'4', 3,
  390. L'2', L'1', L'5', 3,
  391. L'2', L'1', L'6', 3,
  392. L'2', L'1', L'7', 3,
  393. L'2', L'1', L'8', 3,
  394. L'2', L'1', L'9', 3,
  395. L'2', L'2', L'0', 3,
  396. L'2', L'2', L'1', 3,
  397. L'2', L'2', L'2', 3,
  398. L'2', L'2', L'3', 3,
  399. L'2', L'2', L'4', 3,
  400. L'2', L'2', L'5', 3,
  401. L'2', L'2', L'6', 3,
  402. L'2', L'2', L'7', 3,
  403. L'2', L'2', L'8', 3,
  404. L'2', L'2', L'9', 3,
  405. L'2', L'3', L'0', 3,
  406. L'2', L'3', L'1', 3,
  407. L'2', L'3', L'2', 3,
  408. L'2', L'3', L'3', 3,
  409. L'2', L'3', L'4', 3,
  410. L'2', L'3', L'5', 3,
  411. L'2', L'3', L'6', 3,
  412. L'2', L'3', L'7', 3,
  413. L'2', L'3', L'8', 3,
  414. L'2', L'3', L'9', 3,
  415. L'2', L'4', L'0', 3,
  416. L'2', L'4', L'1', 3,
  417. L'2', L'4', L'2', 3,
  418. L'2', L'4', L'3', 3,
  419. L'2', L'4', L'4', 3,
  420. L'2', L'4', L'5', 3,
  421. L'2', L'4', L'6', 3,
  422. L'2', L'4', L'7', 3,
  423. L'2', L'4', L'8', 3,
  424. L'2', L'4', L'9', 3,
  425. L'2', L'5', L'0', 3,
  426. L'2', L'5', L'1', 3,
  427. L'2', L'5', L'2', 3,
  428. L'2', L'5', L'3', 3,
  429. L'2', L'5', L'4', 3,
  430. L'2', L'5', L'5', 3
  431. };
  432. VOID
  433. NetworkToUnicode(
  434. IN DWORD dwAddress,
  435. OUT PWCHAR pwszBuffer
  436. )
  437. /*++
  438. Routine Description:
  439. This function takes an Internet address structure specified by the
  440. in parameter. It returns an UNICODE string representing the address
  441. in ".'' notation as "a.b.c.d". Note that unlike inet_ntoa, this requires
  442. the user to supply a buffer. This is good because all of the TLS crap
  443. now can be thrown out - and the function is leaner and meaner. Ofcourse
  444. this does make it incompatible with inet_ntoa since the parameters are
  445. different. And it makes it less safe since bad buffers will cause an
  446. a.v.
  447. Arguments:
  448. iaAddress A structure which represents an Internet host address.
  449. pwszBufer User supplied buffer to ATLEAST WCHAR[16]. Since there is
  450. no try/except - you will crash if you dont supply a "good"
  451. buffer. The formatted address is returned in this buffer
  452. Return Value:
  453. None
  454. --*/
  455. {
  456. PBYTE p;
  457. PWCHAR b;
  458. b = pwszBuffer;
  459. //
  460. // In an unrolled loop, calculate the string value for each of the four
  461. // bytes in an IP address. Note that for values less than 100 we will
  462. // do one or two extra assignments, but we save a test/jump with this
  463. // algorithm.
  464. //
  465. p = (PBYTE)&dwAddress;
  466. *b = NToUWCharStrings[*p][0];
  467. *(b+1) = NToUWCharStrings[*p][1];
  468. *(b+2) = NToUWCharStrings[*p][2];
  469. b += NToUWCharStrings[*p][3];
  470. *b++ = L'.';
  471. p++;
  472. *b = NToUWCharStrings[*p][0];
  473. *(b+1) = NToUWCharStrings[*p][1];
  474. *(b+2) = NToUWCharStrings[*p][2];
  475. b += NToUWCharStrings[*p][3];
  476. *b++ = L'.';
  477. p++;
  478. *b = NToUWCharStrings[*p][0];
  479. *(b+1) = NToUWCharStrings[*p][1];
  480. *(b+2) = NToUWCharStrings[*p][2];
  481. b += NToUWCharStrings[*p][3];
  482. *b++ = L'.';
  483. p++;
  484. *b = NToUWCharStrings[*p][0];
  485. *(b+1) = NToUWCharStrings[*p][1];
  486. *(b+2) = NToUWCharStrings[*p][2];
  487. b += NToUWCharStrings[*p][3];
  488. *b = UNICODE_NULL;
  489. }
  490. DWORD
  491. UnicodeToNetwork(
  492. PWCHAR pwszAddr
  493. )
  494. {
  495. CHAR szAddr[MAX_TOKEN_LENGTH + 1];
  496. INT iCount;
  497. iCount = WideCharToMultiByte(CP_ACP,
  498. 0,
  499. pwszAddr,
  500. wcslen(pwszAddr),
  501. szAddr,
  502. MAX_TOKEN_LENGTH,
  503. NULL,
  504. NULL);
  505. szAddr[iCount] = '\0';
  506. return inet_addr(szAddr);
  507. }