NEW AUTO 3,1 .LIST OFF *-------------------------------------- TCP.IN jsr FRM.GetTargetSKT.TCPUDP jsr SKT.FindMatchingLocRem bcs TCP.IN.JMP.CLOSED no socket, go discard ldy #S.SOCKET.PROTO lda (ZPPtrSKT),y cmp #S.IP.PROTOCOL.TCP bne TCP.IN.JMP.CLOSED wrong protocol, go discard ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.RST RST ? go Kill this socket... bne TCP.IN.RST ...and discard frame ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y asl tax jmp (J.TCP.IN,x) *-------------------------------------- TCP.IN.RST lda SKT.TABLE,x jsr SKT.shutdown *-------------------------------------- TCP.IN.JMP.CLOSED lda hFrameIn stz hFrameIn >SYSCALL2 FreeMem rts *-------------------------------------- TCP.SENDCLOSE ldx #0 .1 phx lda SKT.TABLE,x beq .8 >SYSCALL2 GetMemPtr >STYA ZPPtrSKT ldy #S.SOCKET.AF lda (ZPPtrSKT),y cmp #AF.INET bne .8 iny #S.SOCKET.T lda (ZPPtrSKT),y cmp #S.SOCKET.T.SEQPACKET bcc .8 ldy #S.SOCKET.TCP.S lda (ZPPtrSKT),y cmp #S.SOCKET.TCP.S.TIMEWT beq .4 cmp #S.SOCKET.TCP.S.ESTBLSH bne .8 jsr TCP.OUT bra .8 .4 ldy #S.SOCKET.SQ.hInMem lda (ZPPtrSKT),y >SYSCALL2 freemem ldy #S.SOCKET.SQ.hOutMem lda (ZPPtrSKT),y >SYSCALL2 freemem plx phx lda SKT.TABLE,x >SYSCALL2 freemem plx phx stz SKT.TABLE,x .8 plx inx cpx #K.SKTTABLE.SIZE bne .1 .9 rts *-------------------------------------- TCP.IN.JMP.LISTEN ldy #S.SOCKET.T Create a new client socket lda (ZPPtrSKT),y tax Same type a listening socket iny #S.SOCKET.PROTO lda (ZPPtrSKT),y jsr SKT.Socket.I get new socket in ZPTmpPtr1 bcs TCP.IN.JMP.CLOSED jsr SKT.AddToQueueA Queued successfully ? bcs TCP.IN.JMP.CLOSED no, discard frame and new socket jsr ARP.AddFromFrameInPtr lda ZPTmpPtr1 sta ZPPtrSKT lda ZPTmpPtr1+1 sta ZPPtrSKT+1 jsr SKT.SetLocAddr jsr SKT.SetRemAddr jsr SKT.NewTCB bcs .99 jsr TCP.IN.ACKTheSYN lda #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA SYN received, Send SYN.ACK bcs .9 lda #S.SOCKET.TCP.S.SYNRCVD jmp SKT.StoreTCB.S .9 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 and #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK cmp #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK bne .9 jsr SKT.GetTCB ldx #3 ldy #S.TCP.ACKNUM+3 sec Check if ACK=OUTNEXTSEQ+1 .1 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x adc #0 sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x eor (ZPFrameInPtr),y bne .9 dey dex bpl .1 jsr TCP.IN.ACKTheSYN lda #S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA SYN.ACK recieved, Send, ACK bcs .9 lda #S.SOCKET.TCP.S.ESTBLSH jmp SKT.StoreTCB.S .9 lda #S.TCP.OPTIONS.RST jsr TCP.OUT.SendOptA ldx SKT.Index lda SKT.TABLE,x jmp SKT.shutdown *-------------------------------------- TCP.IN.JMP.SYNRCVD ldy #S.TCP.OPTIONS SYN Received, 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.ACKNUM+3 sec .1 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x Check if ACK=OUTNEXTSEQ+1 adc #0 sta SKT.Cache+S.SOCKET.TCP.OUTSEQNUM,x setup SEQNUM sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x ...and update NEXTSEQ eor (ZPFrameInPtr),y bne .8 dey dex bpl .1 lda #S.SOCKET.TCP.S.ESTBLSH jmp SKT.StoreTCB.S .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.ESTBLSH jsr SKT.GetTCB ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.ACK Remote side ACKed data ? beq .1 jsr SKT.AckDataToSktOut Yes, Discard sent data jsr SKT.StoreTCB and update SKT .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.... bcs .2 jsr SKT.StoreTCB success, update socket .2 ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.FIN beq .8 jsr TCP.IN.ACKTheFIN lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA FIN received, Send FIN.ACK bcs .9 lda #S.SOCKET.TCP.S.CLWAIT jmp SKT.StoreTCB.S .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.CLWAIT clc Wait for SKT.shutdown rts *-------------------------------------- TCP.IN.JMP.LASTACK ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.ACK beq .8 ldy #S.SOCKET.TCP.S lda #S.SOCKET.TCP.S.TIMEWT sta (ZPPtrSKT),y .8 clc rts *-------------------------------------- TCP.IN.JMP.FINWT1 jsr SKT.GetTCB ldy #S.TCP.OPTIONS FIN sent, accept ACK or FIN/ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.FIN bne .1 lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA Send FIN.ACK bcs .9 lda #S.SOCKET.TCP.S.FINWT2 jmp SKT.StoreTCB.S .1 jsr TCP.IN.ACKTheFIN FIN/ACK lda #S.TCP.OPTIONS.FIN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA Send FIN.ACK bcs .9 lda #S.SOCKET.TCP.S.TIMEWT jmp SKT.StoreTCB.S * clc .9 rts *-------------------------------------- TCP.IN.JMP.FINWT2 ldy #S.TCP.OPTIONS only accept FIN packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.FIN beq .8 jsr SKT.GetTCB jsr TCP.IN.ACKTheFIN lda #S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOptA FIN received, Send ACK bcs .9 lda #S.SOCKET.TCP.S.TIMEWT jmp SKT.StoreTCB.S .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.CLOSING ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y bit #S.TCP.OPTIONS.ACK beq .1 ldy #S.SOCKET.TCP.S lda #S.SOCKET.TCP.S.TIMEWT sta (ZPPtrSKT),y .1 clc rts *-------------------------------------- TCP.IN.JMP.TIMEWT clc Wait for TCP.Close rts *-------------------------------------- TCP.IN.ACKTheSYN ldy #S.TCP.SEQNUM+3 Get Remote SEQ ldx #3 sec .3 lda (ZPFrameInPtr),y Set OUTACK=SEQ+1 for new socket... adc #0 sta SKT.Cache+S.SOCKET.TCP.INLASTSEQNUM,x sta SKT.Cache+S.SOCKET.TCP.OUTACKNUM,x dey dex bpl .3 rts *-------------------------------------- TCP.IN.ACKTheFIN ldy #S.SOCKET.TCP.O lda (ZPPtrSKT),y ora #S.TCP.OPTIONS.ACK sta (ZPPtrSKT),y ldx #3 sec .2 lda SKT.Cache+S.SOCKET.TCP.INLASTSEQNUM,x adc #0 sta SKT.Cache+S.SOCKET.TCP.INLASTSEQNUM,x dex bpl .2 ldx #3 sec .3 lda SKT.Cache+S.SOCKET.TCP.OUTACKNUM,x adc #0 sta SKT.Cache+S.SOCKET.TCP.OUTACKNUM,x dex bpl .3 rts *-------------------------------------- TCP.IN.SetDataInPtrAndLen ldy #S.IP.TOTAL.LENGTH+1 lda (ZPFrameInPtr),y sec sbc #S.IP-S.ETH.EII sta ZPDataInLen dey lda (ZPFrameInPtr),y sbc /S.IP-S.ETH.EII sta ZPDataInLen+1 ldy #S.TCP.DATAOFFSET lda (ZPFrameInPtr),y and #$F0 Get TCP Header len in DWORD lsr lsr sta TmpOffset lda ZPDataInLen sec sbc TmpOffset sta ZPDataInLen bcs .1 dec ZPDataInLen+1 .1 lda ZPFrameInPtr clc adc #S.IP pha lda ZPFrameInPtr+1 adc /S.IP tax pla clc adc TmpOffset bcc .2 inx .2 sta ZPDataInPtr stx ZPDataInPtr+1 rts *-------------------------------------- TCP.OUT jsr SKT.GetTCB TCP.OUT.I lda SKT.Cache+S.SOCKET.TCP.OUTTOSEND+1 ldy SKT.Cache+S.SOCKET.TCP.OUTTOSEND bne .1 tax bne .1 * Y,A=0 : no data to send ldy #S.SOCKET.TCP.O lda (ZPPtrSKT),y bne TCP.OUT.SendOptA a least an option... clc No, data, no flag....exit rts .1 cpy #K.TCP.MSS pha sbc /K.TCP.MSS OUTDATA > MSS ? pla bcc .2 no....keep data len >LDYAI K.TCP.MSS yes send only MSS .2 jsr TCP.NewFrame bcs TCP.OUT.9 jsr SKT.GetDataFromSktOut ldy #S.SOCKET.TCP.O lda (ZPPtrSKT),y ora #S.TCP.OPTIONS.ACK+S.TCP.OPTIONS.PSH jsr TCP.OUT.SendOptA.1 bcs TCP.OUT.9 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ+3 clc adc ZPDataOutLen sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ+3 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ+2 adc ZPDataOutLen+1 sta SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ+2 bcc .80 inc SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ+1 bne .80 inc SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ .80 jmp SKT.StoreTCB exits with CC TCP.OUT.9 rts *-------------------------------------- TCP.OUT.SendOptA sta .1+1 >LDYAI 0 jsr TCP.NewFrame bcs TCP.OUT.9 .1 lda #$ff TCP.OUT.SendOptA.1 ldy #S.TCP.OPTIONS sta (ZPFrameOutPtr),y bit #S.TCP.OPTIONS.ACK beq .10 ldx #3 ldy #S.TCP.ACKNUM+3 .1 lda SKT.Cache+S.SOCKET.TCP.OUTACKNUM,x sta (ZPFrameOutPtr),y dey dex bpl .1 .10 ldx #3 ldy #S.TCP.SEQNUM+3 .2 lda SKT.Cache+S.SOCKET.TCP.OUTNEXTSEQ,x sta (ZPFrameOutPtr),y dey dex bpl .2 ldy #S.TCP.WINDOW lda SKT.Cache+S.SOCKET.TCP.INFREE+1 sta (ZPFrameOutPtr),y iny lda SKT.Cache+S.SOCKET.TCP.INFREE sta (ZPFrameOutPtr),y jsr FRM.SendIP bcs .9 ldy #S.SOCKET.TCP.O lda #0 sta (ZPPtrSKT),y * clc .9 rts *-------------------------------------- TCP.NewFrame ldx #S.IP.PROTOCOL.TCP jsr FRM.NewIP bcs .9 jsr SKT.SetFrameOutDstIP jsr SKT.SetFrameOutTCPUDPPorts ldy #S.TCP.DATAOFFSET lda #$50 Header size = 5 DWORDS sta (ZPFrameOutPtr),y ldy #S.TCP.WINDOW lda SKT.Cache+S.SOCKET.TCP.INFREE+1 sta (ZPFrameOutPtr),y iny lda SKT.Cache+S.SOCKET.TCP.INFREE sta (ZPFrameOutPtr),y clc .9 rts *-------------------------------------- MAN SAVE USR/SRC/LIB/LIBTCPIP.S.TCP LOAD USR/SRC/LIB/LIBTCPIP.S ASM