⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpip.c

📁 基于SPCE061A的TCPIP协议
💻 C
📖 第 1 页 / 共 3 页
字号:
///
 // Copyright (c) 2003, Wolver Wang, MinShan Inc. R&D Center
 // wolver@minshan-inc.com
 // All rights reserved. 
 //
 // Redistribution and use in source and binary forms, with or without 
 // modification, are permitted provided that the following conditions 
 // are met: 
 // 1. Redistributions of source code must retain the above copyright 
 //    notice, this list of conditions and the following disclaimer. 
 // 2. Redistributions in binary form must reproduce the above copyright 
 //    notice, this list of conditions and the following disclaimer in the 
 //    documentation and/or other materials provided with the distribution. 
 // 3. All advertising materials mentioning features or use of this software
 //    must display the following acknowledgement:
 //      This product includes software developed by Wolver Wang.
 // 4. The name of the author may not be used to endorse or promote
 //    products derived from this software without specific prior
 //    written permission.  
 //
 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 ///
 

///
 // Copyright (c) 2003, Wolver Wang, MinShan Inc. R&D Center
 // wolver@minshan-inc.com
 // All rights reserved. 
 //
 // Redistribution and use in source and binary forms, with or without 
 // modification, are permitted provided that the following conditions 
 // are met: 
 // 1. Redistributions of source code must retain the above copyright 
 //    notice, this list of conditions and the following disclaimer. 
 // 2. Redistributions in binary form must reproduce the above copyright 
 //    notice, this list of conditions and the following disclaimer in the 
 //    documentation and/or other materials provided with the distribution. 
 // 3. All advertising materials mentioning features or use of this software
 //    must display the following acknowledgement:
 //      This product includes software developed by Wolver Wang.
 // 4. The name of the author may not be used to endorse or promote
 //    products derived from this software without specific prior
 //    written permission.  
 //
 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 // OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 // ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 ///
 

///
 // 版权 2003, 王卫无,四川绵阳岷山集团有限公司--研究开发中心
 // wolver@minshan-inc.com
 // 保留一切权利
 //
 // 如果符合以下条件,则无论是以原代码或非原代码代码形式,且不论是否修改,
 // 再分发和使用本软件都是被允许的。
 // 1. 原代码的再分发必须保留上述的版权声明、本条件说明和以下免责声明。
 // 2. 非原代码形式的再分发,必须在证明文件和(或)其它一同提供的材料中重新
 //    作上述的版权声明、本条件说明和以下免责声明。
 // 3. 一切提及本软件和使用的广告材料必须显示以下致谢:
 //    本产品包含王卫无(四川绵阳岷山集团有限公司--研究开发中心)开发的软件。
 // 4. 如果没有预先得到特定的书面许可,不能用作者的名字来宣传推广基于本软件得到
 //    的产品。
 //
 // 免责声明:
 // 本软件是由某某作者提供,如果出现以下情况,作者都不承担任何责任。
 // 1. 因作者的说明以及任何明确的或暗示的保证(包括但不限于表达某种商业性和适合某一
 //    特定目的暗示性保证)而产生的损失。
 // 2. 无论在何种情况下,对使用本软件造成的任何直接的、间接的、偶然的、特定的、可预
 //    见性的和连带产生的损失(包括但不限于获取产品和服务、作用丧失、数据遗失、利益损
 //    失或商业干预),无论这些损失是怎样造成的,并且是以何种方式阐释责任。
 // 3. 任何因使用本软件而相关的合同、严格赔偿责任和侵权行为(包含:疏忽或其它)的损失,
 //    甚至即便是可能的此类已经明示或暗示的损失。
 ///


#include "tcpip.h"

#if TCP_DHCP == 0
const UINT16 guwIpAddr[2] = {((cIpAddr1<<8)|cIpAddr2), ((cIpAddr3<<8)|cIpAddr4)};
#else
UINT16 guwIpAddr[2];
#endif

#if TCP_DHCP == 0
const UINT16 guwNetMask[2] = {((cNetMask1<<8)|cNetMask2), ((cNetMask3<<8)|cNetMask4)};
#else
UINT16 guwNetMask[2];
#endif

#if TCP_DHCP == 0
const UINT16 guwDR_IpAddr[2] = {((cDR_IpAddr1<<8)|cDR_IpAddr2), ((cDR_IpAddr3<<8)|cDR_IpAddr4)};
#else
UINT16 guwDR_IpAddr[2];
#endif

const UINT16 guwEthAddr[3] = {((cEthAddr1<<8)|cEthAddr2), ((cEthAddr3<<8)|cEthAddr4), ((cEthAddr5<<8)|cEthAddr6)};



// 最大允许的以太包缓冲区
UINT16 guwEthBuf[cEthBufSize];

// 正在处理包的字节长度。这个值随处理层的不同而改变!
volatile UINT16 guwEthLen = 0;

// 分配ARP表的内寸
ArpEntries_Stru		gstArpTab[cArpTabSize];

// 记录本地IP序号
volatile UINT16 guwIpId;

// TCP 本地初始32位序号
volatile UINT16 guwISN[2];

// 记录TCP本地端口号
UINT16 guwListenPorts[cMaxListenPorts];

// TCP最大联接事务记录表
Conn_Stru			gstConns[cMaxConnetions];

// 当前TCP事务联接指针
Conn_Stru *gptConn;

// TCP/IP协议栈和应用程序间通讯的变量
volatile UINT16 guwFlags;

//--------------------------------------------------------------------------------------
void msip_Init(void){
	UINT16 index;

	// Initialize ArpEntries
	for (index = 0; index < cArpTabSize; index++){
		gstArpTab[index].IpAddr[0] = 0;
		gstArpTab[index].IpAddr[1] = 0;
	}

	// Initialize Listen Ports
	for (index = 0; index < cMaxListenPorts; index++)
		guwListenPorts[index] = 0;
	
	// Initialize Listen Ports
	for (index = 0; index < cMaxConnetions; index++){
		gstConns[index].TcpStateFlags = cTCP_CLOSED;
		gstConns[index].PollTime = 0;
	}
		
}

//--------------------------------------------------------------------------------------
void msip_Arp_Time(){
	ArpEntries_Stru *pARP;

	for (pARP = cptArpTabStart; pARP < cptArpTabEnd; pARP++){
		if (((pARP->IpAddr[0] | pARP->IpAddr[1]) != 0) && ((guwTime2 - pARP->Time2) > 2*cArpMaxAge)){
			pARP->IpAddr[0] = 0;
			pARP->IpAddr[1] = 0;
		}
	}

	guwMsg_Route &= ~cM_ARP_TIME;	// 清除ARP表老化处理事件
}

//--------------------------------------------------------------------------------------
ArpEntries_Stru *msip_Arp_Update(UINT16 *uwIpAddr, UINT16 *uwEthAddr){
	ArpEntries_Stru *pARPTAB, *pARPTAB1;
	UINT16 maxtime,cmptime;

	// 如果接收包的源地址与本地相同,说明是DDoS攻击!!!
	if ((uwIpAddr[0] == guwIpAddr[0]) && (uwIpAddr[1] == guwIpAddr[1])){
		return cptArpTabEnd;
	}

	// 如果找到匹配的IP,就更新MAC 
	for (pARPTAB = cptArpTabStart; pARPTAB < cptArpTabEnd; pARPTAB++){
		if((pARPTAB->IpAddr[0] == uwIpAddr[0]) && (pARPTAB->IpAddr[1] == uwIpAddr[1])){
			goto Arp_Update_Exit2;	// 更新 MAC/Time
		}
	}

	// 没有找到匹配IP,找个空记录来更新
	for (pARPTAB = cptArpTabStart; pARPTAB < cptArpTabEnd; pARPTAB++){
		if((pARPTAB->IpAddr[0] | pARPTAB->IpAddr[1]) == 0){
			goto Arp_Update_Exit1;	// 更新 IP/MAC/Time
		}
	}

	// 既没有匹配IP,又没有空记录!把时间最长的记录更新
	maxtime = 0;
	for (pARPTAB1 = cptArpTabStart; pARPTAB1 < cptArpTabEnd; pARPTAB1++){
		cmptime = guwTime2 - pARPTAB1->Time2;	// 计算记录存放时间
		if(cmptime > maxtime){
			maxtime = cmptime;			// 记录最大时间
			pARPTAB = pARPTAB1;				// 记录ARP表指针
		}
	}
	
Arp_Update_Exit1:
	pARPTAB->IpAddr[0] = uwIpAddr[0];
	pARPTAB->IpAddr[1] = uwIpAddr[1];

Arp_Update_Exit2:
	pARPTAB->EthAddr[0] = uwEthAddr[0];
	pARPTAB->EthAddr[1] = uwEthAddr[1];
	pARPTAB->EthAddr[2] = uwEthAddr[2];
	pARPTAB->Time2 = guwTime2;
	
	return pARPTAB;
}

//--------------------------------------------------------------------------------------
void msip_Arp_In(void){
	
	// 如果接收包的源地址与本地相同,说明是DDoS攻击!!!
	if ((cptArpHdrBuf->SndIpAddr[0] == guwIpAddr[0]) &&
		(cptArpHdrBuf->SndIpAddr[1] == guwIpAddr[1])){
		goto arp_in_exit;
	}

	// 如果不是请求本地,就退出!
	if ((cptArpHdrBuf->RcvIpAddr[0] != guwIpAddr[0]) || 
		(cptArpHdrBuf->RcvIpAddr[1] != guwIpAddr[1])){
		goto arp_in_exit;
	}

	switch (cptArpHdrBuf->OpCode){
	case cArpRequest:
	// 如果是ARP请求,就构造ARP回应
		cptEthHdrBuf->DestEthAddr[0] = cptArpHdrBuf->SndEthAddr[0];
		cptArpHdrBuf->RcvEthAddr[0] = cptArpHdrBuf->SndEthAddr[0];
			
		cptEthHdrBuf->DestEthAddr[1] = cptArpHdrBuf->SndEthAddr[1];
		cptArpHdrBuf->RcvEthAddr[1] = cptArpHdrBuf->SndEthAddr[1];
		
		cptEthHdrBuf->DestEthAddr[2] = cptArpHdrBuf->SndEthAddr[2];
		cptArpHdrBuf->RcvEthAddr[2] = cptArpHdrBuf->SndEthAddr[2];
			
		cptEthHdrBuf->SrcEthAddr[0] = guwEthAddr[0];
		cptArpHdrBuf->SndEthAddr[0] = guwEthAddr[0];
			
		cptEthHdrBuf->SrcEthAddr[1] = guwEthAddr[1];
		cptArpHdrBuf->SndEthAddr[1] = guwEthAddr[1];
		
		cptEthHdrBuf->SrcEthAddr[2] = guwEthAddr[2];
		cptArpHdrBuf->SndEthAddr[2] = guwEthAddr[2];
			
		cptArpHdrBuf->RcvIpAddr[0] = cptArpHdrBuf->SndIpAddr[0];
		cptArpHdrBuf->RcvIpAddr[1] = cptArpHdrBuf->SndIpAddr[1];
		cptArpHdrBuf->SndIpAddr[0] = guwIpAddr[0];
		cptArpHdrBuf->SndIpAddr[1] = guwIpAddr[1];

		cptArpHdrBuf->OpCode = cArpReply;
		// cptEthHdrBuf->EthType: is unchanged
		// cptArpHdrBuf->HwType: is unchanged
		// cptArpHdrBuf->ProtoType: is unchanged
		// cptArpHdrBuf->HwLen8Proto8:  is unchanged
			
		// 发送以太包
		guwEthLen = 60;
		ether_Send();
		break;
	case cArpReply:
	// 如果是ARP回应,就更新ARP表
		msip_Arp_Update(cptArpHdrBuf->SndIpAddr, cptArpHdrBuf->SndEthAddr);
	}

arp_in_exit:

	// 释放缓冲区
	guwEthLen = 0;
}


//--------------------------------------------------------------------------------------
void msip_Arp_Out(ArpEntries_Stru *pARPTAB){

	// 如果指针是否在ARP表范围内,就构造以太头
	if ((pARPTAB >= cptArpTabStart) && (pARPTAB < cptArpTabEnd)){
		goto build_eth;
	}
	
	// 指针不在ARP范围,检查远端IP是否在本地网内,以决定ARP请求的远端IP地址
	if (((cptIpHdrBuf->DestIpAddr[0] & guwNetMask[0]) == (guwIpAddr[0] & guwNetMask[0])) &&
		((cptIpHdrBuf->DestIpAddr[1] & guwNetMask[1]) == (guwIpAddr[1] & guwNetMask[1]))){
		// IP在本地网内,在ARP表里查找对应远端IP地址的表指针
		for (pARPTAB = cptArpTabStart; pARPTAB < cptArpTabEnd; pARPTAB++){
		
			if((pARPTAB->IpAddr[0] == cptIpHdrBuf->DestIpAddr[0]) &&
				(pARPTAB->IpAddr[1] == cptIpHdrBuf->DestIpAddr[1])){
				
				goto build_eth;
			}
		}

		goto request_local;

	} else {
		// 远端IP不在本地网内,在ARP表里查找网关IP地址的表指针
		for (pARPTAB = cptArpTabStart; pARPTAB < cptArpTabEnd; pARPTAB++){

			if((pARPTAB->IpAddr[0] == guwDR_IpAddr[0]) && (pARPTAB->IpAddr[1] == guwDR_IpAddr[1])){

				goto build_eth;
			}
		}
		
		//goto request_gateway;
	}


// 如果到这里,表明在ARP表里找不到相应的IP记录!所以构造需要的ARP请求包
request_gateway:
	cptArpHdrBuf->RcvIpAddr[0] = guwDR_IpAddr[0];
	cptArpHdrBuf->RcvIpAddr[1] = guwDR_IpAddr[1];
	goto build_arp;

request_local:
	cptArpHdrBuf->RcvIpAddr[0] = cptIpHdrBuf->DestIpAddr[0];
	cptArpHdrBuf->RcvIpAddr[1] = cptIpHdrBuf->DestIpAddr[1];

build_arp:
	cptArpHdrBuf->SndIpAddr[0] = guwIpAddr[0];
	cptArpHdrBuf->SndIpAddr[1] = guwIpAddr[1];

	cptEthHdrBuf->DestEthAddr[0] = 0xffff;
	cptEthHdrBuf->DestEthAddr[1] = 0xffff;
	cptEthHdrBuf->DestEthAddr[2] = 0xffff;

	cptArpHdrBuf->RcvEthAddr[0] = 0x0000;
	cptArpHdrBuf->RcvEthAddr[1] = 0x0000;
	cptArpHdrBuf->RcvEthAddr[2]	= 0x0000;

	cptEthHdrBuf->SrcEthAddr[0] = guwEthAddr[0];
	cptArpHdrBuf->SndEthAddr[0] = guwEthAddr[0];
	
	cptEthHdrBuf->SrcEthAddr[1] = guwEthAddr[1];
	cptArpHdrBuf->SndEthAddr[1] = guwEthAddr[1];
	
	cptEthHdrBuf->SrcEthAddr[2] = guwEthAddr[2];
	cptArpHdrBuf->SndEthAddr[2] = guwEthAddr[2];

	cptEthHdrBuf->EthType = cEthType_Arp;
	cptArpHdrBuf->HwType = cHwType_Eth;
	cptArpHdrBuf->ProtoType = cEthType_Ip;
	cptArpHdrBuf->Hw8Proto8 = c_vIP4;
	cptArpHdrBuf->OpCode = cArpRequest;
		
	guwEthLen = 60;
	goto send_eth;	// 跳到发送以太包处理

build_eth:
	// 构造需要的以太头
	cptEthHdrBuf->DestEthAddr[0] = pARPTAB->EthAddr[0];
	cptEthHdrBuf->DestEthAddr[1] = pARPTAB->EthAddr[1];
	cptEthHdrBuf->DestEthAddr[2] = pARPTAB->EthAddr[2];
	cptEthHdrBuf->SrcEthAddr[0] = guwEthAddr[0];
	cptEthHdrBuf->SrcEthAddr[1] = guwEthAddr[1];
	cptEthHdrBuf->SrcEthAddr[2] = guwEthAddr[2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -