?? tcpip.c
字號:
///
// 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 + -