📄 udp.c
字号:
#include <general.h>
extern xdata union IP_address temp_ip_address; //用于存放临时IP地址
extern xdata union Ethernet_address my_ethernet_address; //本机的以太网地址
extern xdata union IP_address my_ip_address; //本机的ip地址
extern unsigned int frameindex; //IP包的序列号
extern xdata union netcard rxdnet;
xdata union netcard UDPSend; // 用于UDP发送缓冲区
extern xdata struct wait arpwait; //用于等待ARP.
extern xdata union IP_address sender_ipaddr; //保存发送者的IP地址
unsigned int xdata sender_udpport; //保存发送者端口
unsigned char idata UDPdebug; //用于调试
//------------------------------------------------------------------------
//函数功能:生成UDP包CRC校验
//
//入参:发送区指针,UDP包的长度(包括头部)
//
//
//
//
//作者:
//
//注意:
//
//
//注释: Mingtree
//日期: 2004-11-10
//------------------------------------------------------------------------
void createudpcrc(union netcard xdata *pTxdnet,unsigned int len)//生成UCP包CRC校验
{
unsigned int result;
pTxdnet->ipframe.ttl=0;
pTxdnet->ipframe.crc=len;
pTxdnet->ipframe.protocal=0x11;
result=checksum(&(pTxdnet->ippacket.ippacket[4]),12+ len);
pTxdnet->tcpframe.crc=result;
}
//------------------------------------------------------------------------
//函数功能:对UDP头进行校验,错误返回0,正确返回1
//
//入参: 无
//
//
//
//
//作者:
//
//注意:
//
//
//注释: Mingtree
//日期: 2004-11-10
//------------------------------------------------------------------------
unsigned char verifyudpcrc(union netcard xdata *pRxdnet)//对ucp头进行校验,错误返回0,正确返回1
{
unsigned int crc;
pRxdnet->ipframe.ttl=0;
pRxdnet->ipframe.protocal=0x11;
//将IP包的16位首部检验和替换成UCP包的长度
pRxdnet->ipframe.crc=pRxdnet->ipframe.totallength-(pRxdnet->ipframe.verandihl&0x0f)*4;
crc=checksum(&(pRxdnet->ippacket.ippacket[4]),pRxdnet->ipframe.crc+12);
if(crc==0) return (1);
return(0);
}
//------------------------------------------------------------------------
//函数功能:发送UDP包(数据包)
//
//入参:flags:TCP包的标志,index_conn:表示哪个连接发数据,hdr_len:整个TCP的长度
//
//
//
//
//作者: Mingtree
//
//注意:
//
//
//注释: Mingtree
//日期: 2004-12-5
//------------------------------------------------------------------------
void udp_send(union netcard xdata *pTxdnet,unsigned char xdata * psource,unsigned int len)
{
unsigned int i;
//头部20字节
pTxdnet->udpframe.sourceport = UDP_PORT; //源端口默认为1550
pTxdnet->udpframe.destport = sender_udpport;
pTxdnet->udpframe.length = len; //注意:有待改进
pTxdnet->udpframe.crc = 0;
//计算检验和
pTxdnet->ipframe.sourceip[0] = my_ip_address.words[0];
pTxdnet->ipframe.sourceip[1] = my_ip_address.words[1];
pTxdnet->ipframe.destip[0] = sender_ipaddr.words[0];
pTxdnet->ipframe.destip[1] = sender_ipaddr.words[1];
for(i=0;i<len-8;i++)
pTxdnet->udpframe.udpdata[i]=psource[i];
createudpcrc(pTxdnet,len);
ip_send(pTxdnet, sender_ipaddr, UDP_TYPE, len);
}
void udp_rcve(union netcard xdata *pRxdnet)
{
unsigned int len;
//compute the len of udp from the ip head.
len=pRxdnet->ipframe.totallength-(pRxdnet->ipframe.verandihl&0x0f)*4;
// The IP length "len" should be the same as the redundant length
// udp->length. TCP/IP Illustrated, Vol 2, Sect 23.7 says to use the
// UDP length, unless IP length < UDP length, in which case the frame
// should be discarded.
if (len < pRxdnet->udpframe.length) return;
// If the checksum is zero it means that the sender did not compute
// it and we should not try to check it.
if (pRxdnet->udpframe.crc == 0)
{
if (UDPdebug) PrintStr("UDP: Sender did not compute cksum\r");
}
else
{
if(verifyudpcrc(pRxdnet))
{
if (UDPdebug) PrintStr("UDP: Msg rcvd with good cksum\r");
// Capture sender's port number and ip_addr
// to send return message to
sender_udpport = pRxdnet->udpframe.sourceport;
sender_ipaddr.words[0]=pRxdnet->ipframe.sourceip[0];
sender_ipaddr.words[1]=pRxdnet->ipframe.sourceip[1];
// See if any applications are on any ports
switch (pRxdnet->udpframe.destport)
{
case ECHO_PORT:
// Pass it the payload length
// udp_echo_service(inbuf, udp->length - 8);
break;
default:
// If no application is registered to handle incoming
// UDP message then send ICMP destination unreachable
udp_send(&UDPSend, pRxdnet->udpframe.udpdata,len);
break;
}
}
else
{
if (UDPdebug) PrintStr("UDP: Error, bad cksum\r");
return;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -