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