📄 fnsrip.c
字号:
/** Copyright (c) 1998-2001 by NETsilicon Inc.** This software is copyrighted by and is the sole property of* NETsilicon. All rights, title, ownership, or other interests* in the software remain the property of NETsilicon. This* software may only be used in accordance with the corresponding* license agreement. Any unauthorized use, duplication, transmission,* distribution, or disclosure of this software is expressly forbidden.** This Copyright notice may not be removed or modified without prior* written consent of NETsilicon.** NETsilicon, reserves the right to modify this software* without notice.** NETsilicon* 411 Waverley Oaks Road USA 781.647.1234* Suite 227 http://www.netsilicon.com* Waltham, MA 02452 AmericaSales@netsilicon.com*************************************************************************** $Name: Fusion 6.52 Fusion 6.51 $* $Date: 2002/01/11 15:32:44 $* $Source: M:/psisrc/routing/rip/rcs/fnsrip.c $* $Revision: 1.18 $**************************************************************************** File Description: Some Fusion to RIP interface stuff.***************************************************************************/#include "fnsproto.h"#include "std.h"#include "netdev.h"#include "rconst.h" /* for RIP_PORT */#include "os_const.h" /* for AUTH_TYPE_NONE */#include "ipport.h"#include "riproute.h"#include "rrtask.h"#include "fnsrip.h"#define __FNSRR_C__#include "fnsrr.h"#undef __FNSRR_C__#include "flags.h"#include "in.h"#include "fns_mem.h"#include "nerrno.h"#include "debug.h"#include "icmp.h"import netdev ** ndp_tbl;import int send_2_router(int message_type, netdev * ndp, void *inmsg, void *rmsg );#ifdef DEBUGimport boolean rip_debug;#endif#ifdef TRACEimport boolean fr_trace;#endif#ifdef DEBUGimport boolean fr_debug;#endif/* Called from Fusion UDP to send RIP packets to RIP */export st rip_up (m * mp){#if ROUTER_TASK int err;#endif#if !ROUTER_TASK ipa * from; u16 sport; u32 snethost; int count; use_critical;#endif trace0(fr_trace, "rip_up: \n");#if !ROUTER_TASK /* call riprx directly */ from = &mp->m_src.a_ipa; sport = htons(from->ip_port); snethost = from->ip_nethost; count = m_dsize(mp); critical; /* avoid re-entrancy */ riprx((void *)mp->m_hp, count, ndp_2_cid(mp->m_ndp), snethost, sport); normal; return (st)mp->m_dispfn;#else /* queue the packet to the router task */ mp->m_udsize = m_dsize(mp); mp->m_type = IP_UDP; if( (err = router_task_rx(mp)) != 0 ) { return smerr(mp, err); } return (st)mp->m_dispfn;#endif /* ROUTER_TASK */}/* udptx called from RIP code. It is supposed to send a RIP * packet to the network. * dflag's value is always DELETE, which * means that we will let Fusion free the mp after the RIP packet has been * sent */void udptx(ibd_pt bd, int len, rrword dport, rrword sport, rripa dipa, rripa sipa, int cid,int dflag){ m * mp; int nd_ix; trace0(fr_trace, "udptx\n"); mp = (m *)bd->ibd_gptr; /* ibd_buf points to ULP data (beyond UDP header). Make m_hp point * to it too, since it is used by fusion. */ mp->m_hp = (char *)bd->ibd_buf; assert((mp->m_hp + len) <= mp->m_tp, "udptx buffer corruption\n"); mp->m_tp = mp->m_hp + len; /* RR sometimes over allocate */ /* Initialize mp source and destination fields (used by FUSION * udp_xmit and ip_xmit) */ mp->m_dest.a_len = sizeof(ipa); mp->m_src.a_len = sizeof(ipa); mp->m_dest.a_type = AF_INET; mp->m_src.a_type = AF_INET; mp->m_type = IP_UDP; mp->m_src.a_ipa.ip_port = htons(sport); mp->m_dest.a_ipa.ip_port = htons(dport); mp->m_src.a_ipa.ip_nethost = sipa; mp->m_dest.a_ipa.ip_nethost = dipa;#if !ROUTER_TASK /****** If we don't have a router task ******/ mp->m_flags = F_NONBLOCKING;#else /* if we have a router task */ mp->m_flags = F_BLOCKING;#endif/* cid determines outbound port for a broadcast or multicast. * Otherwise the IP code determines outbound port * by sending to best next hop. */ if (cid != 0) { nd_ix = cid_2_ndix(cid); mp->m_ndp = ndp_tbl[nd_ix]; /* sipa copied above */ } /* If for whatever reason udptx starts needing to be called with dglag != DELETE then we will have to m_dup the message in that case, as is done for ospf (see fnsopsf.c). */ if (dflag != DELETE) { os_panic("udptx called with dflag != DELETE!!\n"); return; } msm(mp, udp_xmit);}/****************************************************************************** * * rip_admin_enable * * Administratively enable/disable RIP for the whole box. Note that it is ON by * default. * * Returns -1 if unrecognized value for adminstate, or if try to enable and * already is enabled, or if try to disable and already is disabled. * * Returns 0 otherwise. */int rip_admin_enable(int adminstate ){ int err = FNS_ENOERR; switch(adminstate) { case RIP_ADMIN_ENABLE:#if ROUTER_TASK err = send_2_router(RIP_MSG_ENABLE_RIP, (netdev *)0, (void *)0, (void *)0);#else err = RipEnable();#endif break; case RIP_ADMIN_DISABLE:#if ROUTER_TASK err = send_2_router(RIP_MSG_DISABLE_RIP, (netdev *)0, (void *)0, (void *)0);#else err = RipDisable(0);#endif break; } if( err < 0 ) { /* The only one right now if that interface was already on/off and tried to turn it on/off. */ err = FNS_EALREADY; } return err;}/****************************************************************************** * * rip_get_admin_state * * Returns: * * RIP_IS_ENABLED if RIP is globally enabled. * RIP_IS_DISABLED if RIP is globally disabled. */int rip_get_admin_state(void){ u32 state; int err;#if ROUTER_TASK err = send_2_router(RIP_MSG_GET_ADMIN_STATE, (netdev *)0, (void *)0, (void *)&state );#else err = rip_do_get_admin_state( &state );#endif if( state == RIP_RET_RIP_DISABLED ) { return RIP_IS_DISABLED; }else { return RIP_IS_ENABLED; }}/****************************************************************************** * * rip_config_interface * * Configure RIP on an interface. * * Inputs: * * devname Fusion device name, e.g. "eth0" * rcfg Pointer to a rip_if_config structure. See * fnsrip.h for the structure definition and * manifest constants available for use with it. * * Returns: * * NOTE: It is no longer clear that it was necessary to use * message-based communication to configure RIP when * using a router task. All of these configuration params * can be changed on the fly with no ill-effect. RIP * circuits are created at startup for now so no chance * of a bad circuit etc. */int rip_configure_interface(char *devname, rip_if_config *rcfg ){ int err = FNS_ENOERR; u32 parm1 = 0; netdev *ndp; int cid; rcirc_pt c; if ((ndp = ll_dev_2_ndp(devname)) == (netdev *)0) { debug1(rip_debug, "rip_configure_interface: no ndevsw entry for \"%s\"",devname); return FNS_ENODEV; } cid = ndp_2_cid(ndp); if((c= ripCircFromId(cid)) == 0 ) { return FNS_ENODEV; /* Really shouldn't happen */ }#if ROUTER_TASK err = send_2_router(RIP_MSG_CONFIG_INTERFACE, ndp, (void *)rcfg, (void *)0 );#else err = rip_do_configure_interface( cid, rcfg );#endif return err;}/****************************************************************************** * * rip_get_interface_info * * Basically the mirror image of rip_configure_interface. Returns * current configuration of given interface. * * Inputs: * * devname - Name of Fusion device, e.g. "eth0" * rinfo - pointer to rip_if_config structure in which current * configuration of interface is returned. * rinfo - sizeof of buffer pointed to by rinfo. Must be * sizeof(rip_if_config). * * See fnsrip.h for rip_if_config structure definition and manifest constants * used with rip_if_config structure. * */int rip_get_interface_info(char *devname, rip_if_config *rinfo, int len){ u32 parm1 = 0; netdev *ndp; int err;#if !ROUTER_TASK int cid;#endif if( !devname || !rinfo || (len != sizeof(rip_if_config)) ) { debug1(rip_debug, "rip_get_interface_info: no ndevsw entry for \"%s\"",devname); } if ((ndp = ll_dev_2_ndp(devname)) == (netdev *)0) { debug1(rip_debug, "rip_get_interface_info: no ndevsw entry for \"%s\"",devname); return FNS_ENODEV; } #if ROUTER_TASK err = send_2_router(RIP_MSG_GET_INTERFACE_INFO, ndp, (void *)0, (void *)rinfo );#else cid = ndp_2_cid(ndp); err = rip_do_get_interface_info( cid, rinfo );#endif return err;}/****************************************************************************** * * The following are either called directly from above if ROUTER_TASK * is false, or are called from rrtask.c in the router task if * ROUTER_TASK is true. * *//****************************************************************************** * * rip_do_configure_interface * * Configure RIP on the circuit for the given interface. * */export int rip_do_configure_interface( int cid, rip_if_config *rcfg ){ int old_state; rcirc_pt c; if((c= ripCircFromId(cid)) == 0 ) { return FNS_ENODEV; /* Really shouldn't happen */ } /* First if RIP was ON on the interface we turn it off and purge all routes learned by RIP (but not static routes). Then we reconfigure and bring back online if it was online. */ old_state = c->rc_state; if(c->rc_state == RCIRC_UP) { c->rc_state = RCIRC_DOWN; RipPurgeRouteByCirc(c); } /* Configure */ switch(rcfg->talk_version) { case RIP_TALK_VERSION_1: c->rc_r2txmode = R2M_TXV1; break; case RIP_TALK_VERSION_2: c->rc_r2txmode = R2M_TXV2; break; case RIP_TALK_VERSION_1_COMPAT: c->rc_r2txmode = R2M_TXV1COMP; break; case RIP_TALK_VERSION_NOCHANGE: break; default: return FNS_EINVAL; } switch(rcfg->talk_state ) { case RIP_TALK_STATE_ENABLED: c->rc_talk = TRUE; break; case RIP_TALK_STATE_DISABLED: c->rc_talk = FALSE; break; case RIP_TALK_STATE_NOCHANGE: break; default: return FNS_EINVAL; } switch(rcfg->listen_version) { case RIP_LISTEN_VERSION_1: c->rc_r2rxmode = R2M_RXV1; break; case RIP_LISTEN_VERSION_2: c->rc_r2rxmode = R2M_RXV2; break; case RIP_LISTEN_VERSION_NOCHANGE: break; default: return FNS_EINVAL; } switch(rcfg->listen_state) { case RIP_LISTEN_STATE_ENABLED: c->rc_listen = TRUE; break; case RIP_LISTEN_STATE_DISABLED: c->rc_listen = FALSE; break; case RIP_LISTEN_STATE_NOCHANGE: break; default: return FNS_EINVAL; } switch(rcfg->auth_type) { case RIP_AUTHTYPE_SIMPLE: c->rc_auth_type = RIP_AUTH_SIMPLE; OS_MEMCPY(c->rc_auth_key, rcfg->auth_key, 16 ); break; case RIP_AUTHTYPE_NONE: c->rc_auth_type = RIP_AUTH_NONE; break; case RIP_AUTHTYPE_NOCHANGE: break; default: return FNS_EINVAL; } if(old_state == RCIRC_UP) { c->rc_state = RCIRC_UP; } return FNS_ENOERR;}/****************************************************************************** * * rip_do_get_interface_info * * Get the configuration of the given interface * * Returns * */export int rip_do_get_interface_info( int cid, rip_if_config *rinfo ){ rcirc_pt c; if((c= ripCircFromId(cid)) == 0 ) { return FNS_ENODEV; /* Really shouldn't happen */ } if( !rinfo ) { return FNS_EINVAL; } /* Fill in the interface info in accordance with the current configuration. */ if( c->rc_r2txmode == R2M_TXV1 ) { rinfo->talk_version = RIP_TALK_VERSION_1; }else if( c->rc_r2txmode == R2M_TXV2 ) { rinfo->talk_version = RIP_TALK_VERSION_2; }else if( c->rc_r2txmode = R2M_TXV1COMP ) { rinfo->talk_version = RIP_TALK_VERSION_1_COMPAT; } if( c->rc_talk != TRUE ) { rinfo->talk_state = RIP_TALK_STATE_DISABLED; }else { rinfo->talk_state = RIP_TALK_STATE_ENABLED; } if( c->rc_r2rxmode == R2M_RXV1 ) { rinfo->listen_version = RIP_LISTEN_VERSION_1; }else if( c->rc_r2txmode == R2M_RXV2 ) { rinfo->listen_version = RIP_LISTEN_VERSION_2; } if( c->rc_listen != TRUE ) { rinfo->listen_state = RIP_LISTEN_STATE_DISABLED; }else { rinfo->listen_state = RIP_LISTEN_STATE_ENABLED; } if( c->rc_auth_type == RIP_AUTH_SIMPLE ) { rinfo->auth_type = RIP_AUTHTYPE_SIMPLE; OS_MEMCPY(rinfo->auth_key, c->rc_auth_key, 16 ); }else if( c->rc_auth_type == RIP_AUTH_NONE ) { rinfo->auth_type = RIP_AUTHTYPE_NONE; } return FNS_ENOERR;}/****************************************************************************** * * Return the global admin state of RIP * */export int rip_do_get_admin_state( u32 *parm1 ){ if( r_node->rn_radmst == ROUTER_OFF ){ *parm1 = RIP_RET_RIP_DISABLED; }else { *parm1 = RIP_RET_RIP_ENABLED; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -