📄 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 "44b.h"
#include "44blib.h"
#include "def.h"
#include "option.h"
#include "ethernet.h"
#include "arp.h"
#include "string.h"
//#include "stdlib.h"
#include "stdio.h"
#include "ip.h"
#include "lib.h"
#include "icmp.h"
#include "udp.h"
extern unsigned char debug;
extern unsigned long my_ipaddr;
unsigned short sender_udpport;
static unsigned long sender_ipaddr;
//extern char text[];
//------------------------------------------------------------------------
// This handles outgoing UDP messages
// See "TCP/IP Illustrated, Volume 1" Sect 11.1 - 11.3
//------------------------------------------------------------------------
void udp_send(unsigned char * inbuf, unsigned short port, unsigned short len)
{
unsigned long sum;
unsigned short result;
unsigned char * outbuf;
struct UDP_HEADER * udp;
struct 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
// Uart_Printf("udp_send_fuction\n");
outbuf = (unsigned char *)malloc(42 + len);
if (outbuf == NULL)
{
// if (debug) printf("UDP: Oops, out of memory\n");
return;
}
udp = (struct UDP_HEADER *)(outbuf + 34);
ip = (struct IP_HEADER *)(outbuf + 14);
// Direct message back to the senders port.
udp->dest_port = ntohs(sender_udpport);
udp->source_port = ntohs(port);
udp->length = ntohs(8 + len);
udp->checksum = 0;
// Fill in data
// Important do not free receive buffer prior to this
memcpy(&udp->msg_data, (inbuf + 42), 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 =ntohl(sender_ipaddr);
ip->source_ipaddr =ntohl(my_ipaddr);
// Sum source_ipaddr, dest_ipaddr, and entire UDP message
sum = (unsigned long)cksum(outbuf + 26, 8 + ntohs(udp->length));
// Add in the rest of pseudoheader which is
// zero, protocol id, and UDP length
sum += (unsigned long)0x0011;
sum += (unsigned long)ntohs(udp->length);
// In case there was a carry, add it back around
result = (unsigned short)(sum + (sum >> 16));
udp->checksum = ntohs(~result);
//if (debug) printf("UDP: Sending msg to IP layer\n");
ip_send(outbuf, sender_ipaddr, UDP_TYPE, ntohs(udp->length));
}
//------------------------------------------------------------------------
// UDP Echo service - see RFC 862
// This simply echos what it received back to the sender
//------------------------------------------------------------------------
void udp_echo_service(unsigned char * inbuf, unsigned short len)
{
// Uart_Printf("udp_echo_service\n");
udp_send(inbuf, ECHO_PORT, len);
}
//------------------------------------------------------------------------
// This handles incoming UDP messages
// See "TCP/IP Illustrated, Volume 1" Sect 11.1 - 11.3
//------------------------------------------------------------------------
void udp_rcve(unsigned char * inbuf, unsigned short len)
{
unsigned short result;
struct UDP_HEADER * udp;
struct IP_HEADER * ip;
unsigned long sum;
// Total of eth & IP headers = 34 bytes
udp = (struct UDP_HEADER *)(inbuf + 34);
ip = (struct 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 < ntohs(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 (ntohs(udp->checksum) == 0)
{
Uart_Printf("UDP: Sender did not compute cksum\n");
}
else
{
// Compute UDP checksum including 12 byte pseudoheader
// Sum source_ipaddr, dest_ipaddr, and entire UDP message
sum = (unsigned long)cksum(inbuf + 26, 8 + ntohs(udp->length));
// Add in the rest of pseudoheader which is
// zero, protocol id, and UDP length
sum += (unsigned long)0x0011;
sum += (unsigned long)ntohs(udp->length);
// In case there was a carry, add it back around
result = (unsigned short)(sum + (sum >> 16));
if (result != 0xFFFF)
{
Uart_Printf("UDP: Error, bad cksum\n");
return;
}
// Uart_Printf("UDP: Msg rcvd with good cksum\n");
}
// Capture sender's port number and ip_addr
// to send return message to
sender_udpport =ntohs(udp->source_port);
// Uart_Printf("sender_udpport= %x\n",sender_udpport);
sender_ipaddr = ntohl(ip->source_ipaddr);
// Uart_Printf(" sender_ipaddr= %x\n",sender_ipaddr);
// See if any applications are on any ports
//Uart_Printf("udp->dest_port= %x\n",ntohs(udp->dest_port));
switch (ntohs(udp->dest_port))
{
case ECHO_PORT:
// Pass it the payload length
udp_echo_service(inbuf, ntohs(udp->length) - 8);
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 + -