mirror of
https://github.com/dschmenk/PLASMA.git
synced 2026-03-12 01:41:40 +00:00
227 lines
5.1 KiB
Plaintext
227 lines
5.1 KiB
Plaintext
include "inc/cmdsys.plh"
|
|
//
|
|
// iNet API - must match inet.plh
|
|
//
|
|
struc t_inet
|
|
word initIP
|
|
word serviceIP
|
|
word openUDP
|
|
word sendUDP
|
|
word closeUDP
|
|
word listenTCP
|
|
word connectTCP
|
|
word sendTCP
|
|
word closeTCP
|
|
word setInterfaceIP
|
|
word getInterfaceHA
|
|
word setDNS
|
|
word resolveIP
|
|
word setCallback
|
|
word setParam
|
|
end
|
|
//
|
|
// DNS message
|
|
//
|
|
struc t_dnshdr
|
|
word dnsID
|
|
word dnsCode
|
|
word dnsQdCount
|
|
word dnsAnCount
|
|
word dnsNsCount
|
|
word dnsArCount
|
|
end
|
|
//
|
|
// External interface to net class. Must be first.
|
|
//
|
|
res[t_inet] iNet
|
|
//
|
|
// List of loadable network device drivers
|
|
//
|
|
byte netDrivers = "UTHERNET2"
|
|
byte = "UTHERNET"
|
|
byte = ""
|
|
word driver = @netDrivers
|
|
//
|
|
// DNS address (default to Google DNS)
|
|
//
|
|
byte[4] dns = 8,8,8,8
|
|
const DNS_QUERY = 1
|
|
const DNS_ANSWER = 2
|
|
byte stateDNS
|
|
|
|
def iNetSetDNS(ipptr)
|
|
memcpy(@dns, ipptr, 4)
|
|
return 0
|
|
end
|
|
|
|
//def dumpbytes(buf, len)
|
|
// word i
|
|
//
|
|
// for i = 0 to len - 1
|
|
// putb(buf->[i])
|
|
// if i & 7 == 7
|
|
// putln
|
|
// else
|
|
// putc(' ')
|
|
// fin
|
|
// next
|
|
//end
|
|
//def putip(ipptr)
|
|
// byte i
|
|
//
|
|
// for i = 0 to 2
|
|
// puti(ipptr->[i]); putc('.')
|
|
// next
|
|
// return puti(ipptr->[i])
|
|
//end
|
|
|
|
def parseIP(ipstr, ipaddr)
|
|
byte i
|
|
word endstr
|
|
|
|
endstr = ipstr + ^ipstr
|
|
for i = 0 to 3
|
|
ipstr = ipstr + 1
|
|
while ^ipstr >= '0' and ^ipstr <= '9' and ipstr <= endstr
|
|
ipaddr->[i] = ipaddr->[i] * 10 + ^ipstr - '0'
|
|
ipstr = ipstr + 1
|
|
loop
|
|
if ^ipstr <> '.' and ipstr < endstr
|
|
return 0
|
|
fin
|
|
next
|
|
return i == 3
|
|
end
|
|
|
|
def parseDomain(domstr, msgptr)
|
|
byte i, l
|
|
|
|
l = 0
|
|
for i = 1 to ^domstr
|
|
if domstr->[i] == '.'
|
|
msgptr->[l] = i - l - 1
|
|
l = i
|
|
else
|
|
msgptr->[i] = domstr->[i]
|
|
fin
|
|
next
|
|
msgptr->[l] = i - l - 1
|
|
msgptr = msgptr + i
|
|
^msgptr = 0 // Terminate label list
|
|
return msgptr + 1
|
|
end
|
|
|
|
def recvDNS(remip, remport, pkt, len, ipaddr)
|
|
byte q, r
|
|
word resptr
|
|
|
|
if pkt=>dnsID == $BEEF
|
|
q = pkt->dnsQdCount.1
|
|
r = pkt->dnsAnCount.1 + pkt->dnsNsCount.1 + pkt->dnsArCount.1
|
|
resptr = pkt + t_dnshdr
|
|
while q
|
|
while ^resptr
|
|
//puts(resptr); putc('.')
|
|
resptr = resptr + ^resptr + 1
|
|
loop
|
|
resptr = resptr + 1
|
|
//putln; dumpbytes(resptr, 4); putln
|
|
resptr = resptr + 4
|
|
q--
|
|
loop
|
|
while r
|
|
//dumpbytes(resptr, 40); putln
|
|
if ^resptr & $C0 == $C0
|
|
resptr = resptr + 2
|
|
else
|
|
while ^resptr
|
|
//puts(resptr); putc('.')
|
|
resptr = resptr + ^resptr + 1
|
|
loop
|
|
resptr = resptr + 1
|
|
fin
|
|
if resptr->1 == 1 and resptr->3 == 1 and resptr->9 == 4
|
|
ipaddr=>0 = resptr=>10
|
|
ipaddr=>2 = resptr=>12
|
|
fin
|
|
//putln; dumpbytes(resptr, 10); putc(':'); putln
|
|
resptr = resptr + 8
|
|
//dumpbytes(resptr + 2, ^(resptr + 1))
|
|
resptr = resptr + 2 + ^(resptr + 1); putln
|
|
r--
|
|
loop
|
|
fin
|
|
stateDNS = DNS_ANSWER
|
|
return 0
|
|
end
|
|
|
|
def iNetResolve(namestr, ipaddr)
|
|
word dnspkt, msgptr, msglen
|
|
word portDNS, timeout
|
|
|
|
ipaddr=>0 = 0
|
|
ipaddr=>2 = 0
|
|
if not parseIP(namestr, ipaddr)
|
|
//
|
|
// Query Domain Name Server for address
|
|
//
|
|
dnspkt = heapalloc(^namestr + t_dnshdr + 8) // Use heap as working DNS query packet
|
|
msgptr = dnspkt
|
|
msgptr=>dnsID = $BEEF
|
|
msgptr=>dnsCode = $0001 // RD (Recursion Desired)
|
|
msgptr=>dnsQdCount = $0100 // BE count = 1
|
|
msgptr=>dnsAnCount = 0
|
|
msgptr=>dnsNsCount = 0
|
|
msgptr=>dnsArCount = 0
|
|
msgptr = parseDomain(namestr, msgptr + t_dnshdr)
|
|
msgptr=>0 = $0100 // BE TYPE = Address
|
|
msgptr=>2 = $0100 // BE CLASS = Internet
|
|
msglen = msgptr - dnspkt + 4
|
|
//
|
|
// Prepare to receive DNS answer from server
|
|
//
|
|
portDNS = iNet:openUDP(3999, @recvDNS, ipaddr)
|
|
//
|
|
// Service IP
|
|
//
|
|
stateDNS = DNS_QUERY
|
|
iNet:sendUDP(portDNS, @dns, 53, dnspkt, msglen)
|
|
for timeout = 1 to 1000
|
|
iNet:serviceIP()
|
|
if stateDNS == DNS_ANSWER
|
|
break
|
|
fin
|
|
next
|
|
iNet:closeUDP(portDNS)
|
|
heaprelease(dnspkt)
|
|
fin
|
|
return ipaddr=>0 <> 0 or ipaddr=>2 <> 0
|
|
end
|
|
//
|
|
// Initialze network stack
|
|
//
|
|
def iNetInit
|
|
//
|
|
// Look for net hardware
|
|
//
|
|
while ^driver
|
|
if cmdsys:modexec(driver) >= 0
|
|
//
|
|
// Get an IP address
|
|
//
|
|
cmdsys:modexec("DHCP")
|
|
iNet:resolveIP = @iNetResolve
|
|
return @iNet
|
|
fin
|
|
driver = driver + ^driver + 1
|
|
loop
|
|
puts("No network adapters found.\n")
|
|
return NULL
|
|
end
|
|
//
|
|
// Fill iNet class
|
|
//
|
|
iNet:initIP = @iNetInit
|
|
iNet:setDNS = @iNetSetDNS
|
|
done
|