⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udp.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************
*                                                                       
*    CopyrIght (c)  1993 - 2001 Accelerated Technology, Inc.            
*                                                                       
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      
* subject matter of this material.  All manufacturing, reproduction,    
* use, and sales rights pertaining to this subject matter are governed  
* by the license agreement.  The recipient of this software implicitly  
* accepts the terms of the license.                                     
*                                                                       
*************************************************************************/

/* Portions of this program were written by:       */
/*************************************************************************
*                                                                        
*     part of:                                                           
*     TCP/IP kernel for NCSA Telnet                                      
*     by Tim Krauskopf                                                   
*                                                                        
*     National Center for Supercomputing Applications                    
*     152 Computing Applications Building                                
*     605 E. Springfield Ave.                                            
*     Champaign, IL  61820                                               
*                                                                        
*************************************************************************/

/*************************************************************************
*                                                                         
*   FILENAME                                                              
*                                                                         
*       UDP.C                                                             
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       UDP Protocol routines                                             
*                                                                         
*   DATA STRUCTURES                                                       
*                                                                         
*       None
*                                                                         
*   FUNCTIONS                                                             
*                                                                         
*       UDP_Read                                                          
*       UDP_Send                                                          
*       UDP_Append                                                        
*       UDP_Cache_Route                                                   
*       UDP_Interpret             
*       UDP_Make_Port                                               
*       UDP_Port_Cleanup
*                                                                         
*   DEPENDENCIES                                                          
*                                                                         
*       nucleus.h                                                         
*       target.h                                                          
*       mem_defs.h                                                        
*       rtab.h
*       udp.h
*       socketd.h                                                         
*       externs.h                                                         
*       nerrs.h                                                           
*       netevent.h                                                        
*       arp.h                                                             
*       ip.h                                                              
*                                                                         
*************************************************************************/

#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/mem_defs.h"
#include "net/inc/rtab.h"
#include "net/inc/udp.h"
#include "net/inc/socketd.h"
#include "net/inc/externs.h"
#include "net/inc/nerrs.h"
#include "net/inc/netevent.h"
#include "net/inc/arp.h"
#include "net/inc/ip.h"

#if (INCLUDE_SNMP == NU_TRUE)
#include SNMP_GLUE
#endif

/* Should this module even be built? */
#if (INCLUDE_UDP == NU_TRUE)

/* Import external variables */
extern NET_BUFFER_HEADER MEM_Buffer_Freelist;
extern NU_TASK           NU_EventsDispatcher_ptr;
extern NU_TASK           timer_task_ptr;

/*
 * Define the UDP portlist table.  This is a critical structure in Nucleus NET
 * as it maintains information about all open UDP ports.
 */
struct uport *UDP_Ports[UDP_MAX_PORTS];      /* allocate like iobuffers in UNIX */

/* Local Prototypes */
STATUS  UDP_Append(INT port_index, NET_BUFFER *buf_ptr);
STATUS  UDP_Cache_Route (UDP_PORT *, UINT32);

/*************************************************************************
*                                                                         
*   FUNCTION                                                              
*                                                                         
*       UDP_Interpret                                                     
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       Take an incoming UDP packet and make it available to the user 
*       level routines.  Currently keeps the last packet coming in to a 
*       port.
*                                                                         
*       Limitations :                                                     
*                                                                         
*       Can only listen to one UDP port at a time, only saves the last    
*       packet received on that port.  Port numbers should be assigned    
*       like TCP ports.                                                   
*                                                                         
*   INPUTS                                                                
*                                                                         
*       *buf_ptr                                                          
*       *tcp_chk                                                          
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       NU_SUCCESS                                                        
*       2                                                                 
*       -1                                                                
*                                                                         
*************************************************************************/
INT16 UDP_Interpret (NET_BUFFER *buf_ptr, struct pseudotcp *tcp_chk)
{
    UINT16          hischeck, mycheck;
    UINT16          i;
    UINT16          dest_port;
    UDP_PORT        *uptr;
    UDPLAYER        *p;
    struct sock_struct *sockptr;

    /* Increment the number of UDP packets received. */
    SNMP_udpInDatagrams_Inc;

    /* Grab a pointer to the udp layer */
    p = (UDPLAYER *)buf_ptr->data_ptr;

    /* Was a checksum computed by the foreign host?
       If so verfiy the checksum.
    */
    if ((hischeck = GET16(p, UDP_CHECK_OFFSET)) != 0)
    {
        PUT16(p, UDP_CHECK_OFFSET, 0);

        /* Perform the checksum. */
        mycheck = TLS_TCP_Check( (UINT16 *) tcp_chk, buf_ptr );

        /* If a checksum of zero is computed it should be replaced with 0xffff. */
        if (mycheck == 0)
            mycheck = 0xFFFF;

        if (hischeck != mycheck)
        {
            /* The Checksum failed log an error and drop the packet. */
            NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);

            MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);

            /* Increment the number of datagrams received with errors. */
            SNMP_udpInErrors_Inc;

            return (2);
        }
        
        PUT16(p, UDP_CHECK_OFFSET, hischeck);                  /* put it back */
    }


    /*
     *  did we want this data ?  If not, then let it go, no comment
     *  If we want it, copy the relevent information into our structure
     */
    uptr = NU_NULL;
    dest_port = GET16(p, UDP_DEST_OFFSET);
    for (i = 0; i < UDP_MAX_PORTS; i++)
    {
        /* Check to make sure this entry in the UDP_Ports actually points to a
           port structure, and check for the destination port matching the local
           port.  Short circuit evaluation will cause the test to fail
           immediately if the pointer to the port structure is NULL.
        */
        if ((UDP_Ports[i]) && ( dest_port == UDP_Ports[i]->up_lport))
        {
            /* When a match is found our search is over. */
            uptr = UDP_Ports[i];
            break;
        }
    }  /* end for i =0 to UDP_MAX_PORTS*/

    /*  If we did not find a port then we are not waiting for this
        so return.  */
    if (uptr == NU_NULL)
    {
        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);

        /* Increment the number of datagrams received for which there was no
            port. */
        SNMP_udpNoPorts_Inc;

        return(-1);
    }

    sockptr = SCK_Sockets[uptr->up_socketd];

    /* Make sure there is room to add the received packet, then call UDP_Append 
       to add this packet to the ports receive list. */
    if (sockptr && sockptr->s_recvpackets >= UMAX_DGRAMS)
    {
        /* Increment the number of datagrams received with errors. */
        SNMP_udpInErrors_Inc;

        /* Drop the packet by placing it back on the buffer_freelist. */
        MEM_Buffer_Chain_Free (&MEM_Buffer_List, &MEM_Buffer_Freelist);
        return(-1);
    }

    /* Pull the current buffer chain off of the receive list. It will be added 
       to the a port's receive list by UDP_Append. */ 
    MEM_Buffer_Dequeue(&MEM_Buffer_List);

    /* Add the received packet to the appropriate port's receive list. */
    UDP_Append((INT)i, buf_ptr);

    return (NU_SUCCESS);
}   /* UDP_Interpret */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       UDP_Append                                                       
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Add a received packet to a sockets receive list.                 
*                                                                       
*   INPUTS                                                                
*                                                                       
*       port_index                                                       
*       *buf_ptr                                                         
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                                                       
*                                                                       
*************************************************************************/
STATUS UDP_Append(INT port_index, NET_BUFFER *buf_ptr)
{
    UDP_PORT    *uptr = UDP_Ports[port_index];
    struct sock_struct *sockptr;
    STATUS      status = NU_SUCCESS;

    if ((sockptr = SCK_Sockets[uptr->up_socketd]) != NU_NULL)
    {

        /* Strip off the UDP layer. */
        buf_ptr->data_ptr           += sizeof (UDPLAYER);
        buf_ptr->data_len           -= sizeof (UDPLAYER);
        buf_ptr->mem_total_data_len -= sizeof (UDPLAYER);

        /* Place the datagram onto this ports datagram list. */
        MEM_Buffer_Enqueue(&sockptr->s_recvlist, buf_ptr);

        /* Update the number of buffered datagrams. */
        sockptr->s_recvpackets++;

        /* If there is a task pending data on the port, then set an event to
           resume that task. */
        sockptr = SCK_Sockets[uptr->up_socketd];
        if(sockptr && sockptr->s_RXTask)
            TLS_Put_Event (UDPDATA, (UNSIGNED)uptr->up_socketd);
    }
    else
    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -