📄 udp.c
字号:
/*
+FHDR------------------------------------------------------------------
Copyright (c),
Tony Yang –51,AVR,ARM firmware developer
Contact:qq 292942278 e-mail:tony_yang123@sina.com.cn
Abstract:
$Id: udp.c,v 1.3 2006/12/31 16:09:13 tony Exp $
-FHDR-------------------------------------------------------------------
*/
#include "config.h"
#include "tcp_ip_cfg.h"
#include "hardware.h"
#include "ethernet.h"
#include "uart0\uart0.h"
#include "icmp.h"
#include "arp.h"
#include "ip.h"
struct UDP_Header * UDp_Header;
SOCKET UDP_Socket[MAX_UDP_LINKS];
/*本地UDP监听端口表*/
u16 UDP_PORT_Listening[MAX_UDP_Listening_Ports];
/****************************************************************************
* 名称:Queue_PUT
* 功能:查询队列QUEUE有效数据字节数
* 入口:无
* 出口: 队列有效数据字节数
****************************************************************************/
u16 Query_Queue_data_available(SOCKET *QUEUE)
{
if(QUEUE->Queue_Front == QUEUE->Queue_Rear)
{
if(QUEUE->Queue_Full)
return(MAX_TCP_UDP_DATA_link_buf_len);
else
return(0);
}
else if(QUEUE->Queue_Rear > QUEUE->Queue_Front)
{
return(QUEUE->Queue_Rear - QUEUE->Queue_Front);
}
else
{
return(MAX_TCP_UDP_DATA_link_buf_len + QUEUE->Queue_Rear - QUEUE->Queue_Front);
}
return(SUCC);
}
/****************************************************************************
* 名称:Queue_PUT
* 功能:查询队列QUEUE空闲空间
* 入口:无
* 出口: 队列空闲字节数
****************************************************************************/
u16 Query_Queue_freespace(SOCKET *QUEUE)
{
return(MAX_TCP_UDP_DATA_link_buf_len - Query_Queue_data_available(QUEUE));
}
/****************************************************************************
* 名称:Queue_PUT
* 功能:QUEUE的队列读取数据
* 入口:buf-数据缓冲区首地址
* len-数据缓存冲区的长度
* 出口: SUCC FAIL
****************************************************************************/
u8 Queue_GET(SOCKET *QUEUE,u8 * buf,u16 len)
{
u16 data_available,i;
data_available = Query_Queue_data_available(QUEUE);
if(len > data_available)
{
len = data_available;
//return(FAIL);
}
if(len >= 1)
QUEUE->Queue_Full = 0;
for(i = 0;i < len;i++)
{
buf[i] = QUEUE->UDP_Buff_Queue[(QUEUE->Queue_Front)++];
if(QUEUE->Queue_Front >= MAX_TCP_UDP_DATA_link_buf_len)
QUEUE->Queue_Front = 0;
}
return(SUCC);
}
/****************************************************************************
* 名称:Queue_PUT
* 功能:向QUEUE的队列写入数据
* 入口:buf-数据缓冲区首地址
* len-数据缓存冲区的长度
* 出口: SUCC FAIL
****************************************************************************/
u8 Queue_PUT(SOCKET *QUEUE,u8 * buf,u16 len)
{
u16 RreeSpace,i;
RreeSpace = Query_Queue_freespace(QUEUE);
if(len > RreeSpace)
{
len = RreeSpace;
//return(FAIL);
}
for(i = 0;i < len;i++)
{
QUEUE->UDP_Buff_Queue[(QUEUE->Queue_Rear)++] = buf[i];
if(QUEUE->Queue_Rear >= MAX_TCP_UDP_DATA_link_buf_len)
QUEUE->Queue_Rear = 0;
}
if(QUEUE->Queue_Rear == QUEUE->Queue_Front)
QUEUE->Queue_Full = 1;
return(SUCC);
}
/****************************************************************************
* 名称:enable_a_port_listen
* 功能:触发一个端口工作为监听状态?
* 入口:PortNUM-端口号
* 出口: SUCC FAIL
****************************************************************************/
u8 enable_a_port_listen(u16 PortNUM)
{
u16 i;
for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
if(UDP_PORT_Listening[i] == 0)
{
UDP_PORT_Listening[i] = PortNUM;
return(SUCC);
}
return(FAIL);
}
/****************************************************************************
* 名称:UDP_initial
* 功能:检查端口是否工作为监听状态?
* 入口:PortNUM-端口号
* 出口: SUCC FAIL
****************************************************************************/
u8 check_port_listening(u16 PortNUM)
{
u16 i;
for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
if(UDP_PORT_Listening[i] == PortNUM)
{
return(SUCC);
}
return(FAIL);
}
/****************************************************************************
* 名称:UDP_initial
* 功能:UDP模块初始化
* 入口:无
* 出口: 无
****************************************************************************/
void UDP_initial(void)
{
u16 i;
u8 j;
for(i = 0;i < MAX_UDP_LINKS;i++)
{
UDP_Socket[i].DEST_Port[0] = 0;
UDP_Socket[i].DEST_Port[1] = 0;
UDP_Socket[i].SRC_Port[0] = 0;
UDP_Socket[i].SRC_Port[1] = 0;
for(j = 0;j < 4;j++)
{
UDP_Socket[i].DEST_IP_Address[j] =0x0;
UDP_Socket[i].SRC_IP_Address[j] = 0x0;
}
UDP_Socket[i].Queue_Rear = 0;
UDP_Socket[i].Queue_Front = 0;
UDP_Socket[i].Queue_Full = 0;
UDP_Socket[i].EN = 0;
}
for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
UDP_PORT_Listening[i] = 0;
}
/****************************************************************************
* 名称:Rcv_UDP_PKT
* 功能:查找四元组,一个四无组表示一个服务器与客户器连接
* 入口:pkt-UDP数据报的首地址,
* index-UDP_Socket的索引
* IP-源/目的首地址
* 出口: 无
****************************************************************************/
u8 Seek_4_elements(u8 * pkt,u16 * index,u8 *IP)
{
u16 i,j,flag;
for(i = 0 ;i < MAX_UDP_Listening_Ports ;i++)
{
if(!UDP_Socket[i].EN)
continue;
/*检查PKT的源端口*/
if(pkt[0] != UDP_Socket[i].DEST_Port[1] || pkt[1] != UDP_Socket[i].DEST_Port[0])
continue;
if(pkt[2] != UDP_Socket[i].SRC_Port[1] || pkt[3] != UDP_Socket[i].SRC_Port[0])
continue;
/*检查PKT的目的地址*/
SendByte(0x55);SendByte(0x55);SendByte(0x55);SendByte(0x55);
flag = SUCC;
for(j = 0;j < 4;j++)
{
if(IP[j] != UDP_Socket[i].DEST_IP_Address[j] )
{
flag = FAIL;
break;
}
}
if(flag == SUCC)
{
*index = i;
return(SUCC);
}
}
return(FAIL);
}
/****************************************************************************
* 名称:Rcv_UDP_PKT
* 功能:写一个四元组,表示一个服务器与客户器连接
* 入口:pkt-UDP数据报的首地址,
index-UDP_Socket的索引
IP-源/目的首地址
* 出口: 无
****************************************************************************/
void Write_4_element(u8 * pkt,u16 index,u8 *IP)
{
u16 i;
UDP_Socket[index].EN = 1;
for(i = 0;i<4;i++)
{
UDP_Socket[index].DEST_IP_Address[i] = IP[i];
UDP_Socket[index].SRC_IP_Address[i] = IP[4+i];
}
UDP_Socket[index].DEST_Port[0] = pkt[1];
UDP_Socket[index].DEST_Port[1] = pkt[0];
UDP_Socket[index].SRC_Port [0] = pkt[3];
UDP_Socket[index].SRC_Port [1] = pkt[2];
}
/****************************************************************************
* 名称:Send_UDP_PKT
* 功能:数据报发送
* 入口:无
* 出口: 无
****************************************************************************/
void Send_UDP_PKT(struct _pkst *TxdData,SOCKET *Sock)
{
u8 buf[1516];
u16 len,i,checksum;
struct _pkst Txddata;
len = 8 + TxdData->length;
for(i = 0;i < 4;i++)
{
buf[i] = Sock->SRC_IP_Address[i];
buf[4 + i] = Sock->DEST_IP_Address[i];
}
buf[8] = 0;
buf[9] = UDP;
buf[10] = len>>8;
buf[11] = len & 0xff;
/*填写UDP首部*/
buf[12] = Sock->SRC_Port[1];
buf[13] = Sock->SRC_Port[0];
buf[14] = Sock->DEST_Port[1];
buf[15] = Sock->DEST_Port[0];
buf[16] = len >> 8;
buf[17] = len & 0xff;
buf[18] = 0;
buf[19] = 0;
for(i = 0;i < TxdData->length;i++)
buf[i + 20] = TxdData->DAPTR[i];
checksum = CheckSumUdp(buf,len + 12 );
buf[18] = checksum >> 8;
buf[19] = checksum & 0xff;
checksum = CheckSumUdp(buf,len + 12 );
SendByte(checksum >> 8); SendByte(checksum & 0xff);
Txddata.DAPTR = buf+12;
Txddata.length = 8;
Txddata.STPTR = TxdData;
Send_IP_PKT(&Txddata,Sock->DEST_IP_Address,UDP);
}
/****************************************************************************
* 名称:Rcv_UDP_PKT
* 功能:数据报接收
* 入口:pkt-UDP数据报的首地址,
lenght-数据报的长度
IP-源/目的首地址
* 出口: 无
****************************************************************************/
void Rcv_UDP_PKT(u8 *pkt,u16 length,u8 * IP)
{
struct _pkst TxdData1;
u16 index;
u16 freespace,i,checksum;
SendByte('y');SendByte('y');
SendByte('y');SendByte('y');
/*计算UDP首部校验和*/
pkt = pkt - 12;/*填充UDP伪首部*/
pkt[0] = 0;
//pkt[1] = UDP;
pkt[2] = pkt[16];
pkt[3] = pkt[17];
pkt = pkt + 12;
checksum = CheckSumUdp(pkt - 12,length + 12);
if(checksum != 0)
return;
//SendByte(checksum >> 8);SendByte(checksum & 0xff);
SendByte('y');SendByte('y');
SendByte('y');SendByte('y');
UDp_Header = (struct UDP_Header *) pkt;
/*检查目的端口是否在监听当中*/
if(check_port_listening(swap_int16(UDp_Header->DEST_Port)) == FAIL)
{
return;
}
SendByte('y');SendByte('y');
SendByte('y');SendByte('y');
/*查找一个四元组*/
if(Seek_4_elements(pkt,&index,IP) == FAIL)
{
SendByte('a');SendByte('a');
SendByte('a');SendByte('a');
/*分配一个UDP_Socket,写入四元组*/
for(i = 0;i < MAX_UDP_LINKS;i++)
{
if(!UDP_Socket[i].EN)
break;
}
if(i >= MAX_UDP_LINKS)
return;
Write_4_element(pkt,i,IP);
index = i;
}
SendByte('z');SendByte('z');
SendByte('z');SendByte('z');
for(i = 0;i<length - 8;i++)
{
SendByte(*(pkt + 8 +i));
}
/*将数据写入UDP_Socket*/
freespace = Query_Queue_freespace(&UDP_Socket[index]);
if((length - 8) > freespace)
return; //溢出
else
{
Queue_PUT(&UDP_Socket[index],pkt + 8,length - 8);
}
freespace = Query_Queue_freespace(&UDP_Socket[index]);
SendByte(freespace & 0xff);SendByte(freespace >> 8);
TxdData1.STPTR = NULL;
TxdData1.length = length - 8;
TxdData1.DAPTR = pkt + 8;
// Send_UDP_PKT(&TxdData1,&UDP_Socket[index]);
return;
}
/*
+FFTR--------------------------------------------------------------------
$Log: udp.c,v $
Revision 1.3 2006/12/31 16:09:13 tony
由于write_file慢(1KB/S)导致FTP服务器put file失序,不写file时序正常
Revision 1.2 2006/12/31 16:04:37 tony
增加FTP代码,SOCKET_status字段
-FFTR--------------------------------------------------------------------
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -