mirror of
https://github.com/dschmenk/PLASMA.git
synced 2025-04-09 16:40:38 +00:00
More compliant DHCP and add updates for port callbacks/params
This commit is contained in:
parent
501964d61c
commit
8933148bca
@ -27,6 +27,8 @@ struc t_inet
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
//
|
||||
// Needed to init subnet
|
||||
@ -66,7 +68,8 @@ const DHCP_RELEASE = $07
|
||||
//
|
||||
// Track DHCP progress
|
||||
//
|
||||
byte stateDHCP, retry, timeout
|
||||
byte retry
|
||||
word timeout
|
||||
//
|
||||
// DHCP ports
|
||||
//
|
||||
@ -85,7 +88,7 @@ byte localnet = 255,255,255,0
|
||||
//
|
||||
// Pre-configured DHCP packet
|
||||
//
|
||||
byte DHCP = $01 // OP = DISCOVER
|
||||
byte DHCP = $01// OP = BOOT
|
||||
byte = $01 // HTYPE = ETHERNET
|
||||
byte = $06 // HLEN = 6
|
||||
byte = $00 // HOPS
|
||||
@ -100,19 +103,17 @@ byte[16] = 0 // CLIENT HA
|
||||
byte[64] = 0 // SERVER HOST NAME
|
||||
byte[128] = 0 // BOOT FILE NAME
|
||||
byte[4] = $63,$82,$53,$63 // MAGIC
|
||||
byte optsDHCP = 53,1,1 // DISCOVER
|
||||
byte = 12, "AppleII"
|
||||
byte = 55,4 ,1,3,6,42
|
||||
byte = 255
|
||||
byte optsREQ = 53,1,3 // REQUEST
|
||||
byte = 50,4,0,0,0,0 // IP requested
|
||||
byte = 54,4,0,0,0,0 // DHCP server
|
||||
byte = 255
|
||||
byte optsOP = 53,1,1 // DISCOVER
|
||||
byte optsCID = 61,7, $01,$00,$00,$00,$00,$00,$00
|
||||
byte = 12, "AppleII"
|
||||
byte optsIP = 50,4, 0,0,0,0 // IP requested
|
||||
byte = 55,4, 1,3,6,42 // Parameter request list
|
||||
byte optsSRV = 54,4, 0,0,0,0 // DHCP server
|
||||
byte = 255
|
||||
byte[] endDHCP
|
||||
//
|
||||
// DEBUG
|
||||
//
|
||||
byte offerstr = "DHCP server offering IP address "
|
||||
byte ackstr = "DHCP acknowledge\n"
|
||||
byte boundstr = "Apple II bound to:\n"
|
||||
byte dnsstr = "DNS: "
|
||||
def putln
|
||||
@ -181,27 +182,27 @@ def parseopts(opts, match)
|
||||
return -1
|
||||
end
|
||||
def recvDHCP(remip, remport, pkt, len, param)
|
||||
word optofst, maskopts, gwopts, dnsopts
|
||||
word servopts, maskopts, gwopts, dnsopts
|
||||
|
||||
//putip(remip);putc(':');puti(remport);putln
|
||||
//dumpdhcp(pkt)
|
||||
if pkt=>dhcp_xid:0 == $0201 and pkt=>dhcp_xid:2 = $0403
|
||||
when pkt->dhcp_opts.[parseopts(@pkt->dhcp_opts, 53) + 2]
|
||||
is DHCP_OFFER
|
||||
stateDHCP = DHCP_OFFER
|
||||
//puts(@offerstr); putip(@pkt->dhcp_yourip); putln
|
||||
//
|
||||
// Copy offer parameters to request
|
||||
//
|
||||
memcpy(@optsDHCP, @optsREQ, 16)
|
||||
memcpy(@optsDHCP.5, @pkt->dhcp_yourip, 4)
|
||||
memcpy(@optsDHCP.11, @pkt->dhcp_serverip, 4)
|
||||
memcpy(@DHCP.dhcp_serverip, @pkt->dhcp_serverip, 4)
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
|
||||
optsOP.2 = DHCP_REQUEST
|
||||
memcpy(@optsIP.2, @pkt->dhcp_yourip, IP4ADR_SIZE)
|
||||
servopts = parseopts(@pkt->dhcp_opts, 54) + 2
|
||||
if servopts >= 0
|
||||
optsSRV = 54
|
||||
memcpy(@optsSRV.2, @pkt->dhcp_opts.[servopts], IP4ADR_SIZE)
|
||||
fin
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @endDHCP - @DHCP)
|
||||
break
|
||||
is DHCP_ACK
|
||||
stateDHCP = DHCP_ACK
|
||||
//puts(@ackstr)
|
||||
optsOP.2 = DHCP_ACK
|
||||
//
|
||||
// Copy parameters to working copy
|
||||
//
|
||||
@ -228,6 +229,7 @@ end
|
||||
// Get the local hardware address into the DHCP packet
|
||||
//
|
||||
iNet:getInterfaceHA(@DHCP.dhcp_clientha)
|
||||
iNet:getInterfaceHA(@optsSRV.3)
|
||||
//
|
||||
// Clear our local IP address
|
||||
//
|
||||
@ -239,26 +241,30 @@ portDHCP = iNet:openUDP(DHCP_CLIENT_PORT, @recvDHCP, 0)
|
||||
//
|
||||
// Service IP
|
||||
//
|
||||
while retry < 5 and stateDHCP <> DHCP_ACK
|
||||
retry = 0
|
||||
repeat
|
||||
//
|
||||
// Broadcast DHCP DISCOVER message
|
||||
//
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, t_dhcp)
|
||||
optsOP.2 = DHCP_DISCOVER
|
||||
optsIP:2 = 0
|
||||
optsIP:4 = 0
|
||||
optsSRV = 255
|
||||
DHCP.dhcp_secs.1 = retry
|
||||
iNet:sendUDP(portDHCP, 0, DHCP_SERVER_PORT, @DHCP, @optsSRV - @DHCP + 1)
|
||||
for timeout = 1 to 1000
|
||||
iNet:serviceIP()
|
||||
if stateDHCP == DHCP_ACK
|
||||
if optsOP.2 == DHCP_ACK
|
||||
break
|
||||
fin
|
||||
next
|
||||
DHCP.dhcp_secs.1 = DHCP.dhcp_secs.1 + 1
|
||||
retry = retry + 1
|
||||
loop
|
||||
until retry > 4 or optsOP.2 == DHCP_ACK
|
||||
iNet:closeUDP(portDHCP)
|
||||
iNet:setInterfaceIP(@localip, @localnet, @localgw)
|
||||
puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
|
||||
if localdns:0 | localdns:2
|
||||
iNet:setDNS(@localdns)
|
||||
puts(@dnsstr);putip(@localdns);putln
|
||||
fin
|
||||
puts(@dnsstr);putip(@localdns);putln
|
||||
|
||||
done
|
||||
|
@ -30,6 +30,8 @@ struc t_inet
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
//
|
||||
// Predefine service routine
|
||||
@ -427,6 +429,42 @@ end
|
||||
def etherCloseTCP(wiz)
|
||||
end
|
||||
//
|
||||
// Update notify callback
|
||||
//
|
||||
def etherSetCallback(port, callback)
|
||||
if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify)
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_func = callback
|
||||
return 0
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
//
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Update notify param
|
||||
//
|
||||
def etherSetParam(port, param)
|
||||
if isuge(port, @portsUDP) and isult(port, @portsUDP + MAX_UDP_NOTIFIES * t_notify)
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
if port=>notify_port
|
||||
port=>notify_parm = param
|
||||
return 0
|
||||
fin
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
//
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Service incoming packets
|
||||
//
|
||||
def etherServiceIP
|
||||
@ -485,8 +523,6 @@ def etherServiceIP
|
||||
// What kind of IP protocol is it?
|
||||
//
|
||||
when iphdr->ip_proto
|
||||
is IP_PROTO_TCP
|
||||
break
|
||||
is IP_PROTO_UDP
|
||||
port = @portsUDP
|
||||
if port
|
||||
@ -500,6 +536,8 @@ def etherServiceIP
|
||||
next
|
||||
fin
|
||||
break
|
||||
is IP_PROTO_TCP
|
||||
break
|
||||
is IP_PROTO_ICMP
|
||||
//
|
||||
// Service ICMP packets
|
||||
@ -589,4 +627,6 @@ iNet:sendTCP = @etherSendTCP
|
||||
iNet:closeTCP = @etherCloseTCP
|
||||
iNet:setInterfaceIP = @setEtherIP
|
||||
iNet:getInterfaceHA = @getEtherHA
|
||||
iNet:setCallback = @etherSetCallback
|
||||
iNet:setParam = @etherSetParam
|
||||
done
|
||||
|
@ -26,6 +26,8 @@ struc t_inet
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
//
|
||||
// DNS message
|
||||
|
@ -29,6 +29,10 @@ struc t_inet
|
||||
word closeTCP
|
||||
word setInterfaceIP
|
||||
word getInterfaceHA
|
||||
word setDNS
|
||||
word resolveIP
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
//
|
||||
// Module don't free memory
|
||||
@ -100,8 +104,8 @@ const WIZ_RXMEM3 = $7800
|
||||
//
|
||||
// Wiznet indirect registers
|
||||
//
|
||||
byte slot, regidx, regdata
|
||||
word saveidx
|
||||
byte regidx, regdata
|
||||
word slot, saveidx
|
||||
//
|
||||
// Wiznet MAC address
|
||||
//
|
||||
@ -716,6 +720,38 @@ def wizCloseTCP(wiz)
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Update notify callback
|
||||
//
|
||||
def wizSetCallback(wiz, callback)
|
||||
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
wiz=>channel_recv_func = callback
|
||||
return 0
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
//
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Update notify param
|
||||
//
|
||||
def wizSetParam(wiz, param)
|
||||
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
|
||||
//
|
||||
// Update param on this port
|
||||
//
|
||||
wiz=>channel_recv_parm = param
|
||||
return 0
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
//
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Service incoming packets
|
||||
//
|
||||
def wizServiceIP
|
||||
@ -736,6 +772,34 @@ def wizServiceIP
|
||||
wizdata = wiz=>channel_rxmem
|
||||
sir = peekreg(wizregs + WIZ_SnIR)
|
||||
when wiz->channel_proto
|
||||
is WIZ_PROTO_UDP
|
||||
//putc('U');putb(sir)
|
||||
if sir & $04
|
||||
//putc('R')
|
||||
//
|
||||
// Receive UDP packet
|
||||
//
|
||||
rxlen = peekregw(wizregs + WIZ_SnRSR)
|
||||
rxrr = peekregw(wizregs + WIZ_SnRXRD)
|
||||
rxwr = rxrr & WIZ_RXMASK
|
||||
rxpkt = heapalloc(rxlen)
|
||||
if rxwr + rxlen >= WIZ_RXSIZE
|
||||
//putc('!')
|
||||
splitlen = WIZ_RXSIZE - rxwr
|
||||
peekregs(wizdata + rxwr, rxpkt, splitlen)
|
||||
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
|
||||
else
|
||||
peekregs(wizdata + rxwr, rxpkt, rxlen)
|
||||
fin
|
||||
//putc('=');putip(rxpkt);putc(' ');puti(rxlen)
|
||||
//putc('/');puti(swab(rxpkt=>6))
|
||||
//putc(' ');puth(rxrr);putc(' ');puth(rxwr);putln
|
||||
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
|
||||
pokereg(wizregs + WIZ_SnCR, $40) // RECV
|
||||
wiz=>channel_recv_func(rxpkt,swab(rxpkt=>4),rxpkt+8,rxlen-8,wiz=>channel_recv_parm)
|
||||
heaprelease(rxpkt)
|
||||
fin
|
||||
break
|
||||
is WIZ_PROTO_TCP
|
||||
if sir & $01
|
||||
//putc('C')
|
||||
@ -822,34 +886,6 @@ def wizServiceIP
|
||||
//
|
||||
//fin
|
||||
break
|
||||
is WIZ_PROTO_UDP
|
||||
//putc('U');putb(sir)
|
||||
if sir & $04
|
||||
//putc('R')
|
||||
//
|
||||
// Receive UDP packet
|
||||
//
|
||||
rxlen = peekregw(wizregs + WIZ_SnRSR)
|
||||
rxrr = peekregw(wizregs + WIZ_SnRXRD)
|
||||
rxwr = rxrr & WIZ_RXMASK
|
||||
rxpkt = heapalloc(rxlen)
|
||||
if rxwr + rxlen >= WIZ_RXSIZE
|
||||
//putc('!')
|
||||
splitlen = WIZ_RXSIZE - rxwr
|
||||
peekregs(wizdata + rxwr, rxpkt, splitlen)
|
||||
peekregs(wizdata, rxpkt + splitlen, rxlen - splitlen)
|
||||
else
|
||||
peekregs(wizdata + rxwr, rxpkt, rxlen)
|
||||
fin
|
||||
//putc('=');putip(rxpkt);putc(' ');puti(rxlen)
|
||||
//putc('/');puti(swab(rxpkt=>6))
|
||||
//putc(' ');puth(rxrr);putc(' ');puth(rxwr);putln
|
||||
pokeregw(wizregs + WIZ_SnRXRD, rxrr + rxlen)
|
||||
pokereg(wizregs + WIZ_SnCR, $40) // RECV
|
||||
wiz=>channel_recv_func(rxpkt,swab(rxpkt=>4),rxpkt+8,rxlen-8,wiz=>channel_recv_parm)
|
||||
heaprelease(rxpkt)
|
||||
fin
|
||||
break
|
||||
otherwise
|
||||
wend
|
||||
pokereg(wiz=>channel_regs + WIZ_SnIR, sir) // Clear SnIR
|
||||
@ -895,7 +931,7 @@ end
|
||||
//
|
||||
// Identify Uthernet II card and initialize
|
||||
//
|
||||
for slot = $F0 downto $90 step $10
|
||||
for slot = $90 to $F0 step $10
|
||||
regdata = peekio(slot)
|
||||
if (regdata & $E4) == $00
|
||||
pokeio(slot, $03) // Try setting auto-increment indirect I/F
|
||||
@ -949,6 +985,8 @@ for slot = $F0 downto $90 step $10
|
||||
iNet:closeTCP = @wizCloseTCP
|
||||
iNet:setInterfaceIP = @setWizIP
|
||||
iNet:getInterfaceHA = @getWizHA
|
||||
iNet:setCallback = @wizSetCallback
|
||||
iNet:setParam = @wizSetParam
|
||||
return modkeep
|
||||
fin
|
||||
fin
|
||||
|
@ -29,6 +29,8 @@ struc t_inet
|
||||
word closeTCP
|
||||
word setInterfaceIP
|
||||
word getInterfaceHA
|
||||
word setCallback
|
||||
word setParam
|
||||
end
|
||||
//
|
||||
// Module don't free memory
|
||||
@ -100,8 +102,8 @@ const WIZ_RXMEM3 = $7800
|
||||
//
|
||||
// Wiznet indirect registers
|
||||
//
|
||||
byte slot, regidx, regdata
|
||||
word saveidx
|
||||
byte regidx, regdata
|
||||
word slot, saveidx
|
||||
//
|
||||
// Wiznet MAC address
|
||||
//
|
||||
@ -397,25 +399,25 @@ def peekreg(reg)
|
||||
return _peekio()
|
||||
end
|
||||
def pokeregs(reg, buf, len)
|
||||
_pokeiow(reg)
|
||||
return pokedata(buf, len)
|
||||
// word i
|
||||
// len = len - 1
|
||||
// for i = 0 to len
|
||||
// _pokeiow(reg + i)
|
||||
// _pokeio(buf->[i])
|
||||
// next
|
||||
// _pokeiow(reg)
|
||||
// return pokedata(buf, len)
|
||||
word i
|
||||
len = len - 1
|
||||
for i = 0 to len
|
||||
_pokeiow(reg + i)
|
||||
_pokeio(buf->[i])
|
||||
next
|
||||
end
|
||||
def peekregs(reg, buf, len)
|
||||
_pokeiow(reg)
|
||||
return peekdata(buf, len)
|
||||
// _pokeiow(reg)
|
||||
// return peekdata(buf, len)
|
||||
// There is an issue missing data on back-to-back reads
|
||||
// word i
|
||||
// len = len - 1
|
||||
// for i = 0 to len
|
||||
// _pokeiow(reg + i)
|
||||
// buf->[i] = _peekio()
|
||||
// next
|
||||
word i
|
||||
len = len - 1
|
||||
for i = 0 to len
|
||||
_pokeiow(reg + i)
|
||||
buf->[i] = _peekio()
|
||||
next
|
||||
end
|
||||
def pokeregw(reg, dataw)
|
||||
_pokeiow(reg)
|
||||
@ -729,6 +731,38 @@ def wizCloseTCP(wiz)
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Update notify callback
|
||||
//
|
||||
def wizSetCallback(wiz, callback)
|
||||
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
|
||||
//
|
||||
// Update callback on this port
|
||||
//
|
||||
wiz=>channel_recv_func = callback
|
||||
return 0
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
//
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Update notify param
|
||||
//
|
||||
def wizSetParam(wiz, param)
|
||||
if wiz->channel_proto == WIZ_PROTO_UDP or wiz->channel_proto == WIZ_PROTO_TCP
|
||||
//
|
||||
// Update param on this port
|
||||
//
|
||||
wiz=>channel_recv_parm = param
|
||||
return 0
|
||||
fin
|
||||
//
|
||||
// Invalid port
|
||||
//
|
||||
return -1
|
||||
end
|
||||
//
|
||||
// Service incoming packets
|
||||
//
|
||||
def wizServiceIP
|
||||
@ -908,7 +942,7 @@ end
|
||||
//
|
||||
// Identify Wiznet card and initialize
|
||||
//
|
||||
for slot = $F0 downto $90 step $10
|
||||
for slot = $90 to $F0 step $10
|
||||
regdata = peekio(slot)
|
||||
if (regdata & $E4) == $00
|
||||
pokeio(slot, $03) // Try setting auto-increment indirect I/F
|
||||
@ -962,6 +996,8 @@ for slot = $F0 downto $90 step $10
|
||||
iNet:closeTCP = @wizCloseTCP
|
||||
iNet:setInterfaceIP = @setWizIP
|
||||
iNet:getInterfaceHA = @getWizHA
|
||||
iNet:setCallback = @wizSetCallback
|
||||
iNet:setParam = @wizSetParam
|
||||
return modkeep
|
||||
fin
|
||||
fin
|
||||
|
Loading…
x
Reference in New Issue
Block a user