DOSPING.C
上传用户:bangxh
上传日期:2007-01-31
资源大小:42235k
文件大小:15k
源码类别:

Windows编程

开发平台:

Visual C++

  1. /*=====================================================================
  2. P I N G . C
  3. This is the DOS side ping program.  It uses Novell's IPX/SPX APIs,
  4. requiring their SDK. It will send/receive 1-n IPX packets.
  5. ======================================================================*/
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <conio.h>
  10. #include <nxtdos.h>
  11. #define TIMER (unsigned long far *) 0x0000046cL
  12. char *progname;
  13. IPXHeader *ipx;
  14. int send_socket=0;
  15. int recv_socket;
  16. int datasize = 1;
  17. ECB send_ecb; 
  18. ECB recv_ecb[10];
  19. char mynodeaddr[6];
  20. char sendb[2048];
  21. char recvb[2048];
  22. int ptype = 4;
  23. int niters = 1;
  24. /**
  25.     This is the address we try to send to.  When
  26.     we find a server, this address is replaced by the address
  27.     of the exact server.  The address is made up of:
  28.     bytes 1-4    = network number
  29.     bytes 5-10   = node number
  30.     bytes 11-12  = socket address
  31. **/
  32. char destaddr[12] = {
  33.     0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, 0x00
  34. };
  35. /** Function Prototypes **/
  36. void   hang_recvs(void);
  37. void   cancel_recvs(void);
  38. void   do_recv(int);
  39. int    get_recv(void);
  40. void   find_a_server(void);
  41. void   print_address(char *);
  42. void   print_network(char *);
  43. void   print_nodeaddr(char *);
  44. void   parse_cmd_line(int, char **);
  45. void   swap_dwf(char *);
  46. char * get_node_number(char * cmd);
  47. char * get_network_number(char * cmd);
  48. /********************************************************************
  49. m a i n
  50. *********************************************************************/
  51. int main(int argc, char **argv)
  52. {
  53.     char *p;
  54.     unsigned long start = *TIMER;
  55.     unsigned long end;
  56.     int cnt = 0;
  57.     long sendpkt = 0L;
  58.     long recvpkt = 0L;
  59.     int ttime;
  60.     float total = 0;
  61.     progname = *argv;
  62.     for (p = progname; *p; p++) {
  63.     if (*p == '\')
  64. progname = p + 1;
  65.     }
  66.     /** Make sure IPX is loaded **/
  67.     if (IPXInitialize()) {
  68. printf("%s: IPX IS NOT LOADEDn", progname);
  69.     exit(1);
  70.     }
  71.     recv_socket = *(short *)(destaddr + 10);
  72.     parse_cmd_line(argc, argv);
  73.     print_network(destaddr);
  74.     print_nodeaddr(destaddr + 4);
  75.     printf("packet type:    %dn",ptype);
  76.     printf("datasize:       %dn", datasize);
  77.     printf("n iterations:   %dn", niters);    
  78.     
  79.     if (IPXOpenSocket(&send_socket, 0)) {
  80. printf("%s: ERROR: unable to open socketn", progname);
  81. exit(1);
  82.     }
  83.     recv_socket = send_socket;
  84.     if (IPXGetLocalTarget(destaddr, send_ecb.immediateAddress, &ttime)) {
  85. printf("%s: ERROR: unable to get local targetn", progname);
  86. exit(1);
  87.     }
  88.     memcpy(mynodeaddr, send_ecb.immediateAddress, 6);
  89.     /** Go find a server **/
  90.     find_a_server(); 
  91. hang_recvs();
  92.     /** Do # iterations (default = 1) **/
  93. while (cnt < niters) {
  94.     int rcv;
  95. /** send a packet **/
  96. *(sendb + 5) = ptype;
  97.     memcpy(sendb + 6, destaddr, 12);
  98.     memcpy(send_ecb.immediateAddress, mynodeaddr, 6);
  99.     send_ecb.socketNumber = send_socket;
  100.     send_ecb.fragmentCount = 1;
  101.     send_ecb.fragmentDescriptor[0].address = sendb;
  102.     send_ecb.fragmentDescriptor[0].size = 30 + datasize;
  103. IPXSendPacket(&send_ecb);
  104. while (send_ecb.inUseFlag) /* wait for it to finish */
  105. ;
  106. if (send_ecb.completionCode) {
  107. cancel_recvs();
  108. IPXCloseSocket(send_socket);
  109. printf("%s: Error sending packet: %dn", progname, send_ecb.completionCode);
  110. exit(1);
  111. }
  112.     sendpkt++;
  113.     total += 30 + datasize;     /* Count the bytes */
  114.     printf("rSend packet Number %d ", sendpkt);
  115.     if ((rcv = get_recv()) == -1)
  116. goto EXIT;
  117.     do_recv(rcv);
  118.     total += 30 + datasize;     /* Count the bytes */
  119.     cnt++;
  120.     recvpkt++;
  121.     printf(": Recv packet Number %d ", recvpkt);
  122. }
  123. /** We did 1000 packets - print KB per second **/
  124. EXIT:
  125. end = *TIMER;
  126. end = (end - start) / 18.2; /* Num seconds it took */
  127. total = (float)((total / 1024.0) / end);
  128.     /** All done - cancel recvs and exit **/
  129.     cancel_recvs();
  130.     IPXCloseSocket(send_socket);
  131.     printf("n%ld packets n", recvpkt);
  132.     if (recvpkt)
  133. printf("Average time per iteration: %5.3fn",total/recvpkt);
  134.     exit(0);
  135. }
  136. /*page**************************************************************
  137. h a n g _ r e c v s
  138. Arguments - None
  139. Returns - nothing
  140. *******************************************************************/
  141. void hang_recvs(void)
  142. {
  143.     int i;
  144.     for (i = 0; i < 10; i++) {
  145. /** Don't hang recv on one that is already hung **/
  146. if (recv_ecb[i].inUseFlag)
  147.     continue;
  148. /** Hang a recv **/
  149. memset(&recv_ecb[i], 0, sizeof(ECB));
  150. recv_ecb[i].socketNumber = recv_socket;
  151. recv_ecb[i].fragmentCount = 1;
  152. recv_ecb[i].fragmentDescriptor[0].address = recvb;
  153. recv_ecb[i].fragmentDescriptor[0].size = 2048;
  154. IPXListenForPacket(&recv_ecb[i]);
  155.     }
  156.     /** All done **/
  157.     return;
  158. }
  159. /*page**************************************************************
  160. c a n c e l _ r e c v s
  161. Arguments - None
  162. Returns - nothing
  163. *******************************************************************/
  164. void cancel_recvs(void)
  165. {
  166.     int i;
  167.     for (i = 0; i < 10; i++) {
  168. /** If recv not in use - skip it **/
  169. if (!recv_ecb[i].inUseFlag)
  170.     continue;
  171. /** Cancel the recv **/
  172. IPXCancelEvent(&recv_ecb[i]);
  173.     }
  174.     /** All done **/
  175.     return;
  176. }
  177. /*page**************************************************************
  178. d o _ r e c v
  179. Arguments - i = recv index to hang
  180. Returns - nothing
  181. *******************************************************************/
  182. void do_recv(int i)
  183. {
  184.     memset(&recv_ecb[i], 0, sizeof(ECB));
  185.     recv_ecb[i].socketNumber = recv_socket;
  186.     recv_ecb[i].fragmentCount = 1;
  187.     recv_ecb[i].fragmentDescriptor[0].address = recvb;
  188.     recv_ecb[i].fragmentDescriptor[0].size = 2048;
  189.     IPXListenForPacket(&recv_ecb[i]);
  190.     return;
  191. }
  192. /*page**************************************************************
  193. g e t _ r e c v
  194. Arguments - none
  195. Returns - -1 = User hit a key
  196.   else = recv index that was hit
  197. *******************************************************************/
  198. int get_recv(void)
  199. {
  200.     int i;
  201.     /** **/
  202.     while (!kbhit()) {
  203. for (i = 0; i < 10; i++) {
  204. if (!recv_ecb[i].inUseFlag)
  205. return i;
  206. }                        
  207. //      try resending the bugger...maybe we be out of synch?..bug,bug,bug???    
  208.     IPXSendPacket(&send_ecb);           
  209.     }
  210.     /** Return that user hit a key **/
  211.     return -1;
  212. }
  213. /*******************************************************************
  214. function name:      f i n d _ a _ s e r v e r
  215.     Description:    make sure can find the machine we want to send to
  216.     Arguments:      none
  217.     Returns:        none
  218. *********************************************************************/
  219. void find_a_server(void)
  220. {
  221.     long start;
  222.     long end;
  223.     ECB send_ecb;
  224.     ECB recv_ecb;
  225.     /** Setup the recv ecb and listen for a packet **/
  226.     memset(&recv_ecb, 0, sizeof(ECB));
  227.     recv_ecb.socketNumber = recv_socket;
  228.     recv_ecb.fragmentCount = 1;
  229.     recv_ecb.fragmentDescriptor[0].address = recvb;
  230.     recv_ecb.fragmentDescriptor[0].size = 31;
  231.     IPXListenForPacket(&recv_ecb);
  232.     memset(&send_ecb, 0, sizeof(ECB));
  233.     memcpy(sendb + 6, destaddr, 12);
  234.     send_ecb.socketNumber = send_socket;
  235.     memcpy(send_ecb.immediateAddress, mynodeaddr, 6);
  236.     send_ecb.fragmentCount = 1;
  237.     send_ecb.fragmentDescriptor[0].address = sendb;
  238.     send_ecb.fragmentDescriptor[0].size = 31;
  239.     IPXSendPacket(&send_ecb);
  240.     while (send_ecb.inUseFlag && !kbhit())
  241. ;
  242.     if (send_ecb.completionCode) {
  243. printf("%s: ERROR: send completion code 0x%02xn", progname, send_ecb.completionCode);
  244. exit(1);
  245.     }
  246.     /** Wait awhile for the recv to pay off **/
  247.     start = *TIMER;
  248.     while (recv_ecb.inUseFlag && !kbhit() && (*TIMER - start) < 180L)
  249. ;
  250.     end = *TIMER;
  251.     /** If we timed out - then we couldn't find a server **/
  252.     if (end - start >= 180L) {
  253. IPXCancelEvent(&recv_ecb);
  254. IPXCloseSocket(send_socket);
  255. printf("%s: Unable to find a servern", progname);
  256. exit(1);
  257.     }
  258.     /** If recv still in use - error **/
  259.     if (recv_ecb.inUseFlag) {
  260. IPXCancelEvent(&recv_ecb);
  261. IPXCloseSocket(send_socket);
  262. printf("%s: Program terminated by a keystroken", progname);
  263. exit(1);
  264.     }
  265.     /** If recv error - clean up and exit **/
  266.     if (recv_ecb.completionCode) {
  267. IPXCancelEvent(&recv_ecb);
  268. IPXCloseSocket(send_socket);
  269. printf("%s: Error receiving packet: %dn", progname, recv_ecb.completionCode);
  270. exit(1);
  271.     }
  272.     /** Get the server address and print it out **/
  273.     memcpy(destaddr, recvb + 18, 12);   /* Set the address to send to */
  274.     memcpy(mynodeaddr, recv_ecb.immediateAddress, 6);
  275.     printf("Found server: ");
  276.     print_address(destaddr);
  277.     /** All done **/
  278.     return;
  279. }
  280. /********************************************************************
  281. p r i n t _ a d d r e s s
  282. Arguments - netaddr = ptr to 14 bytes address to print
  283. Returns - nothing
  284. *********************************************************************/
  285. void print_address(char *netaddr)
  286. {
  287.     int i;
  288.     for (i = 0; i < 12; i++) {
  289. if ((i == 4) || (i == 10))
  290.     printf(" ");
  291. printf("%02X", (unsigned char) *(netaddr + i));
  292. }
  293.     printf("n");
  294.     return;
  295. }
  296. void print_network(char *p)
  297. {
  298.     int i;
  299.     printf("Network Number: ");
  300.     for (i = 0; i < 4; i++)
  301. printf("%02X", (unsigned char) *p++);
  302.     printf("n");
  303.     return;
  304. }
  305. void print_nodeaddr(char *p)
  306. {
  307.     int i;
  308.     printf("Node Address:   ");
  309.     for (i = 0; i < 6; i++)
  310. printf("%02X", (unsigned char) *p++);
  311.     printf("n");
  312.     return;
  313. }
  314. /*-----------------------------------------------------------------
  315. function name: parse_cmd_line
  316. Description:
  317.     Parse the command line for the parameters and host name.
  318. Arguments:     
  319.        -i <number of iterations>
  320.        -p <packet type>
  321.        -d <data size>
  322.   NOTE: must be < frame size - 14 (MAC length) - 30 (IPX header)
  323.        -n <network number>
  324.   NOTE: you can ignore this if on the same subnet.  Must be 4 hex
  325. bytes
  326.        -a <destination address>
  327.   NOTE: must be 6 hex bytes representing the physical NIC address of
  328. the remote machine.
  329.        -s <socket>
  330.   Two byte socket number
  331. Returns:        Nothing
  332. ----------------------------------------------------------------------*/
  333. void parse_cmd_line(int argc, char **argv)
  334. {
  335.     short socket;
  336.     argv++;                      /* skip to first arg */
  337.     while (--argc) {             /* do all args */
  338. if (**argv == '-') {
  339.     ++(*argv);
  340.     switch(tolower(**argv)) {
  341. case 'i':
  342.     niters = atoi(++(*argv));
  343.     if (niters < 0) 
  344.        niters = 1;
  345.     break;   
  346. case 'p':
  347.     ptype = atoi(++(*argv));
  348.     if (ptype < 0 || ptype > 255) {
  349. ptype = 4;
  350. printf("%s: Invalid packet type.  Setting to default = %dn",
  351. progname,ptype);
  352.     }
  353.     break;
  354. case 'd':  /*amount of data to send in a frame */
  355.     datasize = atoi(++(*argv));
  356.     if (!datasize) {
  357. datasize = 1;
  358. printf("%s: Datasize cannot be zero. Setting to default = 1n", progname);
  359.     }
  360.     break;
  361. case 's':  /* socket number, default = 0x3000 */
  362.     socket = (short)strtol(++(*argv), NULL, 16);
  363.     printf("New socket = 0x%xn", socket);
  364.     *(short *)(destaddr + 10) = socket;
  365.     swap_dwf(destaddr + 10);
  366.     break;
  367. case 'n':  /* network number, default = local net (= 0) */
  368.     ++(*argv);
  369.     memcpy(destaddr, get_network_number(*argv),4);
  370.     if (destaddr[0] == 'X') {
  371. printf("n****!n%s is an incorrect net number.n****!n", *argv);
  372. printf("%s E.G.: -nAABBCCDD (I.E.: 8 hex digits)n");
  373. exit(1);
  374.     }
  375.     break;
  376. case 'a': /* remote address, have to know this */
  377.     ++(*argv);
  378.     memcpy(destaddr+4, get_node_number(*argv), 6);
  379.     if (*(destaddr+4) == 'X') {
  380.        printf("n****!n%s is an incorrect Node address.n****!n", *argv);
  381.        printf("n E.G.: -a 023C8DAADDCC (12 hex digits)n");
  382.        exit(1);
  383.     }
  384.     break;
  385. default:
  386.     printf("%s [-p] [-d] [-nxxxxxxxx] [-axxxxxxxxxxxx] [-sx]n", progname);
  387.     printf("     -p - packet typen");
  388.     printf("     -d - data sizen");
  389.     printf("     -n - network number (in hex)n");
  390.     printf("     -a - address (in hex)n");
  391.     printf("     -s - socket number (in hex)n");
  392.     exit(0);
  393.     }
  394.     argv++;
  395. }
  396.     }
  397.     return;
  398. }
  399. /**********************************************************************
  400.     g e t _ h e x _ b y t e
  401.     Converts the character passed in to a hexadecimal nibble.
  402.     Arguments:    char    character to convert
  403.     Returns:      UCHAR   hex nibble
  404. **************************************************************************/
  405. char get_hex_byte(char ch)
  406. {
  407.     if (ch >= '0' && ch <= '9')
  408.     return (ch - '0');
  409.     if (ch >= 'A' && ch <= 'F')
  410.     return ((ch - 'A') + 0x0A);
  411.     return -1;
  412. }
  413. /**********************************************************************
  414.     g e t _ h e x _ s t r i n g
  415.     Reads in a character string containing hex digits and converts
  416.     it to a hexadecimal number.
  417.     Arguments:    src   => source string to convert
  418.   dest  => destination for hex number
  419.   num   => number of chars to convert
  420.     Returns:      nothing
  421. **************************************************************************/
  422. char get_hex_string(char * src, char * dest, int num)
  423. {
  424.     char *   q = src;
  425.     char     hexbyte1,hexbyte2;
  426.     strupr(q);
  427.     while (num--)
  428.       {hexbyte1 = get_hex_byte(*q++);
  429.        hexbyte2 = get_hex_byte(*q++);
  430.        if ( (hexbyte1 < 0) || (hexbyte2 < 0) )
  431.       return -1;
  432.        *dest++ = (hexbyte1 << 4) + hexbyte2;
  433.       }
  434.     return(0);
  435. }
  436. /*************************************************************************
  437.     g e t _ n o d e _ n u m b e r
  438.     Reads a node number from the given string.
  439.     Arguments:    cmd  => string to read from
  440.     Returns:      hex node number
  441. **************************************************************************/
  442. char * get_node_number(char * cmd)
  443. {
  444.     static char hex_num[6];
  445.     memset(hex_num, 0, 6);
  446.     if (strlen(cmd) != 12){
  447.     hex_num[0] = 'X';
  448.     return hex_num;
  449.        }
  450.     if (get_hex_string(cmd, hex_num, 6) < 0)
  451.     hex_num[0] = 'X';
  452.     return hex_num;
  453. }
  454. /**************************************************************************
  455.     g e t _ n e t w o k _ n u m b e r
  456.     Reads a network number from the given string.
  457.     Arguments:    cmd   string to read from
  458.     Returns:      hex network number
  459. **************************************************************************/
  460. char * get_network_number(char * cmd)
  461. {
  462.     static char hex_num[4];
  463.     memset(hex_num, 0, 4);
  464.     if (strlen(cmd) != 8) {
  465.     hex_num[0] = 'X';
  466.     return(hex_num);
  467.     }
  468.     if (get_hex_string(cmd, hex_num, 4) < 0)
  469.     hex_num[0] = 'X';
  470.     return hex_num;
  471. }
  472. /*******************************************************************
  473. s w a p _ d w f
  474. Swap the bytes pointed to by p.
  475. Arguments - p = ptr to word to swap
  476. Returns - nothing
  477. ********************************************************************/
  478. void swap_dwf(char *p)
  479. {
  480.     char tmp;
  481.     tmp = *p;
  482.     *p = *(p + 1);
  483.     *(p + 1) = tmp;
  484.     return;
  485. }