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

📄 rrriptx.c

📁 用于嵌入式系统的TCP/IP协议栈及若干服务
💻 C
📖 第 1 页 / 共 2 页
字号:
					MD5Final(&context);					rrCopyMem((unsigned char *)&start->ra_ipa3,							  context.digest, 16 );				}				/* for src addr, use config src addr if				   we are unnumbered				*/				if(!ipna->ip_add){					/* this may also be unconfigured,					   in which case ip uses routerid					*/					sipa = rc->rc_srcipa;				}				else{					sipa = ipna->ip_add;				}				udptx(rip_bd,len,dport,RIP_PORT,					 dadd,sipa,cid,DELETE);				num_ipadd = 0;				have_hdr = 0;			}			RT_TABLEWALKEND    normal;	/* look at each route in the garbage collection list */	for(iprt= r_node->rn_garb_fwd; iprt; iprt= iprt->iprt_gfwd){			met = RIP_INFINITE;			/* if this is a triggered update, send only			   routes owned by RIP (leaked routes must			   wait) that have the change flag (level			   field used for this) set.			*/			if( trig ){				if(!RT_IS_TRIG(iprt,IPRT_RIP_CHANGED)){					continue;				}			}			/* reset change flag for rip owned routes.			   Only do this for timed updates because			   riptx is called for each port and we			   have no way of knowing in here what the			   last port is.			*/			else if( RT_OWNER(iprt) == IPRT_RIP ){				RT_TRIG_CLR(iprt,IPRT_RIP_CHANGED);			}			/* 			   truncate down to network # if not on			   our subnet, down to our subnet			   mask if in our subnet */			if(rc->rc_r2txmode == R2M_TXV2){				ipadd = RT_DEST(iprt);				mask  = RT_MASK(iprt);			}			else{				/* a real host route */				if( ~RT_MASK(iprt) == 0 ){					ipadd = RT_DEST(iprt);					mask = RT_MASK(iprt);				}				else if( (RT_DEST(iprt) & lclass_mask) ==				    (lnet & lclass_mask) ){					/* same net, diffenent subnet,				        use our subnet mask */					ipadd = RT_DEST(iprt) & lmask;					mask = lmask;				}				else{					/* Truncate add & mask down to class				  	 mask. This does not affect				  	 non-subnets and supernets.					*/					IP_CLASS_MASK(&RT_DEST(iprt), &xmask);					ipadd = RT_DEST(iprt) & xmask;					mask  = RT_MASK(iprt) & xmask;				}				/* make be duplicates due to truncation,				   filter them */				if( have_hdr && RipInPdu(ipadd, start, num_ipadd)){					continue;				}			}						/* build a header if we dont have one */			if(!have_hdr){				/* allocate max len */				if( (rip_bd= (ibd_pt)ripOfAlloc(MAX_RIP_LEN)) == 0){					return;				}				rpdu = (rpdu_pt)rip_bd->ibd_buf;					/* build header ,version1 or 2 */				rpdu->rp_cmd = RIP_CMD_RSP;				if(rc->rc_r2txmode == R2M_TXV1){					rpdu->rp_ver = 1;					rpdu->rp_rd1 = rpdu->rp_rd0 = 0;				}				else{					rpdu->rp_ver = 2;					WTOPDU(&rpdu->rp_rd1,r_node->rn_rdom);				}				start = radd = (ripa_pt)((byte *)rpdu + RIP_HLEN);				if(rc->rc_auth_type == RIP_AUTH_SIMPLE &&				   rc->rc_r2txmode != R2M_TXV1){					/* add an auth entry */					WTOPDU(&radd->ra_afi1, RIP_AFI_AUTH);					WTOPDU(&radd->ra_tag1,rc->rc_auth_type);					rrCopyMem(&radd->ra_ipa3,					          rc->rc_auth_key,16);					radd = ROPT_FWD(radd);					start = radd;					num_ipadd++;				}				else if(rc->rc_auth_type == RIP_AUTH_MD5 &&				   rc->rc_r2txmode != R2M_TXV1){					/* add an auth entry, fill					   in signature before transmit */					WTOPDU(&radd->ra_afi1, RIP_AFI_AUTH);					WTOPDU(&radd->ra_tag1,rc->rc_auth_type);					rrFillMem(&radd->ra_ipa3,0,16);					radd = ROPT_FWD(radd);					start = radd;					num_ipadd++;				}				have_hdr = TRUE;			}			/* fill in IP address option */			WTOPDU(&radd->ra_afi1, RIP_AFI_IP);			WIPA(&radd->ra_ipa3,ipadd);			DWTOPDU(&radd->ra_met3, met);				if(rc->rc_r2txmode == R2M_TXV1){				WIPA(&radd->ra_nh3,0);				WTOPDU(&radd->ra_tag1,0);				DWTOPDU(&radd->ra_msk3,0);			}			else{				if(RT_OWNER(iprt) != IPRT_RIP &&				   RT_OWNER(iprt) != IPRT_LOCAL &&				   RT_TOS0_NHCID(iprt) == cid){					/* route from other prots can				        go directly to next hop */					nhop = RT_TOS0_NHIPA(iprt);				}				else{					nhop = 0;				}				WIPA(&radd->ra_nh3,nhop);				WTOPDU(&radd->ra_tag1,RT_TAG(iprt));				WIPA(&radd->ra_msk3,mask);			}			radd = ROPT_FWD(radd);			if(++num_ipadd >= RIP_MAX_IPADD){				/* pdu full, send it */				len = RIP_HLEN + (num_ipadd * RIP_OPT_LEN); 				/* if md5, need to gen sig now */				if(rc->rc_auth_type == RIP_AUTH_MD5){					MD5Init(&context);					MD5Update(&context,(unsigned char *)start,				       len - RIP_OPT_LEN - RIP_HLEN);					MD5Update(&context,rc->rc_auth_key,16);					start = (ripa_pt)((byte *)start - RIP_OPT_LEN);					/* Fusion MD5 is slightly different.  The digest					   is contained in the MD5_CTX structure.										MD5Final(((unsigned char *)&start->ra_ipa3),&context);					*/					MD5Final(&context);					rrCopyMem((unsigned char *)&start->ra_ipa3,							  context.digest, 16 );									}				/* for src addr, use config src addr if				   we are unnumbered				*/				if(!ipna->ip_add){					/* this may also be unconfigured,					   in which case ip uses routerid					*/					sipa = rc->rc_srcipa;				}				else{					sipa = ipna->ip_add;				}				udptx(rip_bd,len,dport,RIP_PORT,					 dadd,sipa,cid,DELETE);				num_ipadd = 0;				have_hdr = 0;			}			}	/* send off to udp if anything in last fragment */	if(num_ipadd){		len = RIP_HLEN + (num_ipadd * RIP_OPT_LEN); 		/* if md5, need to gen sig now */		if(rc->rc_auth_type == RIP_AUTH_MD5){			MD5Init(&context);			MD5Update(&context,(unsigned char *)start,			          len - RIP_OPT_LEN - RIP_HLEN);			MD5Update(&context,(unsigned char *)rc->rc_auth_key,16);			start = (ripa_pt)((unsigned char *)start - RIP_OPT_LEN);			/* Fusion MD5 is slightly different.  The digest			   is contained in the MD5_CTX structure.						MD5Final(((unsigned char *)&start->ra_ipa3),&context);			*/			MD5Final(&context);			rrCopyMem((unsigned char *)&start->ra_ipa3,					  context.digest, 16 );					}		/* for src addr, use config src addr if		   we are unnumbered		*/		if(!ipna->ip_add){			/* this may also be unconfigured,			   in which case ip uses routerid			*/			sipa = rc->rc_srcipa;		}		else{			sipa = ipna->ip_add;		}		udptx(rip_bd,len,dport,RIP_PORT,				dadd,sipa,cid,DELETE);	}}/*********************************************************RipMetric:get metric value for a route.If owner is RIP, use value in table.If directly connected, use 1.If ISIS and internal type, use rnode.rn_impmet.If ISIS and external, use value in table.********************************************************/int RipMetric(iproute_ent_pt iprt){	/* compiler seems to have problem with switch statement */	/* rip is owner */	if(RT_OWNER(iprt) == IPRT_RIP){		return(RT_TOS0_COST(iprt));	}	/* direct net */	else if(RT_OWNER(iprt) == IPRT_LOCAL){		return(1);	}	/* static */	else if(RT_OWNER(iprt) == IPRT_STATIC){		return(RT_TOS0_COST(iprt));	}	else if(RT_OWNER(iprt) == IPRT_STATICLOW){		return(RT_TOS0_COST(iprt));	}	/* ISIS is owner */	else if(RT_OWNER(iprt) == IPRT_ISIS){		/* internal */		if(RT_IS_INTERNAL(iprt)){			return(r_node->rn_impmet);		}	}	else if(RT_OWNER(iprt) == IPRT_OSPF){		/* internal */		if(RT_IS_INTERNAL(iprt)){			return(r_node->rn_impmet);		}		else{			return(RT_COST2(iprt));		}	}	else if(RT_OWNER(iprt) == IPRT_BGP){			return(r_node->rn_impmet);	}	else{		return(RIP_INFINITE +1);	}	/* for compiler */	return(0);}/**********************************************RipInPdu:determines if address has already been added to pdu.**********************************************/int RipInPdu(rripa ipadd,ripa_pt ripa, int num){	int i;	for(i = 0; i < num; i++, ripa++){		if( XIPA(&ripa->ra_ipa3) == ipadd) return(TRUE);	}	return(FALSE);}/**********************************************RipTxReq:builds and transmits a rip gen request PDU on agiven circuit.**********************************************/void RipTxReq(ipna_pt ipna,int cid){	ibd_pt          rip_bd;	rpdu_pt         rpdu;	ripa_pt 	      radd;	int             len;	rcirc_pt        rc;	rripa			 dadd;	if(r_node->rn_radmst != ROUTER_ON) return;	rc = ripCircFromId(cid);	/* must be on and talking */	if (!rc || rc->rc_state != RCIRC_UP || !rc->rc_talk) {		return;	}	/* allocate max*/	len = RIP_HLEN +RIP_OPT_LEN;	if ((rip_bd = (ibd_pt) ripOfAlloc(len)) == 0) {		return;	}	rpdu = (rpdu_pt) rip_bd->ibd_buf;	/* build header */	rpdu->rp_cmd = RIP_CMD_REQ;	if(rc->rc_r2txmode == R2M_TXV1){		rpdu->rp_ver = 1;		rpdu->rp_rd1 = rpdu->rp_rd0 = 0;	}	else{		rpdu->rp_ver = 2;		WTOPDU(&rpdu->rp_rd1,r_node->rn_rdom);	}	radd = (ripa_pt)((byte *)rpdu + RIP_HLEN);	/* IP address option = all routes */	WTOPDU(&radd->ra_afi1, 0);	WTOPDU(&radd->ra_tag1,0);	WIPA(&radd->ra_ipa3,0);	DWTOPDU(&radd->ra_msk3,0);	DWTOPDU(&radd->ra_nh3,0);	DWTOPDU(&radd->ra_met3, RIP_INFINITE);		/* broadcast dest */	/* always 255.255.255.255 broadcast on ptpt links.	   they may be un-numbered.	*/	if(rc->rc_type == RCIRC_PTPT){		DWTOPDU(&dadd,0xffffffff);	}	/* if rip2 tx mode = rip2, send mcast */	else if(rc->rc_r2txmode == R2M_TXV2){		DWTOPDU(&dadd,RIPV2_MCAST);	}	else{		/* local broadcast */		dadd = ipna->ip_add & ipna->ip_mask;		dadd |= ~ipna->ip_mask;	}	udptx(rip_bd,len,RIP_PORT,RIP_PORT,	             dadd,ipna->ip_add,cid,DELETE);}

⌨️ 快捷键说明

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