📄 rip2.c
字号:
/*************************************************************************
*
* 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 + -