*=*=*=*= ether_listen.html =*=*=*=*
program ether_listen

program ether_listen


      program ether_listen
c
c This program runs against the ethernet adapter in
c promiscuous mode, examining all the packets and
c distinguishing between them. The name of the controller
c is ESA0 as the code was intended for use on a VS3100.
c Change this to whatever the device name of the controller
c you in fact have is (see the I/O users manual for details)
c
c The subroutine "display" uses SMG routines to display
c real time graphs of the ethernet traffic.
c
c This program does not look at the contents of each packet,
c although it could easily do so: the data in buffer(istart:)
c is the place.
c
c (c) J.J.Bunn 1991 CERN
c
      parameter (lbuffer=1500,lpacket=20)
      implicit integer(a-z)
C
      INCLUDE '($SSDEF)'
      INCLUDE '($IODEF)'
      INCLUDE '($DVIDEF)'
C
      character*17 cdest,csorc
      character*5 cprot
      character*8 cform
      character*(lbuffer) cbuf
      character*(lpacket) cblank,cpacket
      character*50 ctime
      real mbs,t1,t2
      integer*4 iosb(2),p2desc(2)
      integer*2 channel,transfer,completion,errsum
      integer*2 ldata
      byte destination(6),source(6)
      byte protocol(2)
      byte packet(lpacket)
      byte buffer(lbuffer)
      byte b1(4),b2(4)
      equivalence (buffer,cbuf)
      equivalence (b1,iosb(1))
      equivalence (b2,iosb(2))
      equivalence (b1(1),completion)
      equivalence (b1(3),transfer)
      equivalence (b2(3),errsum)
      equivalence (cpacket,packet)
      equivalence (packet(1),destination(1))
      equivalence (packet(7),source(1))
      equivalence (packet(13),protocol)
      equivalence (buffer(1),ldata)
C
      STRUCTURE /ITEMLIST/
        INTEGER*2 BUFLEN
        INTEGER*2 ITEMCODE
        INTEGER*4 BUFFADD
        INTEGER*4 RETLADD
      END STRUCTURE
C
      RECORD /ITEMLIST/ ITEM_LIST(10)
c
cdec$ options/align=(records=packed)
      structure /plist/
        integer*2 param_id
        integer*4 param_value
      end structure
c
      record /plist/ p2_list(10)
cdec$ end options
c
C Assign the controller port (for VS 3100)
C
      STATUS = SYS$ASSIGN('ESA0:',channel,,)
      status = lib$signal(%val(status))
c
      iofunc = io$_setmode .or. io$m_ctrl .or. io$m_startup
c
      nma$c_pcli_prm  = 2840            ! promiscuous
      nma$c_pcli_pad  = 2842            ! padding
      nma$c_pcli_mlt  = 2841            ! multicast/broadcast
      nma$c_pcli_pty  = 2830            ! protocol type
      nma$c_pcli_fmt  = 2770            ! packet format
      nma$c_pcli_bfn  = 1105            ! receive buffers
      nma$c_pcli_bus  = 2801            ! max port receive size in bytes
      nma$c_state_on  = 0
      nma$c_state_off = 1
      nma$c_linfm_eth = 1
      nma$c_linfm_802 = 2
      p2_list(1).param_id    = nma$c_pcli_prm
      p2_list(1).param_value = nma$c_state_on
      p2_list(2).param_id    = nma$c_pcli_pad
      p2_list(2).param_value = nma$c_state_off

      p2desc(1) = 12                   ! bytes in p2_list
      p2desc(2) = %loc(p2_list)
c
c NB you'll need privilege to do this. Probably PHY_IO at least.
c
      status = sys$qiow(,%val(channel),%val(iofunc),iosb
     &         ,,,,p2desc,,,,)
      status = lib$signal(%val(status))
      write(6,*) ' promiscuous '
      write(6,*) ' completion ',completion
      write(6,*) ' transfer ',transfer
      write(6,*) ' errsum ',errsum
      if(completion.eq.ss$_badparam) write(6,*) iosb
c
      do i=1,lpacket
         cblank(i:i) = char(0)
      end do
c
c read a packet
c
      iofunc = io$_readpblk ! .or. io$m_now
c
      npackets = 0
      status = lib$date_time(ctime)
      read(ctime(19:23),'(f5.2)') t1
      sum = 0
    1 continue
      cpacket = cblank
      status = sys$qiow(,%val(channel),%val(iofunc),iosb
     &         ,,,buffer,%val(lbuffer),,,packet,)
      npackets = npackets + 1
      write(cdest,500) destination
      write(csorc,500) source
c
c determine packet type
c
      if(packet(17).ne.0.or.packet(18).ne.0) then
        cform = '802 ext.'
        istart = 7
      else if(packet(15).ne.0.or.packet(16).ne.0) then
        cform = '802'
        istart = 6
      else
        cform = 'Standard'
        write(cprot,501) protocol
        status = lib$date_time(ctime)
c        call display(transfer,cprot,ctime)
        istart = 1
        if(ldata.eq.transfer-2) istart = 3
      endif
  500 format(z2.2,'-',z2.2,'-',z2.2,'-',z2.2,'-',z2.2,'-',z2.2)
  501 format(z2.2,'-',z2.2)
c
c write source and destination addresses in standard format, if needed
c
      write(6,*) ' Source ',csorc
      write(6,*) ' Destination ',cdest
      write(6,*) ' IEEE ',cform,' PROTOCOL ',cprot
      write(6,*) ' IOSB ',iosb
      write(6,*) ' Transfer ',transfer,' bytes'
      write(6,*) ' --------------------------------------'
c
c we stop after 10000 packets
c
      if(npackets.lt.100000) goto 1
c
c shut down the port
c
  100 continue
      iofunc = io$_setmode .or. io$m_ctrl .or. io$m_shutdown
      status = sys$qiow(,%val(channel),%val(iofunc),iosb
     &         ,,,,,,,,)
      write(6,*) ' shut'
      write(6,*) ' completion ',completion
      write(6,*) ' transfer ',transfer
      write(6,*) ' errsum ',errsum
c
c deassign the channel
c
      status = sys$dassgn(%val(channel))
      status = sys$exit(%val(1))
c
      end
*=*=*=*= DISPLAY.html =*=*=*=*
SUBROUTINE DISPLAY

SUBROUTINE DISPLAY


      SUBROUTINE DISPLAY(size,protocol,time)
c
c plots graphs of protocol types in real time.
c Unknown protocol types are dumped in the file 'unknown.protocols'
c
      implicit integer (a-z)
      include '($smgdef)'
c
      parameter (maxprot=20,maxcon=60)
      character*10 cprot_type(maxprot)
      character*(*) time
      character*(*) protocol
      character*(maxcon) cbar
      character*6 cnum
      integer count(maxprot),data(maxprot)
      data icall /0/
c
      IF(icall.LE.0) THEN
         icall = 1
         do 6 ip=1,maxcon
            cbar(ip:ip) = char(113)
    6    continue
         do 1 i=1,maxprot
            count(i) = 0
            data(i) = 0
    1    continue
c
c Here we define the names of the standard protocols of interest
c
         cprot_type(1) = 'Vitalink'
         cprot_type(2) = 'X.75'
         cprot_type(3) = 'Dump/Load'
         cprot_type(4) = 'DEC Cons.'
         cprot_type(5) = 'DECnet IV'
         cprot_type(6) = 'LAT'
         cprot_type(7) = 'TCP Sys'
         cprot_type(8) = 'Novell'
         cprot_type(9) = 'LAVC'
         cprot_type(10)= 'DEC Bridge'
         cprot_type(11)= 'IP'
         cprot_type(12)= 'EtherTalk'
         cprot_type(13)= 'Apollo Dom'
         cprot_type(14)= 'Appletalk'
         cprot_type(15)= 'ARP'
         cprot_type(16)= 'Apple ARP'
         cprot_type(17)= 'Unknown'
         nprot = 17
c
c open the file that will contain the dump of unknown
c protocols
c
         open(1,file='unknown.protocols',status='new')
c
c Create the pasteboard for the Terminal Screen
c
         STATUS = SMG$CREATE_PASTEBOARD(IDP,,ROWS,COLS)
         IF(.NOT.STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
c
         STATUS=SMG$CREATE_VIRTUAL_DISPLAY
     &          (ROWS-2,COLS-2,ID,SMG$M_BORDER)
         IF(.NOT.STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
c
         STATUS = SMG$LABEL_BORDER(ID,' Ethernet Listen ',,,SMG$M_BOLD)
         STATUS = SMG$PASTE_VIRTUAL_DISPLAY(ID,IDP,2,2)
         IF(.NOT.STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
         status = smg$set_broadcast_trapping(id)
c
         do 5 ip=1,nprot
            status=smg$put_chars(id,cprot_type(ip),ip+3,1,,
     &      %ref(smg$m_bold),,%ref(smg$c_ascii))
    5    continue
c
      endif
      STATUS=SMG$PUT_CHARS(ID,'Time is '//time(:24),1,1,,
     &   %REF(SMG$M_normal),,%REF(SMG$C_ASCII))
      if(protocol.eq.'80-80') then
         iprot = 1
      else if(protocol.eq.'08-01') then
         iprot = 2
      else if(protocol.eq.'60-01') then
         iprot = 3
      else if(protocol.eq.'60-02') then
         iprot = 4
      else if(protocol.eq.'60-03') then
         iprot = 5
      else if(protocol.eq.'60-04') then
         iprot = 6
      else if(protocol.eq.'90-02') then
         iprot = 7
      else if(protocol.eq.'81-37') then
         iprot = 8
      else if(protocol.eq.'60-07') then
         iprot = 9
      else if(protocol.eq.'80-38') then
         iprot = 10
      else if(protocol.eq.'80-39') then
         iprot = 2
      else if(protocol.eq.'80-40') then
         iprot = 2
      else if(protocol.eq.'80-41') then
         iprot = 2
      else if(protocol.eq.'80-42') then
         iprot = 2
      else if(protocol.eq.'08-00') then
         iprot = 11
      else if(protocol.eq.'80-9B') then
         iprot = 12
      else if(protocol.eq.'80-19') then
         iprot = 13
      else if(protocol.eq.'AA-AA') then
         iprot = 14
      else if(protocol.eq.'08-06') then
         iprot = 15
      else if(protocol.eq.'80-F3') then
         iprot = 16
      else
         write(1,*) protocol
         iprot = 17
      endif
      count(iprot) = count(iprot) + 1
      data(iprot) = data(iprot) + 1
      if (count(iprot).gt.maxcon) then
c
c counts need re-setting (depending on what we want, we could
c re-scale here instead)
c
         count(iprot) = 1
      endif
      irow = iprot + 3
      ic = count(iprot)
      if(ic.eq.1) status = smg$erase_chars(id,maxcon,irow,11)
      status = smg$put_chars(id,cbar(1:1),irow,10+ic,,
     &%ref(smg$m_bold),,%ref(smg$c_spec_graphics))
      write(cnum,'(i6)') data(iprot)
      status = smg$put_chars(id,cnum,irow,maxcon+13,,
     &%ref(smg$m_normal),,%ref(smg$c_ascii))
      end