PR#3 PREFIX /A2OSX.BUILD 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 jmp SKT.Destroy *-------------------------------------- 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 Assign SEQNUM 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 Get Remote SEQ ldx #3 sec .3 lda (ZPFrameInPtr),y Set ACK=SEQ+1 for new socket... adc #0 sta SKT.TCBCache+S.TCB.ACKNUM,x sta SKT.TCBCache+S.TCB.NEXTSEQ,x dey dex bpl .3 jsr SKT.StoreTCB jsr ARP.AddFromFrameInPtr lda #S.TCP.OPTIONS.SYN+S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOpt Send SYN.ACK 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.ACK.NUMBER+3 sec Check if ACK=my SEQ+1 .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 lda #S.TCP.OPTIONS.ACK jsr TCP.OUT.SendOpt 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 Check if ACK=my SEQ+1 adc #0 sta SKT.TCBCache+S.TCB.SEQNUM,x eor (ZPFrameInPtr),y bne .8 dey dex bpl .1 jsr SKT.StoreTCB bcs .9 ldy #S.SOCKET.TCP.STATUS lda #S.SOCKET.TCP.STATUS.ESTBLSH sta (ZPPtrSKT),y .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.... .2 ldy #S.TCP.OPTIONS lda (ZPFrameInPtr),y and #S.TCP.OPTIONS.FIN beq .8 ldy #S.TCP.OPTIONS lda (ZPPtrSKT),y ora #S.TCP.OPTIONS.ACK ACK the FIN.... sta (ZPPtrSKT),y jsr TCP.OUT.I SKT.GetTCB called, try to ACK the FIN bcs .9 ldy #S.SOCKET.TCP.STATUS lda #S.SOCKET.TCP.STATUS.CLWAIT sta (ZPPtrSKT),y .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.CLWAIT clc Wait for SKT.CloseA from Daemon rts *-------------------------------------- TCP.IN.JMP.LASTACK ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y cmp #S.TCP.OPTIONS.ACK bne .8 jmp SKT.Destroy .8 clc rts *-------------------------------------- TCP.IN.JMP.FINWT1 ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y cmp #S.TCP.OPTIONS.ACK bne .1 ldy #S.SOCKET.TCP.STATUS lda #S.SOCKET.TCP.STATUS.FINWT2 sta (ZPPtrSKT),y clc rts .1 cmp #S.TCP.OPTIONS.FIN bne .8 ldy #S.SOCKET.TCP.OPTIONS lda (ZPPtrSKT),y ora #S.TCP.OPTIONS.ACK sta (ZPPtrSKT),y jsr TCP.OUT bcs .9 ldy #S.SOCKET.TCP.STATUS lda #S.SOCKET.TCP.STATUS.CLOSING sta (ZPPtrSKT),y .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.FINWT2 ldy #S.TCP.OPTIONS only accept FIN packet lda (ZPFrameInPtr),y cmp #S.TCP.OPTIONS.FIN bne .8 ldy #S.SOCKET.TCP.OPTIONS lda (ZPPtrSKT),y ora #S.TCP.OPTIONS.ACK sta (ZPPtrSKT),y jsr TCP.OUT bcs .9 ldy #S.SOCKET.TCP.STATUS lda #S.SOCKET.TCP.STATUS.TIMEWT sta (ZPPtrSKT),y .8 clc .9 rts *-------------------------------------- TCP.IN.JMP.CLOSING ldy #S.TCP.OPTIONS only accept ACK packet lda (ZPFrameInPtr),y cmp #S.TCP.OPTIONS.ACK bne .1 ldy #S.SOCKET.TCP.STATUS lda #S.SOCKET.TCP.STATUS.TIMEWT sta (ZPPtrSKT),y .1 clc rts *-------------------------------------- TCP.IN.JMP.TIMEWT *-------------------------------------- TCP.IN.JMP.CLOSED clc rts *-------------------------------------- TCP.IN.SetDataInPtrAndLen ldy #S.IP.TOTAL.LENGTH+1 lda (ZPFrameInPtr),y sec sbc #S.IP-S.ETH sta ZPDataInLen dey lda (ZPFrameInPtr),y sbc /S.IP-S.ETH 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.TCBCache+S.TCB.TOSEND+1 ldy SKT.TCBCache+S.TCB.TOSEND bne .1 tax bne .1 * Y,A=0 : no data to send ldy #S.SOCKET.TCP.OPTIONS lda (ZPPtrSKT),y bne TCP.OUT.SendOpt 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 get only MSS .2 jsr TCP.NewFrame bcs TCP.OUT.9 jsr SKT.GetDataFromSktOut ldy #S.SOCKET.TCP.OPTIONS lda (ZPPtrSKT),y jsr TCP.OUT.Send bcs TCP.OUT.9 lda SKT.TCBCache+S.TCB.SEQNUM+3 clc adc ZPDataOutLen sta SKT.TCBCache+S.TCB.SEQNUM+3 lda SKT.TCBCache+S.TCB.SEQNUM+2 adc ZPDataOutLen+1 sta SKT.TCBCache+S.TCB.SEQNUM+2 bcc .80 inc SKT.TCBCache+S.TCB.SEQNUM+1 bne .80 inc SKT.TCBCache+S.TCB.SEQNUM .80 jmp SKT.StoreTCB TCP.OUT.9 rts *-------------------------------------- TCP.OUT.SendOpt sta .1+1 >LDYAI 0 jsr TCP.NewFrame bcs TCP.OUT.9 .1 lda #$ff TCP.OUT.Send ldy #S.TCP.OPTIONS sta (ZPFrameOutPtr),y bit #S.TCP.OPTIONS.ACK beq .11 ldx #3 ldy #S.TCP.ACK.NUMBER+3 .10 lda SKT.TCBCache+S.TCB.ACKNUM,x sta (ZPFrameOutPtr),y dey dex bpl .10 bra .1 .11 ldy #S.TCP.ACK.NUMBER lda #0 .12 sta (ZPFrameOutPtr),y iny cpy #S.TCP.ACK.NUMBER+4 bne .12 .1 ldx #3 ldy #S.TCP.SEQ.NUMBER+3 .2 lda SKT.TCBCache+S.TCB.SEQNUM,x sta (ZPFrameOutPtr),y dey dex bpl .2 ldy #S.TCP.WINDOW lda SKT.TCBCache+S.TCB.INFREE+1 sta (ZPFrameOutPtr),y iny lda SKT.TCBCache+S.TCB.INFREE sta (ZPFrameOutPtr),y 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 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 lda ZPDataInLen eor #$ff tax lda ZPDataInLen+1 eor #$ff pha .1 inx bne .11 pla inc beq .8 pha .11 lda (ZPTmpPtr1),y adc IP.CHECKSUM sta IP.CHECKSUM iny bne .20 inc ZPTmpPtr1+1 .20 inx bne .2 pla inc beq .7 pha .2 lda (ZPTmpPtr1),y adc IP.CHECKSUM+1 sta IP.CHECKSUM+1 iny bne .1 inc ZPTmpPtr1+1 bra .1 .7 adc IP.CHECKSUM+1 A=0 from beq .7 sta IP.CHECKSUM+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 /A2OSX.SRC/LIB/LIBTCPIP.S.TCP LOAD /A2OSX.SRC/LIB/LIBTCPIP.S ASM