Annotation of mstools/samples/nwlink/ping/dos/dosping.c, revision 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.