📄 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 + -