[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference 7.286::ethernet

Title:Ethernet Volume 3
Moderator:UPSAR::THOMAS
Created:Thu Oct 08 1992
Last Modified:Thu May 22 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:914
Total number of notes:3047

897.0. "Shared-with-destination access mode in C" by CX3PST::NOTAMI::A_ANDERSON (CX03 2/H13 NSU/VAX MacGhille Aindrais) Wed Jan 15 1997 13:46

T.RTitleUserPersonal
Name
DateLines
897.1I had my head in that dark place againCX3PST::NOTAMI::A_ANDERSONCX03 2/H13 NSU/VAX MacGhille AindraisFri Jan 17 1997 18:345
897.2Working example VMS 6.2 and VMS 7.1 work as advertisedCX3PST::NOTAMI::A_ANDERSONCX03 2/H13 NSU/VAX MacGhille AindraisTue Jan 21 1997 16:13525
897.3Sent custmer Alpsys05_070 and alplan04_062CX3PST::NOTAMI::A_ANDERSONCX03 2/H13 NSU/VAX MacGhille AindraisFri Jan 24 1997 15:09527
While the example program ran fine on our test system the customer could not get it to
work on thier system.  They added a few mods to the example so that it would be closer to
the way they use their application used the shared destination.  They were using a 8400
and a 7610.  I'll include the final test code.  But basically it ran fine on our Alpha
2100 with three nodes sending to the receiver process.  

After we sent the customer Alpsys05_070 and Alplan04_062 the customers problem was
resolved.  I do not know which ECO actually fixed the problem.  



/***********************************************************************
                     COPYRIGHT (C) 1994 BY
             DIGITAL EQUIPMENT CORPORATION, MAYNARD
               MASSACHUSETTS.  ALL RIGHTS RESERVED.

THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY OTHER
COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
TRANSFERRED.

THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
CORPORATION.

DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.

NO RESPONSIBILITY IS ASSUMED FOR THE USE OR RELIABILITY OF SOFTWARE ON
EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL EQUIPMENT CORPORATION.

SUPPORT FOR THIS SOFTWARE IS NOT COVERED UNDER ANY DIGITAL SOFTWARE
PRODUCT SUPPORT CONTRACT, BUT MAY BE PROVIDED UNDER THE TERMS OF THE
CONSULTING AGREEMENT UNDER WHICH THIS SOFTWARE WAS DEVELOPED.

------------------------------------------------------------------

name:   ping

purpose: exercise ETHERNET/FDDI driver send and receive with shared
         destination address.

inputs:  ping p1 p2
         where p1 - "PONG", post read AST and wait
                    "PING", send ASTBLKCNT packets, then sleep

               p2 - ethernet device name (ie FXA0, XEB0 , EWA0 )

Define a symbol to run the program

$ping == "$v5user:[wing]ping.exe"
$ping PING XEB0 (invoke PONG process on node with CSMA/CD media)
$ping PONG FXA0 (invoke PING process on node with FDDI media)

Change the array's xmtdestaddr[6] and rcvdestaddr[6] to the correct
destination address for the transmitting and receiving node then compile.

If the controller is a FDDI then use the hardware address.  If the controller
is an ethernet and DECnet has been started then use the MAC address otherwise
if DECnet has not been started on that controller then use the hardware
address.

Compiling instructions

 For Alpha's
Compile:  $ cc/standard=vaxc/nomember_align ping
Link:     $ link ping

 For Vaxes
Compile:  $ cc/standard=vaxc ping
Link:     $ link ping

environment - protocol type (PTY) 22-00 being used

***********************************************************************/
#include descrip
#include iodef
#include "nmadef"
#include ssdef
#include time
#include "sys$login:xmdef"

/* DATA TYPES */
        /* the 8-bit types */
typedef unsigned char TEXT;
typedef unsigned char BYTE;
typedef          char CHAR;

        /* the 16-bit types */
typedef unsigned short WORD;
typedef          short SHORT;
typedef          short METACH;

        /* the 32-bit types */
typedef          int  FILED;
typedef unsigned long LWORD;
typedef unsigned long POINTER;
typedef          long LONG;
typedef          int  BOOL;
typedef          int  VOID;
        /* other data types */

typedef unsigned  BITS;
typedef double    DOUBLE;
#define STRUCT    struct
#define STRUCTURE struct
#define UNION     union

/* declare */
#define SHARE   const
#define NOSHARE noshare
#define ASTBLKCNT 50

/* reference */
#define EXTERN  extern noshare
#define IMPORT  extern const

/* module */
#define LOCAL    static
#define READONLY static const

/* other */
#define FAST    register
#define TRUE            1
#define FALSE           0

#define TRANSMITTER_COUNT       3

/*
--- Flags documented in I/O User's Guide: Part II; Page 6-33.

/*
--- declare iosb-structures following here, instead of in "invedef.h"
--- to use our local definition of an iosb-structure
*/
#pragma nomember_alignment
STRUCT setp
        {
        WORD bus;               /* max rcv buffer size */
        LONG buflen;
        WORD bfn;               /* # rcv buffers */
        LONG bufnum;
        WORD prm;               /* promiscuous mode */
        LONG prmstate;
        WORD pad;               /* pad state */
        LONG padstate;
        WORD crc;               /* crc state */
        LONG crcstate;
        WORD pty;               /* protocol type */
        LONG entype;
        WORD con;               /* controller mode */
        LONG constate;
        WORD restart;           /* restart channel on controller error */
        LONG restart_enable;
                                /* additions for shared dest mode */
        WORD access_mode;
        LONG access_mode_type;
        WORD shared_dest;
        WORD des_size;
        WORD set_clr;
        BYTE add01;
        BYTE add02;
        BYTE add03;
        BYTE add04;
        BYTE add05;
        BYTE add06;
        };

/*
     The destination address of the transmitting node used by
     the receiving node's set mode qio.  The receiving node
     is started with PONG as a P1 paramater.
*/
 BYTE xmtdestadd[TRANSMITTER_COUNT][6]={
        {0x08,0x00,0x2b,0XA3,0x5c,0x49},        /* Nsabl1 */
        {0xAA,0x00,0x04,0X00,0xCD,0xDC},        /* nmstang */
        {0x08,0x00,0x2b,0XA3,0xAC,0x4A}         /* VS4090 */
 };


/*
     The destination address of the receiving node used by
     the transmitting nodes set mode qio.  The receiving node
     is started with PING as a P1 paramater.
*/
 BYTE rcvdestadd[6]={0xAA,0x00,0x04,0X00,0x90,0xDD}; /* nsable */

/* ethernet frame */
STRUCT en_hdr {        /* Ethernet Frame Header*/
    BYTE dest[6];      /* Destination station */
    BYTE source[6];    /* Source station */
    WORD type;         /* Ethernet type */
    };

#define MAX_ETHER_FRAME 1514
#define MIN_ETHER_FRAME 60
#define ETHER_HDR_SIZE (sizeof (STRUCT en_hdr))

STRUCT frame_data_def
    {
    int seqnum;
    BYTE ef_body[1496]; /*frame body*/
    };

STRUCT en_frame
    {
    STRUCT en_hdr ef_header;    /*frame header*/
    STRUCT frame_data_def frame_data;          /*frame data*/
    };

STRUCT iosb
    {
    WORD w0, w1, w2, w3;        /* 4 words in an io status block */
    };

int sequence;
LOCAL   STRUCT  iosb xmtiosb = 0;               /* xmt iosb             */
LOCAL   STRUCT  iosb rcviosb[ASTBLKCNT];        /* rcv iosb             */
LOCAL   STRUCT  en_frame tst_frame[ASTBLKCNT-1];
LOCAL   STRUCT  dp
           {
           BYTE dp_enaddr[6];   /*destination ethernet address*/
           WORD dp_entype;      /*destination port ethernet type*/
           } destport;          /*destination header     */

LOCAL   LONG    vmschan[TRANSMITTER_COUNT];
int     ping, i;                                /* ping = *argv[1] == '1' */
int     frame_size;

/* declare rcv_ast function */
LOCAL   VOID    ast_rc( LWORD i );

/*****************************/

/*****---  Start of main ()  ----*******/
main( int argc, char *argv[] )
{
        LONG status, bintime;

        if (argc < 3)
           {
           printf( "missing p1 p2 (see source)\n" );
           exit(0);
           }


/*      if ping process, ping = true  */
        ping = (strcmp( argv[1], "PING" ) == 0 ||
                strcmp( argv[1], "ping" ) == 0); /* true if PING */

/*      call IO$_SETMODE for transmitter process (PING MODE) */
        if (ping)  /* printf */
        {
          printf ("Value of Ping = %d\n",ping);
          while (!attachnet( argv[2], rcvdestadd, 0 ))
               sleep(5); /* try every minute until success */
       }

/*     call IO$_SETMODE for receiver process (PONG mode) */
       if (!ping)  /* printf */
       {
          printf ("Value of Ping = %d\n",ping);
          for (i = 0; i < TRANSMITTER_COUNT; i++)
            while (!attachnet( argv[2], xmtdestadd[i], i ))
               sleep(5); /* try every minute until success */
        }

/********************************************************************
NOTE:
    Normally we would set the destination address and protocol type
    for the transmit packet now.  But with a Shared Destination
    protocol this is not not required.  The protocol type and
    destination are set up during the IO$_SETMODE.  All packets
    transmitted on that channel will use the destination address and
    protocol type passed on the IO$_SETMODE.
**********************************************************************/

        sequence = 0;

        /* Send 10 packets in row, then sleep for 5 seconds */

        while (ping)
        {
           for (i=0; i<10; i++) {
                sequence = sequence + 1;
                tst_frame[0].frame_data.seqnum = sequence;
                if (sequence&1)
                   frame_size = 1400;
                else
                   frame_size = 46;
                status = SYS$QIOW ( 0, vmschan[0], IO$_WRITEVBLK, &xmtiosb, 0,0,
                               &tst_frame[0].frame_data,
                               frame_size, 0,
                               0, &destport, 0 );

              printf ("$QIO Write Status = %d\n",status);
              printf(" IOSB w0:%d  w1:%d  w2:%d  w3:%d\n",xmtiosb.w0,
                      xmtiosb.w1, xmtiosb.w2, xmtiosb.w3);
              if (status != SS$_NORMAL || xmtiosb.w0 != SS$_NORMAL)
                 printf( "unable write, status %d/%d\n", status, xmtiosb.w0 );
              else
                 printf( "Sequence # %d Sent, Size = %d bytes\n",
                          sequence,frame_size);
              }
         /* remove the sleep(5) to pound the receiver with packets */  
         /*  sleep(5); */

           } /* while ping forever */

/* receive side code , p1=pong */

        while (!ping)  /* pong means the receiving node */
           {
              for (i = 0; i < TRANSMITTER_COUNT; i++)
                {
                   status = SYS$QIO ( 0, vmschan[i], IO$_READVBLK,
                                    &rcviosb[i], ast_rc, i,
                                    &tst_frame[i].frame_data, 1500, 0,
                                    0, &tst_frame[i].ef_header, 0 );

                   printf ("AST # %d Posted\n",i);
                   if (status != SS$_NORMAL)
                      printf( "unable post read, status %d\n", status );
                }

           SYS$HIBER();
           } /* end while pong forever */

} /* end of main */


/******************************************************************************

name:           attachnet - attach to ethernet

purpose         attaches process to a particular Ethernet controller

inputs:         . network id
                . protocol type
                . multicast flag
                . sys_fail on error flag
                . Destination address BYTE array

outputs:        . attached controller

logic:          . convert ethernet address logical name to ascii equivalent
                . validate ethernet address
                . convert ethernet address address to proper address format
                . if dynamic duffers specified for ptype
                . . set NRCVBFRS to specified value for ptype
                . shutdown controller
                . setup port parameters
                . start up port
                . verify port characteristics via read back

revision history: Modified to receive a destination address byte array
-------------------------------------------------------------------

*****************************************************************************/
LOCAL BOOL attachnet( TEXT *devnam_p, BYTE destadd[], int connection )
    {
    BYTE xchar[512];    /* extended characteristics                     */
    int j;

    STRUCT              /* descriptor for extended characteristics      */
        {
        LWORD   xcharlen;
        BYTE    *pxchar;
        } xchardsc = { sizeof xchar, xchar };

    /* setp, controler parameter descriptor for set up */
    STRUCT setp setparam =
        {
        NMA$C_PCLI_BUS, 1500,
        NMA$C_PCLI_BFN, 50,
        NMA$C_PCLI_PRM, NMA$C_STATE_OFF,
        NMA$C_PCLI_PAD, NMA$C_STATE_OFF,
        NMA$C_PCLI_CRC, NMA$C_STATE_ON,
        NMA$C_PCLI_PTY, 0x0022,
        NMA$C_PCLI_CON, NMA$C_LINCN_NOR,
        NMA$C_PCLI_RES, NMA$C_LINRES_ENA,
                                          /* SHARED DESINATION ADDITIONS */
        NMA$C_PCLI_ACC, NMA$C_ACC_LIM,
        NMA$C_PCLI_DES, 8,NMA$C_LINMC_SET,
        destadd[0],
        destadd[1],
        destadd[2],
        destadd[3],
        destadd[4],
        destadd[5],
        };

    STRUCT                      /* descriptor for parameter block       */
        {
        LONG    setparamlen;    /* length of parameter block            */
        STRUCT  setp *psetparam;/* address of parameter block           */
        } setpdsc = { sizeof setparam, &setparam };

    BYTE  devchar[8];           /* space for sense characterisitics     */
    LWORD status;               /* vms status                           */
    LWORD l;
    TEXT buf[30];
    LONG dsc[] = { sprintf ( buf, "%s", devnam_p ), buf };

    printf ("      - registering -   \n");
    printf ("Shared protocol address is: %02X-%02X-%02X-%02X-%02X-%02X\n\n",
             destadd[0],destadd[1],destadd[2],
             destadd[3],destadd[4],destadd[5] ) ;

    /* assign channel */
    status = SYS$ASSIGN(
         dsc, &vmschan[connection], 0, 0 );
    if (status != SS$_NORMAL)
        {
        /* fail if error */
        printf( "unable sys$assign, status=%d\n", status );
        return FALSE;
        }

    /* shutdown controller
    status = SYS$QIOW ( 0, vmschan[connection], IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN,
                        &xmtiosb, 0, 0, 0, 0, 0, 0, 0, 0 );
    if (status != SS$_NORMAL || xmtiosb.w0 != SS$_NORMAL)
        {
        printf( "unable CONTROLLER SHUTDOWN, status %d/%d\n",
                status, xmtiosb.w0 );
        return FALSE;
        }                  */

    status = SYS$QIOW ( 0, vmschan[connection], IO$_SETMODE | IO$M_CTRL | IO$M_STARTUP,
                        &xmtiosb, 0, 0, 0, &setpdsc, 0, 0, 0, 0 );

    if (status != SS$_NORMAL || xmtiosb.w0 != SS$_NORMAL)
        {
        printf( "unable STARTUP/INITIALIZE CONTROLLER, status %d/%d\n",
                status, xmtiosb.w0 );
        printf ("IOSB %d %d %d\n",xmtiosb.w1,xmtiosb.w2,xmtiosb.w3);
        return FALSE;
        }

    /* read back controller characteristics */
    status = SYS$QIOW ( 0, vmschan[connection], IO$_SENSEMODE | IO$M_CTRL,
                        &xmtiosb, 0, 0, devchar, &xchardsc, 0, 0, 0, 0 );

    if ( status != SS$_NORMAL || xmtiosb.w0 != SS$_NORMAL )
        {
        printf( "unable SENSE CONTROLLER MODE, status %d/%d\n",
                status, xmtiosb.w0 );
        return FALSE;
        }

    return TRUE;

} /* end of attachnet */

/**********************************************************************

name:           rcv_ast  Receive AST routine

purpose         Called when a Ethernet packet is received

inputs:         . Data index number of received packet

outputs:        . Prints info form received packet

logic:          . Called when packet is received print out information to
                  standard out from ethernet data packet.  Also prints out
                  ethernet address of transmitting node.
/*------------------------------------------------------------------------*/

LOCAL VOID ast_rc( LWORD i )
{
        LONG status, bintime;

/*      check read completion, error summary, and unit & line statuses */
        if (rcviosb[i].w0 != SS$_NORMAL ||
            *((LWORD *)&rcviosb[i].w2) & XM$M_ERR_FATAL ||
            *((LWORD *)&rcviosb[i].w2) & XM$M_ERR_LOST ||
            *((LWORD *)&rcviosb[i].w2) & XM$M_STS_BUFFAIL ||
            *((LWORD *)&rcviosb[i].w2) & XM$M_STS_TIMO)

           {
           printf( "Read AST #%d, status %d/%d/%d/%d \n", i,
                   rcviosb[i].w0, rcviosb[i].w1,
                   rcviosb[i].w2, rcviosb[i].w3);

           }
        else
           {
           printf ("Read AST # %d, Sequence # %d received, size=%d\n",
                     i, tst_frame[i].frame_data.seqnum,rcviosb[i].w1);

           printf ("   Destination node is: %02X-%02X-%02X-%02X-%02X-%02X",
                 tst_frame[i].ef_header.dest[0],
                 tst_frame[i].ef_header.dest[1],
                 tst_frame[i].ef_header.dest[2],
                 tst_frame[i].ef_header.dest[3],
                 tst_frame[i].ef_header.dest[4],
                 tst_frame[i].ef_header.dest[5]);

           printf (" Source node is: %02X-%02X-%02X-%02X-%02X-%02X\n\n",
                 tst_frame[i].ef_header.source[0],
                 tst_frame[i].ef_header.source[1],
                 tst_frame[i].ef_header.source[2],
                 tst_frame[i].ef_header.source[3],
                 tst_frame[i].ef_header.source[4],
                 tst_frame[i].ef_header.source[5]);

           rcviosb[i].w0 = 0;
           rcviosb[i].w1 = 0;
           rcviosb[i].w2 = 0;
           rcviosb[i].w3 = 0;

           status = SYS$QIO( 0, vmschan[i], IO$_READVBLK,
                             &rcviosb[i], ast_rc, i,
                             &tst_frame[i].frame_data, 1500, 0,
                             0, &tst_frame[i].ef_header, 0 );

           printf ("AST # %d Posted\n",i);
           if (status != SS$_NORMAL)
              printf( "ast_rc - unable post read, status %d\n", status );
           }

} /* end of ast_rc */

897.4ALPLAN04_62?EVMS::JSTICKNEYJay Stickney, OpenVMS LAN Eng., 381-2020, ZK3-4/T12Mon Jan 27 1997 09:494
    Is this the correct name, ALPLAN04_062?  I didn't think that
    kit was released yet.
    
    Jay.