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.

1422 lines
48 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. #include <nt.h>
  4. #include <ntrtl.h>
  5. #include <nturtl.h>
  6. #include <mswsock.h>
  7. #include <stdio.h>
  8. #include <conio.h>
  9. #include <stdlib.h>
  10. #include <ipnatapi.h>
  11. HANDLE Event;
  12. VOID
  13. ReadCompletionRoutine(
  14. ULONG ErrorCode,
  15. ULONG BytesTransferred,
  16. PNH_BUFFER Bufferp
  17. )
  18. {
  19. printf(
  20. "ReadCompletionRoutine: e=%u, b=%u, '%s'\n",
  21. ErrorCode, BytesTransferred, Bufferp->Buffer
  22. );
  23. NhReleaseBuffer(Bufferp);
  24. SetEvent(Event);
  25. }
  26. VOID
  27. WriteCompletionRoutine(
  28. ULONG ErrorCode,
  29. ULONG BytesTransferred,
  30. PNH_BUFFER Bufferp
  31. )
  32. {
  33. printf(
  34. "WriteCompletionRoutine: e=%u, b=%u, %08x\n",
  35. ErrorCode, BytesTransferred, Bufferp
  36. );
  37. NhReleaseBuffer(Bufferp);
  38. SetEvent(Event);
  39. }
  40. VOID
  41. AcceptCompletionRoutine(
  42. ULONG ErrorCode,
  43. ULONG BytesTransferred,
  44. PNH_BUFFER Bufferp
  45. )
  46. {
  47. SOCKET AcceptedSocket;
  48. SOCKET ListeningSocket;
  49. printf(
  50. "AcceptCompletionRoutine: e=%u, b=%u\n",
  51. ErrorCode, BytesTransferred
  52. );
  53. ListeningSocket = (SOCKET)Bufferp->Context;
  54. AcceptedSocket = (SOCKET)Bufferp->Context2;
  55. ErrorCode =
  56. setsockopt(
  57. AcceptedSocket,
  58. SOL_SOCKET,
  59. SO_UPDATE_ACCEPT_CONTEXT,
  60. (PCHAR)&ListeningSocket,
  61. sizeof(ListeningSocket)
  62. );
  63. if (ErrorCode == SOCKET_ERROR) {
  64. printf("error %d updating accept context\n", WSAGetLastError());
  65. NhReleaseBuffer(Bufferp);
  66. SetEvent(Event);
  67. } else {
  68. ErrorCode =
  69. NhReadStreamSocket(
  70. NULL,
  71. AcceptedSocket,
  72. Bufferp,
  73. NH_BUFFER_SIZE,
  74. 0,
  75. ReadCompletionRoutine,
  76. NULL,
  77. NULL
  78. );
  79. if (ErrorCode != NO_ERROR) {
  80. printf("error %d reading from accepted socket\n", ErrorCode);
  81. NhReleaseBuffer(Bufferp);
  82. SetEvent(Event);
  83. }
  84. }
  85. }
  86. VOID
  87. TestApiCompletionRoutine(
  88. HANDLE RedirectHandle,
  89. BOOLEAN Cancelled,
  90. PVOID CompletionContext
  91. )
  92. {
  93. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  94. ULONG Error;
  95. ULONG Length = sizeof(ByteCount);
  96. printf("TestApiCompletionRoutine=%x,%d\n", RedirectHandle, Cancelled);
  97. Error =
  98. NatQueryInformationRedirectHandle(
  99. RedirectHandle,
  100. &ByteCount,
  101. &Length,
  102. NatByteCountRedirectInformation
  103. );
  104. printf(
  105. "TestApiCompletionRoutine=%d,bc={%I64d,%I64d},l=%d\n",
  106. Error, ByteCount.BytesForward, ByteCount.BytesReverse, Length
  107. );
  108. }
  109. VOID
  110. TestRedirect(
  111. int argc,
  112. char* argv[]
  113. )
  114. {
  115. ULONG Error;
  116. HANDLE TranslatorHandle;
  117. Error = NatInitializeTranslator(&TranslatorHandle);
  118. if (Error) {
  119. printf("NatInitializeTranslator=%d\n", Error);
  120. return;
  121. }
  122. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  123. Error =
  124. NatCreateRedirect(
  125. TranslatorHandle,
  126. 0,
  127. (UCHAR)atol(argv[2]),
  128. inet_addr(argv[3]),
  129. htons((USHORT)atol(argv[4])),
  130. inet_addr(argv[5]),
  131. htons((USHORT)atol(argv[6])),
  132. inet_addr(argv[7]),
  133. htons((USHORT)atol(argv[8])),
  134. inet_addr(argv[9]),
  135. htons((USHORT)atol(argv[10])),
  136. TestApiCompletionRoutine,
  137. NULL,
  138. Event
  139. );
  140. printf("NatCreateRedirect=%d\n", Error);
  141. if (!Error) {
  142. for (;;) {
  143. Error = WaitForSingleObjectEx(Event, 1000, TRUE);
  144. printf("WaitForSingleObjectEx=%d\n", Error);
  145. if (Error == WAIT_IO_COMPLETION) {
  146. break;
  147. } else if (Error == WAIT_OBJECT_0) {
  148. NAT_SOURCE_MAPPING_REDIRECT_INFORMATION SourceMapping;
  149. ULONG Length = sizeof(SourceMapping);
  150. CHAR src[32], newsrc[32];
  151. NatQueryInformationRedirect(
  152. TranslatorHandle,
  153. (UCHAR)atol(argv[2]),
  154. inet_addr(argv[3]),
  155. htons((USHORT)atol(argv[4])),
  156. inet_addr(argv[5]),
  157. htons((USHORT)atol(argv[6])),
  158. inet_addr(argv[7]),
  159. htons((USHORT)atol(argv[8])),
  160. inet_addr(argv[9]),
  161. htons((USHORT)atol(argv[10])),
  162. &SourceMapping,
  163. &Length,
  164. NatSourceMappingRedirectInformation
  165. );
  166. lstrcpyA(
  167. src,
  168. inet_ntoa(*(PIN_ADDR)&SourceMapping.SourceAddress)
  169. );
  170. lstrcpyA(
  171. newsrc,
  172. inet_ntoa(*(PIN_ADDR)&SourceMapping.NewSourceAddress)
  173. );
  174. printf("redirect activated: %s->%s\n", src, newsrc);
  175. }
  176. if (_kbhit()) {
  177. switch(getchar()) {
  178. case 'q': { break; }
  179. case 's': {
  180. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  181. ULONG Length = sizeof(ByteCount);
  182. NatQueryInformationRedirect(
  183. TranslatorHandle,
  184. (UCHAR)atol(argv[2]),
  185. inet_addr(argv[3]),
  186. htons((USHORT)atol(argv[4])),
  187. inet_addr(argv[5]),
  188. htons((USHORT)atol(argv[6])),
  189. inet_addr(argv[7]),
  190. htons((USHORT)atol(argv[8])),
  191. inet_addr(argv[9]),
  192. htons((USHORT)atol(argv[10])),
  193. &ByteCount,
  194. &Length,
  195. NatByteCountRedirectInformation
  196. );
  197. printf(
  198. "NatQueryInformationRedirect=%d,{%I64d,%I64d}\n",
  199. Error,
  200. ByteCount.BytesForward,
  201. ByteCount.BytesReverse
  202. );
  203. // fall-through
  204. }
  205. default: continue;
  206. }
  207. break;
  208. }
  209. }
  210. if (Error != WAIT_IO_COMPLETION) {
  211. Error =
  212. NatCancelRedirect(
  213. TranslatorHandle,
  214. (UCHAR)atol(argv[2]),
  215. inet_addr(argv[3]),
  216. htons((USHORT)atol(argv[4])),
  217. inet_addr(argv[5]),
  218. htons((USHORT)atol(argv[6])),
  219. inet_addr(argv[7]),
  220. htons((USHORT)atol(argv[8])),
  221. inet_addr(argv[9]),
  222. htons((USHORT)atol(argv[10]))
  223. );
  224. printf("NatCancelRedirect=%d\n", Error);
  225. }
  226. }
  227. printf("NatShutdownTranslator...");
  228. NatShutdownTranslator(TranslatorHandle);
  229. printf("done\n");
  230. }
  231. VOID
  232. TestPartialRedirect(
  233. int argc,
  234. char* argv[]
  235. )
  236. {
  237. ULONG Error;
  238. HANDLE TranslatorHandle;
  239. Error = NatInitializeTranslator(&TranslatorHandle);
  240. if (Error) {
  241. printf("NatInitializeTranslator=%d\n", Error);
  242. return;
  243. }
  244. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  245. Error =
  246. NatCreatePartialRedirect(
  247. TranslatorHandle,
  248. 0,
  249. (UCHAR)atol(argv[2]),
  250. inet_addr(argv[3]),
  251. htons((USHORT)atol(argv[4])),
  252. inet_addr(argv[5]),
  253. htons((USHORT)atol(argv[6])),
  254. TestApiCompletionRoutine,
  255. NULL,
  256. Event
  257. );
  258. printf("NatCreatePartialRedirect=%d\n", Error);
  259. if (!Error) {
  260. for (;;) {
  261. Error = WaitForSingleObjectEx(Event, 1000, TRUE);
  262. printf("WaitForSingleObjectEx=%d\n", Error);
  263. if (Error == WAIT_IO_COMPLETION) {
  264. break;
  265. } else if (Error == WAIT_OBJECT_0) {
  266. NAT_SOURCE_MAPPING_REDIRECT_INFORMATION SourceMapping;
  267. ULONG Length = sizeof(SourceMapping);
  268. CHAR src[32], newsrc[32];
  269. NatQueryInformationPartialRedirect(
  270. TranslatorHandle,
  271. (UCHAR)atol(argv[2]),
  272. inet_addr(argv[3]),
  273. htons((USHORT)atol(argv[4])),
  274. inet_addr(argv[5]),
  275. htons((USHORT)atol(argv[6])),
  276. &SourceMapping,
  277. &Length,
  278. NatSourceMappingRedirectInformation
  279. );
  280. lstrcpyA(
  281. src,
  282. inet_ntoa(*(PIN_ADDR)&SourceMapping.SourceAddress)
  283. );
  284. lstrcpyA(
  285. newsrc,
  286. inet_ntoa(*(PIN_ADDR)&SourceMapping.NewSourceAddress)
  287. );
  288. printf("redirect activated: %s->%s\n", src, newsrc);
  289. }
  290. if (_kbhit()) {
  291. switch(getchar()) {
  292. case 'q': { break; }
  293. case 's': {
  294. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  295. ULONG Length = sizeof(ByteCount);
  296. NatQueryInformationPartialRedirect(
  297. TranslatorHandle,
  298. (UCHAR)atol(argv[2]),
  299. inet_addr(argv[3]),
  300. htons((USHORT)atol(argv[4])),
  301. inet_addr(argv[5]),
  302. htons((USHORT)atol(argv[6])),
  303. &ByteCount,
  304. &Length,
  305. NatByteCountRedirectInformation
  306. );
  307. printf(
  308. "NatQueryInformationPartialRedirect="
  309. "%d,{%I64d,%I64d}\n",
  310. Error,
  311. ByteCount.BytesForward,
  312. ByteCount.BytesReverse
  313. );
  314. // fall-through
  315. }
  316. default: continue;
  317. }
  318. break;
  319. }
  320. }
  321. if (Error != WAIT_IO_COMPLETION) {
  322. Error =
  323. NatCancelPartialRedirect(
  324. TranslatorHandle,
  325. (UCHAR)atol(argv[2]),
  326. inet_addr(argv[3]),
  327. htons((USHORT)atol(argv[4])),
  328. inet_addr(argv[5]),
  329. htons((USHORT)atol(argv[6]))
  330. );
  331. printf("NatCancelPartialRedirect=%d\n", Error);
  332. }
  333. }
  334. printf("NatShutdownTranslator...");
  335. NatShutdownTranslator(TranslatorHandle);
  336. printf("done\n");
  337. }
  338. VOID
  339. TestPortRedirect(
  340. int argc,
  341. char* argv[]
  342. )
  343. {
  344. ULONG Error;
  345. HANDLE TranslatorHandle;
  346. Error = NatInitializeTranslator(&TranslatorHandle);
  347. if (Error) {
  348. printf("NatInitializeTranslator=%d\n", Error);
  349. return;
  350. }
  351. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  352. Error =
  353. NatCreatePortRedirect(
  354. TranslatorHandle,
  355. 0,
  356. (UCHAR)atol(argv[2]),
  357. htons((USHORT)atol(argv[3])),
  358. inet_addr(argv[4]),
  359. htons((USHORT)atol(argv[5])),
  360. TestApiCompletionRoutine,
  361. NULL,
  362. Event
  363. );
  364. printf("NatCreatePortRedirect=%d\n", Error);
  365. if (!Error) {
  366. for (;;) {
  367. Error = WaitForSingleObjectEx(Event, 1000, TRUE);
  368. printf("WaitForSingleObjectEx=%d\n", Error);
  369. if (Error == WAIT_IO_COMPLETION) {
  370. break;
  371. } else if (Error == WAIT_OBJECT_0) {
  372. NAT_SOURCE_MAPPING_REDIRECT_INFORMATION SourceMapping;
  373. NAT_DESTINATION_MAPPING_REDIRECT_INFORMATION DestinationMapping;
  374. ULONG Length;
  375. CHAR src[32], newsrc[32], dst[32], newdst[32];
  376. Length = sizeof(SourceMapping);
  377. NatQueryInformationPortRedirect(
  378. TranslatorHandle,
  379. (UCHAR)atol(argv[2]),
  380. htons((USHORT)atol(argv[3])),
  381. inet_addr(argv[4]),
  382. htons((USHORT)atol(argv[5])),
  383. &SourceMapping,
  384. &Length,
  385. NatSourceMappingRedirectInformation
  386. );
  387. lstrcpyA(
  388. src,
  389. inet_ntoa(*(PIN_ADDR)&SourceMapping.SourceAddress)
  390. );
  391. lstrcpyA(
  392. newsrc,
  393. inet_ntoa(*(PIN_ADDR)&SourceMapping.NewSourceAddress)
  394. );
  395. Length = sizeof(DestinationMapping);
  396. NatQueryInformationPortRedirect(
  397. TranslatorHandle,
  398. (UCHAR)atol(argv[2]),
  399. htons((USHORT)atol(argv[3])),
  400. inet_addr(argv[4]),
  401. htons((USHORT)atol(argv[5])),
  402. &DestinationMapping,
  403. &Length,
  404. NatDestinationMappingRedirectInformation
  405. );
  406. lstrcpyA(
  407. dst,
  408. inet_ntoa(*(PIN_ADDR)&DestinationMapping.DestinationAddress)
  409. );
  410. lstrcpyA(
  411. newdst,
  412. inet_ntoa(*(PIN_ADDR)&DestinationMapping.NewDestinationAddress)
  413. );
  414. printf("redirect activated: %s:%s->%s:%s\n", src, dst, newsrc, newdst);
  415. }
  416. if (_kbhit()) {
  417. switch(getchar()) {
  418. case 'q': { break; }
  419. case 's': {
  420. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  421. ULONG Length = sizeof(ByteCount);
  422. NatQueryInformationPortRedirect(
  423. TranslatorHandle,
  424. (UCHAR)atol(argv[2]),
  425. htons((USHORT)atol(argv[3])),
  426. inet_addr(argv[4]),
  427. htons((USHORT)atol(argv[5])),
  428. &ByteCount,
  429. &Length,
  430. NatByteCountRedirectInformation
  431. );
  432. printf(
  433. "NatQueryInformationPortRedirect="
  434. "%d,{%I64d,%I64d}\n",
  435. Error,
  436. ByteCount.BytesForward,
  437. ByteCount.BytesReverse
  438. );
  439. // fall-through
  440. }
  441. default: continue;
  442. }
  443. break;
  444. }
  445. }
  446. if (Error != WAIT_IO_COMPLETION) {
  447. Error =
  448. NatCancelPortRedirect(
  449. TranslatorHandle,
  450. (UCHAR)atol(argv[2]),
  451. htons((USHORT)atol(argv[3])),
  452. inet_addr(argv[4]),
  453. htons((USHORT)atol(argv[5]))
  454. );
  455. printf("NatCancelPortRedirect=%d\n", Error);
  456. }
  457. }
  458. printf("NatShutdownTranslator...");
  459. NatShutdownTranslator(TranslatorHandle);
  460. printf("done\n");
  461. }
  462. VOID
  463. TestReceiveOnlyPortRedirect(
  464. int argc,
  465. char* argv[]
  466. )
  467. {
  468. ULONG Error;
  469. HANDLE TranslatorHandle;
  470. Error = NatInitializeTranslator(&TranslatorHandle);
  471. if (Error) {
  472. printf("NatInitializeTranslator=%d\n", Error);
  473. return;
  474. }
  475. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  476. Error =
  477. NatCreatePortRedirect(
  478. TranslatorHandle,
  479. NatRedirectFlagReceiveOnly,
  480. (UCHAR)atol(argv[2]),
  481. htons((USHORT)atol(argv[3])),
  482. inet_addr(argv[4]),
  483. htons((USHORT)atol(argv[5])),
  484. TestApiCompletionRoutine,
  485. NULL,
  486. Event
  487. );
  488. printf("NatCreatePortRedirect=%d\n", Error);
  489. if (!Error) {
  490. for (;;) {
  491. Error = WaitForSingleObjectEx(Event, 1000, TRUE);
  492. printf("WaitForSingleObjectEx=%d\n", Error);
  493. if (Error == WAIT_IO_COMPLETION) {
  494. break;
  495. } else if (Error == WAIT_OBJECT_0) {
  496. NAT_SOURCE_MAPPING_REDIRECT_INFORMATION SourceMapping;
  497. NAT_DESTINATION_MAPPING_REDIRECT_INFORMATION DestinationMapping;
  498. ULONG Length;
  499. CHAR src[32], newsrc[32], dst[32], newdst[32];
  500. Length = sizeof(SourceMapping);
  501. NatQueryInformationPortRedirect(
  502. TranslatorHandle,
  503. (UCHAR)atol(argv[2]),
  504. htons((USHORT)atol(argv[3])),
  505. inet_addr(argv[4]),
  506. htons((USHORT)atol(argv[5])),
  507. &SourceMapping,
  508. &Length,
  509. NatSourceMappingRedirectInformation
  510. );
  511. lstrcpyA(
  512. src,
  513. inet_ntoa(*(PIN_ADDR)&SourceMapping.SourceAddress)
  514. );
  515. lstrcpyA(
  516. newsrc,
  517. inet_ntoa(*(PIN_ADDR)&SourceMapping.NewSourceAddress)
  518. );
  519. Length = sizeof(DestinationMapping);
  520. NatQueryInformationPortRedirect(
  521. TranslatorHandle,
  522. (UCHAR)atol(argv[2]),
  523. htons((USHORT)atol(argv[3])),
  524. inet_addr(argv[4]),
  525. htons((USHORT)atol(argv[5])),
  526. &DestinationMapping,
  527. &Length,
  528. NatDestinationMappingRedirectInformation
  529. );
  530. lstrcpyA(
  531. dst,
  532. inet_ntoa(*(PIN_ADDR)&DestinationMapping.DestinationAddress)
  533. );
  534. lstrcpyA(
  535. newdst,
  536. inet_ntoa(*(PIN_ADDR)&DestinationMapping.NewDestinationAddress)
  537. );
  538. printf("redirect activated: %s:%s->%s:%s\n", src, dst, newsrc, newdst);
  539. }
  540. if (_kbhit()) {
  541. switch(getchar()) {
  542. case 'q': { break; }
  543. case 's': {
  544. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  545. ULONG Length = sizeof(ByteCount);
  546. NatQueryInformationPortRedirect(
  547. TranslatorHandle,
  548. (UCHAR)atol(argv[2]),
  549. htons((USHORT)atol(argv[3])),
  550. inet_addr(argv[4]),
  551. htons((USHORT)atol(argv[5])),
  552. &ByteCount,
  553. &Length,
  554. NatByteCountRedirectInformation
  555. );
  556. printf(
  557. "NatQueryInformationPortRedirect="
  558. "%d,{%I64d,%I64d}\n",
  559. Error,
  560. ByteCount.BytesForward,
  561. ByteCount.BytesReverse
  562. );
  563. // fall-through
  564. }
  565. default: continue;
  566. }
  567. break;
  568. }
  569. }
  570. if (Error != WAIT_IO_COMPLETION) {
  571. Error =
  572. NatCancelPortRedirect(
  573. TranslatorHandle,
  574. (UCHAR)atol(argv[2]),
  575. htons((USHORT)atol(argv[3])),
  576. inet_addr(argv[4]),
  577. htons((USHORT)atol(argv[5]))
  578. );
  579. printf("NatCancelPortRedirect=%d\n", Error);
  580. }
  581. }
  582. printf("NatShutdownTranslator...");
  583. NatShutdownTranslator(TranslatorHandle);
  584. printf("done\n");
  585. }
  586. VOID
  587. TestReceiveOnlyDynamicPartialRedirect(
  588. int argc,
  589. char* argv[]
  590. )
  591. {
  592. ULONG Error;
  593. HANDLE DynamicRedirectHandle;
  594. Error =
  595. NatCreateDynamicPartialRedirect(
  596. NatRedirectFlagReceiveOnly,
  597. (UCHAR)atol(argv[2]),
  598. inet_addr(argv[3]),
  599. htons((USHORT)atol(argv[4])),
  600. inet_addr(argv[5]),
  601. htons((USHORT)atol(argv[6])),
  602. atol(argv[7]),
  603. &DynamicRedirectHandle
  604. );
  605. printf("NatCreateDynamicPartialRedirect=%d\n", Error);
  606. if (!Error) {
  607. printf("Press <Enter> to cancel the dynamic redirect...");
  608. while (!_kbhit()) { Sleep(1000); }
  609. Error = NatCancelDynamicPartialRedirect(DynamicRedirectHandle);
  610. printf("NatCancelDynamicPartialRedirect=%d\n", Error);
  611. }
  612. printf("done\n");
  613. }
  614. VOID
  615. TestReceiveOnlyDynamicPortRedirect(
  616. int argc,
  617. char* argv[]
  618. )
  619. {
  620. ULONG Error;
  621. HANDLE DynamicRedirectHandle;
  622. Error =
  623. NatCreateDynamicPortRedirect(
  624. NatRedirectFlagReceiveOnly,
  625. (UCHAR)atol(argv[2]),
  626. htons((USHORT)atol(argv[3])),
  627. inet_addr(argv[4]),
  628. htons((USHORT)atol(argv[5])),
  629. atol(argv[6]),
  630. &DynamicRedirectHandle
  631. );
  632. printf("NatCreateDynamicPortRedirect=%d\n", Error);
  633. if (!Error) {
  634. printf("Press <Enter> to cancel the dynamic redirect...");
  635. while (!_kbhit()) { Sleep(1000); }
  636. Error = NatCancelDynamicPortRedirect(DynamicRedirectHandle);
  637. printf("NatCancelDynamicPortRedirect=%d\n", Error);
  638. }
  639. printf("done\n");
  640. }
  641. VOID
  642. TestRestrictedPartialRedirect(
  643. int argc,
  644. char* argv[]
  645. )
  646. {
  647. ULONG Error;
  648. HANDLE TranslatorHandle;
  649. Error = NatInitializeTranslator(&TranslatorHandle);
  650. if (Error) {
  651. printf("NatInitializeTranslator=%d\n", Error);
  652. return;
  653. }
  654. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  655. Error =
  656. NatCreateRestrictedPartialRedirect(
  657. TranslatorHandle,
  658. 0,
  659. (UCHAR)atol(argv[2]),
  660. inet_addr(argv[3]),
  661. htons((USHORT)atol(argv[4])),
  662. inet_addr(argv[5]),
  663. htons((USHORT)atol(argv[6])),
  664. inet_addr(argv[7]),
  665. TestApiCompletionRoutine,
  666. NULL,
  667. Event
  668. );
  669. printf("NatCreateRestrictedPartialRedirect=%d\n", Error);
  670. if (!Error) {
  671. for (;;) {
  672. Error = WaitForSingleObjectEx(Event, 1000, TRUE);
  673. printf("WaitForSingleObjectEx=%d\n", Error);
  674. if (Error == WAIT_IO_COMPLETION) {
  675. break;
  676. } else if (Error == WAIT_OBJECT_0) {
  677. NAT_SOURCE_MAPPING_REDIRECT_INFORMATION SourceMapping;
  678. ULONG Length = sizeof(SourceMapping);
  679. CHAR src[32], newsrc[32];
  680. NatQueryInformationPartialRedirect(
  681. TranslatorHandle,
  682. (UCHAR)atol(argv[2]),
  683. inet_addr(argv[3]),
  684. htons((USHORT)atol(argv[4])),
  685. inet_addr(argv[5]),
  686. htons((USHORT)atol(argv[6])),
  687. &SourceMapping,
  688. &Length,
  689. NatSourceMappingRedirectInformation
  690. );
  691. lstrcpyA(
  692. src,
  693. inet_ntoa(*(PIN_ADDR)&SourceMapping.SourceAddress)
  694. );
  695. lstrcpyA(
  696. newsrc,
  697. inet_ntoa(*(PIN_ADDR)&SourceMapping.NewSourceAddress)
  698. );
  699. printf("redirect activated: %s->%s\n", src, newsrc);
  700. }
  701. if (_kbhit()) {
  702. switch(getchar()) {
  703. case 'q': { break; }
  704. case 's': {
  705. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  706. ULONG Length = sizeof(ByteCount);
  707. NatQueryInformationPartialRedirect(
  708. TranslatorHandle,
  709. (UCHAR)atol(argv[2]),
  710. inet_addr(argv[3]),
  711. htons((USHORT)atol(argv[4])),
  712. inet_addr(argv[5]),
  713. htons((USHORT)atol(argv[6])),
  714. &ByteCount,
  715. &Length,
  716. NatByteCountRedirectInformation
  717. );
  718. printf(
  719. "NatQueryInformationPartialRedirect="
  720. "%d,{%I64d,%I64d}\n",
  721. Error,
  722. ByteCount.BytesForward,
  723. ByteCount.BytesReverse
  724. );
  725. // fall-through
  726. }
  727. default: continue;
  728. }
  729. break;
  730. }
  731. }
  732. if (Error != WAIT_IO_COMPLETION) {
  733. Error =
  734. NatCancelPartialRedirect(
  735. TranslatorHandle,
  736. (UCHAR)atol(argv[2]),
  737. inet_addr(argv[3]),
  738. htons((USHORT)atol(argv[4])),
  739. inet_addr(argv[5]),
  740. htons((USHORT)atol(argv[6]))
  741. );
  742. printf("NatCancelPartialRedirect=%d\n", Error);
  743. }
  744. }
  745. printf("NatShutdownTranslator...");
  746. NatShutdownTranslator(TranslatorHandle);
  747. printf("done\n");
  748. }
  749. VOID
  750. TestDuplicateRedirect(
  751. int argc,
  752. char* argv[]
  753. )
  754. {
  755. #define REDIRECT_COUNT 5
  756. ULONG Count;
  757. ULONG Error;
  758. HANDLE EventHandle[REDIRECT_COUNT];
  759. ULONG i;
  760. HANDLE TranslatorHandle;
  761. Error = NatInitializeTranslator(&TranslatorHandle);
  762. if (Error) {
  763. printf("NatInitializeTranslator=%d\n", Error);
  764. return;
  765. }
  766. for (i = 0, Count = 0; i < REDIRECT_COUNT; i++) {
  767. EventHandle[i] = CreateEvent(NULL, FALSE, FALSE, NULL);
  768. Error =
  769. NatCreateRedirect(
  770. TranslatorHandle,
  771. 0,
  772. (UCHAR)atol(argv[2]),
  773. inet_addr(argv[3]),
  774. htons((USHORT)atol(argv[4])),
  775. 0,
  776. 0,
  777. inet_addr(argv[5]),
  778. htons((USHORT)atol(argv[6])),
  779. inet_addr(argv[7]),
  780. htons((USHORT)(atol(argv[8]) + i)),
  781. TestApiCompletionRoutine,
  782. NULL,
  783. EventHandle[i]
  784. );
  785. printf("NatCreateRedirect=%d\n", Error);
  786. if (!Error) { ++Count; }
  787. }
  788. for (;;) {
  789. ULONG Error2;
  790. Error =
  791. WaitForMultipleObjectsEx(
  792. REDIRECT_COUNT,
  793. EventHandle,
  794. FALSE,
  795. 1000,
  796. TRUE
  797. );
  798. printf("WaitForSingleObjectEx=%d\n", Error);
  799. if (Error == WAIT_IO_COMPLETION) {
  800. if (!--Count) { break; }
  801. } else if ((Error - WAIT_OBJECT_0) < REDIRECT_COUNT) {
  802. NAT_KEY_SESSION_MAPPING_INFORMATION Key;
  803. ULONG Length = sizeof(Key);
  804. CHAR src[32], newsrc[32];
  805. i = Error - WAIT_OBJECT_0;
  806. Error2 =
  807. NatLookupAndQueryInformationSessionMapping(
  808. TranslatorHandle,
  809. (UCHAR)atol(argv[2]),
  810. inet_addr(argv[5]),
  811. htons((USHORT)atol(argv[6])),
  812. inet_addr(argv[7]),
  813. htons((USHORT)(atol(argv[8]) + i)),
  814. &Key,
  815. &Length,
  816. NatKeySessionMappingInformation
  817. );
  818. lstrcpyA(
  819. src,
  820. inet_ntoa(*(PIN_ADDR)&Key.SourceAddress)
  821. );
  822. lstrcpyA(
  823. newsrc,
  824. inet_ntoa(*(PIN_ADDR)&Key.NewSourceAddress)
  825. );
  826. printf("redirect activated[%d]: %s->%s\n", Error2, src, newsrc);
  827. }
  828. if (_kbhit()) {
  829. switch(getchar()) {
  830. case 'q': { break; }
  831. case 's': {
  832. NAT_STATISTICS_SESSION_MAPPING_INFORMATION Statistics;
  833. for (i = 0; i < REDIRECT_COUNT; i++) {
  834. ULONG Length = sizeof(Statistics);
  835. Error2 =
  836. NatLookupAndQueryInformationSessionMapping(
  837. TranslatorHandle,
  838. (UCHAR)atol(argv[2]),
  839. inet_addr(argv[5]),
  840. htons((USHORT)atol(argv[6])),
  841. inet_addr(argv[7]),
  842. htons((USHORT)(atol(argv[8]) + i)),
  843. &Statistics,
  844. &Length,
  845. NatStatisticsSessionMappingInformation
  846. );
  847. printf(
  848. "NatLookupAndQueryInformationSessionMapping=%d,{%I64d,%I64d}\n",
  849. Error2,
  850. Statistics.BytesForward,
  851. Statistics.BytesReverse
  852. );
  853. }
  854. // fall-through
  855. }
  856. default: continue;
  857. }
  858. break;
  859. }
  860. }
  861. if (Error != WAIT_IO_COMPLETION) {
  862. for (i = 0; i < REDIRECT_COUNT; i++) {
  863. Error =
  864. NatCancelRedirect(
  865. TranslatorHandle,
  866. (UCHAR)atol(argv[2]),
  867. inet_addr(argv[3]),
  868. htons((USHORT)atol(argv[4])),
  869. 0,
  870. 0,
  871. inet_addr(argv[5]),
  872. htons((USHORT)atol(argv[6])),
  873. inet_addr(argv[7]),
  874. htons((USHORT)(atol(argv[8]) + i))
  875. );
  876. printf("NatCancelRedirect=%d\n", Error);
  877. }
  878. }
  879. printf("NatShutdownTranslator...");
  880. NatShutdownTranslator(TranslatorHandle);
  881. printf("done\n");
  882. }
  883. VOID
  884. TestDatagramIo(
  885. int argc,
  886. char* argv[]
  887. )
  888. {
  889. SOCKET Socket;
  890. NhInitializeTraceManagement();
  891. NhInitializeBufferManagement();
  892. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  893. if (lstrcmpiA(argv[1], "-s") == 0) {
  894. NhCreateDatagramSocket(
  895. inet_addr(argv[2]),
  896. htons(1000),
  897. &Socket
  898. );
  899. NhReadDatagramSocket(
  900. NULL,
  901. Socket,
  902. NULL,
  903. ReadCompletionRoutine,
  904. NULL,
  905. NULL
  906. );
  907. } else if (lstrcmpiA(argv[1], "-c") == 0) {
  908. PNH_BUFFER Bufferp;
  909. NhCreateDatagramSocket(
  910. inet_addr(argv[2]),
  911. 0,
  912. &Socket
  913. );
  914. Bufferp = NhAcquireBuffer();
  915. lstrcpyA(Bufferp->Buffer, "client-to-server message");
  916. NhWriteDatagramSocket(
  917. NULL,
  918. Socket,
  919. inet_addr(argv[3]),
  920. htons(1000),
  921. Bufferp,
  922. lstrlenA(Bufferp->Buffer),
  923. WriteCompletionRoutine,
  924. NULL,
  925. NULL
  926. );
  927. }
  928. WaitForSingleObject(Event, INFINITE);
  929. NhDeleteDatagramSocket(Socket);
  930. }
  931. VOID
  932. TestStreamIo(
  933. int argc,
  934. char* argv[]
  935. )
  936. {
  937. SOCKET AcceptedSocket;
  938. ULONG Error;
  939. SOCKET ListeningSocket;
  940. NhInitializeTraceManagement();
  941. NhInitializeBufferManagement();
  942. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  943. Error = NhCreateStreamSocket(INADDR_ANY, htons(1000), &ListeningSocket);
  944. if (Error != NO_ERROR) {
  945. printf("error %d creating listening socket\n", Error);
  946. } else {
  947. Error = NhCreateStreamSocket(INADDR_NONE, 0, &AcceptedSocket);
  948. if (Error != NO_ERROR) {
  949. printf("error %d creating accepted socket\n", Error);
  950. } else {
  951. Error = listen(ListeningSocket, SOMAXCONN);
  952. if (Error == SOCKET_ERROR) {
  953. printf("error %d listening on socket\n", WSAGetLastError());
  954. } else {
  955. Error =
  956. NhAcceptStreamSocket(
  957. NULL,
  958. ListeningSocket,
  959. AcceptedSocket,
  960. NULL,
  961. AcceptCompletionRoutine,
  962. (PVOID)ListeningSocket,
  963. (PVOID)AcceptedSocket
  964. );
  965. if (Error != NO_ERROR) {
  966. printf("error %d accepting on socket\n", WSAGetLastError());
  967. } else {
  968. WaitForSingleObject(Event, INFINITE);
  969. }
  970. }
  971. NhDeleteStreamSocket(AcceptedSocket);
  972. }
  973. NhDeleteStreamSocket(ListeningSocket);
  974. }
  975. }
  976. VOID
  977. TestNotification(
  978. int argc,
  979. char* argv[]
  980. )
  981. {
  982. ULONG Error;
  983. HANDLE TranslatorHandle;
  984. IO_STATUS_BLOCK IoStatus;
  985. IP_NAT_REQUEST_NOTIFICATION RequestNotification;
  986. IP_NAT_ROUTING_FAILURE_NOTIFICATION RoutingFailureNotification;
  987. NTSTATUS status;
  988. Error = NatInitializeTranslator(&TranslatorHandle);
  989. if (Error) {
  990. printf("NatInitializeTranslator=%d\n", Error);
  991. return;
  992. }
  993. printf("waiting for notification...");
  994. RequestNotification.Code = NatRoutingFailureNotification;
  995. status =
  996. NtDeviceIoControlFile(
  997. TranslatorHandle,
  998. NULL,
  999. NULL,
  1000. NULL,
  1001. &IoStatus,
  1002. IOCTL_IP_NAT_REQUEST_NOTIFICATION,
  1003. (PVOID)&RequestNotification,
  1004. sizeof(RequestNotification),
  1005. &RoutingFailureNotification,
  1006. sizeof(RoutingFailureNotification)
  1007. );
  1008. if (status == STATUS_PENDING) {
  1009. NtWaitForSingleObject(TranslatorHandle, FALSE, NULL);
  1010. status = IoStatus.Status;
  1011. }
  1012. {
  1013. CHAR address[32];
  1014. lstrcpyA(
  1015. address,
  1016. inet_ntoa(*(PIN_ADDR)&RoutingFailureNotification.DestinationAddress)
  1017. );
  1018. printf(
  1019. "status=%x,destination=%s,source=%s\n", status, address,
  1020. inet_ntoa(*(PIN_ADDR)&RoutingFailureNotification.SourceAddress)
  1021. );
  1022. }
  1023. printf("NatShutdownTranslator...");
  1024. NatShutdownTranslator(TranslatorHandle);
  1025. printf("done\n");
  1026. }
  1027. VOID
  1028. TestIoCompletionPartialRedirect(
  1029. int argc,
  1030. char* argv[]
  1031. )
  1032. {
  1033. IP_NAT_CREATE_REDIRECT CreateRedirect;
  1034. ULONG Error;
  1035. FILE_COMPLETION_INFORMATION CompletionInformation;
  1036. HANDLE IoCompletionHandle;
  1037. IO_STATUS_BLOCK IoStatus;
  1038. IP_NAT_REDIRECT_STATISTICS RedirectStatistics;
  1039. NTSTATUS status;
  1040. HANDLE TranslatorHandle;
  1041. Error = NatInitializeTranslator(&TranslatorHandle);
  1042. if (Error) {
  1043. printf("NatInitializeTranslator=%d\n", Error);
  1044. return;
  1045. }
  1046. Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  1047. status =
  1048. NtCreateIoCompletion(
  1049. &IoCompletionHandle,
  1050. IO_COMPLETION_ALL_ACCESS,
  1051. NULL,
  1052. 0
  1053. );
  1054. if (!NT_SUCCESS(status)) {
  1055. printf("NtCreateIoCompletion=%x\n", status);
  1056. return;
  1057. }
  1058. CompletionInformation.Port = IoCompletionHandle;
  1059. CompletionInformation.Key = (PVOID)0xAB01ADE9;
  1060. status =
  1061. NtSetInformationFile(
  1062. TranslatorHandle,
  1063. &IoStatus,
  1064. &CompletionInformation,
  1065. sizeof(CompletionInformation),
  1066. FileCompletionInformation
  1067. );
  1068. if (!NT_SUCCESS(status)) {
  1069. printf("NtSetInformationFile=%x\n", status);
  1070. return;
  1071. }
  1072. ZeroMemory(&CreateRedirect, sizeof(CreateRedirect));
  1073. CreateRedirect.Flags =
  1074. IP_NAT_REDIRECT_FLAG_ASYNCHRONOUS|
  1075. IP_NAT_REDIRECT_FLAG_IO_COMPLETION;
  1076. CreateRedirect.Protocol = (UCHAR)atol(argv[2]);
  1077. CreateRedirect.DestinationAddress = inet_addr(argv[3]);
  1078. CreateRedirect.DestinationPort = htons((USHORT)atol(argv[4]));
  1079. CreateRedirect.NewDestinationAddress = inet_addr(argv[5]);
  1080. CreateRedirect.NewDestinationPort = htons((USHORT)atol(argv[6]));
  1081. status =
  1082. NtDeviceIoControlFile(
  1083. TranslatorHandle,
  1084. Event,
  1085. NULL,
  1086. (PVOID)0x12345678,
  1087. &IoStatus,
  1088. IOCTL_IP_NAT_CREATE_REDIRECT,
  1089. &CreateRedirect,
  1090. sizeof(CreateRedirect),
  1091. &RedirectStatistics,
  1092. sizeof(RedirectStatistics)
  1093. );
  1094. if (status != STATUS_PENDING) {
  1095. printf("NtDeviceIoControlFile=%x\n", status);
  1096. } else {
  1097. PVOID ApcContext;
  1098. PVOID KeyContext;
  1099. LARGE_INTEGER Timeout;
  1100. Timeout.LowPart = (1000 * 1000 * 10);
  1101. Timeout.HighPart = 0;
  1102. Timeout = RtlLargeIntegerNegate(Timeout);
  1103. IoStatus.Status = STATUS_CANCELLED;
  1104. for (;;) {
  1105. status =
  1106. NtRemoveIoCompletion(
  1107. IoCompletionHandle,
  1108. &KeyContext,
  1109. &ApcContext,
  1110. &IoStatus,
  1111. &Timeout
  1112. );
  1113. printf("NtRemoveIoCompletion=%x\n", status);
  1114. if (status == STATUS_SUCCESS &&
  1115. IoStatus.Status != STATUS_PENDING) {
  1116. //
  1117. // Redirect completed.
  1118. //
  1119. printf("redirect %x:%x completed\n", KeyContext, ApcContext);
  1120. break;
  1121. } else if (status == STATUS_SUCCESS &&
  1122. IoStatus.Status == STATUS_PENDING) {
  1123. NAT_SOURCE_MAPPING_REDIRECT_INFORMATION SourceMapping;
  1124. ULONG Length = sizeof(SourceMapping);
  1125. CHAR src[32], newsrc[32];
  1126. //
  1127. // Redirect is activated.
  1128. //
  1129. NatQueryInformationPartialRedirect(
  1130. TranslatorHandle,
  1131. (UCHAR)atol(argv[2]),
  1132. inet_addr(argv[3]),
  1133. htons((USHORT)atol(argv[4])),
  1134. inet_addr(argv[5]),
  1135. htons((USHORT)atol(argv[6])),
  1136. &SourceMapping,
  1137. &Length,
  1138. NatSourceMappingRedirectInformation
  1139. );
  1140. lstrcpyA(
  1141. src,
  1142. inet_ntoa(*(PIN_ADDR)&SourceMapping.SourceAddress)
  1143. );
  1144. lstrcpyA(
  1145. newsrc,
  1146. inet_ntoa(*(PIN_ADDR)&SourceMapping.NewSourceAddress)
  1147. );
  1148. printf(
  1149. "redirect %x:%x activated: %s->%s\n",
  1150. KeyContext, ApcContext, src, newsrc
  1151. );
  1152. }
  1153. if (_kbhit()) {
  1154. switch(getchar()) {
  1155. case 'q': { break; }
  1156. case 's': {
  1157. NAT_BYTE_COUNT_REDIRECT_INFORMATION ByteCount;
  1158. ULONG Length = sizeof(ByteCount);
  1159. NatQueryInformationPartialRedirect(
  1160. TranslatorHandle,
  1161. (UCHAR)atol(argv[2]),
  1162. inet_addr(argv[3]),
  1163. htons((USHORT)atol(argv[4])),
  1164. inet_addr(argv[5]),
  1165. htons((USHORT)atol(argv[6])),
  1166. &ByteCount,
  1167. &Length,
  1168. NatByteCountRedirectInformation
  1169. );
  1170. printf(
  1171. "NatQueryInformationPartialRedirect="
  1172. "%d,{%I64d,%I64d}\n",
  1173. Error,
  1174. ByteCount.BytesForward,
  1175. ByteCount.BytesReverse
  1176. );
  1177. // fall-through
  1178. }
  1179. default: continue;
  1180. }
  1181. break;
  1182. }
  1183. }
  1184. if (status != STATUS_SUCCESS) {
  1185. Error =
  1186. NatCancelPartialRedirect(
  1187. TranslatorHandle,
  1188. (UCHAR)atol(argv[2]),
  1189. inet_addr(argv[3]),
  1190. htons((USHORT)atol(argv[4])),
  1191. inet_addr(argv[5]),
  1192. htons((USHORT)atol(argv[6]))
  1193. );
  1194. printf("NatCancelPartialRedirect=%d\n", Error);
  1195. }
  1196. }
  1197. printf("NatShutdownTranslator...");
  1198. NatShutdownTranslator(TranslatorHandle);
  1199. NtClose(IoCompletionHandle);
  1200. printf("done\n");
  1201. }
  1202. VOID
  1203. TestPortReservation(
  1204. int argc,
  1205. char* argv[]
  1206. )
  1207. {
  1208. HANDLE ReservationHandle;
  1209. for (;;) {
  1210. enum {
  1211. PrInitialize,
  1212. PrAcquire,
  1213. PrRelease,
  1214. PrQuit
  1215. } PrOption;
  1216. NTSTATUS Status;
  1217. printf("Options:\n");
  1218. printf("%d - initialize\n", PrInitialize);
  1219. printf("%d - acquire ports\n", PrAcquire);
  1220. printf("%d - release ports\n", PrRelease);
  1221. printf("%d - quit\n", PrQuit);
  1222. printf("> ");
  1223. scanf("%d", &PrOption);
  1224. switch(PrOption) {
  1225. case PrInitialize: {
  1226. USHORT BlockSize;
  1227. printf("enter block size: ");
  1228. scanf("%u", &BlockSize);
  1229. Status =
  1230. NatInitializePortReservation(BlockSize, &ReservationHandle);
  1231. if (NT_SUCCESS(Status)) {
  1232. printf("succeeded.\n");
  1233. } else {
  1234. printf("status: %x\n", Status);
  1235. }
  1236. break;
  1237. }
  1238. case PrAcquire: {
  1239. USHORT PortBase;
  1240. USHORT PortCount;
  1241. printf("enter port count: ");
  1242. scanf("%u", &PortCount);
  1243. Status =
  1244. NatAcquirePortReservation(
  1245. ReservationHandle, PortCount, &PortBase
  1246. );
  1247. if (NT_SUCCESS(Status)) {
  1248. printf("succeeded: base port %d\n", ntohs(PortBase));
  1249. } else {
  1250. printf("status: %x\n", Status);
  1251. }
  1252. break;
  1253. }
  1254. case PrRelease: {
  1255. USHORT PortBase;
  1256. USHORT PortCount;
  1257. printf("enter base port: ");
  1258. scanf("%u", &PortBase);
  1259. printf("enter port count: ");
  1260. scanf("%u", &PortCount);
  1261. Status =
  1262. NatReleasePortReservation(
  1263. ReservationHandle, ntohs(PortBase), PortCount
  1264. );
  1265. if (NT_SUCCESS(Status)) {
  1266. printf("succeeded\n", ntohs(PortBase));
  1267. } else {
  1268. printf("status: %x\n", Status);
  1269. }
  1270. break;
  1271. }
  1272. case PrQuit: {
  1273. NatShutdownPortReservation(ReservationHandle);
  1274. break;
  1275. }
  1276. }
  1277. }
  1278. }
  1279. int __cdecl
  1280. main(
  1281. int argc,
  1282. char* argv[]
  1283. )
  1284. {
  1285. WSADATA wd;
  1286. WSAStartup(MAKEWORD(2,2), &wd);
  1287. if (!lstrcmpiA(argv[1], "-accept") && argc == 2) {
  1288. TestStreamIo(argc, argv);
  1289. } else if (!lstrcmpiA(argv[1], "-c") && argc == 4) {
  1290. TestDatagramIo(argc, argv);
  1291. } else if (!lstrcmpiA(argv[1], "-s") && argc == 3) {
  1292. TestDatagramIo(argc, argv);
  1293. } else if (!lstrcmpiA(argv[1], "-n") && argc == 2) {
  1294. TestNotification(argc, argv);
  1295. } else if (!lstrcmpiA(argv[1], "-r") && argc == 11) {
  1296. TestRedirect(argc, argv);
  1297. } else if (!lstrcmpiA(argv[1], "-p") && argc == 7) {
  1298. TestPartialRedirect(argc, argv);
  1299. } else if (!lstrcmpiA(argv[1], "-port") && argc == 6) {
  1300. TestPortRedirect(argc, argv);
  1301. } else if (!lstrcmpiA(argv[1], "-rcvport") && argc == 6) {
  1302. TestReceiveOnlyPortRedirect(argc, argv);
  1303. } else if (!lstrcmpiA(argv[1], "-rp") && argc == 8) {
  1304. TestRestrictedPartialRedirect(argc, argv);
  1305. } else if (!lstrcmpiA(argv[1], "-m") && argc == 9) {
  1306. TestDuplicateRedirect(argc, argv);
  1307. } else if (!lstrcmpiA(argv[1], "-iop") && argc == 7) {
  1308. TestIoCompletionPartialRedirect(argc, argv);
  1309. } else if (!lstrcmpiA(argv[1], "-portreservation") && argc == 2) {
  1310. TestPortReservation(argc, argv);
  1311. } else if (!lstrcmpiA(argv[1], "-rcvdynport") && argc == 7) {
  1312. TestReceiveOnlyDynamicPortRedirect(argc, argv);
  1313. } else if (!lstrcmpiA(argv[1], "-rcvdynp") && argc == 7) {
  1314. TestReceiveOnlyDynamicPartialRedirect(argc, argv);
  1315. } else {
  1316. printf("'nhtest -accept' to test connection-acceptance\n");
  1317. printf("'nhtest -c <client-addr> <server-addr>' to start client\n");
  1318. printf("'nhtest -s <server-addr>' to start server\n");
  1319. printf("'nhtest -n' to wait for notification of routing-failure\n");
  1320. printf("'nhtest -r <p> <da> <dp> <sa> <sp> <da> <dp> <sa> <sp>'\n");
  1321. printf(" creates a full-redirect and waits for activation.\n");
  1322. printf("'nhtest -p <p> <da> <dp> <da> <dp>'\n");
  1323. printf(" creates a partial-redirect and waits for activation.\n");
  1324. printf("'nhtest -port <p> <dp> <da> <dp>'\n");
  1325. printf(" creates a port-redirect and waits for activation.\n");
  1326. printf("'nhtest -rcvport <p> <dp> <da> <dp>'\n");
  1327. printf(" creates a port-redirect for received-packets only\n");
  1328. printf(" and waits for activation.\n");
  1329. printf("'nhtest -rp <p> <da> <dp> <da> <dp> <sa>'\n");
  1330. printf(" creates a restricted partial-redirect\n");
  1331. printf(" and waits for activation.\n");
  1332. printf("'nhtest -m <p> <da> <dp> <da> <dp> <sa> <sp>'\n");
  1333. printf(" creates multiple redirects with the same parameters,\n");
  1334. printf(" and waits for activation.\n");
  1335. printf("'nhtest -iop <p> <da> <dp> <da> <dp>'\n");
  1336. printf(" creates a restricted partial-redirect,\n");
  1337. printf(" associates it with an I/O completion port,\n");
  1338. printf(" and waits for activation.\n");
  1339. printf("'nhtest -portreservation'\n");
  1340. printf(" launches interactive port-reservation API test shell\n");
  1341. printf("'nhtest -rcvdynport <p> <dp> <da> <dp> <backlog>'\n");
  1342. printf(" creates a dynamic port-redirect for received-packets\n");
  1343. printf(" only and waits for interruption.\n");
  1344. printf("'nhtest -rcvdynp <p> <da> <dp> <da> <dp> <backlog>'\n");
  1345. printf(" creates a dynamic partial-redirect for received-packets\n");
  1346. printf(" only and waits for interruption.\n");
  1347. }
  1348. WSACleanup();
  1349. return 0;
  1350. }