/*************************************************************
* 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:
* $ CC LAN802E
* $ LINK LAN802E,SYS$INPUT:/OPT
* SYS$SHARE:VAXCRTL.EXE/SHARE
*
* Note: NMADEF.H must be supplied containing definitions for:
*
* #define NMA$C_PCLI_FMT 2770
* #define NMA$C_PCLI_PID 2774
* #define NMA$C_PCLI_PHA 2820
* #define NMA$C_LINFM_802E 0
*
* To build on Alpha, I64:
* $ CC LAN802E+SYS$LIBRARY:SYS$LIB_C.TLB/LIB
* $ LINK LAN802E
*
* To run:
* $ RUN LAN802E
*************************************************************/
#include <ctype> /* Character type classification macros/routines */
#include <descrip> /* For VMS descriptor manipulation */
#include <iodef> /* I/O function code definitions */
#include "nmadef.h" /* LAN parameter 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 $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),&setparm_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};
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),sense_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(&devdsc,&chan,0,0);
if ($FAIL(status)) exit(status);
status = sys$qiow(0,chan,IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP,&qio_iosb,0,0,0,&setparmdsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status)) {
printf("IOSB addl status = %04X %04X\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,&qio_iosb,0,0,0,&sensedsc_loop,0,0,0,0);
if ($SUCCESS(status)) status = qio_iosb.w_err;
if ($FAIL(status)) {
printf("IOSB addl status = %04X %04X\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(&xmt_buffer[4],&sense_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,&qio_iosb,0,0,&xmt_buffer[0],
sizeof(xmt_buffer),0,0,&xmt_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,&qio_iosb,0,0,&rcv_buffer[0],
sizeof(rcv_buffer),0,0,rcv_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");
} |