Annotation of mstools/samples/nwlink/ping/dos/dosping.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.