 | OpenVMS I/O User's Reference Manual
9.16.4.1 IO$M_SENSE_MAC Functional Modifier to IO$_SENSEMODEThe IO$M_SENSE_MAC qualifier, when used with IO$_SENSEMODE, returns theparameters specified in Section 9.16.3.6. In addition to the set macparameters, Table 9-22 shows the returns of the followingparameters: Table 9-22 Parameters of IO$M_SENSE_MAC Parameter ID | Meaning | NMA$C_PCLI_T_NEG | The negotiated value of the token rotation timer (ANSI MAC parameter T_neg) (FDDI only). | NMA$C_PCLI_DAT | The duplicate address test flag (FDDI only). If set, this indicates that there is another station on the ring with the same hardware LAN address. | ++NMA$C_PCLI_UNA | Upstream neighbor's address (FDDI and Token Ring). This is a string parameter specifying the 6-byte LAN address of the upstream neighbor. Not all devices may support this feature. | NMA$C_PCLI_OLD_UNA | The old (previous) upstream neighbor address (FDDI only). Neighbor addresses change as nodes insert and deinsert into the ring. | NMA$C_PCLI_UN_DAT | The upstream neighbor's duplicate address test flag (FDDI only). | NMA$C_PCLI_DNA | The downstream neighbor's LAN address (FDDI only). | NMA$C_PCLI_OLD_DNA | The old (previous) downstream neighbor's LAN address (FDDI only). | NMA$C_PCLI_RPS | The current ring purger state (FDDI only). This longword parameter is one of the following values: 0---Off 1---Candidate 2---Non-purger 3---Purger | NMA$C_PCLI_RER | The latest ring error reason (FDDI only). This longword parameter is one of the following values: 0---No Error 5---Ring Init initiated 6---Ring Init received 7---Ring beaconing initiated 8---Duplicate address detected 9---Duplicate token detected 10---Ring purger error 11---FCI strip error 12---Ring op oscillation 14---PC trace initiated 15---PC trace received | NMA$C_PCLI_NBR_PHY | Neighbor's PHY type (FDDI only). This longword parameter is one of the following values: 0---A 1---B 2---S 3---M 4---Unknown | NMA$C_PCLI_RJR | Ring reject reason (FDDI only). This longword parameter is one of the following values: 0---None 1---Local LCT 2---Remote LCT 3---LCT both sides 4---LEM reject 5---Topology error 6---Noise reject 7---Remote reject 8---Trace in progress 9---Trace received-disabled 10---Standby 11---LCT protocol error | NMA$C_PCLI_LEE | Link error estimate (FDDI only). The longword value is a negative exponent of 10 representing the Link error rate. For example, the value of X represents the error rate of 10^X. | ++NMA$C_PCLI_RNG_NUM | The longword value contains the ring number that the controller is running on (Token Ring only). It is only valid for a controller that is started, and also only valid for rings that have a ring parameter server that is configured for providing this information. | ++Alpha specific.
9.16.4.2 IO$M_SHOW_MAP Functional Modifier to IO$_SENSMODE (Alpha Only)On Alpha systems using Token Ring only, the IO$M_SHOW_MAP qualifier,when used with IO$_SENSEMODE, returns the current setting of themapping table. The P2 buffer is filled with the current multicast tofunctional address mapping information. The entries are 16 bytes longand are in the format shown in Figure 9-28. This QIO requires PHY_IOprivilege. Figure 9-28 Format of IO$M_SHOW_MAP P2 Buffer (AlphaOnly)
 The multicast address and functional address mask are returned incanonical format (that is, not bit-reversed). The following errors mayoccur: - SS$_BUFFEROVF---The passed buffer is not large enough to hold all the data required for the operation.
- SS$_BADPARAM---Not able to get read access to buffer or zero length buffer passed.
9.16.4.3 IO$M_SHOW_ROUTE Functional Modifier to IO$_SENSEMODE (Alpha Only)On Alpha systems with Token Ring only, the IO$M_SHOW_ROUTE qualifier,when used with IO$_SENSEMODE, returns the current value of the sourcerouting cache table. Each entry is 64 bytes long. Figure 9-29 showsthe format of the returned P2 buffer: Figure 9-29 Format of IO$M_SHOW_ROUTE P2 Buffer (AlphaOnly)
 Table 9-23 shows possible states of the entry. Table 9-23 State of the Entry Value | Name | Description | 0 | LOCAL | Address is reachable on the attached ring. | 1 | STALE | Entry is stale (inactive). | 2 | UNKNOWN | Route to the address is unknown. | 3 | DELETED | Entry is marked for deletion. | 4 | KNOWN | Route is known and the route is stored in the routing information string. | 5 | EXPLORING | Route to the address is currently being explored. | The LAN address is returned in canonical format (that is, notbit-reversed). The timers are recorded as seconds before expiration.The transmit and receive timers are initialized from theNMA$C_PCLI_A_TIM parameter, the discovery timer is initialized from theNMA$C_PCLI_ROUTEDIS parameter, and the stale timer is initialized to 10minutes (600 seconds). The following errors may occur: - SS$_BUFFEROVF---The passed buffer is not large enough to hold all the data required for the operation.
- SS$_BADPARAM---Not able to get read access to buffer or zero length buffer passed.
9.17 I/O Status BlockThe I/O status block (IOSB) for all LAN driver functions is shown inFigure 9-30. Appendix A lists the completion status returned forthese functions. (The OpenVMS system messages documentation providesexplanations and suggested user actions for these status codes.) Figure 9-30 IOSB Contents
 The first longword of the IOSB returns, in addition to the completionstatus, either the size (in bytes) of the data transfer or the size (inbytes) of the attribute buffer (P2) returned by a sense mode function.The second longword returns the unit and line status bits listed inTable 9-9 and the error summary bits listed in Table 9-10.9.18 Application Programming Notes This section contains information to assist you in writing application programs that use the LAN device drivers. Section 9.18.1 discusses the additional rules required for application programs that you intend to run in promiscuous mode. Section 9.18.2 describe the Ethernet and 802 sample programs.9.18.1 Promiscuous Mode The LAN drivers allow only one port per controller to enablepromiscuous mode (NMA$C_PCLI_PRM specified as NMA$C_STATE_ON). A portrunning in promiscuous mode usually places an additional load on theCPU because the LAN device is configured to deliver all packets on theLAN to the LAN driver. Table 9-24 details additional rules for ports running in promiscuousmode.
Table 9-24 Rules for Promiscuous Mode Operation I/O Function | Rule | IO$_SETMODE IO$_SETCHAR | It is not necessary to specify a unique identifier (a protocol type, SAP, or protocol identifier parameter ID) in the P2 buffer. The port cannot be running in shared mode. | IO$_WRITE | The user can only transmit packets in the packet format previously specified with a set mode QIO when the user was started. The unique identifier for the packet format must be included in the P5 buffer following the destination address (see Section 9.16.2). | IO$_READ | The LAN driver completes the promiscuous user's read requests with Ethernet, IEEE 802, and 802 extended packets. Because any packet format can be used to complete a read request, the P5 parameter (if specified) must be at least 20 bytes in length (21 bytes for FDDI with RFC turned on). All Ethernet format packets are processed as if they have no size field specified after the protocol type. Therefore, Ethernet packets are always returned with 46 to 1500 bytes of data. If the Ethernet packet contains a size field, it is returned as part of the user data in the first word of the P1 buffer. The promiscuous user should use the information returned in the P5 buffer to determine the packet format. If the application program first filled the P5 buffer with zeros, the program can determine the format of the packet received by scanning the P5 buffer after the read request is completed. | 9.18.2 Local Area Network Programming ExamplesThe VAX MACRO program LANETH.MAR (Example 9-3 shows the typical useof QIO functions in driver operations such as establishing the protocoltype, starting the port, and transmitting and receiving data. Theprogram sends a LOOPBACK packet and waits for the packet to be returned. The DEC C program LAN802E.C (Example 9-4) shows how to initialize an802E port and how to send and receive packets on that port. Thisprogram sends a LOOPBACK packet and waits for the packet to be returned. Example 9-3 LANETH.MAR Local Area Network Programming Example | .TITLE LAN SAMPLE TEST PROGRAM .IDENT /X02/ .PSECT RWDATA,WRT,NOEXE,PAGE; 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 or Alpha:; $ MACRO LANETH; $ LINK LANETH .LIBRARY "SYS$LIBRARY:LIB.MLB" $IODEF ; Define I/O functions and modifiers $NMADEF ; Define Network Management parameters; Setmode parameter buffer and descriptor. Since the loopback protocol does; not include a length word following the protocol type, we have to explicitly; turn off padding since the default is on.SETPARM: .WORD NMA$C_PCLI_FMT ; Packet format .LONG NMA$C_LINFM_ETH ; Ethernet .WORD NMA$C_PCLI_PTY ; Protocol type .LONG ^X0090 ; Loopback .WORD NMA$C_PCLI_PAD ; Padding .LONG NMA$C_STATE_OFF ; OffSETPARMLEN = .-SETPARMSETPARMDSC: .LONG SETPARMLEN .ADDRESS SETPARM; Sensemode parameter buffer and descriptor. This is used to get our physical; address to put into the loopback message.SENSEBUF: .BLKB 512SENSELEN=.-SENSEBUFSENSEDSC: .LONG SENSELEN .ADDRESS SENSEBUF; P2 transmit data buffer.XMTBUF: .WORD 00 ; Skip count .WORD 02 ; Forward requestFORW: .BLKB 6 ; Forward address .WORD 01 ; Reply request .WORD 00XMTBUFLEN = .-XMTBUF ; Size of transmit buffer; P5 transmit destination address, the Loopback Assistant Multicast Address.XMTP5: .BYTE ^XCF,0,0,0,0,0; P2 receive data buffer.RCVBUF: .BLKB 512RCVBUFLEN = .-RCVBUF ; Size of receive buffer; P5 receive header buffer.RCVP5:RCVDA: .BLKB 6RCVSA: .BLKB 6RCVPTY: .BLKB 2; Messages used to display status of this program.GMSG: .ASCID "Successful test"LMSG: .ASCID "No response"EMSG: .ASCID "Error occurred while running test"DMSG: .ASCID "LAN device not found"; Miscellaneous data.IOSB: .BLKQ 1 ; I/O status blockDEVCHAN:.BLKL 1 ; Returned port numberLANDSC: .ASCID 'EWA0' ; Device to use for test;*************************************************************************;; Start of code;;************************************************************************* .PSECT CODE,EXE,NOWRT,PAGE .ENTRY START,^M<>; Assign a port to the LAN device. $ASSIGN_S DEVNAM=LANDSC,CHAN=DEVCHAN BLBS R0,10$ ; Branch if succeeded MOVAL DMSG,R9 ; Get address of error message BRW EXIT ; Print message and exit; Set up the port's characteristics.10$: MOVAL EMSG,R9 ; Assume error message address $QIOW_S FUNC=#<IO$_SETMODE!IO$M_CTRL!IO$M_STARTUP>,- CHAN=DEVCHAN,IOSB=IOSB,- P2=#SETPARMDSC BLBC R0,20$ ; Branch if failed MOVZWL IOSB,R0 ; Get status from IOSB BLBS R0,30$ ; Branch if succeeded20$: BRW EXIT ; Print message and exit; Issue the SENSEMODE QIO to get our physical address for the loopback; message.30$: $QIOW_S FUNC=#<IO$_SENSEMODE!IO$M_CTRL>,- CHAN=DEVCHAN,IOSB=IOSB,- P2=#SENSEDSC BLBC R0,20$ ; Branch if failed MOVZWL IOSB,R0 ; Get status from IOSB BLBC R0,20$ ; Branch if failed; Locate the PHA parameter in the SENSEMODE buffer and copy it into the; LOOPBACK transmit message. The PHA parameter is a string parameter. MOVAB SENSEBUF,R0 ; Start at beginning of buffer40$: BBS #^XC,(R0),50$ ; Branch if a string parameter ADDL #6,R0 ; Skip over longword parameter BRB 40$ ; Check next parameter50$: BICW3 #^XF000,(R0)+,R1 ; Get type field less flag bits CMPW R1,#NMA$C_PCLI_PHA ; Is this the PHA parameter? BEQL 60$ ; Branch if so ADDW (R0)+,R0 ; Skip over string parameter BRW 40$ ; Check next parameter60$: MOVL 2(R0),FORW ; Copy our address to the loopback MOVW 6(R0),FORW+4 ; packet we are about to transmit; Transmit the loopback message. $QIOW_S FUNC=#IO$_WRITEVBLK,CHAN=DEVCHAN,IOSB=IOSB,- P1=XMTBUF,P2=#XMTBUFLEN,P5=#XMTP5 BLBC R0,70$ ; Branch if failed MOVZWL IOSB,R0 ; Get status from IOSB BLBS R0,80$ ; Branch if succeeded70$: BRW EXIT ; Print message and exit; 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.80$: MOVL #1000,R2 ; Check 1000 times90$: $QIOW_S FUNC=#IO$_READVBLK!IO$M_NOW,CHAN=DEVCHAN,IOSB=IOSB,- P1=RCVBUF,P2=#RCVBUFLEN,P5=#RCVP5 BLBC R0,EXIT ; Branch if failed MOVZWL IOSB,R0 ; Get status from IOSB BLBS R0,100$ ; Branch if succeeded CMPL R0,#SS$_ENDOFFILE ; Was there just no message available? BNEQ EXIT ; Branch if failed SOBGTR R2,90$ ; Try again; No response in 1000 attempts. MOVAL LMSG,R9 ; Get address of lost message BRW EXIT ; Print message and exit; Received a message.100$: MOVAL GMSG,R9 ; Get address of success message; The test is done. Call LIB$PUT_OUTPUT to display the test status.EXIT: PUSHL R9 ; P1 = Address of message to print CALLS #1,G^LIB$PUT_OUTPUT ; Print the message $EXIT_S ; Exit .END START |
Example 9-4 LAN802.C Local Area Network Programming Example | /************************************************************* * 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_alignmentstruct 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}; /* 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),&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 (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,&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 (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(&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");} |
|