A2osX/LIB/LIBTCPIP.S.TCP.txt

598 lines
11 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.

PR#3
PREFIX /A2OSX.SRC
LOMEM $900
INC 1
AUTO 6
.LIST OFF
*--------------------------------------
TCP.IN jsr IP.FillSKT.TemplateSrcDst
ldy #S.TCP.SRCPORT
lda (ZPFrameInPtr),y
sta SKT.Template+S.SOCKET.DST.PORT+1
iny
lda (ZPFrameInPtr),y
sta SKT.Template+S.SOCKET.DST.PORT
ldy #S.TCP.DSTPORT
lda (ZPFrameInPtr),y
sta SKT.Template+S.SOCKET.SRC.PORT+1
iny
lda (ZPFrameInPtr),y
sta SKT.Template+S.SOCKET.SRC.PORT
lda hSocketTable
>SYSCALL GetMemPtrA
>STYA ZPPtrSKT
ldx #0
.3 lda (ZPPtrSKT)
beq .7
cmp #S.SOCKET.SOCK.STREAM
bne .7
ldy #S.SOCKET.SRC.ADDR
.4 lda SKT.Template,y
cmp (ZPPtrSKT),y
bne .7 Not for this socket...
iny
cpy #S.SOCKET.SRC.PORT+2
bne .4
ldy #S.SOCKET.SO
lda (ZPPtrSKT),y
and #S.SOCKET.SO.ACCEPTCONN Listening socket?
beq .5 no, go check if Dst Match
ldy #S.TCP.OPTIONS yes, only accept SYN packet
lda (ZPFrameInPtr),y
cmp #S.TCP.OPTIONS.SYN SYN only, if SYN.ACK, pass to regular socket
beq TCP.IN.JMP.LISTEN
.5 ldy #S.SOCKET.DST.ADDR
.6 lda SKT.Template,y regular socket, check remote ADDR/PORT
cmp (ZPPtrSKT),y
bne .7
iny
cpy #S.SOCKET.DST.PORT+2
bne .6
ldy #S.TCP.OPTIONS
lda (ZPFrameInPtr),y
and #S.TCP.OPTIONS.RST RST ? go Kill this socket.
bne TCP.IN.RST
ldy #S.SOCKET.TCP.STATUS
lda (ZPPtrSKT),y
cmp #S.SOCKET.TCP.STATUS.TIMEWT
bcs *
asl
tax
jmp (L.TCP.IN.JMP,x)
.7 lda ZPPtrSKT
clc
adc #S.SOCKET
sta ZPPtrSKT
bcc .8
inc ZPPtrSKT+1
.8 inx
cpx #K.SKTTABLE.SIZE
bne .3
.9 clc Discard frame
rts
*--------------------------------------
TCP.IN.RST lda #0
sta (ZPPtrSKT)
clc
rts
*--------------------------------------
TCP.IN.JMP.LISTEN
lda #S.SOCKET.SOCK.STREAM
sta SKT.Template+S.SOCKET.SOCK
stz SKT.Template+S.SOCKET.SO
stz SKT.Template+S.SOCKET.TCP.STATUS
>PUSHW L.SKT.Template
jsr SKT.New.Listen
bcs .99
sty .1+1
sta .2+1
txa
jsr SKT.AddToQueueA
bcs .99 Queued successfully ?
.1 lda #$ff
sta ZPPtrSKT
.2 lda #$ff
sta ZPPtrSKT+1
ldy #S.TCP.SEQ.NUMBER+3
ldx #3
sec
.3 lda (ZPFrameInPtr),y Set ACK=SEQ+1 for new socket...
adc #0
sta SKT.TCBCache+S.TCB.ACKNUM,x
dey
dex
bpl .3
jsr SKT.StoreTCB
jsr ARP.AddFromFrameInPtr
jsr TCP.OUT.SYNACK
bcs .9
ldy #S.SOCKET.TCP.STATUS
lda #S.SOCKET.TCP.STATUS.SYNRCVD
sta (ZPPtrSKT),y
clc
rts
.9 lda #0 error
sta (ZPPtrSKT) clear this socket
lda #ERR.SKT.OOS
.99 rts
*--------------------------------------
TCP.IN.JMP.SYNSENT
ldy #S.TCP.OPTIONS SYN Send, only accept SYN.ACK packet, then Send ACK
lda (ZPFrameInPtr),y
cmp #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK
bne .8
jsr SKT.GetTCB
ldx #3
ldy #S.TCP.SEQ.NUMBER+3
sec
.1 lda SKT.TCBCache+S.TCB.ACKNUM,x
adc #0
sta SKT.TCBCache+S.TCB.ACKNUM,x
eor (ZPFrameInPtr),y
bne .8
dey
dex
bpl .1
ldy #S.SOCKET.TCP.OPTIONS
lda #S.TCP.OPTIONS.ACK
sta (ZPPtrSKT),y
jsr TCP.OUT.I
bcs .9
ldy #S.SOCKET.TCP.STATUS
lda #S.SOCKET.TCP.STATUS.ESTBLSH
sta (ZPPtrSKT),y
.8 clc
.9 rts
*--------------------------------------
TCP.IN.JMP.SYNRCVD
ldy #S.TCP.OPTIONS SYN Recieved, SYN.ACK Sent, only accept ACK packet
lda (ZPFrameInPtr),y
cmp #S.TCP.OPTIONS.ACK
bne .8
jsr SKT.GetTCB
ldx #3
ldy #S.TCP.ACK.NUMBER+3
sec
.1 lda SKT.TCBCache+S.TCB.SEQNUM,x
adc #0
sta SKT.TCBCache+S.TCB.SEQNUM,x
eor (ZPFrameInPtr),y
bne .8
dey
dex
bpl .1
jsr SKT.StoreTCB
ldy #S.SOCKET.TCP.STATUS
lda #S.SOCKET.TCP.STATUS.ESTBLSH
sta (ZPPtrSKT),y
.8 clc
rts
*--------------------------------------
TCP.IN.JMP.ESTBLSH
jsr SKT.GetTCB
ldy #S.TCP.OPTIONS
lda (ZPFrameInPtr),y
bit #S.TCP.OPTIONS.ACK Remote side ACKed data ?
beq .1
jsr SKT.AckDataToSktOut Yes, Discard sent data
.1 jsr TCP.IN.SetDataInPtrAndLen
lda ZPDataInLen Incoming Data in this frame ?
ora ZPDataInLen+1
beq .2 No data, ...
jsr SKT.AddDataToSktIn yes, queue data if there is room for....
.2 ldy #S.TCP.OPTIONS
lda (ZPFrameInPtr),y
bit #S.TCP.OPTIONS.FIN
beq .8
ldy #S.SOCKET.TCP.STATUS
lda #S.SOCKET.TCP.STATUS.CLWAIT
sta (ZPPtrSKT),y
.8 jmp TCP.OUT.I
.9 rts
*--------------------------------------
TCP.IN.JMP.CLWAIT
clc
rts
*--------------------------------------
TCP.IN.JMP.LASTACK
ldy #S.TCP.OPTIONS only accept ACK packet
lda (ZPFrameInPtr),y
cmp #S.TCP.OPTIONS.ACK
bne .8
ldy #S.SOCKET.SQ.hOutMem
lda (ZPPtrSKT),y
beq .1
>SYSCALL FreeMemA
.1 ldy #S.SOCKET.SQ.hInMem
lda (ZPPtrSKT),y
beq .2
>SYSCALL FreeMemA
.2 ldy #S.SOCKET.SQ.hTCB
lda (ZPPtrSKT),y
beq .3
>SYSCALL FreeMemA
.3 lda #0
sta (ZPPtrSKT)
.8 clc
rts
*--------------------------------------
TCP.IN.JMP.FINWT1
*--------------------------------------
TCP.IN.JMP.FINWT2
*--------------------------------------
TCP.IN.JMP.CLOSING
*--------------------------------------
TCP.IN.JMP.TIMEWT
*--------------------------------------
TCP.IN.JMP.CLOSED
clc
rts
*--------------------------------------
TCP.IN.SetDataInPtrAndLen
ldy #S.TCP.DATAOFFSET
lda (ZPFrameInPtr),y
and #$F0 Get TCP Header len in DWORD
lsr
lsr
* clc
adc #S.IP-2
sta TmpOffset
lda #0
adc /S.IP-2
sta TmpOffset+1 TmpOffset=Data Offset in Frame
lda ZPFrameInLen
sec
sbc TmpOffset
sta ZPDataInLen
lda ZPFrameInLen+1
sbc TmpOffset+1
sta ZPDataInLen+1
lda TmpOffset
clc
adc #2
sta TmpOffset
bcc .1
inc TmpOffset+1
clc
.1 lda ZPFrameInPtr
adc TmpOffset
sta ZPDataInPtr
lda ZPFrameInPtr+1
adc #0
sta ZPDataInPtr+1
rts
*--------------------------------------
TCP.OUT.SYN >LDYAI 0
jsr TCP.NewFrame
bcs .9
ldx #3
ldy #S.TCP.SEQ.NUMBER+3
.1 lda SKT.TCBCache+S.TCB.SEQNUM,x
sta (ZPFrameOutPtr),y
dey
dex
bpl .1
ldy #S.TCP.OPTIONS
lda #S.TCP.OPTIONS.SYN
sta (ZPFrameOutPtr),y
iny S.TCP.WINDOW
lda /K.TCP.WSIZE
sta (ZPFrameOutPtr),y
iny
lda #K.TCP.WSIZE
sta (ZPFrameOutPtr),y
jsr FRM.SendIP
bcs .9
ldy #S.SOCKET.TCP.OPTIONS
lda #0
sta (ZPPtrSKT),y
clc
.9 rts
*--------------------------------------
TCP.OUT.SYNACK >LDYAI 0
jsr TCP.NewFrame
bcs .9
ldx #7
ldy #S.TCP.SEQ.NUMBER+7
.1 lda SKT.TCBCache+S.TCB.SEQNUM,x
sta (ZPFrameOutPtr),y
dey
dex
bpl .1
ldy #S.TCP.OPTIONS
lda #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK
sta (ZPFrameOutPtr),y
iny S.TCP.WINDOW
lda /K.TCP.WSIZE
sta (ZPFrameOutPtr),y
iny
lda #K.TCP.WSIZE
sta (ZPFrameOutPtr),y
jsr FRM.SendIP
bcs .9
ldy #S.SOCKET.TCP.OPTIONS
lda #0
sta (ZPPtrSKT),y
clc
.9 rts
*--------------------------------------
TCP.OUT jsr SKT.GetTCB
TCP.OUT.I lda SKT.TCBCache+S.TCB.OUTUSED+1
ldy SKT.TCBCache+S.TCB.OUTUSED
bne .1
tax
bne .1 Y,A=0 : nothing to send
ldy #S.SOCKET.TCP.OPTIONS
lda (ZPPtrSKT),y
beq .88 No, data, no flag....exit
txa a least one flag to send
tay
bra .2 go send a O len frame
.1 cpy #K.TCP.MSS
pha
sbc /K.TCP.MSS OUTDATA > MSS ?
pla
bcs .2 no....get data len
>LDYAI K.TCP.MSS yes get only MSS
.2 jsr TCP.NewFrame
bcs .9
jsr SKT.GetDataFromSktOut
ldy #S.SOCKET.TCP.OPTIONS
lda (ZPPtrSKT),y
ldy #S.TCP.OPTIONS
sta (ZPFrameOutPtr),y
ldx #7
ldy #S.TCP.SEQ.NUMBER+7
.3 lda SKT.TCBCache+S.TCB.SEQNUM,x
sta (ZPFrameOutPtr),y
dey
dex
bpl .3
.7 jsr FRM.SendIP
bcs .9
ldy #S.SOCKET.TCP.OPTIONS
lda (ZPPtrSKT),y
bit #S.TCP.OPTIONS.FIN
beq .8
ldy #S.SOCKET.TCP.STATUS
lda #S.SOCKET.TCP.STATUS.FINWT1
sta (ZPPtrSKT),y
.8 ldy #S.SOCKET.TCP.OPTIONS
lda #0
sta (ZPPtrSKT),y
jmp SKT.StoreTCB
.88 clc
.9 rts
*--------------------------------------
TCP.NewFrame ldx #S.IP.PROTOCOL.TCP
jsr FRM.NewIP
bcs .9
jsr SKT.SetFrameOutDstIP
ldy #S.SOCKET.SRC.PORT
lda (ZPPtrSKT),y
tax
iny
lda (ZPPtrSKT),y
ldy #S.TCP.SRCPORT
sta (ZPFrameOutPtr),y
iny
txa
sta (ZPFrameOutPtr),y
ldy #S.SOCKET.DST.PORT
lda (ZPPtrSKT),y
tax
iny
lda (ZPPtrSKT),y
ldy #S.TCP.DSTPORT
sta (ZPFrameOutPtr),y
iny
txa
sta (ZPFrameOutPtr),y
ldy #S.TCP.DATAOFFSET
lda #$50 Header size = 5 DWORDS
sta (ZPFrameOutPtr),y
ldy #S.TCP.WINDOW
lda SKT.TCBCache+S.TCB.INFREE+1
sta (ZPFrameOutPtr),y
iny
lda SKT.TCBCache+S.TCB.INFREE
sta (ZPFrameOutPtr),y
clc
.9 rts
*--------------------------------------
TCP.ComputeChecksum
lda #0 RESET.TCP.CHECKSUM
ldy #S.TCP.CHECKSUM
sta (ZPFrameOutPtr),y
iny
sta (ZPFrameOutPtr),y
>LDYA ZPFrameOutPtr
>STYA ZPTmpPtr1
lda ZPFrameOutLen
sec
sbc #S.IP-2
sta ZPDataInLen
lda ZPFrameOutLen+1
sbc /S.IP-2
sta ZPDataInLen+1
clc
* lda ZPDataInLen+1
* adc #0 RESERVED (all zero)
sta IP.CHECKSUM
lda ZPDataInLen
adc #S.IP.PROTOCOL.TCP
sta IP.CHECKSUM+1
ldy #S.IP.SRC
ldx #4 4 words for SRC & DST IP
.10 lda (ZPFrameOutPtr),y
adc IP.CHECKSUM
sta IP.CHECKSUM
iny
lda (ZPFrameOutPtr),y
adc IP.CHECKSUM+1
sta IP.CHECKSUM+1
iny
dex
bne .10
ldy #S.IP
.1 jsr DecDataInLen
beq .8
lda (ZPTmpPtr1),y
adc IP.CHECKSUM
sta IP.CHECKSUM
iny
bne .20
inc ZPTmpPtr1+1
.20 jsr DecDataInLen
bne .2
lda #0
bra .21
.2 lda (ZPTmpPtr1),y
.21 adc IP.CHECKSUM+1
sta IP.CHECKSUM+1
iny
bne .1
inc ZPTmpPtr1+1
bra .1
.8 ldy #S.TCP.CHECKSUM
lda IP.CHECKSUM
adc #0 Don't forget to add last carry!!!
eor #$FF
sta (ZPFrameOutPtr),y
iny
lda IP.CHECKSUM+1
adc #0 Don't forget to add last carry!!!
eor #$FF
sta (ZPFrameOutPtr),y
rts
*--------------------------------------
MAN
SAVE LIB/LIBTCPIP.S.TCP
LOAD LIB/LIBTCPIP.S
ASM