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

📄 rricirc.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 2 页
字号:
/**            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/22 14:09:54 $*  $Source: M:/psisrc/routing/rrfdb/rcs/rricirc.c $*  $Revision: 1.7 $****************************************************************************  File Description: Circuit creation and deletion utilities for IP **************************************************************************/#include <riproute.h>#include <rrport.h>#include <icirc.h>#include "rripfdb.h"#ifdef OSPF_PROTOCOL#include "fnsrr.h"#endiffnc_prot(icirc_pt, ipCircFromId, (int))fnc_prot(void, ipCircDisable,(icirc_pt c))fnc_prot(iproute_ent_pt, ipFindRoute,(ipna_pt,int))fnc_prot(void, ipDelRoute,(iproute_ent_pt iprt))fnc_prot(int,ipCircFreeId,(icirc_pt * link_after))fnc_prot(int,ipCircEnable,(icirc_pt c))/*********************************************ipCircuitInit:initialize contents of newly createdcircuit struct.Reference: utility*********************************************/int ipCircuitInit(icirc_pt circuit, snad_pt ladd, int type, int maxlen, int if_id){	int cid = circuit->rc_id;	ipFillMem((circuit), 0, sizeof(ICIRC));	circuit->rc_id = cid;    /* logical to physical port map */    ipL2PPortMap[if_id] = circuit->rc_id;	ipP2LPortMap[circuit->rc_id] = if_id;	/* We don't currently make any use of the ladd parameter */	if( ladd != (snad_pt)0 ) {		/* ladd is src for lan, dst for ptpt */		ipCopyMem((char *)&circuit->rc_ladd, ladd, sizeof(SNAD));	}	circuit->rc_maxlen = maxlen;	/* speeds up forwarding */	ipCircsMtu[cid] = maxlen;	circuit->rc_type = type;	/* speeds up multicast forwarding */	ipCircsType[cid] = type;	circuit->rc_admst = RCIRC_DOWN;	circuit->rc_state = RCIRC_DOWN;	circuit->rc_arprsp = TRUE;	/* only one on a port at a time */	circuit->rc_mcastenl = FALSE;	circuit->rc_mcastprot = 1;#ifdef IPMULTI	circuit->rc_igmp_version = IGMP_DEF_VERSION;	circuit->rc_igmp_state = IGMP_ST_DOWN;	circuit->rc_igmp_qint = IGMP_CDEF_QINT;	circuit->rc_igmp_maxrsp = IGMP_CDEF_MAXRSP;	circuit->rc_igmp_qptimeout = IGMP_CDEF_QPTIO;	circuit->rc_igmp_leaveena = IGMP_CDEF_LEAVEENA;	circuit->rc_igmp_v1qt = IGMP_CDEF_V1QT;#endif	return (1);}/************************************************ipCircCreate:create a circuit.returns 0 or ptr to circuit structReference: utility************************************************/icirc_pt            ipCircCreate(int type, snad_pt ladd, int maxlen,			                     int if_id, int rcid, dword ifspeed){	icirc_pt            circuit, sc;	int                 si;		    if (i_node->rn_num_circ >= MAX_CIRCUIT) {		return (0);	}	/* circ id must also be <= MAX_CIRCUIT */	if (rcid > MAX_CIRCUIT) {		return (0);	}	if ((circuit = (icirc_pt) ipCircuitAlloc(sizeof(ICIRC))) == NULL) {		return (0);	}	else {		i_node->rn_num_circ++;		/* get an available cid if one not requested */		if (rcid) {			if (ipCircFromId(rcid)) {				/* already used */				ipCircuitFree(circuit);				return (0);			}			circuit->rc_id = rcid;			sc = 0;		}		else {			circuit->rc_id = ipCircFreeId(&sc);		}		/* initialize */		if (!ipCircuitInit(circuit, ladd, type, maxlen, if_id)) {			ipCircuitFree(circuit);			return (0);		}		/* link it to hash list */		si = circuit->rc_id & (CIRC_HASHES - 1);		ipGenLink((dll_pt) circuit, (dll_pt) sc,				  (dll_pt) & ip_circ_hash[si]);	}	circuit->rc_tput = ifspeed;    return (circuit);}/*********************************************ipCircSetIPA:Add an IP address to a circuit.We need to disable circ to do this.*********************************************/int                 ipCircSetIPA(icirc_pt c, ipna_pt ipna, void *magic){	int                 i, old_state;	i = 0;	old_state = c->rc_admst;	if (old_state == RCIRC_UP) {		ipCircDisable(c);	}	ipCopyMem(&c->rc_ipa[i], ipna, sizeof(IPNA));	/* used for ptpt, eg dlci. NOTE: multihoming on single logical	   interface now deprecated */	c->rc_magic = magic;	/* put circpt in map array for fast ifid to circ mapping. if	   member non-empty, put in -1 to indicate a multi-homed lookup	   is required. */   if (old_state == RCIRC_UP) {		ipCircEnable(c);	}	return (0);}/********************************************ipCircDelete:deletes a circuit. The circuit must be in the OFFstate before deletion can take place.Reference: utility**********************************************/int                 ipCircDelete(int cid){	icirc_pt            c, tc, sc;	int                 i, done, ifid;		    if ((c = ipCircFromId(cid)) == 0) {		return (-1);	}	if (c->rc_state != RCIRC_DOWN) {		return (-1);	}    	/* adjust phy to logical port map, if no other circ using port,	   set to 0, if still > 1 circ using port, set to -1, else set to	   id of circ */	sc = 0;	done = 0;	ifid = ipL2PPortMap[c->rc_id];	for (i = 0; i < CIRC_HASHES; i++) {		for (tc = (icirc_pt) ip_circ_hash[i].dll_fwd;			 tc; tc = tc->rc_fwd) {			if (tc == c)				continue;			if (ipL2PPortMap[tc->rc_id] == ifid) {				/* still more than one circ using phy port */				if (sc) {					ipP2LPortMap[ifid] = -1;					done = 1;					break;				}				sc = tc;			}			if (done)				break;		}	}	/* physical to logical port map */	if (!done) {		/* 1 or 0 with same ifid */		ipP2LPortMap[ifid] = (sc) ? sc->rc_id : 0;	}#ifdef IP_VLAN	/* foreach port in vlan, adjust phy to log map */	for (ifid = 0; ifid <= MAX_IFID; ifid++) {		if (!RRMSK_CIS_SET(&ipL2PPortMap[c->rc_id], ifid))			continue;		for (i = 0; i < CIRC_HASHES; i++) {			for (tc = (icirc_pt) ip_circ_hash[i].dll_fwd;				 tc; tc = tc->rc_fwd) {				if (tc == c)					continue;				/* if ifid is in tc's port mask */				if (RRMSK_CIS_SET(								  &ipL2PPortMap[tc->rc_id], ifid)) {					/* still more than one circ using phy port */					if (sc) {						ipP2LPortMap[ifid] = -1;						done = 1;						break;					}					sc = tc;				}				if (done)					break;			}		}		/* physical to logical port map */		if (!done) {			/* 1 or 0 with same ifid */			ipP2LPortMap[ifid] = (sc) ? sc->rc_id : 0;		}	}#endif	/* logical to physical port map */#ifdef IP_VLAN	RRMSK_ALLCLR(&ipL2PPortMap[c->rc_id]);#else	ipL2PPortMap[c->rc_id] = 0;#endif#if defined(RIP_PROTOCOL)	/* free associated circs */	ripCircDelete(c->rc_id);#endif#ifdef RR_DVMRP	dvmrpCircDelete(c->rc_id);#endif#ifdef RR_PIM	pimCircDelete(c->rc_id);#endif	/* free the circuit itself */	ipULink((dll_pt) c,	 (dll_pt) & ip_circ_hash[c->rc_id & (CIRC_HASHES - 1)].dll_fwd);#ifndef IP_VLAN#ifdef IPMULTI	/* if does igmp, look for another to replace it */	if (c->rc_mcastenl) {		xc = ipCircFromIFID(ifid);		if (xc)			igmpCircEnable(xc->rc_id);	}#endif#endif	i_node->rn_num_circ--;	ipCircuitFree(c);	return (0);}/*****************************************ipCircFromId:   returns circuit ptr with specified idReference: utility********************************************/icirc_pt            ipCircFromId(int id){	int                 i, index;	icirc_pt            c;	/* go through the hash list */	index = id & (CIRC_HASHES - 1);	for (i = 0, c = (icirc_pt) ip_circ_hash[index].dll_fwd; i < MAX_CIRCUIT && c;		 i++, c = c->rc_fwd) {		if (c->rc_id == id) {			return (c);		}	}	return (0);}/**********************************************ipCircFromIFID:locates circ from ifif, NOT id. Used only forlans. called to find any circ when ip srcaddr = 0. note that it is primarily used foraddr mask req.*********************************************/icirc_pt            ipCircFromIFID(int id){	int                 i;	icirc_pt            c, maybe = 0;	for (i = 0; i < CIRC_HASHES; i++) {		for (c = (icirc_pt) ip_circ_hash[i].dll_fwd; c; c = c->rc_fwd) {			if (!(c->rc_type & RCIRC_LAN))				continue;#ifdef IP_VLAN			if (RRMSK_CIS_SET(&ipL2PPortMap[c->rc_id], id)) {#else			if (ipL2PPortMap[c->rc_id] == id) {#endif				/* we prefer one with multicasting enabled */				if (c->rc_mcastenl) {					return (c);				}				maybe = c;			}		}	}	return ((icirc_pt) maybe);}/******************************************ipCircNextId:gets next greater used id value.used primarily by snmp getnext.Reference: utility******************************************/int                 ipCircNextId(int old_id){	int                 next_id = MAX_CIRCUIT + 1;	int                 i;	icirc_pt            c;	/* go through hash list */	for (i = 0; i < CIRC_HASHES; i++) {		for (c = (icirc_pt) ip_circ_hash[i].dll_fwd; c; c = c->rc_fwd) {			/* see if this ID is lower than last suspect */			if ((c->rc_id > old_id) && (c->rc_id < next_id)) {				next_id = c->rc_id;			}		}	}	if (next_id < MAX_CIRCUIT + 1) {		return (next_id);	}	else {		return (0);	}}/*********************************************************ipCircFreeId:gets the lowest unused circuit id.returns 0 on none free.Reference: utility*********************************************************/int                 ipCircFreeId(icirc_pt * link_after){	icirc_pt            tc;	int                 i, sid = MAX_CIRCUIT + 1;	icirc_pt            sc = 0;	/* find lowest available circ_id */	for (i = 0; i < CIRC_HASHES; i++) {		/* hash bin is empty */		if ((tc = (icirc_pt) ip_circ_hash[i].dll_fwd) == 0) {			/* NOTE: 0 is not used, first index in bin 0 is			   CIRC_HASHES  */			if (i) {				sid = i;				/* done, no need to check further */				break;			}			else {				sid = CIRC_HASHES;			}			/* next bin */			continue;		}		/* bin 0 and first in bin not lowest possible */		if (!i && (tc->rc_id != CIRC_HASHES)) {			sid = CIRC_HASHES;			sc = (icirc_pt) & ip_circ_hash[i].dll_fwd;			continue;		}		/* bin !=0 and first in bin not lowest possible */		if (i && (tc->rc_id != i)) {			sid = i;			sc = (icirc_pt) & ip_circ_hash[i].dll_fwd;			/* no need to check further */			break;		}		/* bin has lowest possbile in first entry */		for (; tc; tc = tc->rc_fwd) {			if (!tc->rc_fwd ||				(tc->rc_fwd->rc_id != (tc->rc_id + CIRC_HASHES))) {				/* end of bin or hole in bin */				if (tc->rc_id + CIRC_HASHES < sid) {					sid = tc->rc_id + CIRC_HASHES;

⌨️ 快捷键说明

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