mirror of
https://github.com/dschmenk/PLASMA.git
synced 2026-04-19 09:23:06 +00:00
231 lines
5.7 KiB
Plaintext
231 lines
5.7 KiB
Plaintext
//
|
|
// DHCP
|
|
//
|
|
include "inc/cmdsys.plh"
|
|
include "inc/inet.plh"
|
|
//
|
|
// Needed to init subnet
|
|
//
|
|
const IP_BROADCAST = $FFFF
|
|
const IP4ADR_SIZE = 4
|
|
//
|
|
// DHCP message
|
|
//
|
|
struc t_dhcp
|
|
byte dhcp_op
|
|
byte dhcp_htype
|
|
byte dhcp_hlen
|
|
byte dhcp_hops
|
|
byte[4] dhcp_xid
|
|
word dhcp_secs
|
|
word dhcp_flags
|
|
byte[4] dhcp_clientip
|
|
byte[4] dhcp_yourip
|
|
byte[4] dhcp_serverip
|
|
byte[4] dhcp_gatewayip
|
|
byte[16] dhcp_clientha
|
|
byte[192] dhcp_bootp
|
|
byte[4] dhcp_magic
|
|
byte[60] dhcp_opts
|
|
end
|
|
//
|
|
// DHCP messages
|
|
//
|
|
const DHCP_DISCOVER = $01
|
|
const DHCP_OFFER = $02
|
|
const DHCP_REQUEST = $03
|
|
const DHCP_DECLINE = $04
|
|
const DHCP_ACK = $05
|
|
const DHCP_NACK = $06
|
|
const DHCP_RELEASE = $07
|
|
//
|
|
// Track DHCP progress
|
|
//
|
|
byte retry
|
|
word timeout
|
|
//
|
|
// DHCP ports
|
|
//
|
|
const DHCP_CLIENT_PORT = 68
|
|
const DHCP_SERVER_PORT = 67
|
|
word portDHCP
|
|
byte[4] zeros
|
|
byte[4] ones = $FF, $FF, $FF, $FF
|
|
//
|
|
// Default static net IP addresses
|
|
//
|
|
byte localdns = 8,8,8,8
|
|
byte localgw = 192,168,1,1
|
|
byte localip = 192,168,1,10
|
|
byte localnet = 255,255,255,0
|
|
//
|
|
// Pre-configured DHCP packet
|
|
//
|
|
byte DHCP = $01// OP = BOOT
|
|
byte = $01 // HTYPE = ETHERNET
|
|
byte = $06 // HLEN = 6
|
|
byte = $00 // HOPS
|
|
byte[4] = $01,$02,$03,$04 // TRANSACTION ID
|
|
word = $0000 // SECONDS
|
|
word = 0 // FLAGS
|
|
byte[4] = 0 // CLIENT IP
|
|
byte[4] = 0 // YOUR IP
|
|
byte[4] = 0 // SERVER IP
|
|
byte[4] = 0 // GATEWAY IP
|
|
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 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 boundstr = "Apple II bound to:\n"
|
|
//byte dnsstr = "DNS: "
|
|
//def putb(hexb)
|
|
// return call($FDDA, hexb, 0, 0, 0)
|
|
//end
|
|
//def puth(hex)
|
|
// return call($F941, hex >> 8, hex, 0, 0)
|
|
//end
|
|
//def putip(ipptr)
|
|
// byte i
|
|
//
|
|
// for i = 0 to 2
|
|
// puti(ipptr->[i]); putc('.')
|
|
// next
|
|
// puti(ipptr->[i])
|
|
//end
|
|
//def dumpbytes(buf, len)
|
|
// word i
|
|
//
|
|
// for i = 0 to len - 1
|
|
// putb(buf->[i])
|
|
// if i & 15 == 15
|
|
// putln
|
|
// else
|
|
// putc(' ')
|
|
// fin
|
|
// next
|
|
//end
|
|
//def dumpdhcp(pkt)
|
|
// putb(pkt->dhcp_op);putln
|
|
// putb(pkt->dhcp_htype);putln
|
|
// putb(pkt->dhcp_hlen);putln
|
|
// putb(pkt->dhcp_hops);putln
|
|
// dumpbytes(@pkt->dhcp_xid, 4);putln
|
|
// putip(@pkt->dhcp_clientip);putln
|
|
// putip(@pkt->dhcp_yourip);putln
|
|
// putip(@pkt->dhcp_serverip);putln
|
|
// putip(@pkt->dhcp_gatewayip);putln
|
|
// dumpbytes(@pkt->dhcp_opts, 48);putln
|
|
//end
|
|
def parseopts(opts, match)
|
|
byte i
|
|
|
|
i = 0
|
|
while opts->[i] <> $FF and i < 64
|
|
while !opts->[i] and i < 64
|
|
i = i + 1
|
|
loop
|
|
if opts->[i] == match
|
|
return i
|
|
fin
|
|
i = i + opts->[i + 1] + 2
|
|
loop
|
|
return -1
|
|
end
|
|
def recvDHCP(remip, remport, pkt, len, param)
|
|
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
|
|
//
|
|
// Copy offer parameters to request
|
|
//
|
|
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
|
|
optsOP.2 = DHCP_ACK
|
|
//
|
|
// Copy parameters to working copy
|
|
//
|
|
memcpy(@localip, @pkt->dhcp_yourip, IP4ADR_SIZE)
|
|
maskopts = parseopts(@pkt->dhcp_opts, 1) + 2
|
|
if maskopts >= 0
|
|
memcpy(@localnet, @pkt->dhcp_opts.[maskopts], IP4ADR_SIZE)
|
|
fin
|
|
gwopts = parseopts(@pkt->dhcp_opts, 3) + 2
|
|
if gwopts >= 0
|
|
memcpy(@localgw, @pkt->dhcp_opts.[gwopts], IP4ADR_SIZE)
|
|
fin
|
|
dnsopts = parseopts(@pkt->dhcp_opts, 6) + 2
|
|
if dnsopts >= 0
|
|
memcpy(@localdns, @pkt->dhcp_opts.[dnsopts], IP4ADR_SIZE)
|
|
fin
|
|
break
|
|
otherwise
|
|
//dumpdhcp(pkt)
|
|
wend
|
|
fin
|
|
return 0
|
|
end
|
|
//
|
|
// Get the local hardware address into the DHCP packet
|
|
//
|
|
iNet:getInterfaceHA(@DHCP.dhcp_clientha)
|
|
iNet:getInterfaceHA(@optsCID.3)
|
|
//
|
|
// Clear our local IP address
|
|
//
|
|
iNet:setInterfaceIP(@zeros,@ones, @zeros)
|
|
//
|
|
// Prepare to receive DHCP packets from a server
|
|
//
|
|
portDHCP = iNet:openUDP(DHCP_CLIENT_PORT, @recvDHCP, 0)
|
|
//
|
|
// Service IP
|
|
//
|
|
retry = 0
|
|
repeat
|
|
//
|
|
// Broadcast DHCP DISCOVER message
|
|
//
|
|
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 = 0 to 1000
|
|
iNet:serviceIP()
|
|
if optsOP.2 == DHCP_ACK
|
|
break
|
|
fin
|
|
next
|
|
retry = retry + 1
|
|
until retry > 4 or optsOP.2 == DHCP_ACK
|
|
iNet:closeUDP(portDHCP)
|
|
iNet:setInterfaceIP(@localip, @localnet, @localgw)
|
|
//puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
|
|
iNet:setDNS(@localdns)
|
|
//puts(@dnsstr);putip(@localdns);putln
|
|
done
|