1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2024-09-30 23:54:41 +00:00

Working DNS resolution

This commit is contained in:
dschmenk 2015-10-31 17:01:01 -07:00
parent ce7ae5df49
commit ff1fb15531
2 changed files with 177 additions and 27 deletions

View File

@ -255,7 +255,9 @@ loop
iNet:closeUDP(portDHCP)
iNet:setInterfaceIP(@localip, @localnet, @localgw)
puts(@boundstr);putip(@localip);putc('/');putip(@localnet);putln
iNet:setDNS(@localdns)
if localdns:0 | localdns:2
iNet:setDNS(@localdns)
fin
puts(@dnsstr);putip(@localdns);putln
done

View File

@ -28,6 +28,17 @@ struc t_inet
word resolveIP
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.
//
export byte[t_inet] iNet
@ -39,35 +50,56 @@ byte = "UTHERNET"
byte = ""
word driver = @netDrivers
//
// DNS address
// DNS address (default to Google DNS)
//
byte[4] dns
export def iNetInit
//
// Look for net hardware
//
while ^driver
//puts(driver);putln
if modexec(driver) >= 0
break
fin
driver = driver + ^driver + 1
loop
if !^driver
return 0
fin
//
// Get an IP address
//
modexec("DHCP")
return @iNet
end
byte[4] dns = 8,8,8,8
const DNS_QUERY = 1
const DNS_ANSWER = 2
byte stateDNS
def iNetSetDNS(ipptr)
return memcpy(@dns, ipptr, 4)
end
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
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 parseIP(ipstr, ipaddr)
byte i
word endstr
@ -86,21 +118,137 @@ def parseIP(ipstr, ipaddr)
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 = q - 1
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 = r - 1
loop
fin
stateDNS = DNS_ANSWER
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 = heapmark // 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
heapalloc(msglen)
//
// 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 1
return ipaddr=>0 <> 0 or ipaddr=>2 <> 0
end
export def iNetInit
//
// Look for net hardware
//
while ^driver
//puts(driver);putln
if modexec(driver) >= 0
break
fin
driver = driver + ^driver + 1
loop
if !^driver
return 0
fin
//
// Get an IP address
//
modexec("DHCP")
iNet:resolveIP = @iNetResolve
return @iNet
end
//
// Fill iNet
// Fill iNet class
//
iNet:initIP = @iNetInit
iNet:setDNS = @iNetSetDNS
iNet:resolveIP = @iNetResolve
done