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

📄 rip2.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************
*                                                                       
*            Copyright (c) 1998 - 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.                                     
*                                                                       
*************************************************************************/

/*************************************************************************
*                                                                       
*   FILE NAME                                         VERSION                     
*                                                                               
*       RIP2.C                                          4.4                      
*                                                                               
*   COMPONENT                                                             
*                                                                       
*       Routing                                                          
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Routing Information Protocol 2 per RFC 2453                      
*                                                                       
*   DATA STRUCTURES                                                       
*                                                                       
*       debug_string
*       RIP2_List
*       RIP2_Socket
*                                                                       
*   FUNCTIONS                                                             
*                                                                       
*       NU_Rip2_Initialized                                              
*       RIP2_Task_Entry                                                  
*       RIP2_Update_Table                                                
*       RIP2_IsNetworkClass_ABC                                          
*       RIP2_IsBroadcast_Address                                         
*       RIP2_IsFromMe                                                    
*       RIP2_Find_Route                                                  
*       RIP2_Find_Entry                                                  
*       RIP2_Find_Index                                                  
*       RIP2_Delete_Old                                                  
*       RIP2_Gather_Old                                                  
*       RIP2_Gather_Updated                                              
*       RIP2_Gather_All                                                  
*       RIP2_Send_Updates                                                
*       RIP2_Send_Table                                                  
*       RIP2_Broadcast                                                   
*       RIP2_Request_Routing_Table                                       
*                                                                       
*   DEPENDENCIES                                                          
*                                                                       
*       nucleus.h                                                        
*       target.h                                                         
*       externs.h                                                        
*       ip.h
*       tcp.h
*       nerrs.h
*       rip2.h                                                           
*       rtab.h                                                           
*       udp.h
*       ipraw.h
*                                                                       
*************************************************************************/

#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/ip.h"
#include "net/inc/tcp.h"
#include "net/inc/nerrs.h"
#include "net/inc/rip2.h"
#include "net/inc/rtab.h"
#include "net/inc/udp.h"
#include "net/inc/ipraw.h"

/* Change to NU_TRUE to add debugging output */
#define NU_DEBUG_RIP2    NU_FALSE

#if (NU_DEBUG_RIP2 == NU_TRUE)

/* This debugging function is only an example. You will need to
set this macro to your debug printing routine. */
#define ATI_DEBUG_PRINT(x)  NU_Printf(x);

CHAR debug_string[250];     /* String ATI_DEBUG_PRINT passes */

#endif

#if (INCLUDE_UDP == NU_FALSE)
#error UDP must be included in order to use RIP2.  If you do not wish to use RIP2, remove the file from the build.
#endif

static INT RIP2_Socket;       /* Send or receive socket for broadcasts */

/* delete n at a any one time. */
static ROUTE_NODE *delete_nodes[MAX_DELETES];
static ROUTE_NODE *updated_nodes[MAX_PER_PACKET];
static INT delete_num = 0;
static INT8       *RIP2_Recv_Buffer;

NU_SEMAPHORE      RIP2_Semaphore;
NU_TASK           RIP2_Tcb;

/*  Local prototypes.  */
VOID RIP2_Task_Entry(UNSIGNED argc, VOID *argv);
VOID RIP2_Broadcast( VOID );
VOID RIP2_Request_Routing_Table(RIP2_LIST_NODE *node);
VOID RIP2_Gather_Old(ROUTE_NODE *, UINT32, INT16);
INT RIP2_Delete_Old(VOID);
VOID RIP2_Gather_Updated(ROUTE_NODE *, DV_DEVICE_ENTRY *, INT *);
VOID RIP2_Gather_All(ROUTE_NODE *, DV_DEVICE_ENTRY *, UINT32, INT *);
VOID RIP2_Send_Table( RIP2_LIST_NODE *, RIP2_PACKET *, RIP2_AUTH *, 
                     struct addr_struct *);
VOID RIP2_Send_Updates(RIP2_PACKET *, RIP2_LIST_NODE *, INT,
                       struct addr_struct *);
RIP2_LIST_NODE *RIP2_Find_Entry(UINT8 *addr);
INT16 RIP2_Find_Index(DEV_DEVICE *, UINT16, UINT8 *);
ROUTE_NODE *RIP2_Find_Route( RIP2_ENTRY * );
INT16 RIP2_IsNetworkClass_ABC(UINT8 *);
INT16 RIP2_IsBroadcast_Address(UINT8 *, INT16);
INT16 RIP2_IsFromMe(DV_DEVICE_ENTRY *, struct addr_struct *);
INT RIP2_Update_Table(RIP2_LIST_NODE *, RIP2_PACKET *, INT, RIP2_AUTH *);

extern INT RTAB_Delete_Node( ROUTE_NODE * );
extern ROUTE_NODE *RTAB_Root_Node( VOID );
extern INT RTAB_Compare_Addresses( ROUTE_NODE *, ROUTE_NODE * );
extern VOID RTAB_Init( VOID );

#define RIP2_STACK_SIZE             3000
#define RIP2_BUFFER_SIZE            550

RIP2_LIST_STRUCT  RIP2_List;

/*************************************************************************
*                                                                         
*   FUNCTION                                                              
*                                                                         
*       NU_Rip2_Initialize                                                
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*       This function initializes the RIP 2 module.                       
*                                                                         
*   INPUTS                                                                
*                                                                         
*       RIP2_STRUCT *rip2        Beginning node.                          
*       INT num                  The number of nodes in the tree.         
*                                                                         
*   OUTPUTS                                                               
*                                                                         
*       Returns one of the following Nucleus Status Codes:                
*
*           NU_MEM_ALLOC        Failed to allocate memory.                
*           NU_INVAL            An error occurred.                        
*           NU_SUCCESS          No errors occurred.                       
*                                                                         
*************************************************************************/
STATUS NU_Rip2_Initialize(RIP2_STRUCT *rip2, INT num)
{
    STATUS              status;
    VOID                *pointer;
    struct addr_struct  bcastaddr;
    UINT16              val;
    INT                 i;
    RIP2_LIST_NODE      *node;
    UINT8               rip2_multi_addr[] = {224, 0, 0, 9};    
    NU_IOCTL_OPTION     option;
    IP_MREQ             mgroup;
    
    /*  Allocate space for the RIP2 buffer.  */
    status = NU_Allocate_Memory (&System_Memory, (void **) &RIP2_Recv_Buffer, 
        RIP2_BUFFER_SIZE, NU_SUSPEND);
    
    if (status != NU_SUCCESS)
    {
        NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
        return (NU_MEM_ALLOC);
    }
    
    /* This semaphore will control access to the RIP2 route tables. */
    status = NU_Create_Semaphore(&RIP2_Semaphore, "RIP2SEMA", 1, NU_PRIORITY);
    if( status != NU_SUCCESS )
    {
        NERRS_Log_Error( NERR_FATAL, __FILE__, __LINE__);
        return(NU_INVAL);
    }
    
    /* Next setup the socket that will be used by RIP to send and receive. */
    
    /* fill in a structure with the listening address */
    bcastaddr.family    = NU_FAMILY_IP;
    bcastaddr.port      = RIP_PORT;
    
    /* open a socket interface that we will listen and send on. */
    RIP2_Socket = NU_Socket(NU_FAMILY_IP, NU_TYPE_DGRAM, 0);
    if( RIP2_Socket < 0 )
    {
        NERRS_Log_Error(NERR_FATAL, __FILE__, __LINE__);
        return(NU_INVAL);
    }
    
    /* RIP does not care which address message came from. */
    ((UINT32 *)bcastaddr.id.is_ip_addrs)[0]  = IP_ADDR_ANY;
    bcastaddr.name = "RIP2";
    
    status = NU_Bind(RIP2_Socket, &bcastaddr, 0);
    if( status < 0)
    {
        NERRS_Log_Error(NERR_FATAL, __FILE__, __LINE__);
        return(NU_INVAL);
    }
    
    /* turn on broadcasting for the transmitting socket */
    val = 1;
    status = NU_Setsockopt(RIP2_Socket, SOL_SOCKET,
        SO_BROADCAST, &val, sizeof(val));
    
    if( status != NU_SUCCESS )
    {
        NERRS_Log_Error(NERR_FATAL, __FILE__, __LINE__);
        return(NU_INVAL);
    }
    
    /* Create the list of devices and their configurations to be used with
    RIP2. */
    status = NU_Allocate_Memory(&System_Memory, (VOID **)&node, 
        (UNSIGNED)(num * sizeof(RIP2_LIST_NODE)), 
        (UNSIGNED)NU_NO_SUSPEND);
    if (status != NU_SUCCESS)
        return(NU_MEM_ALLOC);
    
    for (i = 0; i < num; i++)
    {
        /* Look up the device the user wishes to use RIP2 with. */
        node[i].r2_device = DEV_Get_Dev_By_Name(rip2[i].rip2_device_name);
        
        if (node[i].r2_device == NU_NULL)
            return (NU_INVAL);

        /* Does this device want to RX RIP2 messages? If so join the
           multicast group for this device. */
        if ( (rip2[i].rip2_recvmode == RECV_RIP2) ||
             (rip2[i].rip2_recvmode == RECV_BOTH) )
        {
            /* Store the devices name. */
            option.s_optval = (UINT8 *) rip2[i].rip2_device_name;
           
            /* Get the IP address of the device for which we desire to join a
               multicast group. */
            if ( (NU_Ioctl(IOCTL_GETIFADDR, &option, sizeof(option))) == NU_SUCCESS)
            {
                /* Setup the multicast group structure. */
                memcpy (&mgroup.sck_multiaddr, rip2_multi_addr, 4);
                memcpy (&mgroup.sck_inaddr, option.s_ret.s_ipaddr, 4);

                /* Join a multicast group. */
                if ( (NU_Setsockopt(RIP2_Socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mgroup,
                                   sizeof(mgroup)) != NU_SUCCESS) )
                    NERRS_Log_Error(NERR_RECOVERABLE, __FILE__, __LINE__);


            }

        } /* end if RX multicast packets */

        /* If the user specified a new metric then use it. Otherwise continue
           to use the metric already associated with this device. */
        if (rip2[i].rip2_metric)
            node[i].r2_device->dev_metric = rip2[i].rip2_metric;
        
        node[i].r2_sendmode = rip2[i].rip2_sendmode;
        node[i].r2_recvmode = rip2[i].rip2_recvmode;
        
        /* Add this one to the list. */
        DLL_Enqueue (&RIP2_List, &node[i]);
    }
    
    /* Create RIP2 task */
    status = NU_Allocate_Memory(&System_Memory, &pointer, 
        (UNSIGNED)RIP2_STACK_SIZE,
        (UNSIGNED)NU_NO_SUSPEND);
    if (status != NU_SUCCESS)
        return(NU_MEM_ALLOC);
    
    pointer = TLS_Normalize_Ptr(pointer);
    
    status = NU_Create_Task(&RIP2_Tcb, "RIP2TASK", RIP2_Task_Entry,
        (UNSIGNED)0, NU_NULL, pointer,
        (UNSIGNED)RIP2_STACK_SIZE, 3, (UNSIGNED)0,
        NU_PREEMPT, NU_START);
    
    if (status != NU_SUCCESS)
        return(NU_INVAL);
    
    return NU_SUCCESS;
    
} /* NU_Rip2_Initialize */

/*************************************************************************
*                                                                         
*   FUNCTION                                                              
*                                                                         
*       RIP2_Task_Entry                                                   
*                                                                         
*   DESCRIPTION                                                           
*                                                                         
*                                                                         

⌨️ 快捷键说明

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