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.

2000 lines
55 KiB

  1. /****************************************************************************
  2. * (c) Copyright 1990, 1993 Micro Computer Systems, Inc. All rights reserved.
  3. *****************************************************************************
  4. *
  5. * Title: IPX/SPX Compatible Source Routing Daemon for Windows NT
  6. *
  7. * Module: ipx/route/ipxroute.c
  8. *
  9. * Version: 1.00.00
  10. *
  11. * Date: 04-08-93
  12. *
  13. * Author: Brian Walker
  14. *
  15. *****************************************************************************
  16. *
  17. * Change Log:
  18. *
  19. * Date DevSFC Comment
  20. * -------- ------ -------------------------------------------------------
  21. * 02-14-95 RamC Added command line options to support displaying
  22. * Router Table, Router Statistics and SAP information.
  23. * Basically a merge of ipxroute and Stefan's rttest.
  24. * 03-12-98 Pmay Added translation of if name to version int the
  25. connections folder.
  26. *****************************************************************************
  27. *
  28. * Functional Description:
  29. *
  30. *
  31. ****************************************************************************/
  32. #include <nt.h>
  33. #include <ntrtl.h>
  34. #include <nturtl.h>
  35. #include <windef.h>
  36. #include <winbase.h>
  37. #include <winnls.h>
  38. #include <winuser.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <ntstapi.h>
  42. #include <nwsap.h>
  43. #include <stropts.h>
  44. #include <mprapi.h>
  45. #include <winnlsp.h>
  46. #include "errno.h"
  47. #include "tdi.h"
  48. #include "isnkrnl.h"
  49. #include "ipxrtmsg.h"
  50. #include "driver.h"
  51. #include "utils.h"
  52. typedef struct _IPX_ROUTE_ENTRY {
  53. UCHAR Network[4];
  54. USHORT NicId;
  55. UCHAR NextRouter[6];
  56. PVOID NdisBindingContext;
  57. USHORT Flags;
  58. USHORT Timer;
  59. UINT Segment;
  60. USHORT TickCount;
  61. USHORT HopCount;
  62. PVOID AlternateRoute[2];
  63. PVOID NicLinkage[2];
  64. struct {
  65. PVOID Linkage[2];
  66. ULONG Reserved[1];
  67. } PRIVATE;
  68. } IPX_ROUTE_ENTRY, * PIPX_ROUTE_ENTRY;
  69. IPX_ROUTE_ENTRY rte;
  70. /** Global Variables **/
  71. int sr_def = 0;
  72. int sr_bcast = 0;
  73. int sr_multi = 0;
  74. int boardnum = 0;
  75. int clear = 0;
  76. int config = 0;
  77. int showtable = 0;
  78. int showservers = 0;
  79. int showstats = 0;
  80. int clearstats = 0;
  81. int ripout = 0;
  82. int resolveguid = 0;
  83. int resolvename = 0;
  84. int servertype;
  85. unsigned long netnum;
  86. char nodeaddr[6]; /* Node address to remove */
  87. HANDLE nwlinkfd;
  88. HANDLE isnipxfd;
  89. HANDLE isnripfd;
  90. char ebuffer[128];
  91. char nwlinkname[] = "\\Device\\Streams\\NWLinkIpx";
  92. wchar_t isnipxname[] = L"\\Device\\NwlnkIpx";
  93. wchar_t isnripname[] = L"\\Device\\Ipxroute";
  94. char pgmname[] = "IPXROUTE";
  95. #define SHOW_ALL_SERVERS 0XFFFF
  96. /** **/
  97. #define INVALID_HANDLE (HANDLE)(-1)
  98. /** Structure to send REMOVE with **/
  99. typedef struct rterem {
  100. int rterem_bnum; /* Board number */
  101. char rterem_node[6]; /* Node to remove */
  102. } rterem;
  103. typedef int (__cdecl * PQSORT_COMPARE)(const void * p0, const void * p1);
  104. /** Internal Function Prototypes **/
  105. extern void print_table(int);
  106. extern void usage(void);
  107. extern void print_version(void);
  108. extern char *print_type(int);
  109. extern int my_strncmp(char *, char *, int);
  110. extern int get_board_num(char *, int *);
  111. extern int get_node_num(char *, char *);
  112. extern int get_server_type(char *, int *);
  113. extern unsigned char get_hex_byte(char *);
  114. extern int get_driver_parms(void);
  115. extern int set_driver_parms(void);
  116. extern int do_strioctl(HANDLE, int, char *, int, int);
  117. extern void remove_address(char *);
  118. extern void clear_table(void);
  119. extern void print_config(void);
  120. extern unsigned long get_emsg(int);
  121. int do_isnipxioctl(HANDLE fd, int cmd, char *datap, int dlen);
  122. unsigned long put_msg(BOOLEAN error, unsigned long MsgNum, ... );
  123. char *load_msg( unsigned long MsgNum, ... );
  124. extern void show_router_table(PHANDLE, PIO_STATUS_BLOCK);
  125. extern void show_stats(HANDLE, PIO_STATUS_BLOCK);
  126. extern void clear_stats(HANDLE, PIO_STATUS_BLOCK);
  127. extern void show_servers(int);
  128. extern void show_ripout(unsigned long);
  129. extern void resolve_guid(char *);
  130. extern void resolve_name(char *);
  131. extern int __cdecl CompareServerNames( void * p0, void * p1);
  132. extern int __cdecl CompareNetNumber( void * p0, void * p1);
  133. /*page*************************************************************
  134. m a i n
  135. This is the main routine that gets executed when a NET START
  136. happens.
  137. Arguments - None
  138. Returns - Nothing
  139. ********************************************************************/
  140. void __cdecl main(int argc, char **argv)
  141. {
  142. char *p;
  143. int todo;
  144. int remove_flag;
  145. UNICODE_STRING FileString;
  146. OBJECT_ATTRIBUTES ObjectAttributes, RouterObjectAttributes;
  147. IO_STATUS_BLOCK IoStatusBlock, RouterIoStatusBlock;
  148. NTSTATUS Status;
  149. // Set language code page to system locale.
  150. SetThreadUILanguage(0);
  151. /** **/
  152. print_version();
  153. /** Open the nwlink driver **/
  154. nwlinkfd = s_open(nwlinkname, 0, 0);
  155. /** Open the isnipx driver **/
  156. RtlInitUnicodeString (&FileString, isnipxname);
  157. InitializeObjectAttributes(
  158. &ObjectAttributes,
  159. &FileString,
  160. OBJ_CASE_INSENSITIVE,
  161. NULL,
  162. NULL);
  163. Status = NtOpenFile(
  164. &isnipxfd,
  165. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  166. &ObjectAttributes,
  167. &IoStatusBlock,
  168. FILE_SHARE_READ | FILE_SHARE_WRITE,
  169. FILE_SYNCHRONOUS_IO_ALERT);
  170. if (!NT_SUCCESS(Status)) {
  171. isnipxfd = INVALID_HANDLE;
  172. put_msg (TRUE, MSG_OPEN_FAILED, "\\Device\\NwlnkIpx");
  173. }
  174. /** Open the isnrip driver **/
  175. RtlInitUnicodeString (&FileString, isnripname);
  176. InitializeObjectAttributes(
  177. &RouterObjectAttributes,
  178. &FileString,
  179. OBJ_CASE_INSENSITIVE,
  180. NULL,
  181. NULL);
  182. Status = NtOpenFile(
  183. &isnripfd,
  184. SYNCHRONIZE | GENERIC_READ,
  185. &RouterObjectAttributes,
  186. &RouterIoStatusBlock,
  187. FILE_SHARE_READ | FILE_SHARE_WRITE,
  188. FILE_SYNCHRONOUS_IO_NONALERT);
  189. if (!NT_SUCCESS(Status)) {
  190. isnripfd = INVALID_HANDLE;
  191. // don't display any error message, but display the
  192. // message that the IPX router is not started when
  193. // the user actually tries to look at the router.
  194. }
  195. if ((nwlinkfd == INVALID_HANDLE) &&
  196. (isnipxfd == INVALID_HANDLE) &&
  197. (isnripfd == INVALID_HANDLE))
  198. {
  199. exit(1);
  200. }
  201. /** Go thru the command line and set it up **/
  202. argc--;
  203. argv++;
  204. /** Parse the command line **/
  205. todo = 0;
  206. remove_flag = 0;
  207. while (argc--) {
  208. /** Uppercase the arg **/
  209. p = *argv;
  210. _strupr(p);
  211. /** Parse the argument **/
  212. //if (!strcmp(p, "CLEAR")) {
  213. // todo = 1;
  214. // clear = 1;
  215. // }
  216. /*else*/ if (!strcmp(p, "DEF")) {
  217. todo = 1;
  218. sr_def = 1;
  219. }
  220. else if (!strcmp(p, "GBR")) {
  221. todo = 1;
  222. sr_bcast = 1;
  223. }
  224. else if (!strcmp(p, "MBR")) {
  225. todo = 1;
  226. sr_multi = 1;
  227. }
  228. else if (!strcmp(p, "CONFIG")) {
  229. todo = 1;
  230. config = 1;
  231. }
  232. else if (!my_strncmp(p, "BOARD=", 6))
  233. get_board_num(p + 6, &boardnum);
  234. else if (!my_strncmp(p, "REMOVE=", 7)) {
  235. remove_flag = 1;
  236. get_node_num(p + 7, nodeaddr);
  237. }
  238. //else if (!strcmp(p, "TABLE")) {
  239. // todo = 1;
  240. // showtable = 1;
  241. // }
  242. else if (!strcmp(p, "SERVERS")) {
  243. todo = 1;
  244. showservers = 1;
  245. /** default is to show all server types **/
  246. servertype = SHOW_ALL_SERVERS;
  247. argv++;
  248. if(argc--) {
  249. p = *argv;
  250. _strupr(p);
  251. if (!my_strncmp(p, "/TYPE=", 6)) {
  252. get_server_type(p + 6, &servertype);
  253. }
  254. else
  255. usage();
  256. }
  257. /** no more arguments - break out of while lop **/
  258. else
  259. break;
  260. }
  261. else if (!strcmp(p, "RIPOUT")) {
  262. todo = 1;
  263. ripout = 1;
  264. /** default look for local network **/
  265. netnum = 0L;
  266. argv++;
  267. if(argc--) {
  268. p = *argv;
  269. netnum = strtoul (p, NULL, 16);
  270. if (netnum == 0)
  271. usage();
  272. }
  273. /** no more arguments - break out of while lop **/
  274. else
  275. break;
  276. }
  277. else if (!strcmp(p, "RESOLVE")) {
  278. argv++;
  279. if(argc--) {
  280. p = *argv;
  281. if (!strcmp(p, "guid")) {
  282. todo = 1;
  283. resolveguid = 1;
  284. argc--;
  285. argv++;
  286. p = *argv;
  287. }
  288. else if (!strcmp(p, "name")) {
  289. todo = 1;
  290. resolvename = 1;
  291. argc--;
  292. argv++;
  293. p = *argv;
  294. }
  295. else
  296. usage();
  297. }
  298. /** no more arguments - break out of while lop **/
  299. else
  300. break;
  301. }
  302. //else if (!strcmp(p, "STATS")) {
  303. // todo = 1;
  304. // /** default is to show the router statistics **/
  305. // showstats = 1;
  306. // argv++;
  307. // if(argc--) {
  308. // p = *argv;
  309. // _strupr(p);
  310. // if (!strcmp(p, "/CLEAR")) {
  311. // clearstats = 1;
  312. // showstats = 0;
  313. // }
  314. // else if (!strcmp(p, "/SHOW")) {
  315. // showstats = 1;
  316. // }
  317. // else
  318. // usage;
  319. // }
  320. // /** no more arguments - break out of while lop **/
  321. // else
  322. // break;
  323. // }
  324. else
  325. usage();
  326. /** Goto the next entry **/
  327. argv++;
  328. }
  329. /** Go update the driver **/
  330. #if 0
  331. printf("todo = %d\n", todo);
  332. printf("remove_flag= %d\n", remove_flag);
  333. printf("Clear flag = %d\n", clear);
  334. printf("Config flag = %d\n", config);
  335. printf("SR_DEF = %d\n", sr_def);
  336. printf("SR_BCAST = %d\n", sr_bcast);
  337. printf("SR_MULTI = %d\n", sr_multi);
  338. printf("Board = %d\n", boardnum);
  339. printf("Node = %02x:%02x:%02x:%02x:%02x:%02x\n",
  340. (unsigned char)nodeaddr[0],
  341. (unsigned char)nodeaddr[1],
  342. (unsigned char)nodeaddr[2],
  343. (unsigned char)nodeaddr[3],
  344. (unsigned char)nodeaddr[4],
  345. (unsigned char)nodeaddr[5]);
  346. #endif
  347. /** If we have a remove - go remove it and leave **/
  348. if (remove_flag)
  349. remove_address(nodeaddr); /* Does not return */
  350. /** If clear - go clear the source routing table **/
  351. if (clear)
  352. clear_table(); /* Does not return */
  353. /** If config - print out config **/
  354. if (config)
  355. print_config(); /* Does not return */
  356. /** If showtable - print out routing table **/
  357. if (showtable)
  358. show_router_table(&isnripfd, &RouterIoStatusBlock); /* Does not return */
  359. /** If showservers - print out selected servers list **/
  360. if (showservers)
  361. show_servers(servertype); /* Does not return */
  362. /** If ripout - rip out and print results **/
  363. if (ripout)
  364. show_ripout(netnum); /* Does not return */
  365. /** If resolveguid - resolve a guid name **/
  366. if (resolveguid)
  367. resolve_guid(p); /* Does not return */
  368. /** If resolvename - resolve a friendly name **/
  369. if (resolvename)
  370. resolve_name(p); /* Does not return */
  371. /** If showstats - print out statistics **/
  372. if (showstats)
  373. show_stats(&isnripfd, &RouterIoStatusBlock); /* Does not return */
  374. /** If clearstats - go clear statistics **/
  375. if (clearstats)
  376. clear_stats(&isnripfd, &RouterIoStatusBlock); /* Does not return */
  377. /** If there is nothing to do - just print out everything **/
  378. if (!todo) {
  379. /** Get the driver parms **/
  380. if (get_driver_parms()) {
  381. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  382. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  383. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  384. exit(1);
  385. }
  386. /** Print out the table (Never comes back) **/
  387. print_table(1);
  388. }
  389. /** Go set the parameters **/
  390. set_driver_parms();
  391. /** Print the table out **/
  392. print_table(0);
  393. /** All Done **/
  394. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  395. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  396. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  397. exit(0);
  398. }
  399. /*page*************************************************************
  400. p r i n t _ t a b l e
  401. Print out the status of the source routing.
  402. Arguments - flag = 0 - Do NOT print the table
  403. 1 - Do print the table (Never returns)
  404. Returns - Nothing
  405. ********************************************************************/
  406. void print_table(int flag)
  407. {
  408. /** Print the information **/
  409. char * ptype;
  410. printf("\n");
  411. ptype = print_type(sr_def);
  412. put_msg (FALSE, MSG_DEFAULT_NODE, ptype);
  413. LocalFree (ptype);
  414. printf("\n");
  415. ptype = print_type(sr_bcast);
  416. put_msg (FALSE, MSG_BROADCAST, ptype);
  417. LocalFree (ptype);
  418. printf("\n");
  419. ptype = print_type(sr_multi);
  420. put_msg (FALSE, MSG_MULTICAST, ptype);
  421. LocalFree (ptype);
  422. printf("\n");
  423. if (!flag)
  424. return;
  425. #if 0
  426. printf("\n");
  427. printf(" Node Address Source Route\n");
  428. printf("\n");
  429. #endif
  430. /** All Done **/
  431. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  432. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  433. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  434. exit(0);
  435. }
  436. /*page*************************************************************
  437. u s a g e
  438. Print the usage message.
  439. Arguments - None
  440. Returns - Nothing
  441. ********************************************************************/
  442. void usage(void)
  443. {
  444. put_msg( FALSE, MSG_USAGE, pgmname );
  445. /** All Done **/
  446. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  447. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  448. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  449. exit(0);
  450. }
  451. /*page*************************************************************
  452. p r i n t _ v e r s i o n
  453. Print the version number
  454. Arguments - None
  455. Returns - Nothing
  456. ********************************************************************/
  457. void print_version(void)
  458. {
  459. printf("\n");
  460. put_msg (FALSE, MSG_VERSION);
  461. return;
  462. }
  463. /*page*************************************************************
  464. p r i n t _ t y p e
  465. Returns the broadcast type given in a string, the caller
  466. must free the string.
  467. Arguments - 0 = SINGLE ROUTE
  468. Else = ALL ROUTES
  469. Returns - Nothing
  470. ********************************************************************/
  471. char *print_type(int flag)
  472. {
  473. if (flag)
  474. return load_msg (MSG_ALL_ROUTE);
  475. else
  476. return load_msg (MSG_SINGLE_ROUTE);
  477. }
  478. /*page*************************************************************
  479. m y _ s t r n c m p
  480. Given a string (p), see if the first len chars are the same
  481. as those of the 2nd string (s).
  482. Arguments - p = Ptr to first string
  483. s = Ptr to 2nd string
  484. len = Length to check
  485. Returns - 0 = Matched
  486. Else = Not matched
  487. ********************************************************************/
  488. int my_strncmp(char *p, char *s, int len)
  489. {
  490. /** **/
  491. while (len--) {
  492. if (*p++ != *s++)
  493. return 1;
  494. }
  495. /** They matched **/
  496. return 0;
  497. }
  498. /*page*************************************************************
  499. g e t _ b o a r d _ n u m
  500. Get the decimal number from the command line
  501. Arguments - p = Ptr to the ASCII number
  502. nump = Store the number here
  503. Returns - 0 = Got the number OK
  504. Else = Bad number
  505. ********************************************************************/
  506. int get_board_num(char *p, int *nump)
  507. {
  508. *nump = atoi(p);
  509. return 0;
  510. }
  511. /*page*************************************************************
  512. g e t _ n o d e _ n u m
  513. Get a node address from the command line
  514. Arguments - p = Ptr to the ASCII number
  515. nodep = Store the node number here
  516. Returns - 0 = Got the number OK
  517. Else = Bad number
  518. ********************************************************************/
  519. int get_node_num(char *p, char *nodep)
  520. {
  521. int i;
  522. unsigned char c1;
  523. unsigned char c2;
  524. /** **/
  525. if (strlen(p) != 12) {
  526. put_msg (TRUE, MSG_INVALID_REMOVE);
  527. exit(1);
  528. }
  529. /** Get the number **/
  530. for (i = 0 ; i < 6 ; i++) {
  531. /** Get the next 2 digits **/
  532. c1 = get_hex_byte(p++);
  533. c2 = get_hex_byte(p++);
  534. /** If we got a bad number - return error **/
  535. if ((c1 == 0xFF) || (c2 == 0xFF)) {
  536. put_msg (TRUE, MSG_INVALID_REMOVE);
  537. exit(1);
  538. }
  539. /** Set the next byte **/
  540. *nodep++ = (c1 << 4) + c2;
  541. }
  542. /** Return OK **/
  543. return 0;
  544. }
  545. /*page*************************************************************
  546. g e t _ s e r v e r _ t y p e
  547. Get the decimal number from the command line
  548. Arguments - p = Ptr to the ASCII number
  549. nump = Store the number here
  550. Returns - 0 = Got the number OK
  551. Else = Bad number
  552. ********************************************************************/
  553. int get_server_type(char *p, int *nump)
  554. {
  555. *nump = atoi(p);
  556. return 0;
  557. }
  558. /*page*************************************************************
  559. g e t _ h e x _ b y t e
  560. Take 1 ascii hex chars and convert to a hex byte
  561. Arguments - p = Ptr to the ASCII number
  562. Returns - The number
  563. (0xFF = Error)
  564. ********************************************************************/
  565. unsigned char get_hex_byte(char *p)
  566. {
  567. unsigned char c;
  568. /** Get the char **/
  569. c = *(unsigned char *)p;
  570. /** If 0-9 handle it **/
  571. if ((c >= '0') && (c <= '9')) {
  572. c -= '0';
  573. return c;
  574. }
  575. /** If A-F handle it **/
  576. if ((c >= 'A') && (c <= 'F')) {
  577. c -= ('A' - 10);
  578. return c;
  579. }
  580. /** This is a bad number **/
  581. return 0xFF;
  582. }
  583. /*page***************************************************************
  584. g e t _ d r i v e r _ p a r m s
  585. Get the parameters from the driver
  586. Arguments - None
  587. Returns - 0 = OK
  588. else = Error
  589. ********************************************************************/
  590. int get_driver_parms()
  591. {
  592. int rc;
  593. int buffer[4];
  594. /** Set the board number **/
  595. buffer[0] = boardnum;
  596. sr_def = 0;
  597. sr_bcast = 0;
  598. sr_multi = 0;
  599. /** Get the parms **/
  600. if (nwlinkfd != INVALID_HANDLE) {
  601. rc = do_strioctl(nwlinkfd, MIPX_SRGETPARMS, (char *)buffer, 4*sizeof(int), 0);
  602. if (rc) {
  603. /** Get the error code **/
  604. rc = GetLastError();
  605. put_msg (TRUE, MSG_BAD_PARAMETERS, "nwlink");
  606. put_msg (TRUE, get_emsg(rc));
  607. /** Return the error **/
  608. return rc;
  609. }
  610. }
  611. if (isnipxfd != INVALID_HANDLE) {
  612. rc = do_isnipxioctl(isnipxfd, MIPX_SRGETPARMS, (char *)buffer, 4*sizeof(int));
  613. if (rc) {
  614. put_msg (TRUE, MSG_BAD_PARAMETERS, "nwlnkipx");
  615. put_msg (TRUE, get_emsg(rc));
  616. /** Return the error **/
  617. return rc;
  618. }
  619. }
  620. /** Get the variables **/
  621. sr_def = buffer[1];
  622. sr_bcast = buffer[2];
  623. sr_multi = buffer[3];
  624. /** Return OK **/
  625. return 0;
  626. }
  627. /*page***************************************************************
  628. s e t _ d r i v e r _ p a r m s
  629. Set the parameters for the driver
  630. Arguments - None
  631. Returns - 0 = OK
  632. else = Error
  633. ********************************************************************/
  634. int set_driver_parms()
  635. {
  636. int rc;
  637. int buffer[2];
  638. /** Set the DEFAULT parm **/
  639. buffer[0] = boardnum;
  640. buffer[1] = sr_def;
  641. if (nwlinkfd != INVALID_HANDLE) {
  642. rc = do_strioctl(nwlinkfd, MIPX_SRDEF, (char *)buffer, 2 * sizeof(int), 0);
  643. if (rc) {
  644. rc = GetLastError();
  645. put_msg (TRUE, MSG_SET_DEFAULT_ERROR, "nwlink");
  646. put_msg (TRUE, get_emsg(rc));
  647. return rc;
  648. }
  649. }
  650. if (isnipxfd != INVALID_HANDLE) {
  651. rc = do_isnipxioctl(isnipxfd, MIPX_SRDEF, (char *)buffer, 2 * sizeof(int));
  652. if (rc) {
  653. put_msg (TRUE, MSG_SET_DEFAULT_ERROR, "nwlnkipx");
  654. put_msg (TRUE, get_emsg(rc));
  655. return rc;
  656. }
  657. }
  658. /** Set the BROADCAST parm **/
  659. buffer[0] = boardnum;
  660. buffer[1] = sr_bcast;
  661. if (nwlinkfd != INVALID_HANDLE) {
  662. rc = do_strioctl(nwlinkfd, MIPX_SRBCAST, (char *)buffer, 2 * sizeof(int), 0);
  663. if (rc) {
  664. rc = GetLastError();
  665. put_msg (TRUE, MSG_SET_BROADCAST_ERROR, "nwlink");
  666. put_msg (TRUE, get_emsg(rc));
  667. return rc;
  668. }
  669. }
  670. if (isnipxfd != INVALID_HANDLE) {
  671. rc = do_isnipxioctl(isnipxfd, MIPX_SRBCAST, (char *)buffer, 2 * sizeof(int));
  672. if (rc) {
  673. put_msg (TRUE, MSG_SET_BROADCAST_ERROR, "nwlnkipx");
  674. put_msg (TRUE, get_emsg(rc));
  675. return rc;
  676. }
  677. }
  678. /** Set the MULTICAST parm **/
  679. buffer[0] = boardnum;
  680. buffer[1] = sr_multi;
  681. if (nwlinkfd != INVALID_HANDLE) {
  682. rc = do_strioctl(nwlinkfd, MIPX_SRMULTI, (char *)buffer, 2 * sizeof(int), 0);
  683. if (rc) {
  684. rc = GetLastError();
  685. put_msg (TRUE, MSG_SET_MULTICAST_ERROR, "nwlink");
  686. put_msg (TRUE, get_emsg(rc));
  687. return rc;
  688. }
  689. }
  690. if (isnipxfd != INVALID_HANDLE) {
  691. rc = do_isnipxioctl(isnipxfd, MIPX_SRMULTI, (char *)buffer, 2 * sizeof(int));
  692. if (rc) {
  693. put_msg (TRUE, MSG_SET_MULTICAST_ERROR, "nwlnkipx");
  694. put_msg (TRUE, get_emsg(rc));
  695. return rc;
  696. }
  697. }
  698. /** Return OK **/
  699. return 0;
  700. }
  701. /*page***************************************************************
  702. d o _ s t r i o c t l
  703. Do a stream ioctl
  704. Arguments - fd = Handle to put on
  705. cmd = Command to send
  706. datap = Ptr to ctrl buffer
  707. dlen = Ptr to len of data buffer
  708. timout = Timeout value
  709. Returns - 0 = OK
  710. else = Error
  711. ********************************************************************/
  712. int do_strioctl(HANDLE fd, int cmd, char *datap, int dlen, int timout)
  713. {
  714. int rc;
  715. struct strioctl io;
  716. /** Fill out the structure **/
  717. io.ic_cmd = cmd;
  718. io.ic_dp = datap;
  719. io.ic_len = dlen;
  720. io.ic_timout = timout;
  721. /** Issue the ioctl **/
  722. rc = s_ioctl(fd, I_STR, &io);
  723. /** All Done **/
  724. return rc;
  725. }
  726. /*page***************************************************************
  727. r e m o v e _ a d d r e s s
  728. Remove an address from the source routing table.
  729. Arguments - nodep = Ptr to node address to remove
  730. Returns - Does not return
  731. ********************************************************************/
  732. void remove_address(char *nodep)
  733. {
  734. int rc;
  735. int len;
  736. rterem buf;
  737. /** Build the area to send down to the driver **/
  738. buf.rterem_bnum = boardnum;
  739. memcpy(buf.rterem_node, nodep, 6);
  740. len = sizeof(int) + 6;
  741. /** Send the ioctl to remove the address **/
  742. if (nwlinkfd != INVALID_HANDLE) {
  743. rc = do_strioctl(nwlinkfd, MIPX_SRREMOVE, (char *)&buf, len, 0);
  744. if (rc) {
  745. rc = GetLastError();
  746. put_msg (TRUE, MSG_REMOVE_ADDRESS_ERROR, "nwlink");
  747. put_msg (TRUE, get_emsg(rc));
  748. }
  749. }
  750. if (isnipxfd != INVALID_HANDLE) {
  751. rc = do_isnipxioctl(isnipxfd, MIPX_SRREMOVE, (char *)&buf, len);
  752. if (rc) {
  753. put_msg (TRUE, MSG_REMOVE_ADDRESS_ERROR, "nwlnkipx");
  754. if (rc == EINVAL) {
  755. put_msg (TRUE, MSG_ADDRESS_NOT_FOUND);
  756. } else {
  757. put_msg (TRUE, get_emsg(rc));
  758. }
  759. }
  760. }
  761. /** Close up and exit **/
  762. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  763. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  764. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  765. exit(0);
  766. }
  767. /*page***************************************************************
  768. c l e a r _ t a b l e
  769. Clear out the routing table
  770. Arguments - None
  771. Returns - Does not return
  772. ********************************************************************/
  773. void clear_table(void)
  774. {
  775. int rc;
  776. /** Send the ioctl to clear the table **/
  777. if (nwlinkfd != INVALID_HANDLE) {
  778. rc = do_strioctl(nwlinkfd, MIPX_SRCLEAR, (char *)&boardnum, sizeof(int), 0);
  779. if (rc) {
  780. rc= GetLastError();
  781. put_msg (TRUE, MSG_CLEAR_TABLE_ERROR, "nwlink");
  782. put_msg (TRUE, get_emsg(rc));
  783. }
  784. }
  785. if (isnipxfd != INVALID_HANDLE) {
  786. rc = do_isnipxioctl(isnipxfd, MIPX_SRCLEAR, (char *)&boardnum, sizeof(int));
  787. if (rc) {
  788. put_msg (TRUE, MSG_CLEAR_TABLE_ERROR, "nwlnkipx");
  789. put_msg (TRUE, get_emsg(rc));
  790. }
  791. }
  792. /** Close up and exit **/
  793. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  794. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  795. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  796. exit(0);
  797. }
  798. /*
  799. typedef struct _ISN_ACTION_GET_DETAILS {
  800. USHORT NicId; // passed by caller
  801. BOOLEAN BindingSet; // returns TRUE if in set
  802. UCHAR Type; // 1 = lan, 2 = up wan, 3 = down wan
  803. ULONG FrameType; // returns 0 through 3
  804. ULONG NetworkNumber; // returns virtual net if NicId is 0
  805. UCHAR Node[6]; // adapter's MAC address.
  806. WCHAR AdapterName[64]; // terminated with Unicode NULL
  807. } ISN_ACTION_GET_DETAILS, *PISN_ACTION_GET_DETAILS;
  808. */
  809. #define REORDER_ULONG(_Ulong) \
  810. ((((_Ulong) & 0xff000000) >> 24) | \
  811. (((_Ulong) & 0x00ff0000) >> 8) | \
  812. (((_Ulong) & 0x0000ff00) << 8) | \
  813. (((_Ulong) & 0x000000ff) << 24))
  814. void show_ripout(unsigned long netnum) {
  815. int rc;
  816. ISN_ACTION_GET_LOCAL_TARGET Target;
  817. if (isnipxfd != INVALID_HANDLE) {
  818. ZeroMemory (&Target, sizeof (Target));
  819. Target.IpxAddress.NetworkAddress = REORDER_ULONG(netnum);
  820. rc = do_isnipxioctl(isnipxfd, MIPX_LOCALTARGET, (char *)&Target, sizeof(Target));
  821. if (rc)
  822. put_msg (TRUE, MSG_RIPOUT_NOTFOUND);
  823. else
  824. put_msg (TRUE, MSG_RIPOUT_FOUND);
  825. }
  826. exit(0);
  827. }
  828. #define mbtowc(wname, aname) MultiByteToWideChar(CP_ACP,0,aname,-1,wname,1024)
  829. void resolve_guid(char * guidname) {
  830. WCHAR pszName[512], pszGuidName[1024];
  831. char * psz;
  832. HANDLE hMpr;
  833. DWORD dwErr;
  834. if (MprConfigServerConnect(NULL, &hMpr) != NO_ERROR)
  835. return;
  836. mbtowc(pszGuidName, guidname);
  837. dwErr = MprConfigGetFriendlyName(hMpr, pszGuidName, pszName, sizeof(pszName));
  838. if (dwErr == NO_ERROR)
  839. put_msg (TRUE, MSG_RESOLVEGUID_OK, pszName);
  840. else
  841. put_msg (TRUE, MSG_RESOLVEGUID_NO, guidname);
  842. MprConfigServerDisconnect(hMpr);
  843. exit(0);
  844. }
  845. void resolve_name(char * name) {
  846. WCHAR pszName[1024], pszGuidName[1024];
  847. char * pszGuid;
  848. DWORD dwErr;
  849. HANDLE hMpr;
  850. if (MprConfigServerConnect(NULL, &hMpr) != NO_ERROR)
  851. return;
  852. // Convert to wc and look up the name
  853. mbtowc (pszName, name);
  854. dwErr = MprConfigGetGuidName(hMpr, pszName, pszGuidName, sizeof(pszGuidName));
  855. if (dwErr == NO_ERROR)
  856. put_msg (TRUE, MSG_RESOLVENAME_OK, pszGuidName);
  857. else
  858. put_msg (TRUE, MSG_RESOLVENAME_NO);
  859. // Cleanup interface map
  860. MprConfigServerDisconnect(hMpr);
  861. exit(0);
  862. }
  863. /*page***************************************************************
  864. p r i n t _ c o n f i g
  865. Prints out the current config
  866. Arguments - None
  867. Returns - Does not return
  868. ********************************************************************/
  869. void print_config(void)
  870. {
  871. int rc;
  872. int nicidcount;
  873. USHORT nicid;
  874. int showlegend = 0;
  875. char nicidbuf[6];
  876. char network[9];
  877. char * frametype;
  878. char node[13];
  879. char special[2];
  880. char adaptername[64];
  881. ISN_ACTION_GET_DETAILS getdetails;
  882. HANDLE hMpr;
  883. DWORD dwErr;
  884. // Initialize the map from guid to interface name
  885. MprConfigServerConnect(NULL, &hMpr);
  886. if (isnipxfd != INVALID_HANDLE) {
  887. /** First query nicid 0 **/
  888. getdetails.NicId = 0;
  889. rc = do_isnipxioctl(isnipxfd, MIPX_CONFIG, (char *)&getdetails, sizeof(getdetails));
  890. if (rc) {
  891. put_msg (TRUE, MSG_QUERY_CONFIG_ERROR, "nwlnkipx");
  892. put_msg (TRUE, get_emsg(rc));
  893. goto errorexit;
  894. }
  895. printf("\n");
  896. put_msg (FALSE, MSG_NET_NUMBER_HDR);
  897. if (getdetails.NetworkNumber != 0) {
  898. sprintf (network, "%.8x", REORDER_ULONG(getdetails.NetworkNumber));
  899. put_msg(FALSE, MSG_SHOW_INTERNAL_NET, network);
  900. }
  901. //
  902. // The NicId 0 query returns the total number.
  903. //
  904. nicidcount = getdetails.NicId;
  905. for (nicid = 1; nicid <= nicidcount; nicid++) {
  906. getdetails.NicId = nicid;
  907. rc = do_isnipxioctl(isnipxfd, MIPX_CONFIG, (char *)&getdetails, sizeof(getdetails));
  908. if (rc) {
  909. continue;
  910. }
  911. sprintf (nicidbuf, "%d.", nicid);
  912. sprintf (network, "%.8x", REORDER_ULONG(getdetails.NetworkNumber));
  913. switch (getdetails.FrameType) {
  914. case 0: frametype = load_msg (MSG_ETHERNET_II); break;
  915. case 1: frametype = load_msg (MSG_802_3); break;
  916. case 2: frametype = load_msg (MSG_802_2); break;
  917. case 3: frametype = load_msg (MSG_SNAP); break;
  918. case 4: frametype = load_msg (MSG_ARCNET); break;
  919. default: frametype = load_msg (MSG_UNKNOWN); break;
  920. }
  921. // Translate the adapter name
  922. if (getdetails.Type == 1) { // lan
  923. WCHAR pszName[512];
  924. PWCHAR pszGuid = &(getdetails.AdapterName[0]);
  925. dwErr = MprConfigGetFriendlyName(hMpr, pszGuid, pszName, sizeof(pszName));
  926. if (dwErr == NO_ERROR)
  927. sprintf (adaptername, "%ws", pszName);
  928. else
  929. sprintf (adaptername, "%ws", getdetails.AdapterName);
  930. }
  931. else
  932. sprintf (adaptername, "%ws", getdetails.AdapterName);
  933. sprintf (node, "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
  934. getdetails.Node[0],
  935. getdetails.Node[1],
  936. getdetails.Node[2],
  937. getdetails.Node[3],
  938. getdetails.Node[4],
  939. getdetails.Node[5]);
  940. special[1] = '\0';
  941. if (getdetails.BindingSet) {
  942. special[0] = '*';
  943. showlegend |= 1;
  944. } else if (getdetails.Type == 2) {
  945. special[0] = '+';
  946. showlegend |= 2;
  947. } else if (getdetails.Type == 3) {
  948. special[0] = '-';
  949. showlegend |= 4;
  950. } else {
  951. special[0] = '\0';
  952. }
  953. put_msg (FALSE, MSG_SHOW_NET_NUMBER,
  954. nicidbuf,
  955. network,
  956. frametype,
  957. adaptername,
  958. node,
  959. special);
  960. LocalFree (frametype);
  961. }
  962. if (showlegend) {
  963. put_msg (FALSE, MSG_NET_NUMBER_LEGEND_HDR);
  964. if (showlegend & 1) {
  965. put_msg (FALSE, MSG_LEGEND_BINDING_SET);
  966. }
  967. if (showlegend & 2) {
  968. put_msg (FALSE, MSG_LEGEND_ACTIVE_WAN);
  969. }
  970. if (showlegend & 4) {
  971. put_msg (FALSE, MSG_LEGEND_DOWN_WAN);
  972. }
  973. printf("\n");
  974. }
  975. }
  976. errorexit:
  977. /** Close up and exit **/
  978. // Cleanup interface map
  979. MprConfigServerDisconnect(hMpr);
  980. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  981. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  982. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  983. exit(0);
  984. }
  985. /*page***************************************************************
  986. g e t _ e m s g
  987. Get an error message for an error
  988. Arguments - None
  989. Returns - Does not return
  990. ********************************************************************/
  991. unsigned long get_emsg(int rc)
  992. {
  993. /**
  994. We have 3 defined error codes that can come back.
  995. 1 - EINVAL means that we sent down parameters wrong
  996. (SHOULD NEVER HAPPEN)
  997. 2 - ERANGE means that the board number is invalid
  998. (CAN HAPPEN IF USER ENTERS BAD BOARD)
  999. 3 - ENOENT means that on remove - the address given
  1000. is not in the source routing table.
  1001. **/
  1002. switch (rc) {
  1003. case EINVAL:
  1004. return MSG_INTERNAL_ERROR;
  1005. case ERANGE:
  1006. return MSG_INVALID_BOARD;
  1007. case ENOENT:
  1008. return MSG_ADDRESS_NOT_FOUND;
  1009. default:
  1010. return MSG_UNKNOWN_ERROR;
  1011. }
  1012. }
  1013. /*page***************************************************************
  1014. d o _ i s n i p x i o c t l
  1015. Do the equivalent of a stream ioctl to isnipx
  1016. Arguments - fd = Handle to put on
  1017. cmd = Command to send
  1018. datap = Ptr to ctrl buffer
  1019. dlen = Ptr to len of data buffer
  1020. Returns - 0 = OK
  1021. else = Error
  1022. ********************************************************************/
  1023. int do_isnipxioctl(HANDLE fd, int cmd, char *datap, int dlen)
  1024. {
  1025. NTSTATUS Status;
  1026. UCHAR buffer[sizeof(NWLINK_ACTION) + sizeof(ISN_ACTION_GET_DETAILS) - 1];
  1027. PNWLINK_ACTION action;
  1028. IO_STATUS_BLOCK IoStatusBlock;
  1029. int rc;
  1030. /** Fill out the structure **/
  1031. action = (PNWLINK_ACTION)buffer;
  1032. action->Header.TransportId = ISN_ACTION_TRANSPORT_ID;
  1033. action->OptionType = NWLINK_OPTION_CONTROL;
  1034. action->BufferLength = sizeof(ULONG) + dlen;
  1035. action->Option = cmd;
  1036. RtlMoveMemory(action->Data, datap, dlen);
  1037. /** Issue the ioctl **/
  1038. Status = NtDeviceIoControlFile(
  1039. fd,
  1040. NULL,
  1041. NULL,
  1042. NULL,
  1043. &IoStatusBlock,
  1044. IOCTL_TDI_ACTION,
  1045. NULL,
  1046. 0,
  1047. action,
  1048. FIELD_OFFSET(NWLINK_ACTION,Data) + dlen);
  1049. if (Status != STATUS_SUCCESS) {
  1050. if (Status == STATUS_INVALID_PARAMETER) {
  1051. rc = ERANGE;
  1052. } else {
  1053. rc = EINVAL;
  1054. }
  1055. } else {
  1056. if (dlen > 0) {
  1057. RtlMoveMemory (datap, action->Data, dlen);
  1058. }
  1059. rc = 0;
  1060. }
  1061. return rc;
  1062. }
  1063. //*****************************************************************************
  1064. //
  1065. // Name: put_msg
  1066. //
  1067. // Description: Reads a message resource, formats it in the current language
  1068. // and displays the message.
  1069. //
  1070. // NOTE: This routine was stolen from net\sockets\tcpcmd\common2\util.c.
  1071. //
  1072. // Parameters: error - TRUE if this is an error message.
  1073. // unsigned long MsgNum: ID of the message resource.
  1074. //
  1075. // Returns: unsigned long: number of characters displayed.
  1076. //
  1077. // History:
  1078. // 01/05/93 JayPh Created.
  1079. //
  1080. //*****************************************************************************
  1081. unsigned long put_msg(BOOLEAN error, unsigned long MsgNum, ... )
  1082. {
  1083. unsigned long msglen;
  1084. char *vp;
  1085. char *oemp;
  1086. va_list arglist;
  1087. va_start( arglist, MsgNum );
  1088. msglen = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1089. FORMAT_MESSAGE_FROM_HMODULE,
  1090. NULL,
  1091. MsgNum,
  1092. 0L, // Default country ID.
  1093. (LPTSTR)&vp,
  1094. 0,
  1095. &arglist );
  1096. if ( (msglen == 0) || (vp == NULL))
  1097. {
  1098. return ( 0 );
  1099. }
  1100. oemp = (char *) malloc(msglen*sizeof(char) + 1);
  1101. if (oemp != NULL) {
  1102. CharToOem(vp, oemp);
  1103. fprintf( error ? stderr : stdout, "%s", oemp );
  1104. free(oemp);
  1105. } else {
  1106. printf("Failed to allocate memory of %d bytes\n",msglen*sizeof(char));
  1107. }
  1108. LocalFree( vp );
  1109. return ( msglen );
  1110. }
  1111. //*****************************************************************************
  1112. //
  1113. // Name: load_msg
  1114. //
  1115. // Description: Reads and formats a message resource and returns a pointer
  1116. // to the buffer containing the formatted message. It is the
  1117. // responsibility of the caller to free the buffer.
  1118. //
  1119. // NOTE: This routine was stolen from net\sockets\tcpcmd\common2\util.c.
  1120. //
  1121. // Parameters: unsigned long MsgNum: ID of the message resource.
  1122. //
  1123. // Returns: char *: pointer to the message buffer, NULL if error.
  1124. //
  1125. // History:
  1126. // 01/05/93 JayPh Created.
  1127. //
  1128. //*****************************************************************************
  1129. char *load_msg( unsigned long MsgNum, ... )
  1130. {
  1131. unsigned long msglen;
  1132. char *vp;
  1133. va_list arglist;
  1134. va_start( arglist, MsgNum );
  1135. msglen = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  1136. FORMAT_MESSAGE_FROM_HMODULE,
  1137. NULL,
  1138. MsgNum,
  1139. 0L, // Default country ID.
  1140. (LPTSTR)&vp,
  1141. 0,
  1142. &arglist );
  1143. if ( msglen == 0 )
  1144. {
  1145. return(0);
  1146. }
  1147. return ( vp );
  1148. }
  1149. #define MAX_NETWORK_INTERFACES 255
  1150. typedef struct router_info
  1151. {
  1152. ULONG NetNumber;
  1153. USHORT TickCount;
  1154. USHORT HopCount;
  1155. USHORT NicId;
  1156. UCHAR InterfaceNumber[10];
  1157. } ROUTER_INFO, *PROUTER_INFO;
  1158. /*page***************************************************************
  1159. s h o w _ r o u t e r _ t a b l e
  1160. Display the IPX routing table
  1161. Arguments - FileHandle = Router File Handle
  1162. IoStatusBlock = Device IO Status Block
  1163. Returns - Does not return
  1164. ********************************************************************/
  1165. VOID
  1166. show_router_table(
  1167. PHANDLE FileHandle,
  1168. PIO_STATUS_BLOCK IoStatusBlock
  1169. )
  1170. {
  1171. SHOW_NIC_INFO nis[MAX_NETWORK_INTERFACES];
  1172. ULONG NetNumber;
  1173. char InterfaceNumber[10];
  1174. NTSTATUS Status;
  1175. USHORT index, i, NumEntries, count;
  1176. char router_entry[128];
  1177. char buffer[32];
  1178. PROUTER_INFO RouterInfo = NULL;
  1179. if (*FileHandle == INVALID_HANDLE) {
  1180. put_msg(TRUE, MSG_IPXROUTER_NOT_STARTED );
  1181. goto exit_show_table;
  1182. }
  1183. /** First get the Network numbers for all interfaces **/
  1184. index = 0;
  1185. while(TRUE) {
  1186. Status = NtDeviceIoControlFile(
  1187. *FileHandle, // HANDLE to File
  1188. NULL, // HANDLE to Event
  1189. NULL, // ApcRoutine
  1190. NULL, // ApcContext
  1191. IoStatusBlock, // IO_STATUS_BLOCK
  1192. IOCTL_IPXROUTER_SHOWNICINFO, // IoControlCode
  1193. &index, // Input Buffer
  1194. sizeof(USHORT), // Input Buffer Length
  1195. &nis[index], // Output Buffer
  1196. sizeof(SHOW_NIC_INFO)); // Output Buffer Length
  1197. if(IoStatusBlock->Status == STATUS_NO_MORE_ENTRIES) {
  1198. break;
  1199. }
  1200. index ++;
  1201. if(Status != STATUS_SUCCESS) {
  1202. sprintf(buffer, "%x", Status);
  1203. put_msg(TRUE, MSG_SHOWSTATS_FAILED, buffer);
  1204. goto exit_show_table;
  1205. }
  1206. if (index >= MAX_NETWORK_INTERFACES) {
  1207. // break out of this loop if there are more than 255 network
  1208. // interfaces because we only have storage for 255.
  1209. break;
  1210. }
  1211. }
  1212. Status = NtDeviceIoControlFile(
  1213. *FileHandle, // HANDLE to File
  1214. NULL, // HANDLE to Event
  1215. NULL, // ApcRoutine
  1216. NULL, // ApcContext
  1217. IoStatusBlock, // IO_STATUS_BLOCK
  1218. IOCTL_IPXROUTER_SNAPROUTES, // IoControlCode
  1219. NULL, // Input Buffer
  1220. 0, // Input Buffer Length
  1221. NULL, // Output Buffer
  1222. 0); // Output Buffer Length
  1223. if (IoStatusBlock->Status != STATUS_SUCCESS) {
  1224. sprintf(buffer, "%x", Status);
  1225. put_msg(TRUE, MSG_SNAPROUTES_FAILED, buffer);
  1226. goto exit_show_table;
  1227. }
  1228. // first determine the number of router table entries to
  1229. // allocate sufficient storage
  1230. NumEntries = 0;
  1231. while(TRUE) {
  1232. Status = NtDeviceIoControlFile(
  1233. *FileHandle, // HANDLE to File
  1234. NULL, // HANDLE to Event
  1235. NULL, // ApcRoutine
  1236. NULL, // ApcContext
  1237. IoStatusBlock, // IO_STATUS_BLOCK
  1238. IOCTL_IPXROUTER_GETNEXTROUTE, // IoControlCode
  1239. NULL, // Input Buffer
  1240. 0, // Input Buffer Length
  1241. &rte, // Output Buffer
  1242. sizeof(IPX_ROUTE_ENTRY)); // Output Buffer Length
  1243. if(IoStatusBlock->Status == STATUS_NO_MORE_ENTRIES) {
  1244. break;
  1245. }
  1246. if(Status != STATUS_SUCCESS) {
  1247. sprintf(buffer,"%x",Status);
  1248. put_msg(TRUE, MSG_GETNEXTROUTE_FAILED, buffer);
  1249. goto exit_show_table;
  1250. }
  1251. NumEntries ++;
  1252. }
  1253. RouterInfo = (PROUTER_INFO) LocalAlloc(LPTR, sizeof(ROUTER_INFO) * NumEntries);
  1254. if(!RouterInfo) {
  1255. put_msg(FALSE, MSG_INSUFFICIENT_MEMORY);
  1256. goto exit_show_table;
  1257. }
  1258. Status = NtDeviceIoControlFile(
  1259. *FileHandle, // HANDLE to File
  1260. NULL, // HANDLE to Event
  1261. NULL, // ApcRoutine
  1262. NULL, // ApcContext
  1263. IoStatusBlock, // IO_STATUS_BLOCK
  1264. IOCTL_IPXROUTER_SNAPROUTES, // IoControlCode
  1265. NULL, // Input Buffer
  1266. 0, // Input Buffer Length
  1267. NULL, // Output Buffer
  1268. 0); // Output Buffer Length
  1269. if (IoStatusBlock->Status != STATUS_SUCCESS) {
  1270. sprintf(buffer, "%x", Status);
  1271. put_msg(TRUE, MSG_SNAPROUTES_FAILED, buffer);
  1272. goto exit_show_table;
  1273. }
  1274. index = 0;
  1275. while(TRUE) {
  1276. Status = NtDeviceIoControlFile(
  1277. *FileHandle, // HANDLE to File
  1278. NULL, // HANDLE to Event
  1279. NULL, // ApcRoutine
  1280. NULL, // ApcContext
  1281. IoStatusBlock, // IO_STATUS_BLOCK
  1282. IOCTL_IPXROUTER_GETNEXTROUTE, // IoControlCode
  1283. NULL, // Input Buffer
  1284. 0, // Input Buffer Length
  1285. &rte, // Output Buffer
  1286. sizeof(IPX_ROUTE_ENTRY)); // Output Buffer Length
  1287. if(IoStatusBlock->Status == STATUS_NO_MORE_ENTRIES) {
  1288. break;
  1289. }
  1290. if(Status != STATUS_SUCCESS) {
  1291. sprintf(buffer,"%x",Status);
  1292. put_msg(TRUE, MSG_GETNEXTROUTE_FAILED, buffer);
  1293. goto exit_show_table;
  1294. }
  1295. // make sure we don't exceed the number of entries
  1296. if (index > NumEntries) {
  1297. break;
  1298. }
  1299. // get net nr in "on the wire" order
  1300. GETLONG2ULONG(&(RouterInfo[index].NetNumber), rte.Network);
  1301. // find out the matching Network number based on NIC ID
  1302. for(i=0; i < MAX_NETWORK_INTERFACES; i++) {
  1303. if(rte.NicId == nis[i].NicId) {
  1304. sprintf(RouterInfo[index].InterfaceNumber, "%.2x%.2x%.2x%.2x",
  1305. nis[i].Network[0],
  1306. nis[i].Network[1],
  1307. nis[i].Network[2],
  1308. nis[i].Network[3]);
  1309. break;
  1310. }
  1311. }
  1312. RouterInfo[index].TickCount = rte.TickCount;
  1313. RouterInfo[index].HopCount = rte.HopCount;
  1314. RouterInfo[index].NicId = rte.NicId;
  1315. index++;
  1316. }
  1317. // Now sort the entries by net number
  1318. qsort( (void*) RouterInfo,
  1319. NumEntries,
  1320. sizeof(ROUTER_INFO),
  1321. (PQSORT_COMPARE)CompareNetNumber );
  1322. put_msg(FALSE, MSG_ROUTER_TABLE_HEADER);
  1323. for(index =0, count = 0; index < NumEntries; index++, count++)
  1324. {
  1325. if (count > 50) {
  1326. count = 0;
  1327. // display router table header every 25 entries
  1328. // to make reading the table easier.
  1329. put_msg(FALSE, MSG_ROUTER_TABLE_HEADER);
  1330. }
  1331. printf("%.8x %6d %2d %-16s %d\n",
  1332. RouterInfo[index].NetNumber,
  1333. RouterInfo[index].TickCount,
  1334. RouterInfo[index].HopCount,
  1335. RouterInfo[index].InterfaceNumber,
  1336. RouterInfo[index].NicId );
  1337. }
  1338. /** Close up and exit **/
  1339. exit_show_table:
  1340. if (RouterInfo) LocalFree(RouterInfo);
  1341. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  1342. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  1343. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  1344. exit(0);
  1345. }
  1346. int __cdecl CompareNetNumber( void * p0, void * p1)
  1347. {
  1348. PROUTER_INFO pLeft = (PROUTER_INFO) p0;
  1349. PROUTER_INFO pRight = (PROUTER_INFO) p1;
  1350. if(pLeft->NetNumber == pRight->NetNumber)
  1351. return(0);
  1352. if(pLeft->NetNumber > pRight->NetNumber)
  1353. return(1);
  1354. else
  1355. return(-1);
  1356. }
  1357. PUCHAR DeviceType[2] = { "LAN", "WAN" };
  1358. PUCHAR NicState[4] = { "CLOSED", "CLOSING", "ACTIVE", "PENDING_OPEN" };
  1359. /*page***************************************************************
  1360. s h o w _ s t a t s
  1361. Displays IPX internal routing statistics
  1362. Arguments - FileHandle = Router File Handle
  1363. IoStatusBlock = Device IO Status Block
  1364. Returns - Does not return
  1365. ********************************************************************/
  1366. VOID
  1367. show_stats(
  1368. PHANDLE FileHandle,
  1369. PIO_STATUS_BLOCK IoStatusBlock
  1370. )
  1371. {
  1372. SHOW_NIC_INFO nis;
  1373. USHORT index, i;
  1374. char NicId[4];
  1375. char NetworkNumber[10];
  1376. char RipRcvd[32], RipSent[32];
  1377. char RoutedRcvd[32], RoutedSent[32];
  1378. char Type20Rcvd[32], Type20Sent[32];
  1379. char BadRcvd[32];
  1380. char buffer[32];
  1381. NTSTATUS Status;
  1382. if (*FileHandle == INVALID_HANDLE) {
  1383. put_msg(TRUE, MSG_IPXROUTER_NOT_STARTED );
  1384. goto end_stats;
  1385. }
  1386. index = 0;
  1387. while(TRUE) {
  1388. Status = NtDeviceIoControlFile(
  1389. *FileHandle, // HANDLE to File
  1390. NULL, // HANDLE to Event
  1391. NULL, // ApcRoutine
  1392. NULL, // ApcContext
  1393. IoStatusBlock, // IO_STATUS_BLOCK
  1394. IOCTL_IPXROUTER_SHOWNICINFO, // IoControlCode
  1395. &index, // Input Buffer
  1396. sizeof(USHORT), // Input Buffer Length
  1397. &nis, // Output Buffer
  1398. sizeof(nis)); // Output Buffer Length
  1399. if(IoStatusBlock->Status == STATUS_NO_MORE_ENTRIES) {
  1400. goto end_stats;
  1401. }
  1402. index ++;
  1403. if(Status != STATUS_SUCCESS) {
  1404. sprintf(buffer, "%x", Status);
  1405. put_msg(TRUE, MSG_SHOWSTATS_FAILED, buffer);
  1406. goto end_stats;
  1407. }
  1408. sprintf(NicId, "%d", nis.NicId);
  1409. sprintf(NetworkNumber,
  1410. "%.2x%.2x%.2x%.2x",
  1411. nis.Network[0],
  1412. nis.Network[1],
  1413. nis.Network[2],
  1414. nis.Network[3]);
  1415. sprintf(RipRcvd, "%-8d", nis.StatRipReceived);
  1416. sprintf(RipSent, "%-8d", nis.StatRipSent);
  1417. sprintf(RoutedRcvd, "%-8d", nis.StatRoutedReceived);
  1418. sprintf(RoutedSent, "%-8d", nis.StatRoutedSent);
  1419. sprintf(Type20Rcvd, "%-8d", nis.StatType20Received);
  1420. sprintf(Type20Sent, "%-8d", nis.StatType20Sent);
  1421. sprintf(BadRcvd, "%-8d", nis.StatBadReceived);
  1422. put_msg(FALSE,
  1423. MSG_SHOW_STATISTICS,
  1424. NicId,
  1425. NetworkNumber,
  1426. RipRcvd,
  1427. RipSent,
  1428. Type20Rcvd,
  1429. Type20Sent,
  1430. RoutedRcvd,
  1431. RoutedSent,
  1432. BadRcvd);
  1433. }
  1434. /** Close up and exit **/
  1435. end_stats:
  1436. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  1437. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  1438. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  1439. exit(0);
  1440. }
  1441. /*page***************************************************************
  1442. c l e a r _ s t a t s
  1443. Clears the IPX internal routing statistics
  1444. Arguments - FileHandle = Router File Handle
  1445. IoStatusBlock = Device IO Status Block
  1446. Returns - Does not return
  1447. ********************************************************************/
  1448. VOID
  1449. clear_stats(
  1450. PHANDLE FileHandle,
  1451. PIO_STATUS_BLOCK IoStatusBlock
  1452. )
  1453. {
  1454. NTSTATUS Status;
  1455. char buffer[32];
  1456. if (*FileHandle == INVALID_HANDLE) {
  1457. put_msg(TRUE, MSG_IPXROUTER_NOT_STARTED );
  1458. goto end_clearstats;
  1459. }
  1460. Status = NtDeviceIoControlFile(
  1461. *FileHandle, // HANDLE to File
  1462. NULL, // HANDLE to Event
  1463. NULL, // ApcRoutine
  1464. NULL, // ApcContext
  1465. IoStatusBlock, // IO_STATUS_BLOCK
  1466. IOCTL_IPXROUTER_ZERONICSTATISTICS, // IoControlCode
  1467. NULL, // Input Buffer
  1468. 0, // Input Buffer Length
  1469. NULL, // Output Buffer
  1470. 0); // Output Buffer Length
  1471. if(Status != STATUS_SUCCESS) {
  1472. sprintf(buffer, "%x", Status);
  1473. put_msg(TRUE, MSG_CLEAR_STATS_FAILED, buffer);
  1474. }
  1475. /** Close up and exit **/
  1476. end_clearstats:
  1477. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  1478. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  1479. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  1480. exit(0);
  1481. }
  1482. typedef struct server_info
  1483. {
  1484. USHORT ObjectType;
  1485. UCHAR ObjectName[100];
  1486. UCHAR IpxAddress[12];
  1487. } SERVER_INFO, *PSERVER_INFO;
  1488. /*page***************************************************************
  1489. s h o w _ s e r v e r s
  1490. Display the servers from the SAP table
  1491. Arguments - servertype = Type of servers to display
  1492. Defaults to show all server types
  1493. Returns - Does not return
  1494. ********************************************************************/
  1495. VOID
  1496. show_servers(int servertype)
  1497. {
  1498. INT rc;
  1499. ULONG ObjectID = 0xFFFFFFFF;
  1500. UCHAR ObjectName[100];
  1501. USHORT ObjectType;
  1502. USHORT ScanType = (USHORT) servertype;
  1503. UCHAR IpxAddress[12];
  1504. USHORT i;
  1505. USHORT index, count, NumServers;
  1506. PSERVER_INFO ServerInfo = NULL;
  1507. if(rc = SapLibInit() != SAPRETURN_SUCCESS) {
  1508. put_msg(TRUE, MSG_SAP_NOT_STARTED);
  1509. goto show_servers_end;
  1510. }
  1511. memset(&ObjectName, 0, 100);
  1512. // find out how many servers are there so that we can allocate
  1513. // sufficient storage
  1514. NumServers = 0;
  1515. while((rc = SapScanObject(&ObjectID,
  1516. ObjectName,
  1517. &ObjectType,
  1518. ScanType)) == SAPRETURN_SUCCESS)
  1519. {
  1520. NumServers++;
  1521. }
  1522. ServerInfo = (PSERVER_INFO) LocalAlloc(LPTR, sizeof(SERVER_INFO) * NumServers);
  1523. if(!ServerInfo)
  1524. {
  1525. put_msg(FALSE, MSG_INSUFFICIENT_MEMORY);
  1526. goto show_servers_end;
  1527. }
  1528. index = 0;
  1529. ObjectID = 0xFFFFFFFF;
  1530. while((rc = SapScanObject(&ObjectID,
  1531. ObjectName,
  1532. &ObjectType,
  1533. ScanType)) == SAPRETURN_SUCCESS)
  1534. {
  1535. if (index >= NumServers) {
  1536. break;
  1537. }
  1538. // get object address
  1539. SapGetObjectName(ObjectID,
  1540. ObjectName,
  1541. &ObjectType,
  1542. IpxAddress);
  1543. ServerInfo[index].ObjectType = ObjectType;
  1544. strcpy(ServerInfo[index].ObjectName, ObjectName);
  1545. CopyMemory(ServerInfo[index].IpxAddress, IpxAddress, 12);
  1546. index++;
  1547. }
  1548. // Now sort the entries by server name
  1549. qsort( (void*) ServerInfo,
  1550. NumServers,
  1551. sizeof(SERVER_INFO),
  1552. (PQSORT_COMPARE)CompareServerNames );
  1553. if(servertype == SHOW_ALL_SERVERS)
  1554. put_msg(FALSE, MSG_SHOW_ALL_SERVERS_HEADER);
  1555. else
  1556. put_msg(FALSE, MSG_SHOW_SPECIFIC_SERVER_HEADER);
  1557. for(index = 0, count = 0; index < NumServers; index++, count++)
  1558. {
  1559. if (count > 50) {
  1560. // write the table header for every 50 entries
  1561. // to make this more readable.
  1562. count = 0;
  1563. if(servertype == SHOW_ALL_SERVERS)
  1564. put_msg(FALSE, MSG_SHOW_ALL_SERVERS_HEADER);
  1565. else
  1566. put_msg(FALSE, MSG_SHOW_SPECIFIC_SERVER_HEADER);
  1567. }
  1568. for(i=0; i<4; i++) {
  1569. printf("%.2x", ServerInfo[index].IpxAddress[i]);
  1570. }
  1571. printf(".");
  1572. for(i=4; i<10; i++) {
  1573. printf("%.2x", ServerInfo[index].IpxAddress[i]);
  1574. }
  1575. if(servertype == SHOW_ALL_SERVERS) {
  1576. printf(" %-6d", ServerInfo[index].ObjectType);
  1577. }
  1578. printf(" %s\n", ServerInfo[index].ObjectName);
  1579. }
  1580. /** Close up and exit **/
  1581. show_servers_end:
  1582. if (ServerInfo) LocalFree(ServerInfo);
  1583. if (isnipxfd != INVALID_HANDLE) NtClose(isnipxfd);
  1584. if (nwlinkfd != INVALID_HANDLE) NtClose(nwlinkfd);
  1585. if (isnripfd != INVALID_HANDLE) NtClose(isnripfd);
  1586. exit(0);
  1587. }
  1588. int __cdecl CompareServerNames( void * p0, void * p1)
  1589. {
  1590. PSERVER_INFO pLeft = (PSERVER_INFO) p0;
  1591. PSERVER_INFO pRight = (PSERVER_INFO) p1;
  1592. return(strcmp(pLeft->ObjectName, pRight->ObjectName));
  1593. }
  1594.