1
0
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:
dschmenk 2015-11-10 12:41:22 -08:00
parent 501964d61c
commit 8933148bca
6 changed files with 203 additions and 81 deletions

BIN
HTTPD.PO

Binary file not shown.

View File

@ -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

View File

@ -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

View File

@ -26,6 +26,8 @@ struc t_inet
word getInterfaceHA
word setDNS
word resolveIP
word setCallback
word setParam
end
//
// DNS message

View File

@ -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

View File

@ -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