?? net_tcp.c
字號:
#include "stdio.h"
#include "alt_types.h"
void IP_TCP(void) //tcp協議處理程序
{
TCP_Symbol_Receive=Receive_Buffer[Start_TCP+13]&0x3f; //接收到的TCP標志
//printf("\nTCP_Symbole_Receive = 0x%4x\n",TCP_Symbol_Receive);
/*
0x01 FIN 發端完成發送任務
0x02 SYN 同步序號用來發起一個連接
0x04 RST 重建連接
0x08 PSH 接收方應該盡快將這個報文段交給應用層
0x10 ACK 確認序號有效
0x20 URG 緊急指針(urgent pointer)有效*/
TCP_Port_O=Receive_Buffer[Start_TCP+0]*256+Receive_Buffer[Start_TCP+1]; //外部端口號
TCP_Port =Receive_Buffer[Start_TCP+2]*256+Receive_Buffer[Start_TCP+3]; //本地端口號
TCP_ISN_O =Change_UCHAR_UINT(Receive_Buffer,Start_TCP+4); //外部ISN
//printf("TCP_ISN_O =%u\n",TCP_ISN_O);
TCP_ISN_OA=Change_UCHAR_UINT(Receive_Buffer,Start_TCP+8); //外部確認ISN
Receive_PACK_HTTP_Len=Receive_Buffer[Start_IP+2]*0x100+Receive_Buffer[Start_IP+3]-(Receive_Buffer[Start_TCP+12]/0x10)*4-20;
switch(TCP_State)
{
case 0: //初始狀態,等待被動連接
if((TCP_Symbol_Receive&0x02)==0x02) //Symbol = SYN
{
TCP_ISN_A=TCP_ISN_O+1;
TCP_Symbol_Send=0x12; //SYN,ACK
Send_TCP_PACK(); //Send SYN,ACK 發送被動連接的第2次握手信號
TCP_ISN++;
TCP_State=1;
}
break;
case 1: //等待被動連接的第3次握手
if((TCP_Symbol_Receive&0x10)==0x10) //Symbol = ACK
//if(TCP_ISN_OA==ISN); //被動連接第3次握手信號有效
TCP_State=2;
break;
case 2: //正常傳輸狀態,或等待被動斷開
if((TCP_Symbol_Receive&0x01)==0x01) //Symbol = FIN
{
TCP_ISN_A=TCP_ISN_O+1;
TCP_Symbol_Send=0x10; //ASK
Send_TCP_PACK(); //發送被動斷開的第2次握手信號
TCP_Symbol_Send=0x11; //? 似乎可以改成0x01
Send_TCP_PACK(); //發送被動斷開的第3次握手信號
TCP_ISN++;
TCP_State=3;
}
else
//printf("調用應用處理程序\n");
if(TCP_Port==80) //? 按照要求需要判斷http包是否是GET請求信號,不僅僅是判斷端口
{
APP_HTTP(); //調用HTTP處理程序
//Send_HTTP_Response(); //發送HTTP的請求響應包
//TCP_State=6;
}
break;
case 3: //在被動斷開情況下,等待第4次握手
if((TCP_Symbol_Receive&0x10)==0x10) //Symbol = ACK
//if(TCP_ISN_OA==TCP_ISN); //判斷被動斷開情況下,第4次握手是否有效
TCP_State=0;
break;
case 4: //在主動斷開情況下,等待第2次握手
if((TCP_Symbol_Receive&0x10)==0x10) //Symbol = ACK
//if(TCP_ISN_OA==TCP_ISN); //判斷主動斷開情況下,第2次握手信號是否有效
TCP_State=5;
break;
case 5: //在主動斷開情況下,等待第3次握手
if((TCP_Symbol_Receive&0x01)==0x01) //Symbol = FIN
{
TCP_ISN_A=TCP_ISN_O+1;
TCP_Symbol_Send=0x10; //ACK
Send_TCP_PACK(); //在主動斷開情況下,發送第4次握手信號
TCP_State=0;
}
break;
case 6: //等待HTTP響應的ACK
if((TCP_Symbol_Receive&0x10)==0x10) //Symbol = ACK
{
//if(TCP_ISN_OA==TCP_ISN); //判斷http連接中,發送的http頭是否被收到
Send_HTTP_Content(); //發送HTTP內容數據包
TCP_State=7;
}
break;
case 7: //等待HTTP內容的ACK
if((TCP_Symbol_Receive&0x10)==0x10) //Symbol = ACK
{
//if(TCP_ISN_OA==TCP_ISN); //判斷http連接中,發送的http內容是否被收到
TCP_Symbol_Send=0x01; //FIN
TCP_ISN_A=TCP_ISN_O;
Send_TCP_PACK(); //發送FIN數據包
TCP_ISN++;
TCP_State=4;
}
break;
}
//printf("TCP狀態 = %d\n",TCP_State);
}
void Send_TCP_PACK(void) //發送TCP連接用的標志數據包
{
UINT Len=Start_TCP,Bogus_Len=0;
UINT i,Head_Len,Data_SUM;
UCHAR TCP_Bogus_Head[12];
for(i=0;i<2;i++)
Send_Buffer[Len++]=Receive_Buffer[Len+2]; //16位源端口號
for(i=0;i<2;i++)
Send_Buffer[Len++]=Receive_Buffer[Len-2]; //16位目的端口號
Change_UINT_UCHAR(Send_Buffer,Len,TCP_ISN); //32位序號
Len+=4;
Change_UINT_UCHAR(Send_Buffer,Len,TCP_ISN_A); //32位確認序號
Len+=4;
Send_Buffer[Len++]=Receive_Buffer[Len]; //4位首部長度和前4位保留
//Send_Buffer[Len++]=0x70;
//printf("首部長度<<4后的結果 = %x",Receive_Buffer[Len]);
Send_Buffer[Len++]=TCP_Symbol_Send; //后2位保留,6個標志位
for(i=0;i<2;i++)
Send_Buffer[Len++]=Receive_Buffer[Len]; //16位窗口大小
for(i=0;i<2;i++)
Send_Buffer[Len++]=0; //16位校驗和,先設置為0
for(i=0;i<2;i++)
Send_Buffer[Len++]=0; //16位緊急指針
Head_Len=(Receive_Buffer[Start_TCP+12]/0x10)*4;
if(Head_Len>20)
for(i=0;i<Head_Len-20;i++)
Send_Buffer[Len++]=Receive_Buffer[Len]; //選項數據
//設置TCP的偽首部
for(i=0;i<4;i++)
TCP_Bogus_Head[Bogus_Len++]=IP_Addr[i];
for(i=0;i<4;i++)
TCP_Bogus_Head[Bogus_Len++]=IP_O_Addr[i];
TCP_Bogus_Head[Bogus_Len++]=0;
TCP_Bogus_Head[Bogus_Len++]=6;
TCP_Bogus_Head[Bogus_Len++]=Head_Len/0x100;
TCP_Bogus_Head[Bogus_Len++]=Head_Len&0xff;
Data_SUM=CHECK_SUM(TCP_Bogus_Head,0,12)&0xffff; //偽首部的校驗和
Data_SUM+=CHECK_SUM(Send_Buffer,Start_TCP,Head_Len)&0xffff; //TCP首部校驗和
Data_SUM+=Data_SUM/0x10000;
Send_Buffer[Start_TCP+16]=Data_SUM/0x100;
Send_Buffer[Start_TCP+17]=Data_SUM&0xff;
IP_PACK_Len=Head_Len+20;
HEAD_IP(); //IP首部
HEAD_Ethernet(); //以太網首部
NET_Send_Packet(Send_Buffer,Len); //發送數據包
}
void Change_UINT_UCHAR(UCHAR *Buffer,UINT Start,UINT Data) //將一個32位的數據轉換成4個8位的數組
{
Buffer[Start+0]=(Data/0x1000000)&0xff; //32位確認序號
Buffer[Start+1]=(Data/0x10000)&0xff;
Buffer[Start+2]=(Data/0x100)&0xff;
Buffer[Start+3]=Data&0xff;
}
UINT Change_UCHAR_UINT(UCHAR *Buffer,UINT Start) //數據轉換,將4個8位數組轉換成一個32位無符號整數
{
UINT Data;
Data =Buffer[Start+3];
Data+=Buffer[Start+2]*0x100;
Data+=Buffer[Start+1]*0x10000;
Data+=Buffer[Start+0]*0x1000000;
return Data;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -