📄 udp.c
字号:
/***********************************************************************//* *//* Module: tcp_ip/udp.c *//* Release: 2001.3 *//* Version: 2000.0 *//* Purpose: UDP Related Routines *//* *//*---------------------------------------------------------------------*//* *//* Copyright 2000, Blunk Microsystems *//* ALL RIGHTS RESERVED *//* *//* Licensees have the non-exclusive right to use, modify, or extract *//* this computer program for software development at a single site. *//* This program may be resold or disseminated in executable format *//* only. The source code may not be redistributed or resold. *//* *//* *//***********************************************************************/#include "tcp_ipp.h"#include "ip/ip.h"#include <string.h>/***********************************************************************//* Configuration *//***********************************************************************/#define UDP_MAX_QUEUE 4 /* max number of bufs stored at socket *//***********************************************************************//* Global Variable Definitions *//***********************************************************************/CircLink UdpLruList;/***********************************************************************//* Local Function Definitions *//***********************************************************************//***********************************************************************//* checksum: Compute a UDP pseudo-header checksum *//* *//***********************************************************************/static ui16 checksum(const NetBuf *buf){ Ip *ip = (Ip *)buf->ip_pkt; ui16 *wordp; ui32 sum; /*-------------------------------------------------------------------*/ /* Include source and destination IP addresses. */ /*-------------------------------------------------------------------*/ wordp = (ui16 *)&ip->src_ip; /*lint !e740 */ sum = *wordp++; sum += *wordp++; sum += *wordp++; /*lint !e415 !e416 */ sum += *wordp; /*lint !e415 !e416 */ /*-------------------------------------------------------------------*/ /* Include segment length and protocol value. */ /*-------------------------------------------------------------------*/ sum += htons(buf->length + IPT_UDP); /*-------------------------------------------------------------------*/ /* Calculate checksum on possibly unaligned UDP data. */ /*-------------------------------------------------------------------*/ return DataChecksum(sum, buf);}/***********************************************************************//* Global Function Definitions *//***********************************************************************//***********************************************************************//* UdpInit: Initialize UDP protocol software *//* *//***********************************************************************/void UdpInit(void){ UdpLruList.next_fwd = UdpLruList.next_bck = &UdpLruList;}/***********************************************************************//* UdpNextPort: Return next unused UDP local port number *//* *//***********************************************************************/ui16 UdpNextPort(void){ static ui16 port_num; CircLink *link; int i; for (i = 0; i < (HI_PORT_NUM - LO_PORT_NUM); ++i) { /*-----------------------------------------------------------------*/ /* Increment the port number, wrapping around as necessary. */ /*-----------------------------------------------------------------*/ ++port_num; if ((port_num < LO_PORT_NUM) || (port_num > HI_PORT_NUM)) port_num = LO_PORT_NUM; /*-----------------------------------------------------------------*/ /* Check if the port number is being used. */ /*-----------------------------------------------------------------*/ for (link = UdpLruList.next_bck;; link = link->next_bck) { SOCKET sock = (SOCKET)link; if (link == &UdpLruList) return htons(port_num); if (sock->local.sin_port == htons(port_num)) break; } } return 0;}/***********************************************************************//* UdpIn: Handle an inbound UDP datagram *//* *//***********************************************************************/void UdpIn(void){ Udp *udp; CircLink *link; SOCKET sock; ui16 dst_port, src_port; ui32 dst_addr, src_addr; void *aligned; /*-------------------------------------------------------------------*/ /* Assign application data pointer and length. */ /*-------------------------------------------------------------------*/ RxBuf->app_data = (ui8 *)RxBuf->ip_data + UDP_HLEN; RxBuf->app_len = RxBuf->length - UDP_HLEN; /*-------------------------------------------------------------------*/ /* Ensure UDP header is four-byte aligned. */ /*-------------------------------------------------------------------*/ aligned = (void *)((ui32)RxBuf->ip_data & ~3); if (aligned != RxBuf->ip_data) { memmove(aligned, RxBuf->ip_data, UDP_HLEN); RxBuf->ip_data = aligned; } /*-------------------------------------------------------------------*/ /* Assign pointer to UDP datagram. */ /*-------------------------------------------------------------------*/ udp = aligned; /*-------------------------------------------------------------------*/ /* Verify UDP length. */ /*-------------------------------------------------------------------*/ if (RxBuf->length != ntohs(udp->length)) return; /*-------------------------------------------------------------------*/ /* If optional checksum is set, verify its correctness. */ /*-------------------------------------------------------------------*/ if (udp->checksum && checksum(RxBuf)) return; /*-------------------------------------------------------------------*/ /* Extract local and remote port and address from datagram. */ /*-------------------------------------------------------------------*/ dst_port = udp->dst_port; dst_addr = Net.Ip->dst_ip; src_port = udp->src_port; src_addr = Net.Ip->src_ip; /*-------------------------------------------------------------------*/ /* Try to match local and remote addresses on connected sockets. */ /*-------------------------------------------------------------------*/ for (link = UdpLruList.next_bck;; link = link->next_bck) { if (link == &UdpLruList) { sock = NULL; break; } sock = (SOCKET)link; if ((sock->flags & SF_CONNECTED) == FALSE) continue; if ((sock->local.sin_port == dst_port) && (sock->remote.sin_port == src_port) && (sock->local.sin_addr.s_addr == dst_addr) && (sock->remote.sin_addr.s_addr == src_addr)) { break; } } /*-------------------------------------------------------------------*/ /* If no match, try local address match on unconnected sockets. */ /*-------------------------------------------------------------------*/ if (sock == NULL) { SOCKET port_match = NULL; for (link = UdpLruList.next_bck;; link = link->next_bck) { if (link == &UdpLruList) { sock = NULL; break; } sock = (SOCKET)link; if (sock->flags & SF_CONNECTED) continue; if (sock->local.sin_port == dst_port) { port_match = sock; if (sock->local.sin_addr.s_addr == dst_addr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -