📄 udp.c
字号:
//-----------------------------------------------------------------------------
// Net UDP.C
//
// This module handles UDP messages
// Refer to RFC 768, 1122
// Also RFC 862 echo, RFC 867 daytime, and RFC 868 time
//-----------------------------------------------------------------------------
#include <string.h>
#include <stdlib.h>
#include "net.h"
#include "ip.h"
#include "cksum.h"
#include "icmp.h"
#include "udp.h"
#include "general.h"
#include "serial.h"
#include "timer.h"
#include <avr/io.h>
extern char text[];
extern ULONG my_ipaddr;
UINT sender_udpport;
ULONG sender_ipaddr;
//------------------------------------------------------------------------
// UDP Echo service - see RFC 862
// This simply echos what it received back to the sender
//------------------------------------------------------------------------
void udp_echo_service(UCHAR * inbuf, UINT len)
{
#ifdef DEBUG
PrintStr("ECHO: Nr chars = ");
memset(text, 0, 10);
itoa(len, text, 10);
PrintStr(text);
PrintStr("\n");
#endif
udp_send(inbuf+42, ECHO_PORT, len);
}
//------------------------------------------------------------------------
// This handles outgoing UDP messages
// See "TCP/IP Illustrated, Volume 1" Sect 11.1 - 11.3
//------------------------------------------------------------------------
void udp_send(UCHAR * buf, UINT port, UINT len)
{
ULONG sum;
UINT result;
UCHAR * outbuf;
UDP_HEADER * udp;
IP_HEADER * ip;
// Allocate memory for entire outgoing message including
// eth & IP headers. Total ethernet message length is:
// 14 byte eth header + 20 byte IP header + 8 byte UDP header
// + length of this data
outbuf = (UCHAR *)malloc(42 + len);
if (outbuf == NULL)
{
#ifdef DEBUG
PrintStr("UDP: Oops, out of memory\n");
#endif
return;
}
udp = (UDP_HEADER *)(outbuf + 34);
ip = (IP_HEADER *)(outbuf + 14);
// Direct message back to the senders port.
udp->dest_port = sender_udpport;
udp->source_port = port;
udp->length = swapint(8 + len);
udp->checksum = 0;
// Fill in data
// Important do not free receive buffer prior to this
memcpy(&udp->msg_data, buf, len);
// Compute checksum including 12 bytes of pseudoheader
// Must pre-fill 2 items in outbuf to do this
// Direct message back to senders ip address
ip->dest_ipaddr = sender_ipaddr;
ip->source_ipaddr = my_ipaddr;
// Sum source_ipaddr, dest_ipaddr, and entire UDP message
sum = (UINT)cksum(outbuf + 26, 8 + swapint(udp->length));
// Add in the rest of pseudoheader which is
// zero, protocol id, and UDP length
sum += (UINT)0x1100;////!!!!
sum += (UINT)udp->length;
// In case there was a carry, add it back around
result = (UINT)(sum + (sum >> 16));
udp->checksum = ~result;
#ifdef DEBUG
PrintStr("UDP: Sending msg to IP layer\n");
#endif
ip_send(outbuf, sender_ipaddr, UDP_TYPE, swapint(udp->length));
}
//------------------------------------------------------------------------
// This handles incoming UDP messages
// See "TCP/IP Illustrated, Volume 1" Sect 11.1 - 11.3
//------------------------------------------------------------------------
void udp_rcve(UCHAR * inbuf, UINT len)
{
UDP_HEADER * udp;
IP_HEADER * ip;
ULONG sum=0;
UINT result=0;
// Total of eth & IP headers = 34 bytes
udp = (UDP_HEADER *)(inbuf + 34);
ip = (IP_HEADER *)(inbuf + 14);
// 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 < swapint(udp->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 (udp->checksum == 0)
{
#ifdef DEBUG
PrintStr("UDP: Sender did not compute cksum\n");
#endif
}
else
{
// Compute UDP checksum including 12 byte pseudoheader
// Sum source_ipaddr, dest_ipaddr, and entire UDP message
sum = (UINT)cksum(inbuf + 26, 8 + swapint(udp->length));
// Add in the rest of pseudoheader which is
// zero, protocol id, and UDP length
sum += (UINT)0x1100;////!!!!
sum += (UINT)udp->length;
// In case there was a carry, add it back around
result = (UINT)(sum + (sum >> 16));
if (result != 0xFFFF)
{
#ifdef DEBUG
PrintStr("UDP: Error, bad cksum\n");
#endif
return;
}
#ifdef DEBUG
PrintStr("UDP: Msg rcvd with good cksum\n");
#endif
}
// Capture sender's port number and ip_addr
// to send return message to
sender_udpport = udp->source_port;
sender_ipaddr = ip->source_ipaddr;
// See if any applications are on any ports
switch (udp->dest_port)
{
case ECHO_PORT:
// Pass it the payload length
udp_echo_service(inbuf, swapint(udp->length) - 8);
break;
case 0x0C1A://6668: RS232 API PORT
// exchange UDP message with rs232
if(swapint(udp->length)-8)PrintStr(inbuf + 34 + 8);
udp_send(RxBuf, 0x0C1A, RxBufLen);
break;
default:
// If no application is registered to handle incoming
// UDP message then send ICMP destination unreachable
dest_unreach_send(inbuf, ip->source_ipaddr);
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -