mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-01-12 04:30:42 +00:00
REady for use Uthernet IP modules
This commit is contained in:
parent
f2c9526c79
commit
235d6f5363
@ -7,14 +7,12 @@ import cmdsys
|
|||||||
predef heapmark, heapallocalign, heapalloc, heaprelease
|
predef heapmark, heapallocalign, heapalloc, heaprelease
|
||||||
byte MACHID
|
byte MACHID
|
||||||
end
|
end
|
||||||
import etherip
|
import inet
|
||||||
byte localha, localip, subnet_mask, gateway
|
byte localha, localip, subnet, gateway
|
||||||
predef swab, sendUDP, recvUDP, shutUDP, serviceIP
|
predef swab, sendUDP, listenUDP, hangupUDP, serviceIP
|
||||||
end
|
|
||||||
import icmp
|
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Needed to init subnet_mask
|
// Needed to init subnet
|
||||||
//
|
//
|
||||||
const IP_BROADCAST = $FFFF
|
const IP_BROADCAST = $FFFF
|
||||||
//
|
//
|
||||||
@ -48,6 +46,10 @@ const DHCP_ACK = $05
|
|||||||
const DHCP_NACK = $06
|
const DHCP_NACK = $06
|
||||||
const DHCP_RELEASE = $07
|
const DHCP_RELEASE = $07
|
||||||
//
|
//
|
||||||
|
// Track DHCP progress
|
||||||
|
//
|
||||||
|
byte stateDHCP, retry, timeout
|
||||||
|
//
|
||||||
// DHCP ports
|
// DHCP ports
|
||||||
//
|
//
|
||||||
const DHCP_CLIENT_PORT = 68
|
const DHCP_CLIENT_PORT = 68
|
||||||
@ -156,6 +158,7 @@ def servdhcp(remip, remport, lclport, pkt, len, param)
|
|||||||
if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 = $0403
|
if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 = $0403
|
||||||
when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2]
|
when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2]
|
||||||
is DHCP_OFFER
|
is DHCP_OFFER
|
||||||
|
stateDHCP = DHCP_OFFER
|
||||||
//puts(@offerstr); putip(@pkt->dhcp_yourip); putln
|
//puts(@offerstr); putip(@pkt->dhcp_yourip); putln
|
||||||
//
|
//
|
||||||
// Copy offer parameters to request
|
// Copy offer parameters to request
|
||||||
@ -167,13 +170,18 @@ def servdhcp(remip, remport, lclport, pkt, len, param)
|
|||||||
sendUDP(0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT, @DHCP, t_dhcp)
|
sendUDP(0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT, @DHCP, t_dhcp)
|
||||||
break
|
break
|
||||||
is DHCP_ACK
|
is DHCP_ACK
|
||||||
|
stateDHCP = DHCP_ACK
|
||||||
|
//
|
||||||
|
// Stop listening to UDP port
|
||||||
|
//
|
||||||
|
hangupUDP(DHCP_CLIENT_PORT)
|
||||||
//puts(@ackstr)
|
//puts(@ackstr)
|
||||||
//
|
//
|
||||||
// Copy parameters to working copy
|
// Copy parameters to working copy
|
||||||
//
|
//
|
||||||
memcpy(@localip, @pkt->dhcp_yourip, 4)
|
memcpy(@localip, @pkt->dhcp_yourip, 4)
|
||||||
memcpy(@subnet_mask, @pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 1) + 2], 4)
|
memcpy(@subnet, @pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 1) + 2], 4)
|
||||||
puts(@boundstr);putip(@localip);putc('/');putip(@subnet_mask);putln
|
puts(@boundstr);putip(@localip);putc('/');putip(@subnet);putln
|
||||||
break
|
break
|
||||||
otherwise
|
otherwise
|
||||||
dumpdhcp(pkt)
|
dumpdhcp(pkt)
|
||||||
@ -191,20 +199,30 @@ memset(@localip, 0, 4)
|
|||||||
//
|
//
|
||||||
// Set subnet mask to all 1's
|
// Set subnet mask to all 1's
|
||||||
//
|
//
|
||||||
memset(@subnet_mask, IP_BROADCAST, 4)
|
memset(@subnet, IP_BROADCAST, 4)
|
||||||
//
|
//
|
||||||
// Prepare to receive DHCP packets from a server
|
// Prepare to receive DHCP packets from a server
|
||||||
//
|
//
|
||||||
recvUDP(DHCP_CLIENT_PORT, @servdhcp, 0)
|
listenUDP(DHCP_CLIENT_PORT, @servdhcp, 0)
|
||||||
//
|
|
||||||
// Broadcast DHCP DISCOVER message
|
|
||||||
//
|
|
||||||
sendUDP(0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT, @DHCP, t_dhcp)
|
|
||||||
//
|
//
|
||||||
// Service IP
|
// Service IP
|
||||||
//
|
//
|
||||||
repeat
|
while retry < 3
|
||||||
serviceIP
|
//
|
||||||
until ^$C000 > 127
|
// Broadcast DHCP DISCOVER message
|
||||||
^$C010
|
//
|
||||||
|
sendUDP(0, DHCP_SERVER_PORT, DHCP_CLIENT_PORT, @DHCP, t_dhcp)
|
||||||
|
for timeout = 1 to 1000
|
||||||
|
serviceIP
|
||||||
|
if stateDHCP == DHCP_ACK
|
||||||
|
return 0
|
||||||
|
fin
|
||||||
|
next
|
||||||
|
retry = retry + 1
|
||||||
|
loop
|
||||||
|
//
|
||||||
|
// Nobody answered
|
||||||
|
//
|
||||||
|
return -1
|
||||||
|
|
||||||
done
|
done
|
@ -1,12 +1,18 @@
|
|||||||
import cmdsys
|
import cmdsys
|
||||||
predef syscall, call, getc, gets, putc, puts, putln
|
predef syscall, call, getc, gets, putc, puts, putln
|
||||||
predef memset, memcpy, modaddr, modexec
|
predef memset, memcpy, modaddr, modexec
|
||||||
predef heapmark, heapallocalign, heapalloc, heaprelease
|
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
|
||||||
byte MACHID
|
byte MACHID
|
||||||
end
|
end
|
||||||
import uthernet
|
//
|
||||||
predef copyMAC, writeEther, writevEther, readEther, recvEther
|
// Module don't free memory
|
||||||
end
|
//
|
||||||
|
const modkeep = $2000
|
||||||
|
const modinitkeep = $4000
|
||||||
|
//
|
||||||
|
// Predefine service routine
|
||||||
|
//
|
||||||
|
predef serviceIP
|
||||||
//
|
//
|
||||||
// Segment list element
|
// Segment list element
|
||||||
//
|
//
|
||||||
@ -47,50 +53,26 @@ struc t_iphdr
|
|||||||
byte[IPADR_SIZE] ip_dst
|
byte[IPADR_SIZE] ip_dst
|
||||||
byte[] ip_options
|
byte[] ip_options
|
||||||
end
|
end
|
||||||
|
const t_ethriphdr = t_ethrhdr + t_iphdr
|
||||||
const IP_BROADCAST = $FFFF
|
const IP_BROADCAST = $FFFF
|
||||||
const IP_PROTO_ICMP = $01
|
const IP_PROTO_ICMP = $01
|
||||||
const IP_PROTO_UDP = $11
|
const IP_PROTO_UDP = $11
|
||||||
const IP_PROTO_TCP = $06
|
const IP_PROTO_TCP = $06
|
||||||
//
|
//
|
||||||
// ARP packet
|
// ICMP type/codes
|
||||||
//
|
//
|
||||||
const HW_ETHER = $0100 // BE format
|
const IP_PROTO_ICMP = 1
|
||||||
const ARP_PROTO = $0008 // BE format
|
const ICMP_ECHO_REQST = 8
|
||||||
const ARP_REQST = $0100 // BE format
|
const ICMP_ECHO_REPLY = 0
|
||||||
const ARP_REPLY = $0200 // BE format
|
//
|
||||||
struc t_arp
|
// ICMP message format
|
||||||
word arp_hw
|
//
|
||||||
word arp_proto
|
struc t_icmp
|
||||||
byte arp_hlen
|
byte icmp_type
|
||||||
byte arp_plen
|
byte icmp_code
|
||||||
word arp_op
|
word icmp_chksm
|
||||||
byte[MAC_SIZE] arp_senderha
|
word[2] icmp_header
|
||||||
byte[IPADR_SIZE] arp_senderip
|
|
||||||
byte[MAC_SIZE] arp_targha
|
|
||||||
byte[IPADR_SIZE] arp_targip
|
|
||||||
end
|
end
|
||||||
const t_earp = t_ethrhdr+t_arp
|
|
||||||
//
|
|
||||||
// Pre-configured ARP packet
|
|
||||||
//
|
|
||||||
byte[] ARP
|
|
||||||
byte[MAC_SIZE] dstMAC
|
|
||||||
byte[MAC_SIZE] srcMAC
|
|
||||||
word = PAYLOAD_ARP
|
|
||||||
word = HW_ETHER // HW TYPE
|
|
||||||
word = ARP_PROTO // PROTO TYPE
|
|
||||||
byte = MAC_SIZE // HLEN
|
|
||||||
byte = IPADR_SIZE // PLEN
|
|
||||||
word opARP // OP
|
|
||||||
export byte[MAC_SIZE] localha
|
|
||||||
export byte[IPADR_SIZE] localip
|
|
||||||
byte[MAC_SIZE] remoteha
|
|
||||||
byte[IPADR_SIZE] remoteip
|
|
||||||
//
|
|
||||||
// Local network parameters
|
|
||||||
//
|
|
||||||
export byte[IPADR_SIZE] subnet_mask
|
|
||||||
export byte[IPADR_SIZE] gateway
|
|
||||||
//
|
//
|
||||||
// UDP IPv4 psuedo header
|
// UDP IPv4 psuedo header
|
||||||
//
|
//
|
||||||
@ -120,6 +102,60 @@ struc t_tcphdr
|
|||||||
word tcp_chksm
|
word tcp_chksm
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
|
// ARP packet
|
||||||
|
//
|
||||||
|
const HW_ETHER = $0100 // BE format
|
||||||
|
const ARP_PROTO = $0008 // BE format
|
||||||
|
const ARP_REQST = $0100 // BE format
|
||||||
|
const ARP_REPLY = $0200 // BE format
|
||||||
|
struc t_arp
|
||||||
|
word arp_hw
|
||||||
|
word arp_proto
|
||||||
|
byte arp_hlen
|
||||||
|
byte arp_plen
|
||||||
|
word arp_op
|
||||||
|
byte[MAC_SIZE] arp_senderha
|
||||||
|
byte[IPADR_SIZE] arp_senderip
|
||||||
|
byte[MAC_SIZE] arp_targha
|
||||||
|
byte[IPADR_SIZE] arp_targip
|
||||||
|
end
|
||||||
|
const t_earp = t_ethrhdr+t_arp
|
||||||
|
//
|
||||||
|
// Pre-configured Ethernet header
|
||||||
|
//
|
||||||
|
byte[] eFrame
|
||||||
|
//
|
||||||
|
// Destination MAC address
|
||||||
|
//
|
||||||
|
byte[MAC_SIZE] dstMAC
|
||||||
|
//
|
||||||
|
// My MAC address
|
||||||
|
//
|
||||||
|
byte[MAC_SIZE] myMAC
|
||||||
|
//
|
||||||
|
// Ethernet payload
|
||||||
|
//
|
||||||
|
word ePayload = PAYLOAD_ARP
|
||||||
|
//
|
||||||
|
// Pre-configured ARP packet - MUST follow ethernet header!
|
||||||
|
//
|
||||||
|
word ARP = HW_ETHER // HW TYPE
|
||||||
|
word = ARP_PROTO // PROTO TYPE
|
||||||
|
byte = MAC_SIZE // HLEN
|
||||||
|
byte = IPADR_SIZE // PLEN
|
||||||
|
word opARP // OP
|
||||||
|
export byte[MAC_SIZE] localha
|
||||||
|
export byte[IPADR_SIZE] localip
|
||||||
|
byte[MAC_SIZE] remoteha
|
||||||
|
byte[IPADR_SIZE] remoteip
|
||||||
|
//
|
||||||
|
// Local network parameters
|
||||||
|
//
|
||||||
|
export byte[IPADR_SIZE] subnet
|
||||||
|
export byte[IPADR_SIZE] gateway
|
||||||
|
const MAX_UDP_NOTIFIES = 16
|
||||||
|
const MAX_TCP_NOTIFIES = 8
|
||||||
|
//
|
||||||
// Notify callbacks
|
// Notify callbacks
|
||||||
//
|
//
|
||||||
struc t_notify
|
struc t_notify
|
||||||
@ -127,14 +163,16 @@ struc t_notify
|
|||||||
word notify_func
|
word notify_func
|
||||||
word notify_parm
|
word notify_parm
|
||||||
end
|
end
|
||||||
const MAX_UDP_NOTIFIES = 16
|
|
||||||
const MAX_TCP_NOTIFIES = 8
|
|
||||||
word portsUDP
|
word portsUDP
|
||||||
word portsTCP
|
word portsTCP
|
||||||
//
|
//
|
||||||
// Service ICMP externally
|
// Service ICMP hook
|
||||||
//
|
//
|
||||||
export word serviceICMP
|
export word hookICMP
|
||||||
|
//
|
||||||
|
// Ethernet driver entrypoints
|
||||||
|
//
|
||||||
|
word setFrameLen, writeFrame, getFrameLen, readFrame
|
||||||
//
|
//
|
||||||
// Defines for ASM routines
|
// Defines for ASM routines
|
||||||
//
|
//
|
||||||
@ -142,8 +180,6 @@ asm equates
|
|||||||
!SOURCE "vmsrc/plvmzp.inc"
|
!SOURCE "vmsrc/plvmzp.inc"
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// ASM utility functions
|
|
||||||
//
|
|
||||||
// Swap bytes in word
|
// Swap bytes in word
|
||||||
//
|
//
|
||||||
export asm swab
|
export asm swab
|
||||||
@ -201,214 +237,12 @@ CHKLP LDA (SRC),Y
|
|||||||
INX
|
INX
|
||||||
INX
|
INX
|
||||||
RTS
|
RTS
|
||||||
end//
|
|
||||||
// DEBUG
|
|
||||||
//
|
|
||||||
def putln
|
|
||||||
return putc($0D)
|
|
||||||
end
|
|
||||||
def putb(hexb)
|
|
||||||
return call($FDDA, hexb, 0, 0, 0)
|
|
||||||
end
|
|
||||||
def puth(hex)
|
|
||||||
return call($F941, hex >> 8, hex, 0, 0)
|
|
||||||
end
|
|
||||||
def puti(i)
|
|
||||||
if i < 0; putc('-'); i = -i; fin
|
|
||||||
if i < 10
|
|
||||||
putc(i + '0')
|
|
||||||
else
|
|
||||||
puti(i / 10)
|
|
||||||
putc(i % 10 + '0')
|
|
||||||
fin
|
|
||||||
end
|
|
||||||
def putha(haptr)
|
|
||||||
byte i
|
|
||||||
|
|
||||||
for i = 0 to 4
|
|
||||||
putb(haptr->[i]); putc(':')
|
|
||||||
next
|
|
||||||
return putb(haptr->[i])
|
|
||||||
end
|
|
||||||
def putip(ipptr)
|
|
||||||
byte i
|
|
||||||
|
|
||||||
for i = 0 to 2
|
|
||||||
puti(ipptr->[i]); putc('.')
|
|
||||||
next
|
|
||||||
return puti(ipptr->[i])
|
|
||||||
end
|
|
||||||
def dumpehdr(packet)
|
|
||||||
putha(packet + ethr_dst); putc(' ')
|
|
||||||
putha(packet + ethr_src); putc(' ')
|
|
||||||
putc('$');puth(packet=>ethr_payload); putln
|
|
||||||
end
|
|
||||||
def dumparp(packet)
|
|
||||||
putc('$');puth(packet=>arp_hw); putln
|
|
||||||
putc('$');puth(packet=>arp_proto); putln
|
|
||||||
putc('$');putb(packet->arp_hlen); putln
|
|
||||||
putc('$');putb(packet->arp_plen); putln
|
|
||||||
putc('$');puth(packet=>arp_op); putln
|
|
||||||
putha(packet + arp_senderha)
|
|
||||||
putc('=')
|
|
||||||
putip(packet + arp_senderip); putln
|
|
||||||
putha(packet + arp_targha)
|
|
||||||
putc('=')
|
|
||||||
putip(packet + arp_targip); putln
|
|
||||||
end
|
|
||||||
def dumpip(packet)
|
|
||||||
putc('$');putb(packet->ip_vers_hlen); putln
|
|
||||||
puti(swab(packet=>ip_length)); putln
|
|
||||||
puti(packet->ip_proto); putln
|
|
||||||
putip(packet + ip_src); putln
|
|
||||||
putip(packet + ip_dst); putln
|
|
||||||
end
|
|
||||||
def dumpudp(packet)
|
|
||||||
puti(swab(packet=>udp_src));putln
|
|
||||||
puti(swab(packet=>udp_dst));putln
|
|
||||||
puti(swab(packet=>udp_len));putln
|
|
||||||
end
|
|
||||||
def dumpfrm(packet, len)
|
|
||||||
word i
|
|
||||||
|
|
||||||
if len > 64
|
|
||||||
len = 64
|
|
||||||
fin
|
|
||||||
len = len - 1
|
|
||||||
for i = 0 to len
|
|
||||||
if (i & 7) == 0
|
|
||||||
putln
|
|
||||||
else
|
|
||||||
putc(' ')
|
|
||||||
fin
|
|
||||||
putb(^(packet+i))
|
|
||||||
next
|
|
||||||
putln
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Service incoming packets
|
|
||||||
//
|
|
||||||
export def serviceIP
|
|
||||||
word pkt, iphdr, hdr, opt, len, optlen, port, lclport, remport
|
|
||||||
byte i
|
|
||||||
|
|
||||||
len = recvEther
|
|
||||||
if len
|
|
||||||
len = len - t_ethrhdr
|
|
||||||
when readEther(t_ethrhdr)=>ethr_payload
|
|
||||||
is PAYLOAD_ARP
|
|
||||||
pkt = readEther(len)
|
|
||||||
len = 0
|
|
||||||
when pkt=>arp_op
|
|
||||||
is ARP_REPLY
|
|
||||||
//
|
|
||||||
// Fill in ARP cache
|
|
||||||
//
|
|
||||||
memcpy(@remoteha, @pkt=>arp_senderha, 10) // copy ha and ip
|
|
||||||
//putha(pkt+arp_senderha);putc('=');putip(pkt+arp_senderip);putln
|
|
||||||
break
|
|
||||||
is ARP_REQST
|
|
||||||
//
|
|
||||||
// Is this a request for me?
|
|
||||||
//
|
|
||||||
if pkt=>arp_targip:0 == localip:0 and pkt=>arp_targip:2 == localip:2
|
|
||||||
memcpy(@dstMAC, @pkt=>arp_senderha, MAC_SIZE)
|
|
||||||
memcpy(@remoteha, @pkt=>arp_senderha, 10) // copy ha and ip
|
|
||||||
opARP = ARP_REPLY
|
|
||||||
writeEther(@ARP, t_earp)
|
|
||||||
//putha(pkt+arp_senderha);putc('=');putip(pkt+arp_senderip);putln
|
|
||||||
fin
|
|
||||||
break
|
|
||||||
otherwise
|
|
||||||
//dumparp(pkt)
|
|
||||||
wend
|
|
||||||
break
|
|
||||||
is PAYLOAD_IP
|
|
||||||
len = len - t_iphdr
|
|
||||||
iphdr = readEther(t_iphdr)
|
|
||||||
if iphdr->ip_vers_hlen <> $45
|
|
||||||
optlen = iphdr=>ip_vers_hlen
|
|
||||||
if optlen & $F0 <> $40
|
|
||||||
//
|
|
||||||
// Not IPv4, ignore
|
|
||||||
//
|
|
||||||
break
|
|
||||||
fin
|
|
||||||
optlen = (optlen & $0F) << 2
|
|
||||||
if optlen > t_iphdr
|
|
||||||
//
|
|
||||||
// Read the options and throw them on the ground!
|
|
||||||
//
|
|
||||||
opt = readEther(optlen - t_iphdr)
|
|
||||||
len = len - (optlen - t_iphdr)
|
|
||||||
fin
|
|
||||||
fin
|
|
||||||
//
|
|
||||||
// Filter valid destination address
|
|
||||||
//
|
|
||||||
if iphdr=>ip_dst:2 <> localip:2 // Yes, this is a little lazy
|
|
||||||
if (iphdr=>ip_dst:0|subnet_mask:0) & (iphdr=>ip_dst:2|subnet_mask:2) <> IP_BROADCAST
|
|
||||||
break
|
|
||||||
fin
|
|
||||||
fin
|
|
||||||
when iphdr->ip_proto
|
|
||||||
is IP_PROTO_UDP
|
|
||||||
port = portsUDP
|
|
||||||
if port
|
|
||||||
len = len - t_udphdr
|
|
||||||
hdr = readEther(t_udphdr)
|
|
||||||
lclport = swab(hdr=>udp_dst)
|
|
||||||
for i = 1 to MAX_UDP_NOTIFIES
|
|
||||||
if port=>notify_port == lclport)
|
|
||||||
//dumpip(iphdr)
|
|
||||||
//dumpudp(hdr)
|
|
||||||
port=>notify_func(@iphdr=>ip_src,swab(hdr=>udp_src),lclport,readEther(len),swab(hdr=>udp_len),port=>notify_parm)
|
|
||||||
len = 0
|
|
||||||
break
|
|
||||||
fin
|
|
||||||
port = port + t_notify
|
|
||||||
next
|
|
||||||
fin
|
|
||||||
break
|
|
||||||
is IP_PROTO_TCP
|
|
||||||
port = portsTCP
|
|
||||||
if port
|
|
||||||
len = len - t_tcphdr
|
|
||||||
hdr = readEther(t_tcphdr)
|
|
||||||
lclport = swab(hdr=>tcp_dst)
|
|
||||||
remport = swab(hdr=>tcp_src)
|
|
||||||
for i = 1 to MAX_TCP_NOTIFIES
|
|
||||||
if port=>notify_port == lclport)
|
|
||||||
//dumpip(iphdr)
|
|
||||||
//dumptcp(tcphdr)
|
|
||||||
port=>notify_func(@iphdr=>ip_src,swab(hdr=>tcp_src),lclport,readEther(len),swab(hdr=>tcp_len),port=>notify_parm)
|
|
||||||
len = 0
|
|
||||||
break
|
|
||||||
fin
|
|
||||||
port = port + t_notify
|
|
||||||
next
|
|
||||||
fin
|
|
||||||
break
|
|
||||||
is IP_PROTO_ICMP
|
|
||||||
if serviceICMP
|
|
||||||
serviceICMP(@iphdr=>ip_src, readEther(len), len)
|
|
||||||
len = 0
|
|
||||||
fin
|
|
||||||
wend
|
|
||||||
break
|
|
||||||
otherwise
|
|
||||||
//dumpehdr(readEther(len) - t_ethrhdr)
|
|
||||||
//len = 0
|
|
||||||
wend
|
|
||||||
if len; readEther(len); fin // Drop it
|
|
||||||
fin
|
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Send IP datagram
|
// Send IP datagram
|
||||||
//
|
//
|
||||||
export def sendIP(ipdst, proto, seglist, size)
|
export def sendIP(ipdst, proto, seglist, size)
|
||||||
byte[t_iphdr] hdr
|
byte[t_iphdr] hdr
|
||||||
byte[MAC_SIZE] dstha
|
|
||||||
byte retry
|
byte retry
|
||||||
word timeout
|
word timeout
|
||||||
|
|
||||||
@ -423,19 +257,22 @@ export def sendIP(ipdst, proto, seglist, size)
|
|||||||
memcpy(@hdr.ip_src, @localip, IPADR_SIZE)
|
memcpy(@hdr.ip_src, @localip, IPADR_SIZE)
|
||||||
if !ipdst // IP_BROADCAST
|
if !ipdst // IP_BROADCAST
|
||||||
memset(@hdr.ip_dst, IP_BROADCAST, IPADR_SIZE)
|
memset(@hdr.ip_dst, IP_BROADCAST, IPADR_SIZE)
|
||||||
memset(@dstha, MAC_BROADCAST, MAC_SIZE)
|
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
|
||||||
else
|
else
|
||||||
|
memcpy(@hdr.ip_dst, ipdst, IPADR_SIZE)
|
||||||
retry = 0
|
retry = 0
|
||||||
while ipdst=>0 <> remoteip:0 and ipdst=>2 <> remoteip:2
|
while hdr:ip_dst:0 <> remoteip:0 and hdr:ip_dst:2 <> remoteip:2
|
||||||
if retry >= 3
|
if retry >= 3
|
||||||
return -1 // ARP failed
|
return -1 // ARP failed
|
||||||
fin
|
fin
|
||||||
retry = retry + 1
|
retry = retry + 1
|
||||||
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
|
memset(@dstMAC, MAC_BROADCAST, MAC_SIZE)
|
||||||
memset(@remoteha, 0, MAC_SIZE)
|
memset(@remoteha, 0, MAC_SIZE)
|
||||||
memcpy(@remoteip, ipdst, IPADR_SIZE)
|
memcpy(@remoteip, @hdr.ip_dst, IPADR_SIZE)
|
||||||
opARP = ARP_REQST
|
ePayload = PAYLOAD_ARP
|
||||||
writeEther(@ARP, t_earp)
|
opARP = ARP_REQST
|
||||||
|
setFrameLen(t_earp)
|
||||||
|
writeFrame(@eFrame, t_earp)
|
||||||
for timeout = 1000 downto 0
|
for timeout = 1000 downto 0
|
||||||
serviceIP
|
serviceIP
|
||||||
if remoteha:0 | remoteha:2 | remoteha:4
|
if remoteha:0 | remoteha:2 | remoteha:4
|
||||||
@ -443,53 +280,55 @@ export def sendIP(ipdst, proto, seglist, size)
|
|||||||
fin
|
fin
|
||||||
next
|
next
|
||||||
loop
|
loop
|
||||||
memcpy(@hdr.ip_dst, ipdst, IPADR_SIZE)
|
memcpy(@dstMAC, @remoteha, MAC_SIZE)
|
||||||
memcpy(@dstha, @remoteha, MAC_SIZE)
|
|
||||||
fin
|
fin
|
||||||
//
|
//
|
||||||
// Calculate checksum
|
// Calculate checksum
|
||||||
//
|
//
|
||||||
hdr:ip_chksm = sum1(0, @hdr, t_iphdr) ^ $FFFF
|
hdr:ip_chksm = sum1(0, @hdr, t_iphdr) ^ $FFFF
|
||||||
//
|
//
|
||||||
// Fill in remaining segment list for IP header and write it out
|
// set the ethernet payload and frame length
|
||||||
//
|
//
|
||||||
seglist=>seg_buf = @hdr
|
ePayload = PAYLOAD_IP
|
||||||
seglist=>seg_len = t_iphdr
|
setFrameLen(t_ethriphdr + size)
|
||||||
return writevEther(@dstha, PAYLOAD_IP, seglist, t_iphdr + size)
|
//
|
||||||
|
// Write the ethernet header
|
||||||
|
//
|
||||||
|
writeFrame(@eFrame, t_ethrhdr)
|
||||||
|
//
|
||||||
|
// Write the IP header
|
||||||
|
//
|
||||||
|
writeFrame(@hdr, t_iphdr)
|
||||||
|
//
|
||||||
|
// Write the remaining segments
|
||||||
|
//
|
||||||
|
while size > 0
|
||||||
|
writeFrame(seglist=>seg_buf, seglist=>seg_len)
|
||||||
|
size = size - seglist=>seg_len
|
||||||
|
seglist = seglist + t_segment
|
||||||
|
loop
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Send UDP datagram
|
// Send UDP datagram
|
||||||
//
|
//
|
||||||
export def sendUDP(ipdst, portdst, portsrc, data, len)
|
export def sendUDP(ipdst, portdst, portsrc, data, len)
|
||||||
word[12] seglist // list of data and header segments
|
word[8] seglist // list of data and header segments
|
||||||
//word segsum
|
|
||||||
//byte[t_piphdr] phdr
|
|
||||||
byte[t_udphdr] hdr
|
byte[t_udphdr] hdr
|
||||||
|
|
||||||
//memcpy(@phdr.pip_src, @localip, IPADR_SIZE)
|
|
||||||
//memcpy(@phdr.pip_dst, ipdst, IPADR_SIZE)
|
|
||||||
//phdr.pip_zero = 0
|
|
||||||
//phdr.pip_proto = IP_PROTO_UDP
|
|
||||||
//phdr.pip_len = swab(t_udphdr + len)
|
|
||||||
hdr:udp_src = swab(portsrc)
|
hdr:udp_src = swab(portsrc)
|
||||||
hdr:udp_dst = swab(portdst)
|
hdr:udp_dst = swab(portdst)
|
||||||
hdr:udp_len = swab(t_udphdr + len)
|
hdr:udp_len = swab(t_udphdr + len)
|
||||||
hdr:udp_chksm = 0
|
hdr:udp_chksm = 0
|
||||||
//segsum = sum1(0, @phdr, t_piphdr + t_udphdr)
|
seglist:0:seg_buf = @hdr
|
||||||
//segsum = sum1(segsum, data, len)
|
seglist:0:seg_len = t_udphdr
|
||||||
//hdr:udp_chksm = segsum ^ $FFFF
|
seglist:4:seg_buf = data
|
||||||
//seglist:0:seg_buf reserved for IP header
|
seglist:4:seg_len = len
|
||||||
//seglist:0:seg_len reserved for IP header
|
|
||||||
seglist:4:seg_buf = @hdr
|
|
||||||
seglist:4:seg_len = t_udphdr
|
|
||||||
seglist:8:seg_buf = data
|
|
||||||
seglist:8:seg_len = len
|
|
||||||
return sendIP(ipdst, IP_PROTO_UDP, @seglist, t_udphdr + len)
|
return sendIP(ipdst, IP_PROTO_UDP, @seglist, t_udphdr + len)
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Notify on UDP datagram received
|
// Notify on UDP datagram received
|
||||||
//
|
//
|
||||||
export def recvUDP(localport, callback, param)
|
export def listenUDP(localport, callback, param)
|
||||||
word port
|
word port
|
||||||
byte i
|
byte i
|
||||||
|
|
||||||
@ -530,7 +369,7 @@ end
|
|||||||
//
|
//
|
||||||
// Clear notify on UDP port
|
// Clear notify on UDP port
|
||||||
//
|
//
|
||||||
export def shutUDP(localport)
|
export def hangupUDP(localport)
|
||||||
word port
|
word port
|
||||||
byte i
|
byte i
|
||||||
|
|
||||||
@ -548,8 +387,136 @@ export def shutUDP(localport)
|
|||||||
return -1
|
return -1
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Fill in MAC
|
// Service incoming packets
|
||||||
//
|
//
|
||||||
copyMAC(@srcMAC)
|
export def serviceIP
|
||||||
copyMAC(@localha)
|
word rxsize, rxpacket, rxptr
|
||||||
done
|
word iphdr, opt, optlen, port, lclport, remport
|
||||||
|
byte i, echolen
|
||||||
|
word[4] seglist
|
||||||
|
byte[128] echo_reply
|
||||||
|
|
||||||
|
//
|
||||||
|
// Check for received packet
|
||||||
|
//
|
||||||
|
rxsize = getFrameLen()
|
||||||
|
if rxsize
|
||||||
|
//
|
||||||
|
// Read the entire packet into memory
|
||||||
|
//
|
||||||
|
rxpacket = heapalloc(rxsize)
|
||||||
|
readFrame(rxpacket, rxsize)
|
||||||
|
rxptr = rxpacket + t_ethrhdr
|
||||||
|
rxsize = rxsize - t_ethrhdr
|
||||||
|
//
|
||||||
|
// What kind of packet is it?
|
||||||
|
//
|
||||||
|
when rxpacket=>ethr_payload
|
||||||
|
is PAYLOAD_IP
|
||||||
|
iphdr = rxptr
|
||||||
|
rxptr = rxptr + t_iphdr
|
||||||
|
rxsize = rxsize - t_iphdr
|
||||||
|
if iphdr->ip_vers_hlen <> $45
|
||||||
|
optlen = iphdr=>ip_vers_hlen
|
||||||
|
if optlen & $F0 <> $40
|
||||||
|
//
|
||||||
|
// Not IPv4, ignore
|
||||||
|
//
|
||||||
|
break
|
||||||
|
fin
|
||||||
|
optlen = (optlen & $0F) << 2
|
||||||
|
if optlen > t_iphdr
|
||||||
|
//
|
||||||
|
// Read the options and throw them on the ground!
|
||||||
|
//
|
||||||
|
rxptr = rxptr + (optlen - t_iphdr)
|
||||||
|
rxsize = rxsize - (optlen - t_iphdr)
|
||||||
|
fin
|
||||||
|
fin
|
||||||
|
//
|
||||||
|
// Filter valid destination address
|
||||||
|
//
|
||||||
|
if iphdr=>ip_dst:2 <> localip:2 // Yes, this is a little lazy
|
||||||
|
if (iphdr=>ip_dst:0|subnet:0) & (iphdr=>ip_dst:2|subnet:2) <> IP_BROADCAST
|
||||||
|
break
|
||||||
|
fin
|
||||||
|
fin
|
||||||
|
//
|
||||||
|
// What kind of IP protocol is it?
|
||||||
|
//
|
||||||
|
when iphdr->ip_proto
|
||||||
|
is IP_PROTO_UDP
|
||||||
|
port = portsUDP
|
||||||
|
if port
|
||||||
|
lclport = swab(rxptr=>udp_dst)
|
||||||
|
for i = 1 to MAX_UDP_NOTIFIES
|
||||||
|
if port=>notify_port == lclport)
|
||||||
|
port=>notify_func(@iphdr=>ip_src,swab(rxptr=>udp_src),lclport,rxptr+t_udphdr,swab(rxptr=>udp_len),port=>notify_parm)
|
||||||
|
break
|
||||||
|
fin
|
||||||
|
port = port + t_notify
|
||||||
|
next
|
||||||
|
fin
|
||||||
|
break
|
||||||
|
is IP_PROTO_TCP
|
||||||
|
break
|
||||||
|
is IP_PROTO_ICMP
|
||||||
|
//
|
||||||
|
// Service ICMP packets
|
||||||
|
//
|
||||||
|
if rxptr->icmp_type == ICMP_ECHO_REQST
|
||||||
|
if rxsize > 128
|
||||||
|
echolen = 128
|
||||||
|
else
|
||||||
|
echolen = rxsize
|
||||||
|
fin
|
||||||
|
memcpy(@echo_reply, rxptr, echolen)
|
||||||
|
echo_reply.icmp_type = ICMP_ECHO_REPLY
|
||||||
|
echo_reply:icmp_chksm = 0
|
||||||
|
seglist:seg_buf = @echo_reply
|
||||||
|
seglist:seg_len = echolen
|
||||||
|
sendIP(@iphdr=>ip_src, IP_PROTO_ICMP, @seglist, echolen)
|
||||||
|
fin
|
||||||
|
if hookICMP
|
||||||
|
hookICMP(@iphdr=>ip_src, rxptr, rxsize)
|
||||||
|
fin
|
||||||
|
wend
|
||||||
|
break
|
||||||
|
is PAYLOAD_ARP
|
||||||
|
when rxptr=>arp_op
|
||||||
|
is ARP_REPLY
|
||||||
|
//
|
||||||
|
// Fill in ARP cache
|
||||||
|
//
|
||||||
|
memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip
|
||||||
|
break
|
||||||
|
is ARP_REQST
|
||||||
|
//
|
||||||
|
// Is this a request for me?
|
||||||
|
//
|
||||||
|
if rxptr=>arp_targip:0 == localip:0 and rxptr=>arp_targip:2 == localip:2
|
||||||
|
memcpy(@dstMAC, @rxptr=>arp_senderha, MAC_SIZE)
|
||||||
|
memcpy(@remoteha, @rxptr=>arp_senderha, 10) // copy ha and ip
|
||||||
|
ePayload = PAYLOAD_ARP
|
||||||
|
opARP = ARP_REPLY
|
||||||
|
setFrameLen(t_earp)
|
||||||
|
writeFrame(@eFrame, t_earp)
|
||||||
|
fin
|
||||||
|
wend
|
||||||
|
wend
|
||||||
|
heaprelease(rxpacket)
|
||||||
|
fin
|
||||||
|
end
|
||||||
|
//
|
||||||
|
// Initialize the driver interface
|
||||||
|
//
|
||||||
|
export def setEtherDriver(MAC, getlen, readframe, setlen, writeframe)
|
||||||
|
memcpy(@myMAC, MAC, MAC_SIZE)
|
||||||
|
memcpy(@localha, MAC, MAC_SIZE)
|
||||||
|
getFrameLen = getlen
|
||||||
|
readFrame = readframe
|
||||||
|
setFrameLen = setlen
|
||||||
|
writeFrame = writeframe
|
||||||
|
end
|
||||||
|
|
||||||
|
done
|
35
src/libsrc/inet.pla
Normal file
35
src/libsrc/inet.pla
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import cmdsys
|
||||||
|
predef syscall, call, getc, gets, putc, puts, putln
|
||||||
|
predef memset, memcpy, modaddr, modexec
|
||||||
|
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
|
||||||
|
byte MACHID
|
||||||
|
end
|
||||||
|
import uthernet
|
||||||
|
byte localip, subnet, gateway
|
||||||
|
predef serviceIP
|
||||||
|
end
|
||||||
|
|
||||||
|
byte dhcp = "DHCP"
|
||||||
|
|
||||||
|
byte serverip = 192,168,123,1
|
||||||
|
byte staticip = 192,168,123,10
|
||||||
|
byte staticmask = 255,255,255,0
|
||||||
|
|
||||||
|
if modexec(@dhcp) < 0
|
||||||
|
//
|
||||||
|
// Set our local IP address
|
||||||
|
//
|
||||||
|
memcpy(@localip, @staticip, 4)
|
||||||
|
memcpy(@subnet, @staticmask, 4)
|
||||||
|
memcpy(@gateway, @serverip, 4)
|
||||||
|
fin
|
||||||
|
|
||||||
|
//
|
||||||
|
// Service IP
|
||||||
|
//
|
||||||
|
repeat
|
||||||
|
serviceIP
|
||||||
|
until ^$C000 > 127
|
||||||
|
^$C010
|
||||||
|
|
||||||
|
done
|
@ -1,8 +1,8 @@
|
|||||||
import cmdsys
|
//
|
||||||
predef syscall, call, getc, gets, putc, puts, putln
|
// Include dependency on S/W IP stack
|
||||||
predef memset, memcpy, modaddr, modexec
|
//
|
||||||
predef heapmark, heapallocalign, heapalloc, heaprelease, heapavail
|
import etherip
|
||||||
byte MACHID
|
predef setEtherDriver
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Module don't free memory
|
// Module don't free memory
|
||||||
@ -10,33 +10,6 @@ end
|
|||||||
const modkeep = $2000
|
const modkeep = $2000
|
||||||
const modinitkeep = $4000
|
const modinitkeep = $4000
|
||||||
//
|
//
|
||||||
// Segment list element
|
|
||||||
//
|
|
||||||
struc t_segment
|
|
||||||
word seg_buf
|
|
||||||
word seg_len
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// MAC size
|
|
||||||
//
|
|
||||||
const MAC_SIZE = 6
|
|
||||||
//
|
|
||||||
// Ethernet header
|
|
||||||
//
|
|
||||||
struc t_ethrhdr
|
|
||||||
byte[MAC_SIZE] ethr_dst
|
|
||||||
byte[MAC_SIZE] ethr_src
|
|
||||||
word ethr_payload
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Max Ethernet frame size
|
|
||||||
//
|
|
||||||
const MAX_FRAME_SIZE = 1518
|
|
||||||
//
|
|
||||||
// MAC address
|
|
||||||
//
|
|
||||||
byte MAC = $00,$0A,$99,$1E,$02,$00
|
|
||||||
//
|
|
||||||
// Uthernet register offsets
|
// Uthernet register offsets
|
||||||
//
|
//
|
||||||
const TXDATA = $00
|
const TXDATA = $00
|
||||||
@ -58,9 +31,9 @@ byte isq
|
|||||||
byte pregidx
|
byte pregidx
|
||||||
byte pregdata
|
byte pregdata
|
||||||
//
|
//
|
||||||
// Current receive status and packet size
|
// Uthernet MAC address
|
||||||
//
|
//
|
||||||
word rxsize, rxpacket, rxptr
|
byte[6] utherMAC = $00,$0A,$99,$1E,$02,$00
|
||||||
//
|
//
|
||||||
// Defines for ASM routines
|
// Defines for ASM routines
|
||||||
//
|
//
|
||||||
@ -68,21 +41,7 @@ asm equates
|
|||||||
!SOURCE "vmsrc/plvmzp.inc"
|
!SOURCE "vmsrc/plvmzp.inc"
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// I/O access
|
// Uthernet I/O functions
|
||||||
//
|
|
||||||
// POKE BYTE INTO I/O SPACE
|
|
||||||
// _pokeio(DATA)
|
|
||||||
//
|
|
||||||
//asm _pokeio
|
|
||||||
// LDA ESTKL,X
|
|
||||||
//end
|
|
||||||
//asm _pokeiol
|
|
||||||
// STA $C000
|
|
||||||
// RTS
|
|
||||||
//end
|
|
||||||
//
|
|
||||||
// POKE WORD INTO I/O SPACE
|
|
||||||
// _pokeiow(DATA)
|
|
||||||
//
|
//
|
||||||
asm _pokeiow
|
asm _pokeiow
|
||||||
LDA ESTKL,X
|
LDA ESTKL,X
|
||||||
@ -126,7 +85,7 @@ asm _peekiowh
|
|||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// WRITE PACKET FRAME INTO I/O SPACE
|
// WRITE FRAME DATA INTO I/O SPACE
|
||||||
// pokefrm(BUF, LEN)
|
// pokefrm(BUF, LEN)
|
||||||
//
|
//
|
||||||
asm pokefrm
|
asm pokefrm
|
||||||
@ -164,7 +123,7 @@ asm _pokefrmh
|
|||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// READ PACKET FRAME FROM I/O SPACE
|
// READ FRAME DATA FROM I/O SPACE
|
||||||
// peekfrm(BUF, LEN)
|
// peekfrm(BUF, LEN)
|
||||||
//
|
//
|
||||||
asm peekfrm
|
asm peekfrm
|
||||||
@ -201,10 +160,6 @@ asm _peekfrmh
|
|||||||
EXPSW INX
|
EXPSW INX
|
||||||
RTS
|
RTS
|
||||||
end
|
end
|
||||||
//def pokeio(io, data)
|
|
||||||
// _pokeiowl.1 = io
|
|
||||||
// return _pokeio(data)
|
|
||||||
//end
|
|
||||||
def pokeiow(io, data)
|
def pokeiow(io, data)
|
||||||
_pokeiowl.1 = io
|
_pokeiowl.1 = io
|
||||||
_pokeiowh.1 = io+1
|
_pokeiowh.1 = io+1
|
||||||
@ -228,63 +183,30 @@ def peekpreg(reg)
|
|||||||
return peekiow(pregdata)
|
return peekiow(pregdata)
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Uthernet interface
|
// Set the length of the next packet to send and wait for data space availability
|
||||||
//
|
//
|
||||||
export def copyMAC(ptr)
|
def pokefrmlen(len)
|
||||||
if !rxpacket; rxpacket = heapalloc(MAX_FRAME_SIZE); fin
|
|
||||||
memcpy(ptr, @MAC, MAC_SIZE)
|
|
||||||
return MAC_SIZE
|
|
||||||
end
|
|
||||||
export def writeEther(packet, size)
|
|
||||||
pokeiow(txcmd, $C0)
|
pokeiow(txcmd, $C0)
|
||||||
pokeiow(txlen, size)
|
pokeiow(txlen, len)
|
||||||
repeat; until peekpreg($0138) & $0100
|
repeat; until peekpreg($0138) & $0100
|
||||||
return pokefrm(packet, size)
|
|
||||||
end
|
end
|
||||||
export def writevEther(destha, payload, seglist, size)
|
//
|
||||||
pokeiow(txcmd, $C0)
|
// Return the length of awaiting packet, 0 otherwise
|
||||||
pokeiow(txlen, size + t_ethrhdr)
|
//
|
||||||
repeat; until peekpreg($0138) & $0100
|
def peekfrmlen
|
||||||
pokefrm(destha, MAC_SIZE)
|
word len
|
||||||
pokefrm(@MAC, MAC_SIZE)
|
len = 0
|
||||||
pokefrm(@payload, 2)
|
if peekiow(isq) & $3F == $04
|
||||||
while size > 0
|
if peekio(rxdata_hi) & $01
|
||||||
pokefrm(seglist=>seg_buf, seglist=>seg_len)
|
peekio(rxdata_lo)
|
||||||
size = size - seglist=>seg_len
|
len.1 = peekio(rxdata_hi)
|
||||||
seglist = seglist + t_segment
|
len.0 = peekio(rxdata_lo)
|
||||||
loop
|
else
|
||||||
end
|
peekio(rxdata_lo)
|
||||||
export def readEther(size)
|
pokepreg($0102, $0140) // Skip pkt
|
||||||
word segptr
|
|
||||||
|
|
||||||
if rxsize > 0
|
|
||||||
if size > rxsize
|
|
||||||
size = rxsize
|
|
||||||
fin
|
|
||||||
segptr = rxptr
|
|
||||||
rxptr = rxptr + size
|
|
||||||
rxsize = rxsize - size
|
|
||||||
else
|
|
||||||
segptr = 0
|
|
||||||
fin
|
|
||||||
return segptr
|
|
||||||
end
|
|
||||||
export def recvEther
|
|
||||||
if rxsize == 0
|
|
||||||
if peekiow(isq) & $3F == $04
|
|
||||||
if peekio(rxdata_hi) & $01
|
|
||||||
peekio(rxdata_lo)
|
|
||||||
rxsize.1 = peekio(rxdata_hi)
|
|
||||||
rxsize.0 = peekio(rxdata_lo)
|
|
||||||
peekfrm(rxpacket, rxsize)
|
|
||||||
rxptr = rxpacket
|
|
||||||
else
|
|
||||||
peekio(rxdata_lo)
|
|
||||||
pokepreg($0102, $0140) // Skip pkt
|
|
||||||
fin
|
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
||||||
return rxsize
|
return len
|
||||||
end
|
end
|
||||||
//
|
//
|
||||||
// Identify Uthernet card and initialize
|
// Identify Uthernet card and initialize
|
||||||
@ -304,13 +226,17 @@ for slot = $F0 downto $90 step $10
|
|||||||
_pokefrmh.1 = slot+1
|
_pokefrmh.1 = slot+1
|
||||||
_peekfrml.1 = slot
|
_peekfrml.1 = slot
|
||||||
_peekfrmh.1 = slot+1
|
_peekfrmh.1 = slot+1
|
||||||
pokepreg($0158, MAC:0) // MAC addr
|
pokepreg($0158, utherMAC:0) // MAC addr
|
||||||
pokepreg($015A, MAC:2) // MAC addr
|
pokepreg($015A, utherMAC:2) // MAC addr
|
||||||
pokepreg($015C, MAC:4) // MAC addr
|
pokepreg($015C, utherMAC:4) // MAC addr
|
||||||
pokepreg($0102, $0100) // Recv cfg
|
pokepreg($0102, $0100) // Recv cfg
|
||||||
pokepreg($0104, $0D00) // Recv ctrl
|
pokepreg($0104, $0D00) // Recv ctrl
|
||||||
pokepreg($0106, $8200) // Xmit cfg
|
pokepreg($0106, $8200) // Xmit cfg
|
||||||
pokepreg($0112, $00C0) // Line ctrl
|
pokepreg($0112, $00C0) // Line ctrl
|
||||||
|
//
|
||||||
|
// Install etherip driver
|
||||||
|
//
|
||||||
|
setEtherDriver(@utherMAC, @peekfrmlen, @peekfrm, @pokefrmlen, @pokefrm)
|
||||||
return modkeep
|
return modkeep
|
||||||
fin
|
fin
|
||||||
fin
|
fin
|
33
src/makefile
33
src/makefile
@ -11,9 +11,8 @@ ROD = ROD\#FE1000
|
|||||||
SIEVE = SIEVE\#FE1000
|
SIEVE = SIEVE\#FE1000
|
||||||
UTHERNET= UTHERNET\#FE1000
|
UTHERNET= UTHERNET\#FE1000
|
||||||
ETHERIP = ETHERIP\#FE1000
|
ETHERIP = ETHERIP\#FE1000
|
||||||
ICMP = ICMP\#FE1000
|
INET = INET\#FE1000
|
||||||
DHCP = DHCP\#FE1000
|
DHCP = DHCP\#FE1000
|
||||||
STATICIP= STATICIP\#FE1000
|
|
||||||
ROGUE = ROGUE\#FE1000
|
ROGUE = ROGUE\#FE1000
|
||||||
ROGUEIO = ROGUEIO\#FE1000
|
ROGUEIO = ROGUEIO\#FE1000
|
||||||
ROGUEMAP= ROGUEMAP\#FE1000
|
ROGUEMAP= ROGUEMAP\#FE1000
|
||||||
@ -46,7 +45,7 @@ TXTTYPE = .TXT
|
|||||||
#SYSTYPE = \#FF2000
|
#SYSTYPE = \#FF2000
|
||||||
#TXTTYPE = \#040000
|
#TXTTYPE = \#040000
|
||||||
|
|
||||||
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET) $(ETHERIP) $(ICMP) $(DHCP) $(STATICIP) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1)
|
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
|
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
|
||||||
@ -123,25 +122,21 @@ $(SIEVE): samplesrc/sieve.pla $(PLVM02) $(PLASM)
|
|||||||
./$(PLASM) -AM < samplesrc/sieve.pla > samplesrc/sieve.a
|
./$(PLASM) -AM < samplesrc/sieve.pla > samplesrc/sieve.a
|
||||||
acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a
|
acme --setpc 4094 -o $(SIEVE) samplesrc/sieve.a
|
||||||
|
|
||||||
$(UTHERNET): samplesrc/uthernet.pla $(PLVM02) $(PLASM)
|
$(UTHERNET): libsrc/uthernet.pla $(PLVM02) $(PLASM)
|
||||||
./$(PLASM) -AM < samplesrc/uthernet.pla > samplesrc/uthernet.a
|
./$(PLASM) -AM < libsrc/uthernet.pla > libsrc/uthernet.a
|
||||||
acme --setpc 4094 -o $(UTHERNET) samplesrc/uthernet.a
|
acme --setpc 4094 -o $(UTHERNET) libsrc/uthernet.a
|
||||||
|
|
||||||
$(ETHERIP): samplesrc/etherip.pla $(PLVM02) $(PLASM)
|
$(ETHERIP): libsrc/etherip.pla $(PLVM02) $(PLASM)
|
||||||
./$(PLASM) -AM < samplesrc/etherip.pla > samplesrc/etherip.a
|
./$(PLASM) -AM < libsrc/etherip.pla > libsrc/etherip.a
|
||||||
acme --setpc 4094 -o $(ETHERIP) samplesrc/etherip.a
|
acme --setpc 4094 -o $(ETHERIP) libsrc/etherip.a
|
||||||
|
|
||||||
$(ICMP): samplesrc/icmp.pla $(PLVM02) $(PLASM)
|
$(INET): libsrc/inet.pla $(PLVM02) $(PLASM)
|
||||||
./$(PLASM) -AM < samplesrc/icmp.pla > samplesrc/icmp.a
|
./$(PLASM) -AM < libsrc/inet.pla > libsrc/inet.a
|
||||||
acme --setpc 4094 -o $(ICMP) samplesrc/icmp.a
|
acme --setpc 4094 -o $(INET) libsrc/inet.a
|
||||||
|
|
||||||
$(DHCP): samplesrc/dhcp.pla $(PLVM02) $(PLASM)
|
$(DHCP): libsrc/dhcp.pla $(PLVM02) $(PLASM)
|
||||||
./$(PLASM) -AM < samplesrc/dhcp.pla > samplesrc/dhcp.a
|
./$(PLASM) -AM < libsrc/dhcp.pla > libsrc/dhcp.a
|
||||||
acme --setpc 4094 -o $(DHCP) samplesrc/dhcp.a
|
acme --setpc 4094 -o $(DHCP) libsrc/dhcp.a
|
||||||
|
|
||||||
$(STATICIP): samplesrc/staticip.pla $(PLVM02) $(PLASM)
|
|
||||||
./$(PLASM) -AM < samplesrc/staticip.pla > samplesrc/staticip.a
|
|
||||||
acme --setpc 4094 -o $(STATICIP) samplesrc/staticip.a
|
|
||||||
|
|
||||||
$(ROGUE): samplesrc/rogue.pla $(PLVM02) $(PLASM)
|
$(ROGUE): samplesrc/rogue.pla $(PLVM02) $(PLASM)
|
||||||
./$(PLASM) -AM < samplesrc/rogue.pla > samplesrc/rogue.a
|
./$(PLASM) -AM < samplesrc/rogue.pla > samplesrc/rogue.a
|
||||||
|
@ -1,96 +0,0 @@
|
|||||||
//
|
|
||||||
// ICMP service
|
|
||||||
//
|
|
||||||
import cmdsys
|
|
||||||
predef syscall, call, getc, gets, putc, puts, putln
|
|
||||||
predef memset, memcpy, modaddr, modexec
|
|
||||||
predef heapmark, heapallocalign, heapalloc, heaprelease
|
|
||||||
byte MACHID
|
|
||||||
end
|
|
||||||
import etherip
|
|
||||||
byte localha, localip
|
|
||||||
word serviceICMP
|
|
||||||
predef sendIP
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Segment list element
|
|
||||||
//
|
|
||||||
struc t_segment
|
|
||||||
word seg_buf
|
|
||||||
word seg_len
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// ICMP type/codes
|
|
||||||
//
|
|
||||||
const IP_PROTO_ICMP = 1
|
|
||||||
const ICMP_ECHO_REQST = 8
|
|
||||||
const ICMP_ECHO_REPLY = 0
|
|
||||||
//
|
|
||||||
// ICMP message format
|
|
||||||
//
|
|
||||||
struc t_icmp
|
|
||||||
byte icmp_type
|
|
||||||
byte icmp_code
|
|
||||||
word icmp_chksm
|
|
||||||
word[2] icmp_header
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// DEBUG
|
|
||||||
//
|
|
||||||
byte icmpstr = "ICMP "
|
|
||||||
def putln
|
|
||||||
return putc($0D)
|
|
||||||
end
|
|
||||||
def putb(hexb)
|
|
||||||
return call($FDDA, hexb, 0, 0, 0)
|
|
||||||
end
|
|
||||||
def puth(hex)
|
|
||||||
return call($F941, hex >> 8, hex, 0, 0)
|
|
||||||
end
|
|
||||||
def puti(i)
|
|
||||||
if i < 0; putc('-'); i = -i; fin
|
|
||||||
if i < 10
|
|
||||||
putc(i + '0')
|
|
||||||
else
|
|
||||||
puti(i / 10)
|
|
||||||
putc(i % 10 + '0')
|
|
||||||
fin
|
|
||||||
end
|
|
||||||
def putip(ipptr)
|
|
||||||
byte i
|
|
||||||
|
|
||||||
for i = 0 to 2
|
|
||||||
puti(ipptr->[i]); putc('.')
|
|
||||||
next
|
|
||||||
return puti(ipptr->[i])
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Service ICMP packets
|
|
||||||
//
|
|
||||||
def icmp(srcip, pkt, len)
|
|
||||||
byte[4] echoip
|
|
||||||
word[8] seglist
|
|
||||||
byte[128] echo_reply
|
|
||||||
|
|
||||||
//puts(@icmpstr);putip(srcip);putc(' ')
|
|
||||||
//puti(pkt->icmp_type);putc(' ');puti(pkt->icmp_code);putln
|
|
||||||
|
|
||||||
if pkt->icmp_type == ICMP_ECHO_REQST
|
|
||||||
if len > 128
|
|
||||||
len = 128
|
|
||||||
fin
|
|
||||||
memcpy(@echo_reply, pkt, len)
|
|
||||||
echo_reply.icmp_type = ICMP_ECHO_REPLY
|
|
||||||
echo_reply:icmp_chksm = 0
|
|
||||||
//echo_reply:icmp_chksm = sum1(0, @echo_reply, len) ^ $FFFF
|
|
||||||
memcpy(@echoip, srcip, 4)
|
|
||||||
seglist:4:seg_buf = @echo_reply
|
|
||||||
seglist:4:seg_len = len
|
|
||||||
sendIP(@echoip, IP_PROTO_ICMP, @seglist, len)
|
|
||||||
fin
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Set to notify on ICMP packets
|
|
||||||
//
|
|
||||||
serviceICMP = @icmp
|
|
||||||
done
|
|
@ -1,98 +0,0 @@
|
|||||||
//
|
|
||||||
// Static IP
|
|
||||||
//
|
|
||||||
import cmdsys
|
|
||||||
predef syscall, call, getc, gets, putc, puts, putln
|
|
||||||
predef memset, memcpy, modaddr, modexec
|
|
||||||
predef heapmark, heapallocalign, heapalloc, heaprelease
|
|
||||||
byte MACHID
|
|
||||||
end
|
|
||||||
import etherip
|
|
||||||
byte localha, localip
|
|
||||||
predef sendUDP, recvUDP, shutUDP, sendIP, serviceIP, sum1
|
|
||||||
end
|
|
||||||
import icmp
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Segment list element
|
|
||||||
//
|
|
||||||
struc t_segment
|
|
||||||
word seg_buf
|
|
||||||
word seg_len
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// ICMP type/codes
|
|
||||||
//
|
|
||||||
const ICMP_ECHO_REQST = 8
|
|
||||||
const ICMP_ECHO_REPLY = 0
|
|
||||||
//
|
|
||||||
// ICMP message format
|
|
||||||
//
|
|
||||||
struc t_icmp
|
|
||||||
byte icmp_type
|
|
||||||
byte icmp_code
|
|
||||||
word icmp_chksm
|
|
||||||
word[2] icmp_header
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// ICMP echo packet
|
|
||||||
//
|
|
||||||
const IP_PROTO_ICMP = $01
|
|
||||||
byte ECHO = 8 // ECHO request
|
|
||||||
byte = 0 // code
|
|
||||||
word = 0 // checksum
|
|
||||||
byte = 0, 69, 0, 1 // rest of header
|
|
||||||
word segecho = 0, 0, @ECHO, 8
|
|
||||||
byte serverip = 192,168,123,129
|
|
||||||
byte staticip = 192,168,123,10
|
|
||||||
byte staticmask = 255,255,255,0
|
|
||||||
word echo_reply
|
|
||||||
//
|
|
||||||
// DEBUG
|
|
||||||
//
|
|
||||||
def putln
|
|
||||||
return putc($0D)
|
|
||||||
end
|
|
||||||
def putb(hexb)
|
|
||||||
return call($FDDA, hexb, 0, 0, 0)
|
|
||||||
end
|
|
||||||
def puth(hex)
|
|
||||||
return call($F941, hex >> 8, hex, 0, 0)
|
|
||||||
end
|
|
||||||
def puti(i)
|
|
||||||
if i < 0; putc('-'); i = -i; fin
|
|
||||||
if i < 10
|
|
||||||
putc(i + '0')
|
|
||||||
else
|
|
||||||
puti(i / 10)
|
|
||||||
putc(i % 10 + '0')
|
|
||||||
fin
|
|
||||||
end
|
|
||||||
def putip(ipptr)
|
|
||||||
byte i
|
|
||||||
|
|
||||||
for i = 0 to 2
|
|
||||||
puti(ipptr->[i]); putc('.')
|
|
||||||
next
|
|
||||||
return puti(ipptr->[i])
|
|
||||||
end
|
|
||||||
//
|
|
||||||
// Set our local IP address
|
|
||||||
//
|
|
||||||
memcpy(@localip, @staticip, 4)
|
|
||||||
//
|
|
||||||
// Calculate checksum
|
|
||||||
//
|
|
||||||
ECHO:icmp_chksm = sum1(0, @ECHO, t_icmp) ^ $FFFF
|
|
||||||
//
|
|
||||||
// Send an echo to the server
|
|
||||||
//
|
|
||||||
sendIP(@serverip, IP_PROTO_ICMP, @segecho, 0)
|
|
||||||
//
|
|
||||||
// Service IP
|
|
||||||
//
|
|
||||||
repeat
|
|
||||||
serviceIP
|
|
||||||
until ^$C000 > 127
|
|
||||||
^$C010
|
|
||||||
done
|
|
Loading…
x
Reference in New Issue
Block a user