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

📄 fnsrip.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 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 + -