Czy ktoś uruchomil sieć TCP/IP za pomocą kości RTL8019,
czy procedury w programie Bascom bedą pasowały do tej kości,
:? Mam problem z uruchomieniem tego układu , proszę o pomoc
Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięobsługa RTL8019
Moderatorzy:Jacek Bogusz, robertw, k.pawliczak, Moderatorzy
-
- -
- Posty:1
- Rejestracja:10 cze 2003, o 07:53
- Lokalizacja:Wrocław
- Kontaktowanie:
' Whac51_0702.BAS
'BASCOM-51 RTL8019AS Test Program By Kent D. Smith.
'This code controls an EDTP Electronic's Packet Whacker.
'ARP, ICMP, and UDP protocols are all supported. The code is easily expanded to
'handle TCP as well.
'The Code is written using MCS Electronic's (mcselec.com) BASCOM-51 BASIC Compiler for
'8051 family devices.
'All routines from TCP/IP-decode to the end of the program are written by Ben Zijlstra
'For checksumroutines parts of the routines written by Kent are used.
'
'*******************************************************************************
'* Hardware Setup
'*******************************************************************************
'The Packet Whacker is Memory Mapped starting at hex location E000.
'The RSTDRV line of the Whacker is connected to Port P1.7.
'The Whacked 8051 Development Board uses P1.5 for the RSTDRV
'Use any port pin you wish but be sure to change the code!
'INT0 of the 8051 is tied to the Whackers interrupt line (INT0) via an inverter to notify the
'8051 that a packet has been received. Use an IC inverter or a single NPN transistor and
'two resistors.
'If you have other devices or RAM memory-mapped in your system, you must use an OR
'gate (such as the 74HCT32) to OR the /CS from your address decoder with the /RD and
'/WR signals from your 8051 family microprocessor to the /IORB and /IOWB lines of the Whacker.
'
'This code is set for a Philips 89c668 microprocessor but should work on any 8051
'system with external RAM of 2K or more. The 89c668 has 8K of internal RAM mapped into
'the external RAM memory space.
'If you use the 89c668 microprocessor note that Port pins P1.6 and P1.7 are open drain
'and will require a pull-up resistor.
'For debugging and testing purposes, the serial port of the processor is used to send
'information to a PC's serial port with the PC running a terminal emulator program.
'NOTE: The 93c46 emulation is not implemented in this code.
$large
$romstart = &H0
'Set the following to your system's RAM starting address and size.
$ramstart = &H0
$ramsize = &H7FFF
$default Xram
'Set regfile to your microprocessor type. See BASCOM-51 help.
$regfile = "89c668.dat"
'The debugging/testing serial port runs at 9600 baud.
$baud = 9600
'The Philips 89c668 runs at twice the speed of a regular 8051. I use an 11.0592
'crystal but must tell the compiler to use double the speed for the serial port
'baud rate to work
$crystal = 22118400 'Double 11059200 - Using 6X Clock
'*******************************************************************************
'* Variable Declarations
'*******************************************************************************
Dim Work As Byte
Dim Mymac(6) As Byte
Dim Myip(4) As Byte
Dim Packet(1500) As Byte 'This array receives and transmit the packet from the Whacker.
Dim Ptype0 As Byte
Dim Ptype1 As Byte
Dim Packetlenl As Byte
Dim Packetlenh As Byte
Dim Packetlen As Integer
Dim Xmitpacketlen As Integer
Dim I As Integer
Dim J As Integer
Dim K As Integer
Dim Interupptstatus As Byte
Dim Bnryptr As Byte
Dim Currptr As Byte
Dim Csptr As Integer
Dim Csbytecnt As Integer
Dim Checksum As Long
Dim Checktemp As Word
Dim Checksumout As Word
Dim Tempword As Word
Dim Tempint As Integer
Dim Templong As Long
Dim Tcp_fin As Bit
Dim Tcp_syn As Bit
Dim Tcp_rst As Bit
Dim Tcp_psh As Bit
Dim Tcp_ack As Bit
Dim Tcp_urg As Bit
Dim Seqnum As Long
Dim Acknum As Long
Dim Udpdata As String * 254
Dim Tempstr As String * 1
' added by Ben Zijlstra
Dim Vhigh16 As Byte
Dim Vlow16 As Byte
Dim Result16 As Word
Dim Portaddr As Word
Dim Tcpdatalen_in As Word
Dim Tcpdatalen_out As Word
Dim Ip_packet_len As Long
Dim Tempbyte1 As Byte
Dim Tempbyte2 As Byte
Dim Tempbyte3 As Byte
Dim Tempword1 As Word
Dim Tempword2 As Word
Dim Templong1 As Long
Dim Data_l As Byte
Dim Data_h As Byte
Dim A32 As Byte , B32 As Byte , C32 As Byte , D32 As Byte
Dim Hulp1 As Byte , Hulp2 As Byte , Hulp3 As Byte
Dim Resultaat As Long
Dim Client_seqnum As Long
Dim D As Byte
Dim S As Long , S_temp As Long
Dim O8 As Byte
Dim A8 As Byte
Dim My_seqnum As Long
Dim Txlen As Long
Dim Isn As Word
Dim Flags As Byte
Dim Flag_temp As Byte
Dim Hdr_chksum As Long
Dim Msg As String * 1500
Dim Incoming_ack As Long
Dim X As Byte
Dim Expected_ack As Long
Dim Aux_data(1500) As Byte
Dim Tempstring1 As String * 1
Const Debug = -1
Const My_port_address = 8088
Const Synflag = 0
Const Finflag = 1
'*******************************************************************************
'* Ethernet Packet Layout constants
'*******************************************************************************
Const Destmac1 = 1
Const Destmac2 = 2
Const Destmac3 = 3
Const Destmac4 = 4
Const Destmac5 = 5
Const Destmac6 = 6
Const Srcmac1 = 7
Const Srcmac2 = 8
Const Srcmac3 = 9
Const Srcmac4 = 10
Const Srcmac5 = 11
Const Srcmac6 = 12
Const Packtype0 = 13
Const Packtype1 = 14
'*******************************************************************************
'* ARP Data Section Layout
'*******************************************************************************
Const Arp_hwtype0 = 15
Const Arp_hwtype1 = 16
Const Arp_prtype0 = 17
Const Arp_prtype1 = 18
Const Arp_hwlen = 19
Const Arp_prlen = 20
Const Arp_op0 = 21
Const Arp_op1 = 22
Const Arp_shaddr = 23 'Arp Source Mac Address
Const Arp_sipaddr = 29 'Arp Source Ip Address
Const Arp_thaddr = 33 'Arp Target Mac Address
Const Arp_tipaddr = 39 'Arp Target Ip Address
'*******************************************************************************
'* IP Header Layout
'*******************************************************************************
Const Ip_vers_len = 15 'IP version and header length
Const Ip_tos = 16 'Ip Type Of Service
Const Ip_pktlenh = 17 'packet length High
Const Ip_pktlenl = 18 'Low
Const Ip_id0 = 19 'datagram id
Const Ip_id1 = 20
Const Ip_frag_offset0 = 21 'fragment offset
Const Ip_frag_offset1 = 22
Const Ip_ttl = 23 'time to live
Const Ip_proto = 24 'protocol (ICMP=1, TCP=6, UDP=11)
Const Ip_hdr_cksumh = 25 'header checksum
Const Ip_hdr_cksuml = 26
Const Ip_srcaddr0 = 27 'IP address of source
Const Ip_srcaddr1 = 28
Const Ip_srcaddr2 = 29
Const Ip_srcaddr3 = 30
Const Ip_destaddr0 = 31 'IP addess of destination
Const Ip_destaddr1 = 32
Const Ip_destaddr2 = 33
Const Ip_destaddr3 = 34
Const Ip_data = 35 'IP data area
'*******************************************************************************
'* ICMP Header
'*******************************************************************************
Const Icmp_type = 35 'Ip_data
Const Icmp_code = 36 'ICMP_type+1
Const Icmp_cksumh = 37 'ICMP_code+1
Const Icmp_cksuml = 38
Const Icmp_idh = 39 'Icmp_cksum + 2
Const Icmp_idl = 40
Const Icmp_seqnumh = 41 'ICMP_id+2
Const Icmp_seqnuml = 42
Const Icmp_data = 43 'ICMP_seqnum+2
'*******************************************************************************
'* UDP Header
'*******************************************************************************
Const Udp_srcporth = 35 'Ip_data
Const Udp_srcportl = 36 'Ip_data
Const Udp_destporth = 37 'UDP_srcport+2
Const Udp_destportl = 38 'UDP_srcport+2
Const Udp_lenh = 39 'UDP_destport+2
Const Udp_lenl = 40 'UDP_destport+2
Const Udp_cksumh = 41 'Udp_len + 2
Const Udp_cksuml = 42 'Udp_len + 2
Const Udp_data = 43 'UDP_cksum+2
'*******************************************************************************
'* TCP Header
'*******************************************************************************
Const Tcp_srcporth = 35 'Tcp Source Port MSB
Const Tcp_srcportl = 36 'Tcp Source Port LSB
Const Tcp_destporth = 37 'TCP destination port
Const Tcp_destportl = 38 'TCP destination port
Const Tcp_seqnum3 = 39 'MSB sequence number
Const Tcp_seqnum2 = 40 'NSB sequence number
Const Tcp_seqnum1 = 41 'NSB sequence number
Const Tcp_seqnum0 = 42 'LSB sequence number
Const Tcp_acknum3 = 43 'MSB acknowledgement number
Const Tcp_acknum2 = 44 'NSB acknowledgement number
Const Tcp_acknum1 = 45 'NSB acknowledgement number
Const Tcp_acknum0 = 46 'LSB acknowledgement number
Const Tcp_hdr = 47 'MSN 4 -bit Header Len
Const Tcp_flags = 48 'TCP Flags
Const Tcp_windowh = 49 'Window size MSB
Const Tcp_windowl = 50 'Window size MSB
Const Tcp_cksumh = 51 'Tcp Checksum MSB
Const Tcp_cksuml = 52 'Tcp Checksum LSB
Const Tcp_urgentptrh = 53 'Urgent pointer MSB
Const Tcp_urgentptrl = 54 'Urgent pointer LSB
Const Tcp_data = 55 'Options / Data
'*******************************************************************************
'* REALTEK CONTROL REGISTER OFFSETS
'* All offsets in Page 0 unless otherwise specified
'* These values are for the a memory-mapped Whacker starting at E000 hex.
'*******************************************************************************
Const Cr = &HE000
Const Pstart = &HE001
Const Par0 = &HE001 'Page 1
Const Cr9346 = &HE001 'Page 3
Const Pstop = &HE002
Const Bnry = &HE003
Const Tsr = &HE004
Const Tpsr = &HE004
Const Tbcr0 = &HE005
Const Ncr = &HE005
Const Tbcr1 = &HE006
Const Isr = &HE007
Const Curr = &HE007 'Page 1
Const Rsar0 = &HE008
Const Crda0 = &HE008
Const Rsar1 = &HE009
Const Crdal = &HE009
Const Rbcr0 = &HE00A
Const Rbcr1 = &HE00B
Const Rsr = &HE00C
Const Rcr = &HE00C
Const Tcr = &HE00D
Const Cntr0 = &HE00D
Const Dcr = &HE00E
Const Cntr1 = &HE00E
Const Imr = &HE00F
Const Cntr2 = &HE00F
Const Rdmaport = &HE010
Const Rstport = &HE018
'*******************************************************************************
'* RTL8019AS INITIAL REGISTER VALUES
'*******************************************************************************
Const Rcrval = &H04
Const Tcrval = &H00
Const Dcrval = &H58 'was &H48
Const Imrval = &H11 'PRX and OVW interrupt enabled
Const Txstart = &H40
Const Rxstart = &H46
Const Rxstop = &H60
'*******************************************************************************
'* RTL8019AS 9346 EEPROM PIN DEFINITIONS - These are NOT implemented
'*******************************************************************************
'Eesk Alias P0.0
'Eedi Alias P0.1
'Eedo Alias P0.2
'*******************************************************************************
'* RTL8016AS ISR REGISTER DEFINITIONS
'*******************************************************************************
'Const Rst = &H07
Const Rdc = &H06
Const Ovw = &H04
Const Prx = &H00
'*******************************************************************************
'* Port Bit Alias - Set It To The Port Pin You Used.
'*******************************************************************************
Rst Alias P1.5 ' changed (Ben) 'This goes to the Whacker RSTDRV line.
'This next line is ONLY needed if you are using the 89c668 processor. In enables the
'internal 8K RAM. REMOVE it if you are not using the 89c668 processor.
Auxr = 0
'*******************************************************************************
'* Initialize the RTL8091AS
'*******************************************************************************
Set Rst 'Put Nic In Reset
Waitms 2 'Delay At Least 1.6ms
Reset Rst 'Disable Reset Line
Work = Inp(rstport) 'read contents of reset port
Out Rstport , Work 'do soft reset
Waitms 10 'give it time
Work = Inp(isr) 'check for good soft reset
If Work.7 = 0 Then
Print "Init Reset Failed!"
End If
Out Cr , &H21 'stop the NIC, abort DMA, page 0
Waitms 2 'make sure nothing is coming in or going out
Out Dcr , Dcrval '&H58
Out Rbcr0 , &H00
Out Rbcr1 , &H00
Out Rcr , &H04
Out Tpsr , Txstart
Out Tcr , &H02
Out Pstart , Rxstart
Out Bnry , Rxstart
Out Pstop , Rxstop
Out Cr , &H61
Waitms 2
Out Curr , Rxstart
'*******************************************************************************
'* Set MAC Address = 00-00-43-4F-4E-41 MSB --> LSB
'* You need to suppy your own. Make it unique for each Whacker you own!
'*******************************************************************************
Mymac(1) = 0
Out &HE001 , 0
Mymac(2) = 0
Out &HE002 , 0
Mymac(3) = &H43
Out &HE003 , &H43
Mymac(4) = &H4F
Out &HE004 , &H4F
Mymac(5) = &H4E
Out &HE005 , &H4E
Mymac(6) = &H41
Out &HE006 , &H41
'*******************************************************************************
'* Define IP Address 192.168.0.xxx is good for localized networks!
'* You need to suppy your own. Make it unique for each Whacker you own!
'*******************************************************************************
Myip(1) = 192
Myip(2) = 168
Myip(3) = 0
Myip(4) = 102
Out Cr , &HC1
'*******************************************************************************
'* Put your code here it fake out the 9346 Serial EEPROM
'* if you decide to do it.
'*******************************************************************************
'Out Cr9346 , &HC0
'Out Cr9346 , &H40
'Fakeout_9346();
Waitms 10
Out Cr , &H21
Out Dcr , Dcrval
Out Cr , &H22
Out Isr , &HFF
Out Imr , Imrval
Out Tcr , Tcrval
#if Debug
Gosub Dump_regs 'This is for debugging
#endif
'*******************************************************************************
'* Start The NIC!!
'*******************************************************************************
'Start the NIC!!
Out Cr , &H22
Main:
Print "Waiting For Packet..."
'*******************************************************************************
'* Enable Interrupts and wait for a packet!
'*******************************************************************************
Enable Interrupts
Enable Int0
On Int0 Nicint
'*******************************************************************************
'* Put any code you want the processor to regularly run here!
'*******************************************************************************
Do
'Wait forever
Loop
End
'*******************************************************************************
'NIC Interrupt Routine
'*******************************************************************************
Nicint:
Disable Int0
'Read The Interrupt Status Register
Interupptstatus = Inp(isr)
'Test if the receive buffer has been overrun
If Interupptstatus.4 = 1 Then
Gosub Overrun
End If
'Test if the receive buffer holds a good packet
If Interupptstatus.0 = 1 Then
Gosub Get_packet
End If
'make sure the receive buffer ring is empty
'if BNRY = CURR, the buffer is empty
Bnryptr = Inp(bnry)
Out Cr , &H62
Currptr = Inp(curr)
Out Cr , &H22
'buffer is not empty.. get next packet
If Bnryptr <> Currptr Then
Gosub Get_packet
End If
'reset the interrupt bits
Out Isr , &HFF
Out Cr , &H22
Enable Int0
Return
'*******************************************************************************
'* Handle Receive Ring Buffer Overrun
'* No packets are recovered
'*******************************************************************************
Overrun:
Work = Inp(cr)
Out Cr , &H21
Waitms 2
Out Rbcr0 , &H00
Out Rbcr1 , &H00
'If(!bit_test(data_l , 2))
' Resend = 0;
'Else If(bit_test(data_l , 2))
' {
' Read_creg(isr);
' Data_l = Byte_read;
' If(bit_test(data_l , 1) || Bit_test(data_l , 3))
' Resend = 0;
' Else
' Resend = 1;
' }
Out Tcr , &H02
Out Cr , &H22
Out Bnry , Rxstart
Out Cr , &H62
Out Curr , Rxstart
Out Cr , &H22
Out Isr , &H10
Out Tcr , Tcrval
Return
'*******************************************************************************
'* Get A Packet From the Ring
'* This routine removes a data packet from the receive buffer
'* ring, analyzes it .
'*******************************************************************************
Get_packet:
Out Cr , &H1A
'Strip off packet status info.
Work = Inp(rdmaport) 'Packet Status - trash.
Work = Inp(rdmaport) 'Next Block Ptr - trash.
Packetlenl = Inp(rdmaport) 'Packet length low byte
Packetlenh = Inp(rdmaport) 'Packet length high byte
Packetlen = Packetlenh * 256
Packetlen = Packetlen + Packetlenl
'Fill up byte array with contents of packet.
For I = 1 To Packetlen
Work = Inp(rdmaport)
Packet(i) = Work
Next
Work = Inp(isr)
While Work.6 = 0
Work = Inp(isr)
Wend
Out Isr , &HFF
'Analyze the Packet and execute according to type
'Process an ARP packet
If Packet(packtype0) = &H08 Then
If Packet(packtype1) = &H06 Then 'ARP Packet
'Print "ARP Packet Received."
'Make sure the ARP packet is valid and for our IP Address.
If Packet(arp_hwtype1) <> 1 Then
Goto Exit_get_packet
End If
If Packet(arp_prtype0) <> 8 Then
Goto Exit_get_packet
End If
If Packet(arp_prtype1) <> 0 Then
Goto Exit_get_packet
End If
If Packet(arp_hwlen) <> 6 Then
Goto Exit_get_packet
End If
If Packet(arp_prlen) <> 4 Then
Goto Exit_get_packet
End If
If Packet(arp_op1) <> 1 Then
Goto Exit_get_packet
End If
J = Arp_tipaddr
If Packet(j) <> Myip(1) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(2) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(3) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(4) Then
Goto Exit_get_packet
End If
Gosub Arp
Elseif Packet(packtype1) = 0 Then 'IP Packet
'Print "IP Packet Received."
'Make sure the IP Packet is for our IP Address.
J = Ip_destaddr0
If Packet(j) <> Myip(1) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(2) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(3) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(4) Then
Goto Exit_get_packet
End If
'Check the type of IP Packet and execute respectively.
If Packet(ip_proto) = 6 Then
'Print "Doing TCP"
Gosub Tcp_decode
Elseif Packet(ip_proto) = &H11 Then
'Print "Doing UDP"
Gosub Udp
Elseif Packet(ip_proto) = 1 Then
'Print "Doing Ping"
Gosub Icmp
End If
End If
End If
Exit_get_packet:
Return
'*******************************************************************************
'ARP Procedure
'*******************************************************************************
Arp:
'Start the NIC
Out Cr , &H22
'Load beginning page for transmit buffer
Out Tpsr , Txstart
'Set start address for remote DMA operation
Out Rsar0 , 0
Out Rsar1 , &H40
'Clear the Interrupts
Out Isr , &HFF
'Load data byte count for remote DMA
Out Rbcr0 , &H3C '60 Bytes
Out Rbcr1 , 0
'Do remote write operation
Out Cr , &H12
'Write destination MAC address
J = Destmac1
For I = 1 To 6
Out Rdmaport , Packet(j)
J = J + 1
Next
'Write source MAC address
For I = 1 To 6
Out Rdmaport , Mymac(i)
Next
'Write typelen hwtype prtype hwlen prlen op:
J = Packtype0
'Packet[arp_op + 1] = 0x02;
For I = 1 To 9
Out Rdmaport , Packet(j)
J = J + 1
Next
Out Rdmaport , 2
'Write ethernet module MAC address
For I = 1 To 6
Out Rdmaport , Mymac(i)
Next
'Write ethernet module IP address
For I = 1 To 4
Out Rdmaport , Myip(i)
Next
'Write remote MAC address
J = Destmac1
For I = 1 To 6
Out Rdmaport , Packet(j)
J = J + 1
Next
'Write remote IP address
J = Arp_sipaddr
For I = 1 To 4
Out Rdmaport , Packet(j)
J = J + 1
Next
'Write some pad characters to fill out the packet to
'the minimum length
For I = 1 To 18
Out Rdmaport , &H00
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
'Load number of bytes to be transmitted
Out Tbcr0 , &H3C
Out Tbcr1 , &H00
'Send the contents of the transmit buffer onto the network
Out Cr , &H24
Return
'*******************************************************************************
' ICMP Procedure
'*******************************************************************************
Icmp:
'set echo reply
Packet(icmp_type) = 0
Packet(icmp_code) = 0
'clear the ICMP checksum
Packet(icmp_cksumh) = 0
Packet(icmp_cksuml) = 0
'setup the IP header
Gosub Setup_packet
'calculate the ICMP checksum
Csbytecnt = Packet(ip_pktlenh) * 256
Csbytecnt = Csbytecnt + Packet(ip_pktlenl)
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Csbytecnt - Work
Csptr = Icmp_type
Gosub General_checksum
Packet(icmp_cksumh) = High(checksumout)
Packet(icmp_cksuml) = Low(checksumout)
'Send the ICMP packet along on its way
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , 0
Out Rsar1 , &H40
Out Isr , &HFF
Packetlen = Packetlen - 4 'Remove trailing 32 bit checksum
Out Rbcr0 , Low(packetlen)
Out Rbcr1 , High(packetlen)
Out Cr , &H12
For I = Destmac1 To Packetlen
Out Rdmaport , Packet(i)
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
Out Tbcr0 , Low(packetlen)
Out Tbcr1 , High(packetlen)
Out Cr , &H24
Return
'*******************************************************************************
' UDP Routine - Just echo Port 7 for now!
'*******************************************************************************
Udp:
'Port 7 is the echo port
If Packet(udp_destporth) = 0 And Packet(udp_destportl) = 7 Then
Print "Building UDP Packet"
'Build The Ip Header
Gosub Setup_packet
'Swap the UDP source and destination ports
Work = Packet(udp_srcporth)
Packet(udp_srcporth) = Packet(udp_destporth)
Packet(udp_destporth) = Work
Work = Packet(udp_srcportl)
Packet(udp_srcportl) = Packet(udp_destportl)
Packet(udp_destportl) = Work
'Calculate the UDP checksum
Packet(udp_cksumh) = 0
Packet(udp_cksuml) = 0
Gosub Udp_checksum
Packet(udp_cksumh) = High(checksumout)
Packet(udp_cksuml) = Low(checksumout)
Tempint = Packet(udp_destporth) * 256
Tempint = Tempint + Packet(udp_destportl)
'Print "Dest Port: " ; Tempint
'Gosub Dump_packet
'send the UDP packet along on its way
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , 0
Out Rsar1 , &H40
Out Isr , &HFF
Packetlen = Packetlen - 4 'Remove trailing 32 bit checksum
Out Rbcr0 , Low(packetlen)
Out Rbcr1 , High(packetlen)
Out Cr , &H12
For I = Destmac1 To Packetlen
Out Rdmaport , Packet(i)
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
Out Tbcr0 , Low(packetlen)
Out Tbcr1 , High(packetlen)
Out Cr , &H24
End If
Return
'*******************************************************************************
' General Checksum
'*******************************************************************************
General_checksum:
'Input:Csbytecnt as number of bytes
'Input:Csptr as pointer to start of array to find checksum
'Output: Checksumout as Integer (16 Bits) containing checksum
Checksum = 0
'Loop
While Csbytecnt > 1
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
Csptr = Csptr + 1
Checksum = Checksum + Packet(csptr)
Csptr = Csptr + 1
Csbytecnt = Csbytecnt - 2
Wend
If Csbytecnt > 0 Then
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
End If
Tempword = Highw(checksum) 'get amount above 16 bit value
Checktemp = Loww(checksum) 'get amount left over in 16 bits
Checksum = Checktemp + Tempword 'add amount over to left over amount
Checksumout = Loww(checksum) 'get 16 bit leftover amount
Checksumout = Not Checksumout 'Perform ones compliment
Return
'*******************************************************************************
' UDP Checksum Routine
'*******************************************************************************
Udp_checksum:
Checksum = 0
'Do IP Source and Destination Addresses
Tempword = Packet(ip_srcaddr0) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_srcaddr1)
Tempword = Packet(ip_srcaddr2) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_srcaddr3)
Tempword = Packet(ip_destaddr0) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_destaddr1)
Tempword = Packet(ip_destaddr2) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_destaddr3)
'Do IP_Proto
Checksum = Checksum + Packet(ip_proto)
'Do UDP Length
Tempword = Packet(udp_lenh) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(udp_lenl)
'Now look through entire UDP header and data
Csptr = Udp_srcporth
Csbytecnt = Tempword + Packet(udp_lenl)
'Loop
While Csbytecnt > 1
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
Csptr = Csptr + 1
Checksum = Checksum + Packet(csptr)
Csptr = Csptr + 1
Csbytecnt = Csbytecnt - 2
Wend
If Csbytecnt > 0 Then
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
End If
Tempword = Highw(checksum) 'get amount above 16 bit value
Checktemp = Loww(checksum) 'get amount left over in 16 bits
Checksum = Checktemp + Tempword 'add amount over to left over amount
Checksumout = Loww(checksum) 'get 16 bit leftover amount
Checksumout = Not Checksumout 'Perform ones compliment
Return
'*******************************************************************************
'Setup Packet Routine
'*******************************************************************************
Setup_packet:
'Move IP source address to destination address
Packet(ip_destaddr0) = Packet(ip_srcaddr0)
Packet(ip_destaddr1) = Packet(ip_srcaddr1)
Packet(ip_destaddr2) = Packet(ip_srcaddr2)
Packet(ip_destaddr3) = Packet(ip_srcaddr3)
'Make ethernet module IP address source address
Packet(ip_srcaddr0) = Myip(1)
Packet(ip_srcaddr1) = Myip(2)
Packet(ip_srcaddr2) = Myip(3)
Packet(ip_srcaddr3) = Myip(4)
'Move hardware source address to destinatin address
Packet(destmac1) = Packet(srcmac1)
Packet(destmac2) = Packet(srcmac2)
Packet(destmac3) = Packet(srcmac3)
Packet(destmac4) = Packet(srcmac4)
Packet(destmac5) = Packet(srcmac5)
Packet(destmac6) = Packet(srcmac6)
'Make ethernet module mac address the source address
Packet(srcmac1) = Mymac(1)
Packet(srcmac2) = Mymac(2)
Packet(srcmac3) = Mymac(3)
Packet(srcmac4) = Mymac(4)
Packet(srcmac5) = Mymac(5)
Packet(srcmac6) = Mymac(6)
' subroutine van maken
'Calculate the IP header checksum
Packet(ip_hdr_cksumh) = 0
Packet(ip_hdr_cksuml) = 0
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Work
Csptr = Ip_vers_len
Gosub General_checksum
Packet(ip_hdr_cksumh) = High(checksumout)
Packet(ip_hdr_cksuml) = Low(checksumout)
Return
'*******************************************************************************
'Dump RTL8019AS Registers Procedure
'*******************************************************************************
Dump_regs:
Print "RTL8019AS Register Dump"
Print "Page0 Page1 Page2 Page3"
For I = &HE000 To &HE00F
Out Cr , &H21
Work = Inp(i)
Printhex Work;
Out Cr , &H61
Work = Inp(i)
Printhex " " ; Work;
Out Cr , &HA1
Work = Inp(i)
Printhex " " ; Work;
Out Cr , &HE1
Work = Inp(i)
Printhex " " ; Work
Next I
Return
'*******************************************************************************
'Dump Packet Routine
'*******************************************************************************
Dump_packet:
For I = 1 To Packetlen
Printhex " " ; Packet(i);
Work = I Mod 8
If Work = 0 Then
Print
End If
Next
Return
'*******************************************************************************
' TCP Decode Routine
'*******************************************************************************
Tcp_decode:
Work = Packet(tcp_flags)
Tcp_fin = Work.0
Tcp_syn = Work.1
Tcp_rst = Work.2
Tcp_psh = Work.3
Tcp_ack = Work.4
Tcp_urg = Work.5
' assemble the destination port address from the incoming packet
Vhigh16 = Packet(tcp_destporth)
Vlow16 = Packet(tcp_destportl)
Result16 = Vhigh16
Shift Result16 , Left , 8
Portaddr = Result16 + Vlow16
' calculate the length of the data coming in with the packet
' tcpdatalen_in = incoming packet length - incoming ip header length
Vhigh16 = Packet(ip_pktlenh)
Vlow16 = Packet(ip_pktlenl)
Result16 = Vhigh16
Shift Result16 , Left , 8
Result16 = Result16 + Vlow16
' calculate IP header length
' MSN is version (IPv4)
' LSN is length
Tempbyte1 = Packet(ip_vers_len) And &H0F
Tempbyte1 = Tempbyte1 * 4
' calculate TCP header length
' MSN is length / 4
Tempbyte2 = Packet(tcp_hdr) And &HF0
Shift Tempbyte2 , Right , 4
Tempbyte2 = Tempbyte2 * 4
Tcpdatalen_in = Result16 - Tempbyte1
Tcpdatalen_in = Tcpdatalen_in - Tempbyte2
' If an ACK is received and the destination port address is valid
' and no data is in the packet
If Tcp_ack = 1 Then
If Portaddr = My_port_address Then
If Tcpdatalen_in = 0 Then
A32 = Packet(tcp_acknum3)
B32 = Packet(tcp_acknum2)
C32 = Packet(tcp_acknum1)
D32 = Packet(tcp_acknum0)
Gosub Make32
Incoming_ack = Resultaat
If Flags.synflag = 1 Then
Gosub Clr_synflag
My_seqnum = Incoming_ack
Msg = "EDTP P89C668 Telnet Server>"
Msg = Msg + Chr(10) + Chr(13)
Tempbyte2 = Len(msg)
For X = 0 To Tempbyte2
Tempbyte1 = X + Tcp_data
Work = X + 1
Tempstring1 = Mid(msg , Work , 1)
Packet(tempbyte1) = Asc(tempstring1)
Next X
Tcpdatalen_out = Tempbyte2
' expect to get an acknowledgment of the banner message
Expected_ack = My_seqnum + Tcpdatalen_out
' send the TCP/IP packet
Gosub Send_tcp_packet
End If
End If
End If
End If
' if an ACK is received and the port address is valid and there is
' data in the incoming packet
If Tcp_ack = 1 Then
If Portaddr = My_port_address Then
If Tcpdatalen_in > 0 Then
For X = 0 To Tcpdatalen_in
Tempbyte1 = Tcp_data + X
Aux_data(x) = Packet(tempbyte1)
Print Chr(aux_data(x))
Next X
Gosub Application_code
A32 = Packet(tcp_acknum3)
B32 = Packet(tcp_acknum2)
C32 = Packet(tcp_acknum1)
D32 = Packet(tcp_acknum0)
Gosub Make32
Incoming_ack = Resultaat
If Incoming_ack <= Expected_ack Then
Templong1 = Expected_ack - Incoming_ack
My_seqnum = Expected_ack - Templong1
End If
Expected_ack = My_seqnum + Tcpdatalen_out
Gosub Send_tcp_packet
End If
End If
End If
' This code segment processes the incoming SYN from the Tenet client
' and sends back the initial sequence number (ISN) and acknowledges
' the incoming SYN packet
If Tcp_syn = 1 Then
If Portaddr = My_port_address Then
Tcpdatalen_in = 1
Gosub Set_synflag
Gosub Setup_packet
Data_l = Packet(tcp_srcportl)
Packet(tcp_srcportl) = Packet(tcp_destportl)
Packet(tcp_destportl) = Data_l
Data_l = Packet(tcp_srcporth)
Packet(tcp_srcporth) = Packet(tcp_destporth)
Packet(tcp_destporth) = Data_l
Gosub Assemble_ack
Tempword1 = Isn + 1
If Tempword1 = 0 Then
My_seqnum = &H1234FFFF
End If
If Tempword1 = &HFFFF Then
My_seqnum = &H1234FFFF
End If
D = Tcp_seqnum3
S = My_seqnum
Gosub Set_packet32
Packet(tcp_flags) = 0
Gosub Syn_out
Gosub Ack_out
Gosub Tcp_checksum
Gosub Echo_packet
End If
End If
If Tcp_fin = 1 Then
If Portaddr = My_port_address Then
If Tcpdatalen_in > 0 Then
Tempbyte2 = Len(tcpdatalen_in)
For X = 0 To Tempbyte2
Tempbyte3 = Tcp_data + X
Aux_data(x) = Packet(tempbyte3)
Next X
Gosub Application_code
End If
End If
Gosub Set_finflag
Incr Tcpdatalen_in
A32 = Packet(tcp_acknum3)
B32 = Packet(tcp_acknum2)
C32 = Packet(tcp_acknum1)
D32 = Packet(tcp_acknum0)
Gosub Make32
Incoming_ack = Resultaat
If Incoming_ack <= Expected_ack Then
Templong1 = Expected_ack - Incoming_ack
My_seqnum = Expected_ack - Templong1
End If
Expected_ack = My_seqnum + Tcpdatalen_out
Gosub Send_tcp_packet
End If
Return
'*******************************************************************************
' Send_tcp_packet Routine
'*******************************************************************************
Send_tcp_packet:
Ip_packet_len = 40 + Tcpdatalen_out
S = Ip_packet_len
O8 = 1
Gosub Make8
Packet(ip_pktlenh) = A8
S = Ip_packet_len
O8 = 0
Gosub Make8
Packet(ip_pktlenl) = A8
Gosub Setup_packet
Data_l = Packet(tcp_srcporth)
Packet(tcp_srcporth) = Packet(tcp_destporth)
Packet(tcp_destporth) = Data_l
Packet(ip_pktlenl) = A8
Data_l = Packet(tcp_srcportl)
Packet(tcp_srcportl) = Packet(tcp_destportl)
Packet(tcp_destportl) = Data_l
Gosub Assemble_ack
D = Tcp_seqnum3
S = My_seqnum
Gosub Set_packet32
Packet(tcp_flags) = 0
Gosub Ack_out
If Flags.finflag = 1 Then
Gosub Fin_out
Gosub Clr_finflag
End If
Gosub Tcp_checksum
Txlen = Ip_packet_len + 14
If Txlen < 60 Then
Txlen = 60
End If
's As Long , O8 As Byte
'result in A8
'in S the variable
'offset in O8
S = Txlen
O8 = 0
Gosub Make8
Data_l = A8
S = Txlen
O8 = 1
Gosub Make8
Data_h = A8
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , &H00
Out Rsar1 , &H40
Out Isr , &HFF
Out Rbcr0 , Low(txlen)
Out Rbcr1 , High(txlen)
Out Cr , &H12
For I = Destmac1 To Txlen
Out Rdmaport , Packet(i)
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
Out Tbcr0 , Low(txlen)
Out Tbcr1 , High(txlen)
Out Cr , &H24
Return
'*******************************************************************************
' Assemble_ack Routine
'*******************************************************************************
Assemble_ack:
A32 = Packet(tcp_seqnum3)
B32 = Packet(tcp_seqnum2)
C32 = Packet(tcp_seqnum1)
D32 = Packet(tcp_seqnum0)
Gosub Make32
Client_seqnum = Resultaat
Client_seqnum = Client_seqnum + Tcpdatalen_in
D = Tcp_acknum3
S = Client_seqnum
Gosub Set_packet32
Return
'*******************************************************************************
' Make32 Routine
'*******************************************************************************
Make32:
Tempword1 = Makeint(b32 , A32)
Resultaat = Tempword1 * 65536
Tempword1 = Makeint(d32 , C32)
Resultaat = Resultaat + Tempword1
Return
'*******************************************************************************
' Set_packet32 Routine
'*******************************************************************************
Set_packet32:
'd As Byte , S As Long
'D as byte for packet(d)-pointer
'S as long the 32 bit that should be broken in four parts
'A8 - tempvar
'O8 - offset
Hulp2 = D
O8 = 3
Gosub Make8
Packet(hulp2) = A8
Hulp2 = Hulp2 + 1
O8 = 2
Gosub Make8
Packet(hulp2) = A8
Hulp2 = Hulp2 + 1
O8 = 1
Gosub Make8
Packet(hulp2) = A8
Hulp2 = Hulp2 + 1
O8 = 0
Gosub Make8
Packet(hulp2) = A8
Return
'*******************************************************************************
' Make8 Routine
'*******************************************************************************
Make8:
's As Long , O8 As Byte
'result in A8
'in S the variable
'offset in O8
'Print "Sub Make8"
S_temp = S
Hulp1 = O8 * 8
If Hulp1 = 0 Then
A8 = S
Else
Shift S_temp , Right , Hulp1
A8 = S_temp
End If
Return
Fin_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.0
Packet(tcp_flags) = Flag_temp
Return
Syn_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.1
Packet(tcp_flags) = Flag_temp
Return
Rst_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.2
Packet(tcp_flags) = Flag_temp
Return
Psh_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.3
Packet(tcp_flags) = Flag_temp
Return
Ack_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.4
Packet(tcp_flags) = Flag_temp
Return
Urg_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.5
Packet(tcp_flags) = Flag_temp
Return
Set_synflag:
Set Flags.synflag
Return
Clr_synflag:
Reset Flags.synflag
Return
Set_finflag:
Set Flags.finflag
Return
Clr_finflag:
Reset Flags.finflag
Return
'*******************************************************************************
' echo-packet routine
'*******************************************************************************
Echo_packet:
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , &H00
Out Rsar1 , &H40
Out Isr , &HFF
Packetlenl = Packetlenl - 4
Out Rbcr0 , Packetlenl
Out Rbcr1 , Packetlenh
Out Cr , &H12
Tempword1 = Packetlenh * 256
Tempword1 = Tempword1 + Packetlenl
Tempword1 = Tempword1 - 4
For I = 0 To Tempword1
Hulp1 = Destmac1 + I
Out Rdmaport , Packet(hulp1)
Next I
While Work.6 = 0
Work = Inp(isr)
Wend
Packetlenl = Packetlenl - 4
Out Tbcr0 , Packetlenl
Out Tbcr1 , Packetlenh
Out Cr , &H24
Return
Application_code:
For I = 1 To Tcpdatalen_in
If Aux_data(i) <> &H0A Then
Tcpdatalen_out = Tcpdatalen_in
End If
If Aux_data(i) = &H0A Then
Tcpdatalen_out = &H00
End If
' here your actioncode
'Work = Aux_data(i)
'Select Case Aux_data(i)
'Case &H0D : Print
'Case &H1B : Print
'Case &H09 : Print
'Case 10 To 20 'test the range from 10 to 20
'Case Else
'End Select
Next I
Return
Tcp_checksum:
'Calculate the IP header checksum
Packet(ip_hdr_cksumh) = 0
Packet(ip_hdr_cksuml) = 0
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Work
Csptr = Ip_vers_len
Gosub General_checksum
Packet(ip_hdr_cksumh) = High(checksumout)
Packet(ip_hdr_cksuml) = Low(checksumout)
Hdr_chksum = 0
Tempword1 = Packet(ip_srcaddr0) * 256
Tempword1 = Tempword1 + Packet(ip_srcaddr1)
Hdr_chksum = Hdr_chksum + Tempword1
Tempword1 = Packet(ip_srcaddr2) * 256
Tempword1 = Tempword1 + Packet(ip_srcaddr3)
Hdr_chksum = Hdr_chksum + Tempword1
Tempword1 = Packet(ip_destaddr0) * 256
Tempword1 = Tempword1 + Packet(ip_destaddr1)
Hdr_chksum = Hdr_chksum + Tempword1
Tempword1 = Packet(ip_destaddr2) * 256
Tempword1 = Tempword1 + Packet(ip_destaddr3)
Hdr_chksum = Hdr_chksum + Tempword1
Hdr_chksum = Hdr_chksum + Packet(ip_proto)
Csbytecnt = Packet(ip_pktlenh) * 256
Csbytecnt = Csbytecnt + Packet(ip_pktlenl)
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Csbytecnt - Work
Hdr_chksum = Hdr_chksum + Csbytecnt
Packet(tcp_cksumh) = 0
Packet(tcp_cksuml) = 0
Csptr = Tcp_srcporth
'Input:Csbytecnt as number of bytes
'Input:Csptr as pointer to start of array to find checksum
'Output: Checksumout as Integer (16 Bits) containing checksum
Checksum = Hdr_chksum
'Loop
While Csbytecnt > 1
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
Csptr = Csptr + 1
Checksum = Checksum + Packet(csptr)
Csptr = Csptr + 1
Csbytecnt = Csbytecnt - 2
Wend
If Csbytecnt > 0 Then
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
End If
Tempword = Highw(checksum) 'get amount above 16 bit value
Checktemp = Loww(checksum) 'get amount left over in 16 bits
Checksum = Checktemp + Tempword 'add amount over to left over amount
Checksumout = Loww(checksum) 'get 16 bit leftover amount
Checksumout = Not Checksumout
Packet(tcp_cksumh) = High(checksumout)
Packet(tcp_cksuml) = Low(checksumout)
Return
'BASCOM-51 RTL8019AS Test Program By Kent D. Smith.
'This code controls an EDTP Electronic's Packet Whacker.
'ARP, ICMP, and UDP protocols are all supported. The code is easily expanded to
'handle TCP as well.
'The Code is written using MCS Electronic's (mcselec.com) BASCOM-51 BASIC Compiler for
'8051 family devices.
'All routines from TCP/IP-decode to the end of the program are written by Ben Zijlstra
'For checksumroutines parts of the routines written by Kent are used.
'
'*******************************************************************************
'* Hardware Setup
'*******************************************************************************
'The Packet Whacker is Memory Mapped starting at hex location E000.
'The RSTDRV line of the Whacker is connected to Port P1.7.
'The Whacked 8051 Development Board uses P1.5 for the RSTDRV
'Use any port pin you wish but be sure to change the code!
'INT0 of the 8051 is tied to the Whackers interrupt line (INT0) via an inverter to notify the
'8051 that a packet has been received. Use an IC inverter or a single NPN transistor and
'two resistors.
'If you have other devices or RAM memory-mapped in your system, you must use an OR
'gate (such as the 74HCT32) to OR the /CS from your address decoder with the /RD and
'/WR signals from your 8051 family microprocessor to the /IORB and /IOWB lines of the Whacker.
'
'This code is set for a Philips 89c668 microprocessor but should work on any 8051
'system with external RAM of 2K or more. The 89c668 has 8K of internal RAM mapped into
'the external RAM memory space.
'If you use the 89c668 microprocessor note that Port pins P1.6 and P1.7 are open drain
'and will require a pull-up resistor.
'For debugging and testing purposes, the serial port of the processor is used to send
'information to a PC's serial port with the PC running a terminal emulator program.
'NOTE: The 93c46 emulation is not implemented in this code.
$large
$romstart = &H0
'Set the following to your system's RAM starting address and size.
$ramstart = &H0
$ramsize = &H7FFF
$default Xram
'Set regfile to your microprocessor type. See BASCOM-51 help.
$regfile = "89c668.dat"
'The debugging/testing serial port runs at 9600 baud.
$baud = 9600
'The Philips 89c668 runs at twice the speed of a regular 8051. I use an 11.0592
'crystal but must tell the compiler to use double the speed for the serial port
'baud rate to work
$crystal = 22118400 'Double 11059200 - Using 6X Clock
'*******************************************************************************
'* Variable Declarations
'*******************************************************************************
Dim Work As Byte
Dim Mymac(6) As Byte
Dim Myip(4) As Byte
Dim Packet(1500) As Byte 'This array receives and transmit the packet from the Whacker.
Dim Ptype0 As Byte
Dim Ptype1 As Byte
Dim Packetlenl As Byte
Dim Packetlenh As Byte
Dim Packetlen As Integer
Dim Xmitpacketlen As Integer
Dim I As Integer
Dim J As Integer
Dim K As Integer
Dim Interupptstatus As Byte
Dim Bnryptr As Byte
Dim Currptr As Byte
Dim Csptr As Integer
Dim Csbytecnt As Integer
Dim Checksum As Long
Dim Checktemp As Word
Dim Checksumout As Word
Dim Tempword As Word
Dim Tempint As Integer
Dim Templong As Long
Dim Tcp_fin As Bit
Dim Tcp_syn As Bit
Dim Tcp_rst As Bit
Dim Tcp_psh As Bit
Dim Tcp_ack As Bit
Dim Tcp_urg As Bit
Dim Seqnum As Long
Dim Acknum As Long
Dim Udpdata As String * 254
Dim Tempstr As String * 1
' added by Ben Zijlstra
Dim Vhigh16 As Byte
Dim Vlow16 As Byte
Dim Result16 As Word
Dim Portaddr As Word
Dim Tcpdatalen_in As Word
Dim Tcpdatalen_out As Word
Dim Ip_packet_len As Long
Dim Tempbyte1 As Byte
Dim Tempbyte2 As Byte
Dim Tempbyte3 As Byte
Dim Tempword1 As Word
Dim Tempword2 As Word
Dim Templong1 As Long
Dim Data_l As Byte
Dim Data_h As Byte
Dim A32 As Byte , B32 As Byte , C32 As Byte , D32 As Byte
Dim Hulp1 As Byte , Hulp2 As Byte , Hulp3 As Byte
Dim Resultaat As Long
Dim Client_seqnum As Long
Dim D As Byte
Dim S As Long , S_temp As Long
Dim O8 As Byte
Dim A8 As Byte
Dim My_seqnum As Long
Dim Txlen As Long
Dim Isn As Word
Dim Flags As Byte
Dim Flag_temp As Byte
Dim Hdr_chksum As Long
Dim Msg As String * 1500
Dim Incoming_ack As Long
Dim X As Byte
Dim Expected_ack As Long
Dim Aux_data(1500) As Byte
Dim Tempstring1 As String * 1
Const Debug = -1
Const My_port_address = 8088
Const Synflag = 0
Const Finflag = 1
'*******************************************************************************
'* Ethernet Packet Layout constants
'*******************************************************************************
Const Destmac1 = 1
Const Destmac2 = 2
Const Destmac3 = 3
Const Destmac4 = 4
Const Destmac5 = 5
Const Destmac6 = 6
Const Srcmac1 = 7
Const Srcmac2 = 8
Const Srcmac3 = 9
Const Srcmac4 = 10
Const Srcmac5 = 11
Const Srcmac6 = 12
Const Packtype0 = 13
Const Packtype1 = 14
'*******************************************************************************
'* ARP Data Section Layout
'*******************************************************************************
Const Arp_hwtype0 = 15
Const Arp_hwtype1 = 16
Const Arp_prtype0 = 17
Const Arp_prtype1 = 18
Const Arp_hwlen = 19
Const Arp_prlen = 20
Const Arp_op0 = 21
Const Arp_op1 = 22
Const Arp_shaddr = 23 'Arp Source Mac Address
Const Arp_sipaddr = 29 'Arp Source Ip Address
Const Arp_thaddr = 33 'Arp Target Mac Address
Const Arp_tipaddr = 39 'Arp Target Ip Address
'*******************************************************************************
'* IP Header Layout
'*******************************************************************************
Const Ip_vers_len = 15 'IP version and header length
Const Ip_tos = 16 'Ip Type Of Service
Const Ip_pktlenh = 17 'packet length High
Const Ip_pktlenl = 18 'Low
Const Ip_id0 = 19 'datagram id
Const Ip_id1 = 20
Const Ip_frag_offset0 = 21 'fragment offset
Const Ip_frag_offset1 = 22
Const Ip_ttl = 23 'time to live
Const Ip_proto = 24 'protocol (ICMP=1, TCP=6, UDP=11)
Const Ip_hdr_cksumh = 25 'header checksum
Const Ip_hdr_cksuml = 26
Const Ip_srcaddr0 = 27 'IP address of source
Const Ip_srcaddr1 = 28
Const Ip_srcaddr2 = 29
Const Ip_srcaddr3 = 30
Const Ip_destaddr0 = 31 'IP addess of destination
Const Ip_destaddr1 = 32
Const Ip_destaddr2 = 33
Const Ip_destaddr3 = 34
Const Ip_data = 35 'IP data area
'*******************************************************************************
'* ICMP Header
'*******************************************************************************
Const Icmp_type = 35 'Ip_data
Const Icmp_code = 36 'ICMP_type+1
Const Icmp_cksumh = 37 'ICMP_code+1
Const Icmp_cksuml = 38
Const Icmp_idh = 39 'Icmp_cksum + 2
Const Icmp_idl = 40
Const Icmp_seqnumh = 41 'ICMP_id+2
Const Icmp_seqnuml = 42
Const Icmp_data = 43 'ICMP_seqnum+2
'*******************************************************************************
'* UDP Header
'*******************************************************************************
Const Udp_srcporth = 35 'Ip_data
Const Udp_srcportl = 36 'Ip_data
Const Udp_destporth = 37 'UDP_srcport+2
Const Udp_destportl = 38 'UDP_srcport+2
Const Udp_lenh = 39 'UDP_destport+2
Const Udp_lenl = 40 'UDP_destport+2
Const Udp_cksumh = 41 'Udp_len + 2
Const Udp_cksuml = 42 'Udp_len + 2
Const Udp_data = 43 'UDP_cksum+2
'*******************************************************************************
'* TCP Header
'*******************************************************************************
Const Tcp_srcporth = 35 'Tcp Source Port MSB
Const Tcp_srcportl = 36 'Tcp Source Port LSB
Const Tcp_destporth = 37 'TCP destination port
Const Tcp_destportl = 38 'TCP destination port
Const Tcp_seqnum3 = 39 'MSB sequence number
Const Tcp_seqnum2 = 40 'NSB sequence number
Const Tcp_seqnum1 = 41 'NSB sequence number
Const Tcp_seqnum0 = 42 'LSB sequence number
Const Tcp_acknum3 = 43 'MSB acknowledgement number
Const Tcp_acknum2 = 44 'NSB acknowledgement number
Const Tcp_acknum1 = 45 'NSB acknowledgement number
Const Tcp_acknum0 = 46 'LSB acknowledgement number
Const Tcp_hdr = 47 'MSN 4 -bit Header Len
Const Tcp_flags = 48 'TCP Flags
Const Tcp_windowh = 49 'Window size MSB
Const Tcp_windowl = 50 'Window size MSB
Const Tcp_cksumh = 51 'Tcp Checksum MSB
Const Tcp_cksuml = 52 'Tcp Checksum LSB
Const Tcp_urgentptrh = 53 'Urgent pointer MSB
Const Tcp_urgentptrl = 54 'Urgent pointer LSB
Const Tcp_data = 55 'Options / Data
'*******************************************************************************
'* REALTEK CONTROL REGISTER OFFSETS
'* All offsets in Page 0 unless otherwise specified
'* These values are for the a memory-mapped Whacker starting at E000 hex.
'*******************************************************************************
Const Cr = &HE000
Const Pstart = &HE001
Const Par0 = &HE001 'Page 1
Const Cr9346 = &HE001 'Page 3
Const Pstop = &HE002
Const Bnry = &HE003
Const Tsr = &HE004
Const Tpsr = &HE004
Const Tbcr0 = &HE005
Const Ncr = &HE005
Const Tbcr1 = &HE006
Const Isr = &HE007
Const Curr = &HE007 'Page 1
Const Rsar0 = &HE008
Const Crda0 = &HE008
Const Rsar1 = &HE009
Const Crdal = &HE009
Const Rbcr0 = &HE00A
Const Rbcr1 = &HE00B
Const Rsr = &HE00C
Const Rcr = &HE00C
Const Tcr = &HE00D
Const Cntr0 = &HE00D
Const Dcr = &HE00E
Const Cntr1 = &HE00E
Const Imr = &HE00F
Const Cntr2 = &HE00F
Const Rdmaport = &HE010
Const Rstport = &HE018
'*******************************************************************************
'* RTL8019AS INITIAL REGISTER VALUES
'*******************************************************************************
Const Rcrval = &H04
Const Tcrval = &H00
Const Dcrval = &H58 'was &H48
Const Imrval = &H11 'PRX and OVW interrupt enabled
Const Txstart = &H40
Const Rxstart = &H46
Const Rxstop = &H60
'*******************************************************************************
'* RTL8019AS 9346 EEPROM PIN DEFINITIONS - These are NOT implemented
'*******************************************************************************
'Eesk Alias P0.0
'Eedi Alias P0.1
'Eedo Alias P0.2
'*******************************************************************************
'* RTL8016AS ISR REGISTER DEFINITIONS
'*******************************************************************************
'Const Rst = &H07
Const Rdc = &H06
Const Ovw = &H04
Const Prx = &H00
'*******************************************************************************
'* Port Bit Alias - Set It To The Port Pin You Used.
'*******************************************************************************
Rst Alias P1.5 ' changed (Ben) 'This goes to the Whacker RSTDRV line.
'This next line is ONLY needed if you are using the 89c668 processor. In enables the
'internal 8K RAM. REMOVE it if you are not using the 89c668 processor.
Auxr = 0
'*******************************************************************************
'* Initialize the RTL8091AS
'*******************************************************************************
Set Rst 'Put Nic In Reset
Waitms 2 'Delay At Least 1.6ms
Reset Rst 'Disable Reset Line
Work = Inp(rstport) 'read contents of reset port
Out Rstport , Work 'do soft reset
Waitms 10 'give it time
Work = Inp(isr) 'check for good soft reset
If Work.7 = 0 Then
Print "Init Reset Failed!"
End If
Out Cr , &H21 'stop the NIC, abort DMA, page 0
Waitms 2 'make sure nothing is coming in or going out
Out Dcr , Dcrval '&H58
Out Rbcr0 , &H00
Out Rbcr1 , &H00
Out Rcr , &H04
Out Tpsr , Txstart
Out Tcr , &H02
Out Pstart , Rxstart
Out Bnry , Rxstart
Out Pstop , Rxstop
Out Cr , &H61
Waitms 2
Out Curr , Rxstart
'*******************************************************************************
'* Set MAC Address = 00-00-43-4F-4E-41 MSB --> LSB
'* You need to suppy your own. Make it unique for each Whacker you own!
'*******************************************************************************
Mymac(1) = 0
Out &HE001 , 0
Mymac(2) = 0
Out &HE002 , 0
Mymac(3) = &H43
Out &HE003 , &H43
Mymac(4) = &H4F
Out &HE004 , &H4F
Mymac(5) = &H4E
Out &HE005 , &H4E
Mymac(6) = &H41
Out &HE006 , &H41
'*******************************************************************************
'* Define IP Address 192.168.0.xxx is good for localized networks!
'* You need to suppy your own. Make it unique for each Whacker you own!
'*******************************************************************************
Myip(1) = 192
Myip(2) = 168
Myip(3) = 0
Myip(4) = 102
Out Cr , &HC1
'*******************************************************************************
'* Put your code here it fake out the 9346 Serial EEPROM
'* if you decide to do it.
'*******************************************************************************
'Out Cr9346 , &HC0
'Out Cr9346 , &H40
'Fakeout_9346();
Waitms 10
Out Cr , &H21
Out Dcr , Dcrval
Out Cr , &H22
Out Isr , &HFF
Out Imr , Imrval
Out Tcr , Tcrval
#if Debug
Gosub Dump_regs 'This is for debugging
#endif
'*******************************************************************************
'* Start The NIC!!
'*******************************************************************************
'Start the NIC!!
Out Cr , &H22
Main:
Print "Waiting For Packet..."
'*******************************************************************************
'* Enable Interrupts and wait for a packet!
'*******************************************************************************
Enable Interrupts
Enable Int0
On Int0 Nicint
'*******************************************************************************
'* Put any code you want the processor to regularly run here!
'*******************************************************************************
Do
'Wait forever
Loop
End
'*******************************************************************************
'NIC Interrupt Routine
'*******************************************************************************
Nicint:
Disable Int0
'Read The Interrupt Status Register
Interupptstatus = Inp(isr)
'Test if the receive buffer has been overrun
If Interupptstatus.4 = 1 Then
Gosub Overrun
End If
'Test if the receive buffer holds a good packet
If Interupptstatus.0 = 1 Then
Gosub Get_packet
End If
'make sure the receive buffer ring is empty
'if BNRY = CURR, the buffer is empty
Bnryptr = Inp(bnry)
Out Cr , &H62
Currptr = Inp(curr)
Out Cr , &H22
'buffer is not empty.. get next packet
If Bnryptr <> Currptr Then
Gosub Get_packet
End If
'reset the interrupt bits
Out Isr , &HFF
Out Cr , &H22
Enable Int0
Return
'*******************************************************************************
'* Handle Receive Ring Buffer Overrun
'* No packets are recovered
'*******************************************************************************
Overrun:
Work = Inp(cr)
Out Cr , &H21
Waitms 2
Out Rbcr0 , &H00
Out Rbcr1 , &H00
'If(!bit_test(data_l , 2))
' Resend = 0;
'Else If(bit_test(data_l , 2))
' {
' Read_creg(isr);
' Data_l = Byte_read;
' If(bit_test(data_l , 1) || Bit_test(data_l , 3))
' Resend = 0;
' Else
' Resend = 1;
' }
Out Tcr , &H02
Out Cr , &H22
Out Bnry , Rxstart
Out Cr , &H62
Out Curr , Rxstart
Out Cr , &H22
Out Isr , &H10
Out Tcr , Tcrval
Return
'*******************************************************************************
'* Get A Packet From the Ring
'* This routine removes a data packet from the receive buffer
'* ring, analyzes it .
'*******************************************************************************
Get_packet:
Out Cr , &H1A
'Strip off packet status info.
Work = Inp(rdmaport) 'Packet Status - trash.
Work = Inp(rdmaport) 'Next Block Ptr - trash.
Packetlenl = Inp(rdmaport) 'Packet length low byte
Packetlenh = Inp(rdmaport) 'Packet length high byte
Packetlen = Packetlenh * 256
Packetlen = Packetlen + Packetlenl
'Fill up byte array with contents of packet.
For I = 1 To Packetlen
Work = Inp(rdmaport)
Packet(i) = Work
Next
Work = Inp(isr)
While Work.6 = 0
Work = Inp(isr)
Wend
Out Isr , &HFF
'Analyze the Packet and execute according to type
'Process an ARP packet
If Packet(packtype0) = &H08 Then
If Packet(packtype1) = &H06 Then 'ARP Packet
'Print "ARP Packet Received."
'Make sure the ARP packet is valid and for our IP Address.
If Packet(arp_hwtype1) <> 1 Then
Goto Exit_get_packet
End If
If Packet(arp_prtype0) <> 8 Then
Goto Exit_get_packet
End If
If Packet(arp_prtype1) <> 0 Then
Goto Exit_get_packet
End If
If Packet(arp_hwlen) <> 6 Then
Goto Exit_get_packet
End If
If Packet(arp_prlen) <> 4 Then
Goto Exit_get_packet
End If
If Packet(arp_op1) <> 1 Then
Goto Exit_get_packet
End If
J = Arp_tipaddr
If Packet(j) <> Myip(1) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(2) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(3) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(4) Then
Goto Exit_get_packet
End If
Gosub Arp
Elseif Packet(packtype1) = 0 Then 'IP Packet
'Print "IP Packet Received."
'Make sure the IP Packet is for our IP Address.
J = Ip_destaddr0
If Packet(j) <> Myip(1) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(2) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(3) Then
Goto Exit_get_packet
End If
J = J + 1
If Packet(j) <> Myip(4) Then
Goto Exit_get_packet
End If
'Check the type of IP Packet and execute respectively.
If Packet(ip_proto) = 6 Then
'Print "Doing TCP"
Gosub Tcp_decode
Elseif Packet(ip_proto) = &H11 Then
'Print "Doing UDP"
Gosub Udp
Elseif Packet(ip_proto) = 1 Then
'Print "Doing Ping"
Gosub Icmp
End If
End If
End If
Exit_get_packet:
Return
'*******************************************************************************
'ARP Procedure
'*******************************************************************************
Arp:
'Start the NIC
Out Cr , &H22
'Load beginning page for transmit buffer
Out Tpsr , Txstart
'Set start address for remote DMA operation
Out Rsar0 , 0
Out Rsar1 , &H40
'Clear the Interrupts
Out Isr , &HFF
'Load data byte count for remote DMA
Out Rbcr0 , &H3C '60 Bytes
Out Rbcr1 , 0
'Do remote write operation
Out Cr , &H12
'Write destination MAC address
J = Destmac1
For I = 1 To 6
Out Rdmaport , Packet(j)
J = J + 1
Next
'Write source MAC address
For I = 1 To 6
Out Rdmaport , Mymac(i)
Next
'Write typelen hwtype prtype hwlen prlen op:
J = Packtype0
'Packet[arp_op + 1] = 0x02;
For I = 1 To 9
Out Rdmaport , Packet(j)
J = J + 1
Next
Out Rdmaport , 2
'Write ethernet module MAC address
For I = 1 To 6
Out Rdmaport , Mymac(i)
Next
'Write ethernet module IP address
For I = 1 To 4
Out Rdmaport , Myip(i)
Next
'Write remote MAC address
J = Destmac1
For I = 1 To 6
Out Rdmaport , Packet(j)
J = J + 1
Next
'Write remote IP address
J = Arp_sipaddr
For I = 1 To 4
Out Rdmaport , Packet(j)
J = J + 1
Next
'Write some pad characters to fill out the packet to
'the minimum length
For I = 1 To 18
Out Rdmaport , &H00
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
'Load number of bytes to be transmitted
Out Tbcr0 , &H3C
Out Tbcr1 , &H00
'Send the contents of the transmit buffer onto the network
Out Cr , &H24
Return
'*******************************************************************************
' ICMP Procedure
'*******************************************************************************
Icmp:
'set echo reply
Packet(icmp_type) = 0
Packet(icmp_code) = 0
'clear the ICMP checksum
Packet(icmp_cksumh) = 0
Packet(icmp_cksuml) = 0
'setup the IP header
Gosub Setup_packet
'calculate the ICMP checksum
Csbytecnt = Packet(ip_pktlenh) * 256
Csbytecnt = Csbytecnt + Packet(ip_pktlenl)
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Csbytecnt - Work
Csptr = Icmp_type
Gosub General_checksum
Packet(icmp_cksumh) = High(checksumout)
Packet(icmp_cksuml) = Low(checksumout)
'Send the ICMP packet along on its way
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , 0
Out Rsar1 , &H40
Out Isr , &HFF
Packetlen = Packetlen - 4 'Remove trailing 32 bit checksum
Out Rbcr0 , Low(packetlen)
Out Rbcr1 , High(packetlen)
Out Cr , &H12
For I = Destmac1 To Packetlen
Out Rdmaport , Packet(i)
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
Out Tbcr0 , Low(packetlen)
Out Tbcr1 , High(packetlen)
Out Cr , &H24
Return
'*******************************************************************************
' UDP Routine - Just echo Port 7 for now!
'*******************************************************************************
Udp:
'Port 7 is the echo port
If Packet(udp_destporth) = 0 And Packet(udp_destportl) = 7 Then
Print "Building UDP Packet"
'Build The Ip Header
Gosub Setup_packet
'Swap the UDP source and destination ports
Work = Packet(udp_srcporth)
Packet(udp_srcporth) = Packet(udp_destporth)
Packet(udp_destporth) = Work
Work = Packet(udp_srcportl)
Packet(udp_srcportl) = Packet(udp_destportl)
Packet(udp_destportl) = Work
'Calculate the UDP checksum
Packet(udp_cksumh) = 0
Packet(udp_cksuml) = 0
Gosub Udp_checksum
Packet(udp_cksumh) = High(checksumout)
Packet(udp_cksuml) = Low(checksumout)
Tempint = Packet(udp_destporth) * 256
Tempint = Tempint + Packet(udp_destportl)
'Print "Dest Port: " ; Tempint
'Gosub Dump_packet
'send the UDP packet along on its way
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , 0
Out Rsar1 , &H40
Out Isr , &HFF
Packetlen = Packetlen - 4 'Remove trailing 32 bit checksum
Out Rbcr0 , Low(packetlen)
Out Rbcr1 , High(packetlen)
Out Cr , &H12
For I = Destmac1 To Packetlen
Out Rdmaport , Packet(i)
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
Out Tbcr0 , Low(packetlen)
Out Tbcr1 , High(packetlen)
Out Cr , &H24
End If
Return
'*******************************************************************************
' General Checksum
'*******************************************************************************
General_checksum:
'Input:Csbytecnt as number of bytes
'Input:Csptr as pointer to start of array to find checksum
'Output: Checksumout as Integer (16 Bits) containing checksum
Checksum = 0
'Loop
While Csbytecnt > 1
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
Csptr = Csptr + 1
Checksum = Checksum + Packet(csptr)
Csptr = Csptr + 1
Csbytecnt = Csbytecnt - 2
Wend
If Csbytecnt > 0 Then
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
End If
Tempword = Highw(checksum) 'get amount above 16 bit value
Checktemp = Loww(checksum) 'get amount left over in 16 bits
Checksum = Checktemp + Tempword 'add amount over to left over amount
Checksumout = Loww(checksum) 'get 16 bit leftover amount
Checksumout = Not Checksumout 'Perform ones compliment
Return
'*******************************************************************************
' UDP Checksum Routine
'*******************************************************************************
Udp_checksum:
Checksum = 0
'Do IP Source and Destination Addresses
Tempword = Packet(ip_srcaddr0) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_srcaddr1)
Tempword = Packet(ip_srcaddr2) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_srcaddr3)
Tempword = Packet(ip_destaddr0) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_destaddr1)
Tempword = Packet(ip_destaddr2) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(ip_destaddr3)
'Do IP_Proto
Checksum = Checksum + Packet(ip_proto)
'Do UDP Length
Tempword = Packet(udp_lenh) * 256
Checksum = Checksum + Tempword
Checksum = Checksum + Packet(udp_lenl)
'Now look through entire UDP header and data
Csptr = Udp_srcporth
Csbytecnt = Tempword + Packet(udp_lenl)
'Loop
While Csbytecnt > 1
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
Csptr = Csptr + 1
Checksum = Checksum + Packet(csptr)
Csptr = Csptr + 1
Csbytecnt = Csbytecnt - 2
Wend
If Csbytecnt > 0 Then
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
End If
Tempword = Highw(checksum) 'get amount above 16 bit value
Checktemp = Loww(checksum) 'get amount left over in 16 bits
Checksum = Checktemp + Tempword 'add amount over to left over amount
Checksumout = Loww(checksum) 'get 16 bit leftover amount
Checksumout = Not Checksumout 'Perform ones compliment
Return
'*******************************************************************************
'Setup Packet Routine
'*******************************************************************************
Setup_packet:
'Move IP source address to destination address
Packet(ip_destaddr0) = Packet(ip_srcaddr0)
Packet(ip_destaddr1) = Packet(ip_srcaddr1)
Packet(ip_destaddr2) = Packet(ip_srcaddr2)
Packet(ip_destaddr3) = Packet(ip_srcaddr3)
'Make ethernet module IP address source address
Packet(ip_srcaddr0) = Myip(1)
Packet(ip_srcaddr1) = Myip(2)
Packet(ip_srcaddr2) = Myip(3)
Packet(ip_srcaddr3) = Myip(4)
'Move hardware source address to destinatin address
Packet(destmac1) = Packet(srcmac1)
Packet(destmac2) = Packet(srcmac2)
Packet(destmac3) = Packet(srcmac3)
Packet(destmac4) = Packet(srcmac4)
Packet(destmac5) = Packet(srcmac5)
Packet(destmac6) = Packet(srcmac6)
'Make ethernet module mac address the source address
Packet(srcmac1) = Mymac(1)
Packet(srcmac2) = Mymac(2)
Packet(srcmac3) = Mymac(3)
Packet(srcmac4) = Mymac(4)
Packet(srcmac5) = Mymac(5)
Packet(srcmac6) = Mymac(6)
' subroutine van maken
'Calculate the IP header checksum
Packet(ip_hdr_cksumh) = 0
Packet(ip_hdr_cksuml) = 0
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Work
Csptr = Ip_vers_len
Gosub General_checksum
Packet(ip_hdr_cksumh) = High(checksumout)
Packet(ip_hdr_cksuml) = Low(checksumout)
Return
'*******************************************************************************
'Dump RTL8019AS Registers Procedure
'*******************************************************************************
Dump_regs:
Print "RTL8019AS Register Dump"
Print "Page0 Page1 Page2 Page3"
For I = &HE000 To &HE00F
Out Cr , &H21
Work = Inp(i)
Printhex Work;
Out Cr , &H61
Work = Inp(i)
Printhex " " ; Work;
Out Cr , &HA1
Work = Inp(i)
Printhex " " ; Work;
Out Cr , &HE1
Work = Inp(i)
Printhex " " ; Work
Next I
Return
'*******************************************************************************
'Dump Packet Routine
'*******************************************************************************
Dump_packet:
For I = 1 To Packetlen
Printhex " " ; Packet(i);
Work = I Mod 8
If Work = 0 Then
End If
Next
Return
'*******************************************************************************
' TCP Decode Routine
'*******************************************************************************
Tcp_decode:
Work = Packet(tcp_flags)
Tcp_fin = Work.0
Tcp_syn = Work.1
Tcp_rst = Work.2
Tcp_psh = Work.3
Tcp_ack = Work.4
Tcp_urg = Work.5
' assemble the destination port address from the incoming packet
Vhigh16 = Packet(tcp_destporth)
Vlow16 = Packet(tcp_destportl)
Result16 = Vhigh16
Shift Result16 , Left , 8
Portaddr = Result16 + Vlow16
' calculate the length of the data coming in with the packet
' tcpdatalen_in = incoming packet length - incoming ip header length
Vhigh16 = Packet(ip_pktlenh)
Vlow16 = Packet(ip_pktlenl)
Result16 = Vhigh16
Shift Result16 , Left , 8
Result16 = Result16 + Vlow16
' calculate IP header length
' MSN is version (IPv4)
' LSN is length
Tempbyte1 = Packet(ip_vers_len) And &H0F
Tempbyte1 = Tempbyte1 * 4
' calculate TCP header length
' MSN is length / 4
Tempbyte2 = Packet(tcp_hdr) And &HF0
Shift Tempbyte2 , Right , 4
Tempbyte2 = Tempbyte2 * 4
Tcpdatalen_in = Result16 - Tempbyte1
Tcpdatalen_in = Tcpdatalen_in - Tempbyte2
' If an ACK is received and the destination port address is valid
' and no data is in the packet
If Tcp_ack = 1 Then
If Portaddr = My_port_address Then
If Tcpdatalen_in = 0 Then
A32 = Packet(tcp_acknum3)
B32 = Packet(tcp_acknum2)
C32 = Packet(tcp_acknum1)
D32 = Packet(tcp_acknum0)
Gosub Make32
Incoming_ack = Resultaat
If Flags.synflag = 1 Then
Gosub Clr_synflag
My_seqnum = Incoming_ack
Msg = "EDTP P89C668 Telnet Server>"
Msg = Msg + Chr(10) + Chr(13)
Tempbyte2 = Len(msg)
For X = 0 To Tempbyte2
Tempbyte1 = X + Tcp_data
Work = X + 1
Tempstring1 = Mid(msg , Work , 1)
Packet(tempbyte1) = Asc(tempstring1)
Next X
Tcpdatalen_out = Tempbyte2
' expect to get an acknowledgment of the banner message
Expected_ack = My_seqnum + Tcpdatalen_out
' send the TCP/IP packet
Gosub Send_tcp_packet
End If
End If
End If
End If
' if an ACK is received and the port address is valid and there is
' data in the incoming packet
If Tcp_ack = 1 Then
If Portaddr = My_port_address Then
If Tcpdatalen_in > 0 Then
For X = 0 To Tcpdatalen_in
Tempbyte1 = Tcp_data + X
Aux_data(x) = Packet(tempbyte1)
Print Chr(aux_data(x))
Next X
Gosub Application_code
A32 = Packet(tcp_acknum3)
B32 = Packet(tcp_acknum2)
C32 = Packet(tcp_acknum1)
D32 = Packet(tcp_acknum0)
Gosub Make32
Incoming_ack = Resultaat
If Incoming_ack <= Expected_ack Then
Templong1 = Expected_ack - Incoming_ack
My_seqnum = Expected_ack - Templong1
End If
Expected_ack = My_seqnum + Tcpdatalen_out
Gosub Send_tcp_packet
End If
End If
End If
' This code segment processes the incoming SYN from the Tenet client
' and sends back the initial sequence number (ISN) and acknowledges
' the incoming SYN packet
If Tcp_syn = 1 Then
If Portaddr = My_port_address Then
Tcpdatalen_in = 1
Gosub Set_synflag
Gosub Setup_packet
Data_l = Packet(tcp_srcportl)
Packet(tcp_srcportl) = Packet(tcp_destportl)
Packet(tcp_destportl) = Data_l
Data_l = Packet(tcp_srcporth)
Packet(tcp_srcporth) = Packet(tcp_destporth)
Packet(tcp_destporth) = Data_l
Gosub Assemble_ack
Tempword1 = Isn + 1
If Tempword1 = 0 Then
My_seqnum = &H1234FFFF
End If
If Tempword1 = &HFFFF Then
My_seqnum = &H1234FFFF
End If
D = Tcp_seqnum3
S = My_seqnum
Gosub Set_packet32
Packet(tcp_flags) = 0
Gosub Syn_out
Gosub Ack_out
Gosub Tcp_checksum
Gosub Echo_packet
End If
End If
If Tcp_fin = 1 Then
If Portaddr = My_port_address Then
If Tcpdatalen_in > 0 Then
Tempbyte2 = Len(tcpdatalen_in)
For X = 0 To Tempbyte2
Tempbyte3 = Tcp_data + X
Aux_data(x) = Packet(tempbyte3)
Next X
Gosub Application_code
End If
End If
Gosub Set_finflag
Incr Tcpdatalen_in
A32 = Packet(tcp_acknum3)
B32 = Packet(tcp_acknum2)
C32 = Packet(tcp_acknum1)
D32 = Packet(tcp_acknum0)
Gosub Make32
Incoming_ack = Resultaat
If Incoming_ack <= Expected_ack Then
Templong1 = Expected_ack - Incoming_ack
My_seqnum = Expected_ack - Templong1
End If
Expected_ack = My_seqnum + Tcpdatalen_out
Gosub Send_tcp_packet
End If
Return
'*******************************************************************************
' Send_tcp_packet Routine
'*******************************************************************************
Send_tcp_packet:
Ip_packet_len = 40 + Tcpdatalen_out
S = Ip_packet_len
O8 = 1
Gosub Make8
Packet(ip_pktlenh) = A8
S = Ip_packet_len
O8 = 0
Gosub Make8
Packet(ip_pktlenl) = A8
Gosub Setup_packet
Data_l = Packet(tcp_srcporth)
Packet(tcp_srcporth) = Packet(tcp_destporth)
Packet(tcp_destporth) = Data_l
Packet(ip_pktlenl) = A8
Data_l = Packet(tcp_srcportl)
Packet(tcp_srcportl) = Packet(tcp_destportl)
Packet(tcp_destportl) = Data_l
Gosub Assemble_ack
D = Tcp_seqnum3
S = My_seqnum
Gosub Set_packet32
Packet(tcp_flags) = 0
Gosub Ack_out
If Flags.finflag = 1 Then
Gosub Fin_out
Gosub Clr_finflag
End If
Gosub Tcp_checksum
Txlen = Ip_packet_len + 14
If Txlen < 60 Then
Txlen = 60
End If
's As Long , O8 As Byte
'result in A8
'in S the variable
'offset in O8
S = Txlen
O8 = 0
Gosub Make8
Data_l = A8
S = Txlen
O8 = 1
Gosub Make8
Data_h = A8
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , &H00
Out Rsar1 , &H40
Out Isr , &HFF
Out Rbcr0 , Low(txlen)
Out Rbcr1 , High(txlen)
Out Cr , &H12
For I = Destmac1 To Txlen
Out Rdmaport , Packet(i)
Next
'Make sure the DMA operation has successfully completed
Work = 0
While Work.6 = 0
Work = Inp(isr)
Wend
Out Tbcr0 , Low(txlen)
Out Tbcr1 , High(txlen)
Out Cr , &H24
Return
'*******************************************************************************
' Assemble_ack Routine
'*******************************************************************************
Assemble_ack:
A32 = Packet(tcp_seqnum3)
B32 = Packet(tcp_seqnum2)
C32 = Packet(tcp_seqnum1)
D32 = Packet(tcp_seqnum0)
Gosub Make32
Client_seqnum = Resultaat
Client_seqnum = Client_seqnum + Tcpdatalen_in
D = Tcp_acknum3
S = Client_seqnum
Gosub Set_packet32
Return
'*******************************************************************************
' Make32 Routine
'*******************************************************************************
Make32:
Tempword1 = Makeint(b32 , A32)
Resultaat = Tempword1 * 65536
Tempword1 = Makeint(d32 , C32)
Resultaat = Resultaat + Tempword1
Return
'*******************************************************************************
' Set_packet32 Routine
'*******************************************************************************
Set_packet32:
'd As Byte , S As Long
'D as byte for packet(d)-pointer
'S as long the 32 bit that should be broken in four parts
'A8 - tempvar
'O8 - offset
Hulp2 = D
O8 = 3
Gosub Make8
Packet(hulp2) = A8
Hulp2 = Hulp2 + 1
O8 = 2
Gosub Make8
Packet(hulp2) = A8
Hulp2 = Hulp2 + 1
O8 = 1
Gosub Make8
Packet(hulp2) = A8
Hulp2 = Hulp2 + 1
O8 = 0
Gosub Make8
Packet(hulp2) = A8
Return
'*******************************************************************************
' Make8 Routine
'*******************************************************************************
Make8:
's As Long , O8 As Byte
'result in A8
'in S the variable
'offset in O8
'Print "Sub Make8"
S_temp = S
Hulp1 = O8 * 8
If Hulp1 = 0 Then
A8 = S
Else
Shift S_temp , Right , Hulp1
A8 = S_temp
End If
Return
Fin_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.0
Packet(tcp_flags) = Flag_temp
Return
Syn_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.1
Packet(tcp_flags) = Flag_temp
Return
Rst_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.2
Packet(tcp_flags) = Flag_temp
Return
Psh_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.3
Packet(tcp_flags) = Flag_temp
Return
Ack_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.4
Packet(tcp_flags) = Flag_temp
Return
Urg_out:
Flag_temp = Packet(tcp_flags)
Set Flag_temp.5
Packet(tcp_flags) = Flag_temp
Return
Set_synflag:
Set Flags.synflag
Return
Clr_synflag:
Reset Flags.synflag
Return
Set_finflag:
Set Flags.finflag
Return
Clr_finflag:
Reset Flags.finflag
Return
'*******************************************************************************
' echo-packet routine
'*******************************************************************************
Echo_packet:
Out Cr , &H22
Out Tpsr , Txstart
Out Rsar0 , &H00
Out Rsar1 , &H40
Out Isr , &HFF
Packetlenl = Packetlenl - 4
Out Rbcr0 , Packetlenl
Out Rbcr1 , Packetlenh
Out Cr , &H12
Tempword1 = Packetlenh * 256
Tempword1 = Tempword1 + Packetlenl
Tempword1 = Tempword1 - 4
For I = 0 To Tempword1
Hulp1 = Destmac1 + I
Out Rdmaport , Packet(hulp1)
Next I
While Work.6 = 0
Work = Inp(isr)
Wend
Packetlenl = Packetlenl - 4
Out Tbcr0 , Packetlenl
Out Tbcr1 , Packetlenh
Out Cr , &H24
Return
Application_code:
For I = 1 To Tcpdatalen_in
If Aux_data(i) <> &H0A Then
Tcpdatalen_out = Tcpdatalen_in
End If
If Aux_data(i) = &H0A Then
Tcpdatalen_out = &H00
End If
' here your actioncode
'Work = Aux_data(i)
'Select Case Aux_data(i)
'Case &H0D : Print
'Case &H1B : Print
'Case &H09 : Print
'Case 10 To 20 'test the range from 10 to 20
'Case Else
'End Select
Next I
Return
Tcp_checksum:
'Calculate the IP header checksum
Packet(ip_hdr_cksumh) = 0
Packet(ip_hdr_cksuml) = 0
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Work
Csptr = Ip_vers_len
Gosub General_checksum
Packet(ip_hdr_cksumh) = High(checksumout)
Packet(ip_hdr_cksuml) = Low(checksumout)
Hdr_chksum = 0
Tempword1 = Packet(ip_srcaddr0) * 256
Tempword1 = Tempword1 + Packet(ip_srcaddr1)
Hdr_chksum = Hdr_chksum + Tempword1
Tempword1 = Packet(ip_srcaddr2) * 256
Tempword1 = Tempword1 + Packet(ip_srcaddr3)
Hdr_chksum = Hdr_chksum + Tempword1
Tempword1 = Packet(ip_destaddr0) * 256
Tempword1 = Tempword1 + Packet(ip_destaddr1)
Hdr_chksum = Hdr_chksum + Tempword1
Tempword1 = Packet(ip_destaddr2) * 256
Tempword1 = Tempword1 + Packet(ip_destaddr3)
Hdr_chksum = Hdr_chksum + Tempword1
Hdr_chksum = Hdr_chksum + Packet(ip_proto)
Csbytecnt = Packet(ip_pktlenh) * 256
Csbytecnt = Csbytecnt + Packet(ip_pktlenl)
Work = Packet(ip_vers_len)
Work = Work And &H0F
Work = Work * 4
Csbytecnt = Csbytecnt - Work
Hdr_chksum = Hdr_chksum + Csbytecnt
Packet(tcp_cksumh) = 0
Packet(tcp_cksuml) = 0
Csptr = Tcp_srcporth
'Input:Csbytecnt as number of bytes
'Input:Csptr as pointer to start of array to find checksum
'Output: Checksumout as Integer (16 Bits) containing checksum
Checksum = Hdr_chksum
'Loop
While Csbytecnt > 1
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
Csptr = Csptr + 1
Checksum = Checksum + Packet(csptr)
Csptr = Csptr + 1
Csbytecnt = Csbytecnt - 2
Wend
If Csbytecnt > 0 Then
Tempword = Packet(csptr) * 256
Checksum = Checksum + Tempword
End If
Tempword = Highw(checksum) 'get amount above 16 bit value
Checktemp = Loww(checksum) 'get amount left over in 16 bits
Checksum = Checktemp + Tempword 'add amount over to left over amount
Checksumout = Loww(checksum) 'get 16 bit leftover amount
Checksumout = Not Checksumout
Packet(tcp_cksumh) = High(checksumout)
Packet(tcp_cksuml) = Low(checksumout)
Return
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 36 gości