Document revision date: 30 March 2001
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]


Previous Contents Index

1.16.4.1 IO$M_SENSE_MAC Functional Modifier to IO$_SENSEMODE

The IO$M_SENSE_MAC qualifier, when used with IO$_SENSEMODE, returns the parameters specified in Section 1.16.3.6. In addition to the set mac parameters, Table 1-22 shows the returns of the following parameters:

1.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 the mapping table. The P2 buffer is filled with the current multicast to functional address mapping information. The entries are 16 bytes long and are in the format shown in Figure 1-28. This QIO requires PHY_IO privilege.

Figure 1-28 Format of IO$M_SHOW_MAP P2 Buffer (Alpha Only)


The multicast address and functional address mask are returned in canonical format (that is, not bit-reversed). The following errors may occur:

1.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 source routing cache table. Each entry is 64 bytes long. Figure 1-29 shows the format of the returned P2 buffer:

Figure 1-29 Format of IO$M_SHOW_ROUTE P2 Buffer (Alpha Only)


Table 1-23 shows possible states of the entry.

The LAN address is returned in canonical format (that is, not bit-reversed). The timers are recorded as seconds before expiration. The transmit and receive timers are initialized from the NMA$C_PCLI_A_TIM parameter, the discovery timer is initialized from the NMA$C_PCLI_ROUTEDIS parameter, and the stale timer is initialized to 10 minutes (600 seconds). The following errors may occur:

1.17 I/O Status Block

The I/O status block (IOSB) for all LAN driver functions is shown in Figure 1-30. <REFERENCE>(io_func_codes_2_app_a) lists the completion status returns for these functions. (The OpenVMS system messages documentation provides explanations and suggested user actions for these returns.)

Figure 1-30 IOSB Contents


The first longword of the IOSB returns, in addition to the completion status, either the size (in bytes) of the data transfer or the size (in bytes) of the attribute buffer (P2) returned by a sense mode function. The second longword returns the unit and line status bits listed in Table 1_9 and the error summary bits listed in Table 1-10.

1.18 Application Programming Notes

This section contains information to assist you in writing application programs that use the LAN device drivers. Section 1.18.1 discusses the additional rules required for application programs that you intend to run in promiscuous mode. Section 1.18.2 describe the Ethernet and 802 sample programs.

1.18.1 Promiscuous Mode

The LAN drivers allow only one port per controller to start with promiscuous mode enabled (NMA$C_PCLI_PRM specified as NMA$C_STATE_ON). Any port running in promiscuous mode usually places an additional load on the CPU because the LAN driver processes every packet on the LAN for the promiscuous user. If there is no promiscuous port on a controller, the controller performs most of the filtering required for the packets on the line.

Table 1-24 details additional rules for ports running in promiscuous mode.

1.18.2 Local Area Network Programming Examples

The VAX MACRO program LANETH.MAR (Example 1-3 shows the typical use of QIO functions in driver operations such as establishing the protocol type, starting the port, and transmitting and receiving data. The program sends a LOOPBACK packet and waits for the packet to be returned.

The DEC C program LAN802E.C (Example 1-4) shows how to initialize an 802E port and how to send and receive packets on that port. This program sends a LOOPBACK packet and waits for the packet to be returned.

 
        .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         ;   Off            
SETPARMLEN = .-SETPARM 
 
SETPARMDSC: 
        .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   512 
SENSELEN=.-SENSEBUF 
 
SENSEDSC: 
        .LONG   SENSELEN 
        .ADDRESS SENSEBUF 
 
; P2 transmit data buffer. 
 
XMTBUF: .WORD   00                      ; Skip count  
        .WORD   02                      ; Forward request  
FORW:   .BLKB   6                       ; Forward address 
        .WORD   01                      ; Reply request  
        .WORD   00 
XMTBUFLEN = .-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   512 
RCVBUFLEN = .-RCVBUF                    ; Size of receive buffer    
 
; P5 receive header buffer. 
 
RCVP5: 
RCVDA:  .BLKB   6 
RCVSA:  .BLKB   6 
RCVPTY: .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 block 
DEVCHAN:.BLKL   1                       ; Returned port number 
LANDSC: .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 succeeded      
20$:    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 buffer   
40$:    BBS     #^XC,(R0),50$           ; Branch if a string parameter     
        ADDL    #6,R0                   ; Skip over longword parameter     
        BRB     40$                     ; Check next parameter   
50$:    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 parameter   
60$:    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 succeeded      
70$:    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 times 
90$:    $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 1-3 LANETH.MAR 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_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};                      /* 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"); 
 
} 
 

1.19 References

The following publications provide more information on local area networks.


Example 1-4 LAN802.C Local Area Network Programming Example
Index Contents

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
6136LAN_006.HTML