📄 tcb.c
字号:
#include "p_tcpip.h"
UCHAR SeqCmp(PXCHAR pData1,PXCHAR pData2);
void TcbListen();
BOOLEAN CheckRstFlag();
void TcbAckit();
UCHAR TcbAcked();
void TcbData();
void TcbFin1();
void TcbFin2();
void TcbSynSent();
void TcbSynRcvd();
void TcbEstablished();
void TcbCloseWait();
void TcbLastAck();
void TcbClosing();
void TcbSetCurrent(PXCHAR pDataBuf)
{
pTcbData=pDataBuf;
pTcbReceiveNextSeq=pTcbData+0x000c;
pTcbSendNextSeq=pTcbData+0x0010;
pTcbSendUnackSeq=pTcbData+0x0014;
pTcbRemoteIP=pTcbData+0x0008;
}
void TcbSendPacket()
{
ULONG lHeaderSum,lCHECKSUM;
DSHORT iCheckSum;
p_memcpy_x2x(pTcpData,Adapter_pReceiveMacAddress,6);
p_memcpy_x2x(pTcbPacket_IP_DST,Adapter_pReceiveIPAddress,4);
pTcpData[0x0f]=0x28; //ip_len=40
lHeaderSum=PXCHAR2ULONG(pTcpHeaderCkSum);
lCHECKSUM=IpModifyCheckSum(lHeaderSum,Adapter_pReceiveIPAddress);
IpCheckSum(lCHECKSUM,pTcbPacket_EP_DATA);
pTcpData[0x30]=0;
pTcpData[0x31]=0;
iCheckSum=TcpCheckSum(0x14,pTcpData);
pTcpData[0x30]=P_HIBYTE(iCheckSum);
pTcpData[0x31]=P_LOBYTE(iCheckSum);
Ne2000Send(0x36,pTcpData);//send len=54 (mac+ip +tcp)header
}
void TcbAlloc() //init syn packet and state
{
*(pTcbData)=01; //client closed=1
*(pTcbData+1)=0; //server state free
*(pTcbData+2)=2; //flag=syn
RandSting(pTcbSendNextSeq,4);
p_memcpy_x2x(pTcbSendUnackSeq,pTcbSendNextSeq,4);
}
void TcbDeAlloc()
{
*(pTcbData)=0; //receive status=0 closed
*(pTcbData+0x18)=01; //tcps_free =1 ff=use
Tcp_bCloseEvent=1;
}
BOOLEAN TcbInit(PXCHAR pTcbData, UCHAR iListenPortHi, UCHAR iListenPortLo)
{
PXCHAR pBuf;
pBuf=pTcbData;
*(pBuf+4)=iListenPortHi;
*(pBuf+5)=iListenPortLo;
*pBuf=0; //listen
*(pBuf+0x18)=0x01;
*(pBuf+0x19)=0; //send size
CY=1;
return CY;
}
//check receive packet if is Local port
BOOLEAN TcbCheckData(PXCHAR pData)
{
if((*(Adapter_pReceivePacket+2)) ^ (*(pData+4)))
{
return FALSE;
}
if((*(Adapter_pReceivePacket+3)) ^ (*(pData+5)))
{
return FALSE;
}
return TRUE;
}
void TcbRun(PXCHAR pTcbDataBuf)// tcb input module
{
DCHAR Tcp_iReceiveHeaderLen;
DCHAR istate;
TcbSetCurrent(pTcbDataBuf);
Tcp_iReceiveHeaderLen=((*(Adapter_pReceivePacket+0x0c)&0xf0)>>2);//get tcp header size
Adapter_pReceiveTcpData=Adapter_pReceivePacket+Tcp_iReceiveHeaderLen;//tcp data
if(Adapter_iReceiveLen<Tcp_iReceiveHeaderLen) //receive data size<tcp header size
TcpReset();
Adapter_iReceiveLen-=Tcp_iReceiveHeaderLen;
if(*(Adapter_pReceivePacket+0x0d)&0x10) //ack=1
bReceiveAckFlag=1;
else
bReceiveAckFlag=0;
if(*(Adapter_pReceivePacket+0x0d)&0x04) //rst=1
bReceiveRstFlag=1;
else
bReceiveRstFlag=0;
if(*(Adapter_pReceivePacket+0x0d)&0x02) //syn=1
bReceiveSynFlag=1;
else
bReceiveSynFlag=0;
if(*(Adapter_pReceivePacket+0x0d)&0x01) //fin=1
bReceiveFinFlag=1;
else
bReceiveFinFlag=0;
istate=*(pTcbData);// getreceive state
if (!istate)
{
TcbListen(); //state=0
return;
}
if ((*(pTcbData+0x06)!=*(Adapter_pReceivePacket))||(*(pTcbData+0x07)!=*(Adapter_pReceivePacket+1)))
{
TcpReset(); //compare remote port
return;
}
if(p_memcmp_x2x(pTcbRemoteIP,Adapter_pReceiveIPAddress,4))
{
TcpReset(); //compare remote ip
return;
}
if ((istate>=0x04)&&(p_memcmp_x2x(pTcbReceiveNextSeq,pTcpReceiveSeq,4)))
{
TcbAckit();
return;
}
if (istate==0x07)
{
TcbFin1();//7
return;
}
else if(istate<0x07)
{
istate=istate+0xfd ;
switch (istate)
{
case 0:
TcbSynSent(); //3
return;
case 1:
TcbSynRcvd(); //4
return;
case 2:
TcbEstablished();//5
return;
case 3:
TcbCloseWait();///6
return;
default:
return;
}
}
//*pTcbData>0x07
istate=istate+0xf8;
switch (istate)
{
case 0:
TcbFin2();// 8
return;
case 1:
TcbLastAck();//9
return;
case 2:
TcbClosing();//10
return;
default:
return;
}
} //TcbRrun
BOOLEAN TcbHandleTimer(PXCHAR pBuf)
{
DCHAR i;
DCHAR iRemotePortHigh,iRemotePortLow;
PXCHAR iRemoteIp;
TcbSetCurrent(pBuf);
i=*(pTcbData+0x1b);//rexmitcount
i--;
if(!i)
{
i=3;
if(*(pTcbData+0x1a)<5)
{
iRemoteIp=TcbGetRemoteIP(pTcbData);
iRemotePortHigh=TcbGetRemotePortHi(pTcbData);
iRemotePortLow=TcbGetRemotePortLo(pTcbData);
// DebugString1(iRemoteIp,iRemotePortHigh,0x1022);
*(pTcbData+0x1a)=*(pTcbData+0x1a)+1;
Ne2000WaitPacket();
Ne2000Send(*(pTcbData+0x19),pTcpSendPacket);
}
else
return FALSE;
}
*(pTcbData+0x1b)=i;
return TRUE;
}
UCHAR SeqCmp(PXCHAR pSource,PXCHAR pDst)
{
DLONG lTemp1,lTemp2;
lTemp1=PXCHAR2ULONG(pSource);
lTemp2=PXCHAR2ULONG(pDst);
lTemp1-=lTemp2;
if (lTemp1==0) return 0;
lTemp2=0x80000000;
if (lTemp1>lTemp2)
return 1;
return 2;
}
BOOLEAN TcbClosed(PXCHAR pTcbData)
{
PXCHAR pBuf;
pBuf=pTcbData;
if(*pBuf)
return TRUE;
else
return FALSE;
}
UCHAR TcbGetLocalPortHi(PXCHAR pTcbData)
{
return *(pTcbData+4);
}
PXCHAR TcbGetRemoteIP(PXCHAR pTcbData)
{
return (pTcbData+0x08);
}
UCHAR TcbGetLocalPortLo(PXCHAR pTcbData)
{
return *(pTcbData+5);
}
UCHAR TcbGetRemotePortHi(PXCHAR pTcbData)
{
return *(pTcbData+0x06);
}
UCHAR TcbGetRemotePortLo(PXCHAR pTcbData)
{
return *(pTcbData+0x07);
}
void TcbListen()
{
if (bReceiveRstFlag)
return;
if (bReceiveAckFlag||!bReceiveSynFlag)
{
TcpReset();
return;
}
// Tcp_bAcceptEvent=1;
TcbAlloc();
*(pTcbData)=04; // synrcvd status
*(pTcbData+6)=*(Adapter_pReceivePacket);
*(pTcbData+7)=*(Adapter_pReceivePacket+1); //local port
//*(pTcbData+4)=*(Adapter_pReceivePacket+2);
//*(pTcbData+5)=*(Adapter_pReceivePacket+3);
p_memcpy_x2x(pTcbReceiveNextSeq,pTcpReceiveSeq,4);
SeqAdd(1,pTcbReceiveNextSeq);
*(pTcbData+2)=0x12;// ack=1 syn=1
*(pTcbData+1)=1; //server status =1
Tcp_bAcceptEvent=1; //send Tcp_bAcceptEvent
TcpPrepareData();
}
void SeqAdd(UCHAR Len,PXCHAR pData)
{
ULONG iTemp;
iTemp=PXCHAR2ULONG(pData)+(ULONG)Len;
ULONG2PUCHAR(iTemp,pData);
}
BOOLEAN CheckRstFlag()
{
if (bReceiveRstFlag)
{
TcbDeAlloc();
return TRUE;
}
if (bReceiveSynFlag)
{
TcpReset();
TcbDeAlloc();
return TRUE;
}
return FALSE;
}
void TcbAckit()
{
if(bReceiveRstFlag) return;
if((!Adapter_iReceiveLen)&&(!bReceiveSynFlag)&&(!bReceiveFinFlag))//tcp data length=0
return;
*(pTcpData+0x20)=*(Adapter_pReceivePacket+2);
*(pTcpData+0x21)=*(Adapter_pReceivePacket+3);// copy souce port
*(pTcpData+0x22)=*(Adapter_pReceivePacket);
*(pTcpData+0x23)=*(Adapter_pReceivePacket+1);//copy dst port
p_memcpy_x2x(pTcbPacket_TCP_SEQ,pTcbSendNextSeq,4);//copy Tcp seq
p_memcpy_x2x(pTcbPacket_TCP_ACK,pTcbReceiveNextSeq,4);//copy tcp ack
*(pTcpData+0x2d)=0x10; //ack=1
*(pTcpData+0x2f)=TCPMAXPACKETLEN; //window size=197
*(pTcpData+0x2c)=0x50; //data offset
TcbSendPacket();
}
UCHAR TcbAcked()//check ack
{
DCHAR i;
bdata UCHAR flags;
if (!bReceiveAckFlag)
{
i=3;
return i;
}
if(!p_memcmp_x2x(pTcpReceiveAckSeq,pTcbSendNextSeq,4))
{
*(pTcbData+0x18)=0x01; //not busy
p_memcpy_x2x(pTcbSendUnackSeq,pTcpReceiveAckSeq,4);
flags=*(pTcbData+2);
if(flags&0x02)//syn=1
*(pTcbData+2)=*(pTcbData+2)&0xfd; //syn=0
flags=*(pTcbData+2);
if(flags&0x01) //fin=1
{
*(pTcbData+2)=*(pTcbData+2)&0xfe; //fin=0
*(pTcbData+1)=*(pTcbData+1)&0xef; //server status.8=0 server fin
}
i=0;
return i;
}
i=SeqCmp(pTcpReceiveAckSeq,pTcbSendUnackSeq);
if (i==1) //pTcpReceiveAckSeq>pTcbSendUnackSeq //error
{
TcbAckit();//send ack packet
i=2;
return i;
}
i=1;
return i; //pTcpReceiveAckSeq<=pTcbSendUnackSeq
}
void TcbData()
{
DCHAR i;
i=Adapter_iReceiveLen;
if(i!=0)
{
SeqAdd(i,pTcbReceiveNextSeq);
*(pTcbData+1)=*(pTcbData+1)|0x01;//server status
*(pTcbData+2)=0x10; //ack=1
Tcp_bDataEvent=TRUE;//send Tcp_bDataEvent
}
if (!bReceiveFinFlag) return;
//if bReceiveFinFlag=1
*(pTcbData+1)=*(pTcbData+1)|0x05; //server ended
*(pTcbData+2)=0x10; //ack=1
SeqAdd(1,pTcbReceiveNextSeq);
Tcp_bCloseEvent=TRUE; //set Tcp_bCloseEvent
}
void TcbFin1()
{
DCHAR i;
bdata UCHAR status,flags;
if(CheckRstFlag()) return;
i=TcbAcked();
if(i>1) return; //error
TcbData();
status=*(pTcbData+1); //server status
if(status&0x04) //if server status done acc.2=1
{
flags=*(pTcbData+2);
if(flags&0x01) // receive fin=1
*(pTcbData)=0x0a;//enter closing status
else //fin acked
{
TcbDeAlloc();
// Tcp_bFreeEvent=1;
}
return;
}
flags=*(pTcbData+2);
if(ACC&0x01) // fin =1
return;
*(pTcbData)=0x08; //enter fin2 status
}
void TcbFin2()
{
DCHAR i;
if(CheckRstFlag()) return;
i=TcbAcked();
if (i>1)
return; //error
TcbData();
ACC=*(pTcbData+1);
if(!(ACC&0x04)) return; //check if server done
TcbDeAlloc();
//Tcp_bFreeEvent=1;
}
void TcbSynSent()
{
bdata UCHAR flags;
if((bReceiveAckFlag)&&(p_memcmp_x2x(pTcpReceiveAckSeq,pTcbSendNextSeq,4)))
{
TcpReset();
return;
}
if (bReceiveRstFlag)
{
TcbDeAlloc();
return;
}
if (!bReceiveSynFlag) return;
p_memcpy_x2x(pTcbReceiveNextSeq,pTcpReceiveSeq,4);
SeqAdd(1,pTcbReceiveNextSeq);
TcbAcked();
flags=*(pTcbData+2);
if(flags&0x02)//syn=1
{
*(pTcbData+2)=0x12;//ack=1 syn=1
*(pTcbData)=0x04;//enter syn recvd status
}
else
{
*(pTcbData+2)=0x10; //ack=1
*(pTcbData)=0x05; //enter eatablished status
Tcp_bConnectEvent=1; //send Tcp_bConnectEvent
}
*(pTcbData+1)=0x01;
}
void TcbSynRcvd()
{
bdata UCHAR flags;
if(CheckRstFlag()) return;
if (!bReceiveAckFlag) return;
if(p_memcmp_x2x(pTcpReceiveAckSeq,pTcbSendNextSeq,4)) return;
*(pTcbData+0x18)=1;//new tcb
p_memcpy_x2x(pTcbSendUnackSeq,pTcpReceiveAckSeq,4);
flags=*(pTcbData+2);
if (flags&0x02) //syn=1
*(pTcbData+2)= *(pTcbData+2)&0xfd; //syn=0
*(pTcbData)=0x05; //enter established status
Tcp_bConnectEvent=1;//send Tcp_bConnectEvent
TcbData();
}
void TcbEstablished()
{
if(CheckRstFlag()) return;
if(TcbAcked()) return; //error
TcbData();
ACC=*(pTcbData+1);
if(!(ACC&0x04)) return; //server status !=4
*(pTcbData)=6;//enter closewait status
}
void TcbCloseWait()
{
if(CheckRstFlag()) return;
TcbAcked();//ack fin
}
void TcbLastAck()
{
DCHAR i;
if(CheckRstFlag()) return ;
i=TcbAcked();
if(!i)
{
TcbDeAlloc();
// Tcp_bFreeEvent=1;
return;
}
if (i!=1) return;
p_memcmp_x2x(pTcbSendNextSeq,pTcbSendUnackSeq,4);
return;
}
void TcbClosing() //等待对Fin 的确认
{
if(CheckRstFlag()) return;
TcbAcked();
ACC=*(pTcbData+2);
if(ACC&0x01) return;//fin=1 fin packet acked
TcbDeAlloc();
// Tcp_bFreeEvent=1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -