CMDLINE.C
/****************************************************************************\ 
*  cmdline.c -- sample program library demonstrating NWLink. 
* 
*       Microsoft Developer Support 
*       Copyright 1992 - 1998 Microsoft Corporation 
* 
*  Demonstrates basic sockets programming with the Windows Sockets API 
*  using the NWLink transport. 
*  
****************************************************************************/ 
#include <stdio.h> 
#include <stdlib.h> 
#include <windows.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include "externs.h" 
#include <wsipx.h> 
#include "testlib.h" 
 
/* 
*   Global variables that can be set on the command line  
*/ 
 
int     verbose = 0; 
int     Socket_Type = SOCK_DGRAM; 
int     Protocol = NSPROTO_IPX; 
int     Backlog = 1; 
int     No_Broadcast = 0; 
int     No_Loop = 0; 
int     Sleep_Time = 250; 
int     Send_Length = 1024; 
int     Receive_Length = 1024; 
int     Local_Packet_Type = 0; 
int     Send_Packet_Type = 9; 
int     Filter_Packet_Type = 0; 
int     Local_Address_Family = AF_NS; 
int     Remote_Address_Family = AF_NS; 
char    Local_Network_Number[4]  = {0x00, 0x00, 0x00, 0x00}; 
char    Local_Node_Number[6]     = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 
char    Local_Socket_Number[2]   = {0x00, 0x00}; 
char    Remote_Network_Number[4] = {0x00, 0x00, 0x00, 0x00}; 
char    Remote_Node_Number[6]    = "\xFF\xFF\xFF\xFF\xFF\xFF"; 
char    Remote_Socket_Number[2]  = {0x12, 0x34}; 
 
/* 
*   Function prototypes for this file  
*/ 
 
void  usage(LPSTR); 
void  dump_defaults(LPSTR); 
void  get_hex_string(LPSTR, LPSTR, int); 
UCHAR get_hex_byte(char); 
 
/**************************************************************************** 
* 
*    FUNCTION:  parse_cmd_line( int argc, char **argv ) 
* 
*    DESCRIPTION:  Routine used by all of the WinSock test programs for NWLink. 
*        Parses the command line and sets the respective global variables.  
* 
*    ARGUMENTS: char **     => array of command line arguments 
*                int         number of command line arguments 
* 
* RETURNS:  nothing 
* 
*\***************************************************************************/ 
void parse_cmd_line(int argc, char **argv) 
{ 
    LPSTR p; 
    int num = 1; 
 
    argc--; 
 
    /* 
    *   Parse each command line parameter  
    */ 
 
    while (num <= argc) { 
        /* 
        *   If option starts with '-' or '/', skip it  
        */ 
 
        p = strupr(argv[num++]); 
        if (*p == '-' || *p == '/') 
            p++; 
 
        /* 
        *   Help ?  
        */ 
 
        printf("***> command: %s\n:",p); 
        if (*p == 'h' || *p == 'H' || *p == '?' || !stricmp(p, "help")) 
    usage(argv[0]); 
 
        /* 
        *   Verbose option?  
        */ 
 
        if (!stricmp(p, "v") || !stricmp(p, "verbose")) { 
            verbose++; 
 
            printf("verbose is ON\n"); 
            continue; 
        } 
 
        /* 
        *   Display default values ?  
        */ 
 
        if (!strnicmp(p, "default", 7)) { 
            p+= 7; 
 
            dump_defaults(argv[0]); 
        } 
 
        /* 
        *   Local address family ?  
        */ 
 
        if (!strnicmp(p, "laf:", 4)) { 
            p+= 4; 
 
            /* 
            *   Get the address family from the option  
            */ 
 
            Local_Address_Family = atoi(p); 
 
            if (verbose) 
                printf("Local_Address_Family = %d\n", Local_Address_Family); 
            continue; 
        } 
 
        /* 
        *   Remote address family ?  
        */ 
 
        if (!strnicmp(p, "raf:", 4)) { 
            p+= 4; 
 
            /* 
            *   Get the address family from the option  
            */ 
 
            Remote_Address_Family = atoi(p); 
 
            if (verbose) 
                printf("Remote_Address_Family = %d\n", Remote_Address_Family); 
            continue; 
        } 
 
        /* 
        *   Socket type ?  
        */ 
 
        if (!strnicmp(p, "st:", 3)) { 
            p+= 3; 
 
            /* 
            *   Get the socket type from the option  
            */ 
 
            Socket_Type = atoi(p); 
            if (verbose) 
printf("Socket_Type = %d\n", Socket_Type); 
            continue; 
        } 
#if(0) 
        /* 
        *   Socket family ?  
        */ 
 
        if (!strnicmp(p, "sf:", 3)) { 
            p+= 3; 
 
            /* 
            *   Get the socket family from the option  
            */ 
 
            Socket_Family = get_socket_family(p); 
            continue; 
        } 
#endif 
        /* 
        *   Protocol ?  
        */ 
 
        if (!strnicmp(p, "proto:", 6)) { 
            p+= 6; 
 
            /* 
            *   Get the protocol from the option  
            */ 
 
            Protocol = atoi(p); 
 
            if (verbose) 
        printf("Protocol = %d\n", Protocol); 
            continue; 
        } 
 
        /* 
        *   Local network number ?  
        */ 
 
        if (!strnicmp(p, "lnet:", 5)) { 
            p+= 5; 
 
            /* 
            *   Get the local network number from the option  
            */ 
 
            memcpy(Local_Network_Number, get_network_number(p), 4); 
            if (verbose) { 
                printf("Local_Network_Number = "); 
                print_network_num(Local_Network_Number); 
                printf("\n"); 
            } 
            continue; 
        } 
 
 
        /* 
        *   Local node number ?  
        */ 
 
        if (!strnicmp(p, "lnode:", 6)) { 
            p+= 6; 
 
            /* 
            *   Get the local network number from the option  
            */ 
 
            memcpy(Local_Node_Number, get_node_number(p), 6); 
            if (verbose) { 
                printf("Local_Node_Number = "); 
 print_node_num(Local_Node_Number); 
                printf("\n"); 
            } 
            continue; 
        } 
 
        /* 
        *   Remote network number ?  
        */ 
 
        if (!strnicmp(p, "rnet:", 5)) { 
            p+= 5; 
 
            /* 
            *   Get the remote network number from the option  
            */ 
 
            memcpy(Remote_Network_Number, get_network_number(p), 4); 
            if (verbose) { 
                printf("Remote_Network_Number = "); 
                print_network_num(Remote_Network_Number); 
                printf("\n"); 
            } 
            continue; 
        } 
 
        /* 
        *   Remote node number ?  
        */ 
 
        if (!strnicmp(p, "rnode:", 6)) { 
            p+= 6; 
 
            /* 
            *   Get the remote network number from the option  
            */ 
 
            memcpy(Remote_Node_Number, get_node_number(p), 6); 
            if (verbose) { 
                printf("Remote_Node_Number = "); 
 print_node_num(Remote_Node_Number); 
                printf("\n"); 
            } 
            continue; 
        } 
 
        /* 
        *   Local socket number ?  
        */ 
 
        if (!strnicmp(p, "lsock:", 6)) { 
            p+= 6; 
 
            /* 
            *   Get the local socket number from the command line  
            */ 
 
            memcpy(Local_Socket_Number, get_socket_number(p), 2); 
 
    if (verbose) { 
                printf("Local_Socket_Number = "); 
                print_socket_num(Local_Socket_Number); 
                printf("\n"); 
            } 
            continue; 
        } 
 
        /* 
        *   Remote socket number ?  
        */ 
 
        if (!strnicmp(p, "rsock:", 6)) { 
            p+= 6; 
 
            /* 
            *   Get the remote socket number from the command line  
            */ 
 
            memcpy(Remote_Socket_Number, get_socket_number(p), 2); 
 
    if (verbose) { 
                printf("Remote_Socket_Number = "); 
                print_socket_num(Remote_Socket_Number); 
                printf("\n"); 
            } 
            continue; 
        } 
 
 
        /* 
        *   Send length ?  
        */ 
 
        if (!strnicmp(p, "sendlen:", 8)) { 
            p+= 8; 
 
            /* 
            *   Get the amount of data to send from the command line  
            */ 
 
            Send_Length = atoi(p); 
            if (verbose) 
                printf("Send length = %d\n", Send_Length); 
 
            continue; 
        } 
 
        /* 
        *   Receive length ?  
        */ 
 
        if (!strnicmp(p, "recvlen:", 8)) { 
            p+= 8; 
 
            /* 
            *   Get the amount of data to send from the command line  
            */ 
 
            Receive_Length = atoi(p); 
            if (verbose) 
                printf("Receive length = %d\n", Receive_Length); 
 
            continue; 
        } 
 
        /* 
        *   Send packet type ?  
        */ 
 
        if (!strnicmp(p, "sptype:", 7)) { 
    p+= 7; 
 
            /* 
            *   Get the packet type from the command line  
            */ 
 
            Send_Packet_Type = atoi(p); 
 
      if (verbose) 
printf("Send_Packet_Type = %d\n", Send_Packet_Type); 
            continue; 
        } 
 
        /* 
        *   Local packet type ?  
        */ 
 
        if (!strnicmp(p, "lptype:", 7)) { 
    p+= 7; 
 
            /* 
            *   Get the packet type from the command line  
            */ 
 
            Local_Packet_Type = atoi(p); 
 
      if (verbose) 
printf("Send_Packet_Type = %d\n", Send_Packet_Type); 
            continue; 
        } 
 
        /* 
        *   Filter packet type ?  
        */ 
 
        if (!strnicmp(p, "fptype:", 7)) { 
    p+= 7; 
 
            /* 
            *   Get the packet type from the command line  
            */ 
 
            Filter_Packet_Type = atoi(p); 
 
      if (verbose) 
printf("Filter_Packet_Type = %d\n", Send_Packet_Type); 
            continue; 
        } 
 
        /* 
        *   Backlog size ?  
        */ 
 
        if (!strnicmp(p, "backlog:", 8)) { 
     p+= 8; 
 
            Backlog = atoi(p); 
 
            if (verbose) 
                printf("Backlog = %d\n", Backlog); 
            continue; 
        } 
 
        /* 
        *   No broadcast flag ?  
        */ 
 
        if (!strnicmp(p, "nobcast", 7)) { 
            p+= 7; 
 
            No_Broadcast++; 
 
            if (verbose) 
                printf("No broadcast flag is set\n"); 
 
            continue; 
        } 
 
        /* 
        *   No loop flag ?  
        */ 
 
        if (!strnicmp(p, "noloop", 6)) { 
            p+= 6; 
 
            No_Loop++; 
 
            if (verbose) 
                printf("No loop flag is set\n"); 
 
            continue; 
        } 
 
        /* 
        *   Sleep time ?  
        */ 
 
        if (!strnicmp(p, "sleep:", 6)) { 
            p+= 6; 
 
            Sleep_Time = atoi(p); 
 
            if (verbose) 
                printf("Sleep time = %d\n", Sleep_Time); 
 
            continue; 
        } 
 
 
        if (*p) 
            printf("Unknown command line parameter: %s\n", p); 
 
    } /* while */ 
 
    if (verbose) 
        printf("\n\n"); 
} 
 
/**************************************************************************** 
* 
*    FUNCTION:  usage( LPSTR progname ) 
* 
*    PURPOSE:   Displays all allowable command line parameters.  (All may not be used 
*       by the program linking to this library, however). 
* 
*    ARGUMENTS:LPSTR=> program name 
* 
* RETURNS:   exits with errorlevel 0 
* 
*\***************************************************************************/ 
void usage(LPSTR progname) 
{ 
    printf("\n\nUsage: %s [options]\n", progname); 
    printf("\n"); 
    printf("Valid options are:\n"); 
    printf("-v               Toggles verbose mode ON\n"); 
    printf("-laf:x           Sets local address family to x\n"); 
    printf("-raf:x           Sets remote address family to x\n"); 
    printf("-st:x            Sets socket type to x\n"); 
    printf("-proto:x         Sets protocol to x\n"); 
    printf("-sleep:x         Sets sleep time between sends to x milliseconds\n"); 
    printf("-backlog:x       Sets listen backlog size to x indications\n"); 
    printf("-nobcast         Sets flag so program won't set sockopt to broadcast\n"); 
    printf("-noloop          Sets flag so program won't loop\n"); 
    printf("-sptype:x        Sets send packet type to x\n"); 
    printf("-lptype:x        Sets local packet type to x\n"); 
    printf("-fptype:x        Sets filter for incoming packet type x\n"); 
    printf("-sendlen:x       Sets amount of data to send to x bytes\n"); 
    printf("-recvlen:x       Sets amount of data to receive to x bytes\n"); 
    printf("-lnet:xxxx       Sets local network number to xxxx (1)\n"); 
    printf("-lnode:xxxxxx    Sets local node number to xxxxxx (1)\n"); 
    printf("-rnet:xxxx       Sets remote network number to xxxx (1)\n"); 
    printf("-rnode:xxxxxx    Sets remote node number to xxxxxx (1)\n"); 
    printf("-rsock:xx        Sets remote socket number to xx (1)\n"); 
    printf("-default         Displays programs default values\n"); 
    printf("-?, -help, or -h Displays this screen\n"); 
    printf("\n"); 
    printf("Notes:  (1) Network numbers (network, node, and socket) must\n"); 
    printf("            be specified as a series of hexadecimal numbers,\n"); 
    printf("            for example: -lnet:04003BFF. \n"); 
    printf("\n"); 
    printf("        All values must come immediately after the ':'\n"); 
    printf("        -default and/or -v should be first\n"); 
    printf("        Not all programs make use of all the above parameters\n"); 
 
    exit(0); 
} 
 
/**************************************************************************** 
* 
*    FUNCTION:  dump_defaults( LPSTR progname ) 
* 
*    PURPOSE:   Prints out the current values of the command line options 
*        
* 
*    ARGUMENTS:LPSTR=> program name 
* 
* RETURNS:   nothing 
* 
*\***************************************************************************/ 
void dump_defaults(LPSTR progname) 
{ 
    printf("Default option values for %s:\n\n", progname); 
 
    printf("verbose =                %d\n", verbose); 
    printf("socket type =            %d\n", Socket_Type); 
    printf("protocol =               %d\n", Protocol); 
    printf("sleep time =             %d\n", Sleep_Time); 
    printf("backlog =                %d\n", Backlog); 
    printf("nobcast =                %d\n", No_Broadcast); 
    printf("noloop =                 %d\n", No_Loop); 
    printf("send length =            %d\n", Send_Length); 
    printf("receive length =         %d\n", Receive_Length); 
    printf("send packet type =       %d\n", Send_Packet_Type); 
    printf("local packet type =      %d\n", Local_Packet_Type); 
    printf("filter packet type =     %d\n", Filter_Packet_Type); 
    printf("local address family =   %d\n", Local_Address_Family); 
    printf("remote address family =  %d\n", Remote_Address_Family); 
    printf("local network number =   "); 
    print_network_num(Local_Network_Number); 
    printf("\nlocal node number =      "); 
    print_node_num(Local_Node_Number); 
    printf("\nlocal socket number =    "); 
    print_socket_num(Local_Socket_Number); 
    printf("\nremote network number =  "); 
    print_network_num(Remote_Network_Number); 
    printf("\nremote node number =     "); 
    print_node_num(Remote_Node_Number); 
    printf("\nremote socket number =   "); 
    print_socket_num(Remote_Socket_Number); 
    printf("\n\n"); 
} 
 
 
/**************************************************************************** 
* 
*    FUNCTION:  get_network_number( LPSTR cmd ) 
* 
*    PURPOSE:   Reads a network number from the given string 
* 
* 
*    ARGUMENTS:LPSTR  => string to read from 
* 
* RETURNS:   LPSTR  => hex network number 
* 
*\***************************************************************************/ 
LPSTR get_network_number(LPSTR cmd) 
{ 
    static char hex_num[4]; 
 
    memset(hex_num, 0, 4); 
 
    if (strlen(cmd) != 8) { 
        printf("Incorrect format for network number.\n"); 
        exit(1); 
    } 
 
    get_hex_string(cmd, hex_num, 4); 
 
    return hex_num; 
} 
 
/**************************************************************************** 
* 
*    FUNCTION:  get_node_number( LPSTR cmd ) 
* 
*    PURPOSE:   Reads a node number from the given string 
* 
* 
*    ARGUMENTS:LPSTR  => string to read from 
* 
* RETURNS:   LPSTR  => hex network number 
* 
*\***************************************************************************/ 
LPSTR get_node_number(LPSTR cmd) 
{ 
    static char hex_num[6]; 
 
    memset(hex_num, 0, 6); 
 
    if (strlen(cmd) != 12) { 
        printf("Incorrect format for node number.\n"); 
        exit(1); 
    } 
 
    get_hex_string(cmd, hex_num, 6); 
 
    return hex_num; 
} 
 
/**************************************************************************** 
* 
*    FUNCTION:  get_socket_number( LPSTR cmd ) 
* 
*    PURPOSE:   Reads a socket number from the given string 
* 
* 
*    ARGUMENTS:LPSTR  => string to read from 
* 
* RETURNS:   LPSTR  => hex network number 
* 
*\***************************************************************************/ 
LPSTR get_socket_number(LPSTR cmd) 
{ 
    static char hex_num[2]; 
 
    memset(hex_num, 0, 2); 
 
    if (strlen(cmd) != 4) { 
        printf("Incorrect format for socket number.\n"); 
        exit(1); 
    } 
 
    get_hex_string(cmd, hex_num, 2); 
 
    return hex_num; 
} 
 
/**************************************************************************** 
* 
*    FUNCTION:  get_hex_string( LPSTR src, LPSTR dest, int num ) 
* 
*    PURPOSE:   Reads in a character string containing hex digits and converts 
*it to a hexadecimal number. 
* 
*    ARGUMENTS:LPSTR  => source string 
*LPSTR  => destination for hex number 
*int    number of bytes to convert 
* 
* RETURNS:   nothing 
* 
*\***************************************************************************/ 
void get_hex_string(LPSTR src, LPSTR dest, int num) 
{ 
    LPSTR q = src; 
 
    while (num--) 
        *dest++ = (get_hex_byte(*q++) << 4) + get_hex_byte(*q++); 
 
} 
 
/**************************************************************************** 
* 
*    FUNCTION:  get_hex_byte( char ch ) 
* 
*    PURPOSE:   Converts the character passed in to a hexadecimal nibble. 
* 
*    ARGUMENTS:char    character to convert 
* 
* RETURNS:   UCHAR   hex nibble 
* 
*\***************************************************************************/ 
UCHAR get_hex_byte(char ch) 
{ 
    if (ch >= '0' && ch <= '9') 
        return (ch - '0'); 
 
    if (ch >= 'A' && ch <= 'F') 
        return ((ch - 'A') + 0x0A); 
 
    printf("Illegal character %c in hex string\n", ch); 
    exit(1); 
}