/************************************************************* * LAN Sample Test Program * * This LAN test program sends a MOP loopback message to the Loopback Assistant * Multicast address and waits for a response. The program uses the LAN device * EWA0. To use a different device, change the device name in the program or * define the desired lan device as EWA0. * * To build on VAX: To build on Alpha: * $ CC LAN802E $ CC LAN802E + SYS$LIBRARY:SYS$LIB_C.TLB/LIB * $ LINK LAN802E,SYS$INPUT:/OPT $ LINK LAN802E * SYS$SHARE:VAXCRTL.EXE/SHARE *************************************************************/ #include <ctype>/* Character type classification macros/routines */#include <descrip> /* For VMS descriptor manipulation */#include <iodef> /* I/O function code definitions */#include <ssdef> /* System service return status code definitions */#include <starlet> /* System library routine prototypes */#include <stdio> /* ANSI C Standard Input/Output */#include <stdlib> /* General utilities */#include <string> /* String handling */#include <stsdef> /* VMS status code definitions */ #define NMA$C_PCLI_FMT 2770#define NMA$C_PCLI_PID 2774#define NMA$C_PCLI_PHA 2820#define NMA$C_LINFM_802E 0#define $SUCCESS(status) ( ((status) & STS$M_SUCCESS) == SS$_NORMAL)#define $FAIL(status) ( ((status) & STS$M_SUCCESS) != SS$_NORMAL) #pragma nomember_alignment struct parm_802e{ short pcli_fmt; /* Format - 802E */ int fmt_value; short pcli_pid; /* Protocol ID - 08-00-2B-90-00 */ short pid_length; char pid_value[5];} setparm_802e = {NMA$C_PCLI_FMT, NMA$C_LINFM_802E,NMA$C_PCLI_PID, 5, 8,0,0x2b,0x90,0}; struct setparmdsc{ int parm_len; void *parm_buffer;}; struct setparmdsc setparmdsc_loop = {sizeof(setparm_802e),_802e}; struct p5_param /* P5 Receive header buffer */{ unsigned char da[6]; unsigned char sa[6]; char misc[20];}; struct iosb /* IOSB structure */{ short w_err; /* Completion Status */ short w_xfer_size; /* Transfer Size */ short w_addl; /* Additional status */ short w_misc; /* Miscellaneous */}; struct ascid /* Device descriptor for assign */{ short w_len; short w_info; char *a_string;} devdsc = {4,0,"EWA0"}; struct iosb qio_iosb; /* IOSB structure */struct p5_param rcv_param; /* Receive header structure */struct p5_param xmt_param={ /* Transmit header structure */ 0xCF,0,0,0,0,0}; /* Loopback Assistant Multicast Address */char rcv_buffer[512]; /* Receive buffer */char xmt_buffer[20]={ /* Transmit buffer */ 0,0, /* Skip count */ 2,0, /* Forward request */ 0,0,0,0,0,0, /* Forward address */ 1,0, /* Reply request */ 0,0}; char sense_buffer[512]; /* Sensemode buffer */ struct setparmdsc sensedsc_loop = {sizeof(sense_buffer),_buffer}; /* * MAIN */ main(int argc, char *argv[]){ int i, j; /* Scratch */ int chan; /* Channel assigned */ int status; /* Return status */ /* * Start a channel. */ status = sys$assign(,,0,0); if ($FAIL(status) ) exit(status); status = sys$qiow(0,chan,IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP,_iosb,0,0,0, _loop,0,0,0,0); if ($SUCCESS(status) ) status = qio_iosb.w_err; if ($FAIL(status) ) { printf("IOSB addl status = %04X %04X (on startup)\n",qio_iosb.w_addl,qio_iosb.w_misc); exit(status); } /* * Issue the SENSEMODE QIO to get our physical address for the loopback message. */ status = sys$qiow(0,chan,IO$_SENSEMODE|IO$M_CTRL,_iosb,0,0,0, _loop,0,0,0,0); if ($SUCCESS(status) ) status = qio_iosb.w_err; if ($FAIL(status) ) { printf("IOSB addl status = %04X %04X (on sensemode)\n", qio_iosb.w_addl,qio_iosb.w_misc); exit(status); } /* * Locate the PHA parameter in the SENSEMODE buffer and copy it into the * LOOPBACK transmit message. The PHA parameter is a string parameter. */ j = 0; while (j < sizeof(sense_buffer) ) { i = (sense_buffer[j] + (sense_buffer[j+1]<<8) ); if (0x1000 & i) { if ( (i & 0xFFF) == NMA$C_PCLI_PHA) { memcpy(_buffer[4],_buffer[j+4],6); break; } j += (sense_buffer[j+2] + (sense_buffer[j+3]<<8) ) + 4; } else { j += 6; /* Skip over longword parameter */ } } /* * Transmit the loopback message. */ status = sys$qiow(0,chan,IO$_WRITEVBLK,_iosb,0,0,_buffer[0], sizeof(xmt_buffer),0,0,_param,0); if ($SUCCESS(status) ) status = qio_iosb.w_err; if ($FAIL(status) ) { printf("IOSB addl status = %04X %04X (on transmit)\n", qio_iosb.w_addl,qio_iosb.w_misc); exit(status); } /* * Look for a response. We use the NOW function modifier on the READ so that * we don't hang here waiting forever if there is no response. If there is no * response in 1000 receive attempts, we declare no response status. */ for (i=0;i<1000;i++) { status = sys$qio(0,chan,IO$_READVBLK|IO$M_NOW,_iosb,0,0,_buffer[0], sizeof(rcv_buffer),0,0,_param,0); if ($SUCCESS(status) ) status = qio_iosb.w_err; if ($SUCCESS(status) ) break; } if ($SUCCESS(status) ) printf("Successful test\n"); else printf("No response\n"); } |