A2osX/LIB/LIBTCPIP.S.DNS.txt
2018-11-17 18:17:13 +01:00

552 lines
9.9 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
PREFIX
AUTO 4,1
.LIST OFF
*/--------------------------------------
* # DNS.Clear
* Clear DNS Cache
* **In:**
* ## RETURN VALUE
*\--------------------------------------
DNS.Clear ldx #K.DNSCACHE.SIZE*S.DNSCACHE
.1 stz DNS.CACHE-1,x
dex
bne .1
clc
rts
*/--------------------------------------
* # DNS.Query
* Query DNS for specified host
* **In:**
* PUSHW = PTR to IP to fill with cached data
* PUSHW = hostname PTR to PSTR
* ## RETURN VALUE
* CC: hit: IP filled with address
* CS: missed
*\--------------------------------------
DNS.Query >PULLW ZPPtrDNS Get host string
>PULLW ZPPtrIP Get IP address to fill
DNS.Query.I jsr DNS.FIND.BY.NAME
bcs DNS.REQUEST
lda (ZPCachePtr) get status...
bpl .9 Pending...
lda ZPCachePtr
clc
adc #S.DNSCACHE.IP
sta ZPCachePtr
bcc .1
inc ZPCachePtr+1
.1 ldy #3
.2 lda (ZPCachePtr),y
sta (ZPPtrIP),y
dey
bpl .2
clc
rts
.9 lda #ERR.DNS.PENDING
sec
rts
*--------------------------------------
DNS.REQUEST lda hDNSSocket
beq .99
jsr DNS.CSTR2DNS Y=DNS string len+0
bcs .99
iny
lda /S.DNS.QTYPE.A
sta DNS.MSG,y
iny
lda #S.DNS.QTYPE.A
sta DNS.MSG,y
iny
lda /S.DNS.QCLASS.IN
sta DNS.MSG,y
iny
lda #S.DNS.QCLASS.IN
sta DNS.MSG,y
iny
tya
sta DNS.MSG.LEN
lda #0
sta DNS.MSG.LEN+1
>LDYA A2osX.RANDOM16
>STYA DNS.MSG.ID
>STYA DNS.TmpCache+S.DNSCACHE.ID
lda #K.DNS.PENDING.TTL
sta DNS.TmpCache+S.DNSCACHE.TTL
stz DNS.TmpCache+S.DNSCACHE.TTL+1
stz DNS.TmpCache+S.DNSCACHE.TTL+2
stz DNS.TmpCache+S.DNSCACHE.TTL+3
lda #S.DNSCACHE.STATUS.PENDING
jsr DNS.ADD.I
bcs .9
jsr DNS.REQUEST.SEND
bcs .99
lda #ERR.DNS.PENDING
sec
rts
.99 lda #ERR.DNS.ERROR
.9 sec
rts
*--------------------------------------
DNS.REQUEST.SEND
>LDYAI UDP.PORT.DNS
>STYA SA.REMOTE+S.SOCKADDR.PORT
ldy #3
.1 lda IPCFG+S.IPCFG.DNS1,y
sta SA.REMOTE+S.SOCKADDR.ADDR,y
dey
bpl .1
jsr .4
ldy #3
.2 lda IPCFG+S.IPCFG.DNS2,y
beq .8
sta SA.REMOTE+S.SOCKADDR.ADDR,y
dey
bpl .2
.4 >PUSHW L.SA.REMOTE
>PUSHW DNS.MSG.LEN
>PUSHW L.DNS.MSG
lda hDNSSocket
jmp SKT.SendTo
.8 clc
rts
*--------------------------------------
DNS.CSTR2DNS lda (ZPPtrDNS)
beq .9
>LDYA ZPPtrDNS
>SYSCALL strlen
tax
bne .9
cpy #K.DNS.MAXLEN-1
bcs .9
lda #0 Ending 0
sta DNS.MSG.NAME+1,y
phy save len for later
ldx #0
dey
.1 lda (ZPPtrDNS),y
and #$7f
cmp #'.'
beq .2
cmp #'A'
bcc .10
cmp #'Z'+1
bcs .10
adc #$20
.10 inx
bra .3
.2 txa
ldx #0
.3 sta DNS.MSG.NAME+1,y
dey
bpl .1
stx DNS.MSG.NAME
pla Get back Len
sec +1
adc #S.DNS-S.UDP compute offset next to NAME
tay
* clc
rts
.9 sec
rts
*/--------------------------------------
* # DNS.Add
* Add a static DNS record
* **In:**
* PUSHW = PTR to IP
* PUSHW = hostname CSTR to Add
*\--------------------------------------
DNS.Add >PULLW ZPPtrDNS Get host string
>PULLW ZPPtrIP Get host IP address
ldy #3
.1 lda (ZPPtrIP),y
sta DNS.TmpCache+S.DNSCACHE.IP,y
dey
bpl .1
stz DNS.TmpCache+S.DNSCACHE.TTL
stz DNS.TmpCache+S.DNSCACHE.TTL+1
stz DNS.TmpCache+S.DNSCACHE.TTL+2
stz DNS.TmpCache+S.DNSCACHE.TTL+3
lda #S.DNSCACHE.STATUS.RESOLVED+S.DNSCACHE.STATUS.STATIC
DNS.ADD.I sta DNS.TmpCache
jsr DNS.FIND.BY.NAME
bcc .2 Found, go update...
jsr DNS.FIND.FREE
>LDYA ZPPtrDNS
>SYSCALL newstr
bcs .9
txa
ldy #S.DNSCACHE.hNAME
sta (ZPCachePtr),y
.2 lda DNS.TmpCache
sta (ZPCachePtr)
ldy #S.DNSCACHE.ID
.3 lda DNS.TmpCache,y
sta (ZPCachePtr),y
iny
cpy #S.DNSCACHE
bne .3
clc
.9 rts
*/--------------------------------------
* # DNS.GetCAche
* Return a Ptr to DNS Cache Table
* **In:**
* ## RETURN VALUE
* Y,A = PTR to DNS.CACHE
*\--------------------------------------
DNS.GetCAche >LDYA L.DNS.CACHE
clc
rts
*--------------------------------------
DNS.FIND.BY.NAME
>LDYA L.DNS.CACHE
>STYA ZPCachePtr
lda #K.DNSCACHE.SIZE
sta TmpOffset
.1 lda (ZPCachePtr)
beq .6 empty DNS cache entry?
>PUSHW ZPPtrDNS
ldy #S.DNSCACHE.hNAME
lda (ZPCachePtr),y
>SYSCALL GetMemPtr
>SYSCALL StrCaseCmp
bcc .8
.6 lda ZPCachePtr
clc
adc #S.DNSCACHE
sta ZPCachePtr
bcc .7
inc ZPCachePtr+1
.7 dec TmpOffset
bne .1
sec
.8 rts
*--------------------------------------
DNS.UPDATE.BY.ID
>LDYA L.DNS.CACHE
>STYA ZPCachePtr
ldx #K.DNSCACHE.SIZE
.1 lda (ZPCachePtr)
beq .6 empty DNS cache entry?
bmi .6 resolved ?
ldy #S.DNSCACHE.ID
lda (ZPCachePtr),y
cmp DNS.TmpCache+S.DNSCACHE.ID
bne .6
iny
lda (ZPCachePtr),y
cmp DNS.TmpCache+S.DNSCACHE.ID+1
bne .6
lda #S.DNSCACHE.STATUS.RESOLVED
sta (ZPCachePtr)
ldy #S.DNSCACHE.TTL
.2 lda DNS.TmpCache,y
sta (ZPCachePtr),y
iny
cpy #S.DNSCACHE
bne .2
clc
rts
.6 lda ZPCachePtr
clc
adc #S.DNSCACHE
sta ZPCachePtr
bcc .7
inc ZPCachePtr+1
.7 dex
bne .1
sec
rts
*--------------------------------------
DNS.FIND.FREE >LDYA L.DNS.CACHE
>STYA ZPCachePtr
lda #K.DNSCACHE.SIZE
sta TmpOffset
lda #$ff
sta TmpDWord
sta TmpDWord+1
sta TmpDWord+2
sta TmpDWord+3
.1 lda (ZPCachePtr)
beq .8 empty DNS cache entry?
bit #S.DNSCACHE.STATUS.STATIC+S.DNSCACHE.STATUS.PENDING
bne .6 Static/Pending.....skip
ldy #S.DNSCACHE.TTL
ldx #3
sec
.2 lda TmpDWord,x is saved TTL greater then actual TTL?
sbc (ZPCachePtr),y
iny
dex
bpl .2
bcc .6 no,
ldy #S.DNSCACHE.TTL
ldx #3
.3 lda (ZPCachePtr),y Save new lowest TTL
sta TmpDWord,x
iny
dex
bpl .3
>LDYA ZPCachePtr
>STYA ZPTmpPtr1 save lowest TTL slot ...
.6 lda ZPCachePtr
clc
adc #S.DNSCACHE
sta ZPCachePtr
bcc .7
inc ZPCachePtr+1
.7 dec TmpOffset
bne .1 no empty slot found, discard lowest TTL
>LDYA ZPTmpPtr1
>STYA ZPCachePtr
jsr DNS.FREE
.8 clc
rts
*--------------------------------------
DNS.EXPIRE >LDYA L.DNS.CACHE
>STYA ZPCachePtr
lda #K.DNSCACHE.SIZE
sta TmpOffset
.1 lda (ZPCachePtr)
beq .7 empty DNS cache entry?
bit #S.DNSCACHE.STATUS.STATIC
bne .7
ldy #S.DNSCACHE.TTL
ldx #4
clc
.2 lda (ZPCachePtr),y
sbc #0
sta (ZPCachePtr),y
iny
dex
bne .2
bcs .7
jsr DNS.FREE
.7 lda ZPCachePtr
clc
adc #S.DNSCACHE
sta ZPCachePtr
bcc .8
inc ZPCachePtr+1
.8 dec TmpOffset
bne .1
clc
rts
*--------------------------------------
DNS.FREE ldy #S.DNSCACHE.hNAME
lda (ZPCachePtr),y
beq .1
>SYSCALL FreeMem
.1 lda #0
sta (ZPCachePtr)
rts
*--------------------------------------
DNS.POLL lda hDNSSocket
beq .8
jsr SKT.Recv
bcs .8
jsr DNS.DecodeMsg
.8 clc
rts
*--------------------------------------
DNS.DecodeMsg sta hFrameIn
>SYSCALL GetMemPtr
>STYA ZPFrameInPtr
ldy #S.DNS.F
lda (ZPFrameInPtr),y
and /S.DNS.F.QR
beq .9
ldy #S.DNS.ID
lda (ZPFrameInPtr),y
sta DNS.TmpCache+S.DNSCACHE.ID
iny
lda (ZPFrameInPtr),y
sta DNS.TmpCache+S.DNSCACHE.ID+1
ldy #S.DNS.ANCOUNT+1
lda (ZPFrameInPtr),y
beq .9
pha save Answer count...
ldy #S.DNS.QDCOUNT+1
lda (ZPFrameInPtr),y
ldy #S.DNS Point to DATA
tax
beq .3 no QUERY to skip
.1 lda (ZPFrameInPtr),y
beq .2
bpl .11 Pointer ?
iny yes, skip 2 bytes
iny
bra .2
.11 tya
sec
adc (ZPFrameInPtr),y Skip LEN+1 bytes
tay
bra .1
.2 iny
iny
iny Skip QTYPE & QCLASS
iny
iny next pos
.21 dex skip another QUERY ?
bne .1
plx get back answer count
.3 lda (ZPFrameInPtr),y
beq .32
bpl .31 Pointer ?
iny yes, skip 2 bytes
iny
bra .32
.31 tya
sec
adc (ZPFrameInPtr),y Skip LEN+1 bytes
tay
bra .3
.32 iny skip S.DNS.QTYPE HIGH
lda (ZPFrameInPtr),y
cmp #S.DNS.QTYPE.A
beq .40
tya
clc
adc #7 skip CLASS,TTL+DATALENHIGH
tay
sec skip DATALENLO
adc (ZPFrameInPtr),y add DATALEN
tay
dex
bne .3
bra .9
.40 iny skip QCLASS
iny
iny next pos
ldx #3
.4 lda (ZPFrameInPtr),y
sta DNS.TmpCache+S.DNSCACHE.TTL,x
iny
dex
bpl .4
iny skip DATALEN
iny
ldx #0
.5 lda (ZPFrameInPtr),y
sta DNS.TmpCache+S.DNSCACHE.IP,x
iny
inx
cpx #4
bne .5
jsr DNS.UPDATE.BY.ID
.9 lda hFrameIn
>SYSCALL FreeMem
clc
rts
*--------------------------------------
MAN
SAVE USR/SRC/LIB/LIBTCPIP.S.DNS
LOAD USR/SRC/LIB/LIBTCPIP.S
ASM