?? udp.c
字號:
/**---------------------版權 (c)----------------------------------------------------------***
*** 作者:顏章健 ***
*** 郵件:jenkinyan@163.com ***
*** ***
***---------------------File Info---------------------------------------------------------***
*** 創 建 人: 顏章健 ***
*** 創建日期: 2008-03-22 ***
*** 創建版本: ***
*** 文件描述: UDP(User Data Protocol) 用戶數據協議 ***
***---------------------------------------------------------------------------------------***
*** 修 訂 人: 顏章健 ***
*** 修訂日期: 2008-04-14 ***
*** 修訂版本: ***
*** 修訂描述: 增加UDP校驗及支持大數據包分片 ***
***---------------------------------------------------------------------------------------**/
#include "config.h"
// UDP 接口鏈表第一個接口
static UDP_SOCKET *UdpFirstSocket;
/********************************************************************************************
*** 函數名稱: UdpCheckSum
*** 函數描述: UDP校驗值計算
*** 入 口:
*** 出 口:
********************************************************************************************/
static uint16 UdpCheckSum(NET_PKT *Packet)
{
__packed uint16 *_ptr;
uint16 i,len;
uint32 sum = 0;
_ptr = (__packed uint16 *)Packet->Data;
while(Packet != NULL)
{
_ptr = (__packed uint16 *)Packet->Data;
len = Packet->Length >> 1;
for(i=0; i<len; i++)
{
sum += *_ptr++;
}
if(Packet->Next == NULL)
{
break;
}
Packet = Packet->Next;
}
if(Packet->Length & 0x0001)
{
sum += ((*_ptr)&0xff);
}
sum = (sum & 0xffff) + ((sum>>16)&0xffff);
if(sum&0xffff0000) sum++;
return (uint16)(sum & 0xffff);
}
/********************************************************************************************
*** 函數名稱: UdpSocketSend
*** 函數描述: 運輸層發送 UDP 數據包
*** 入 口: This :Socket接口
*** Data :用戶數據緩沖區指針
*** Length :用戶數據長度
*** 出 口: 無
********************************************************************************************/
void UdpSocketSend(UDP_SOCKET *This,uint8 *Data,uint16 Length)
{
NET_PKT UdpHead,UdpData;
uint8 i,head[20];
uint16 value16;
// 填充偽頭部內容 TcpHead[] 的前12字節
for(i=0; i<4; i++)
{
head[i] = LinkLayer.Config.Ip[i]; // 本地地址
head[i+4] = This->DestAddr[i]; // 目的地址
}
head[ 8] = 0; head[ 9] = 17;
while(Length)
{
if(Length > 1472)
{
value16 = 1472;
Length -= 1472;
}
else
{
value16 = Length;
Length = 0;
}
UdpData.Data = Data;
UdpData.Length = value16;
UdpData.Next = NULL;
value16 += 8;
head[10] = (value16 >> 8); head[11] = (uint8)value16;
value16 = This->LocalPort;
head[12] = (value16 >> 8); head[13] = (uint8)value16;
value16 = This->DestPort;
head[14] = (value16 >> 8); head[15] = (uint8)value16;
head[16] = head[10]; head[17] = head[11];
head[18] = 0x00; head[19] = 0x00;
UdpHead.Data = head;
UdpHead.Length = 20;
UdpHead.Next = &UdpData;
value16 = ~UdpCheckSum(&UdpHead);
head[18] = (uint8)value16; head[19] = (value16 >> 8);
UdpHead.Data = head + 12;
UdpHead.Length = 8;
UdpHead.Next = &UdpData;
NetLayer.SendPacket(IPF_UDP,This->DestAddr,&UdpHead);
}
}
/********************************************************************************************
*** 函數名稱: UdpSocketCreate
*** 函數描述: 創建UDP接口
*** 入 口: DstAddr :目的地址
*** DstPort :目的端口
*** SrcPort :本地端口
*** Hook :數據處理鉤子函數
*** 出 口:
********************************************************************************************/
//UDP_SOCKET *UdpSocketCreate
uint8 UdpSocketCreate
( UDP_SOCKET *Socket,
uint8 *DstAddr, uint16 DstPort,
uint16 SrcPort, void (*Hook)(UDP_SOCKET *This)
)
{
uint8 i;
UDP_SOCKET *sock;//,*Socket;
/*
if((Socket = (UDP_SOCKET *)malloc(sizeof(UDP_SOCKET))) == NULL)
{
return NULL;
}
// 入口參數過濾
if(DstPort == 0)
{
free(Socket);
return NULL;
}*/
// 設置Socket屬性
for(i=0; i<4; i++) Socket->DestAddr[i] = *DstAddr++;
Socket->This = Socket;
Socket->LocalPort = SrcPort;
Socket->DestPort = DstPort;
Socket->Rxd = NULL;
Socket->Rxl = 0;
//Socket->Send = UdpSendPacket;
Socket->Hook = Hook;
sock = UdpFirstSocket;
while(sock != NULL)
{
if(sock->LocalPort == SrcPort)
{ /*
free(Socket);
return NULL;
*/
return UDP_ERR_PORT_INUSED;
}
sock = sock->Next;
}
// Socket插入鏈表
Socket->Next = UdpFirstSocket;
UdpFirstSocket = Socket;
//return Socket;
return UDP_ERR_NONE;
}
/********************************************************************************************
*** 函數名稱: UdpSocketDelete
*** 函數描述: 刪除已經創建的UDP接口
*** 入 口: Socket :要刪除的接口
*** 出 口: 錯誤信息
********************************************************************************************/
uint8 UdpSocketDelete(UDP_SOCKET *Socket)
{
UDP_SOCKET *sock,*next;
if(Socket != NULL)
{
//free(Socket);
}
else
{
return UDP_ERR_USER;
}
if(UdpFirstSocket == NULL)
{
return UDP_ERR_USER;
}
if(Socket == UdpFirstSocket)
{
UdpFirstSocket = UdpFirstSocket->Next;
return UDP_ERR_NONE;
}
if(UdpFirstSocket->Next == NULL)
{
return UDP_ERR_USER;
}
sock = UdpFirstSocket;
next = sock->Next;
while(next != NULL)
{
if(next == Socket)
{
sock->Next = next->Next;
return UDP_ERR_NONE;
}
next = next->Next;
sock = sock->Next;
}
return UDP_ERR_USER;
}
/********************************************************************************************
*** 函數名稱: UdpReceiveTask
*** 函數描述: UDP 協議接收處理:查找用戶創建的接口,將數據從該接口輸出給用戶Hook處理
*** 入 口: 無
*** 出 口: 無
********************************************************************************************/
void UdpReceiveTask(void)
{
UDP_SOCKET *sock;
uint8 *UdpData;
uint16 UdpDataLength;
uint16 DestPort;
uint16 SourcePort;
// uint8 SourceIp[4];
UdpDataLength = *NetLayer.Rxd;
UdpDataLength = (UdpDataLength & 0x000f) << 2;
UdpData = NetLayer.Rxd + UdpDataLength;
// SourceIp[0] = NetLayer.Rxd[12];
// SourceIp[1] = NetLayer.Rxd[13];
// SourceIp[2] = NetLayer.Rxd[14];
// SourceIp[3] = NetLayer.Rxd[15];
SourcePort = UdpData[0];
SourcePort <<= 8;
SourcePort |= UdpData[1];
DestPort = UdpData[2];
DestPort <<= 8;
DestPort |= UdpData[3];
UdpDataLength = UdpData[4];
UdpDataLength <<= 8;
UdpDataLength |= UdpData[5];
UdpDataLength -= 8;
UdpData += 8;
sock = UdpFirstSocket;
while(sock != NULL)
{
if( (DestPort == sock->LocalPort) // IP包目的端口與Socket的源端口匹配
//&& (SourcePort == sock->DestPort) // IP包的源端口與Socket目的端口匹配
//&& (InetMemCmp(SourceIp,sock->DestAddr,4)) // IP包的源地址與Socket目的地址匹配
)
{
sock->Rxd = UdpData;
sock->Rxl = UdpDataLength;
if(sock->Hook != NULL)
{
sock->Hook(sock->This);
// 把最近活躍的端口排列到鏈表最前面
if(sock != UdpFirstSocket)
{
UdpSocketDelete(sock);
sock->Next = UdpFirstSocket;
UdpFirstSocket = sock;
}
}
sock->Rxd = NULL;
sock->Rxl = 0;
break;
}
sock = sock->Next;
}
}
/********************************************************************************************
*** 函數名稱: UdpInit
*** 函數描述: UDP 協議初始化
*** 入 口: 無
*** 出 口: 無
********************************************************************************************/
void UdpInit(void)
{
UdpFirstSocket = NULL;
}
/********************************************************************************************
*** 文件結束 ***
********************************************************************************************/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -