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

📄 hello.c

📁 unix/linux下的路由守护程序
💻 C
📖 第 1 页 / 共 4 页
字号:
	bzero((caddr_t) &rtparms, sizeof (rtparms));	rtparms.rtp_n_gw = 1;	rtparms.rtp_router = task_recv_srcaddr;	rtparms.rtp_gwp = gw_timestamp(&hello_gw_list,				       tp->task_rtproto,				       tp,				       (as_t) 0,				       (as_t) 0,				       rtparms.rtp_router,				       GWF_NEEDHOLD);	rtparms.rtp_gwp->gw_rtd_dump = hello_rt_dump;	rtparms.rtp_gwp->gw_rtd_free = hello_rt_free;	rtparms.rtp_state = (flag_t) 0;	/* If we have a list of trusted gateways, verify that this gateway is trusted */	if (hello_n_trusted && !BIT_TEST(rtparms.rtp_gwp->gw_flags, GWF_TRUSTED)) {	    BIT_SET(rtparms.rtp_gwp->gw_flags, GWF_REJECT);	    continue;	}	/* Do we share a net with the sender? */	if (!(ifap = if_withdst(rtparms.rtp_router))) {	    trace_log_tp(tp,			 0,			 LOG_WARNING,			 ("hello_recv: gw %A no shared net?",			  rtparms.rtp_router));	    BIT_SET(rtparms.rtp_gwp->gw_flags, GWF_REJECT);	    continue;	}	if (sockaddrcmp_in(rtparms.rtp_router, ifap->ifa_addr_local)) {	    /* A packet from us */	    if (!BIT_TEST(ifap->ifa_state, IFS_SIMPLEX)) {		/* If this interface is not simplex, indicate that the media */		/* is functioning */		if_rtupdate(ifap);	    }	    /* Ignore the packet */	    continue;	}	/* update the interface timer on interface the packet came in on. */	if_rtupdate(ifap);	/* Ignore this packet */	if (BIT_TEST(ifap->ifa_ps[tp->task_rtproto].ips_state, IFPS_NOIN)) {	    continue;	}	/* check the hello checksum */	if (inet_cksum((void_t) hello, hello_len)) {	    trace_log_tp(tp,			 0,			 LOG_WARNING,			 ("hello_recv: bad HELLO checksum from %A",			  rtparms.rtp_router));	    BIT_SET(rtparms.rtp_gwp->gw_flags, GWF_CHECKSUM);	    continue;	}	rt_open(tp);	/* message is made up of one or more sub messages */	hello += Size_hellohdr;	while (hello < end) {	    PickUp_hm_hdr(hello, hm_hdr);	    switch (hm_hdr.hm_type) {	    case 0:		hello += Size_type0pair * hm_hdr.hm_count;		/* not interested in type 0 messages */		break;	    case 1:		for (i = 0; i < hm_hdr.hm_count; i++) {		    register rt_entry *rt;		    struct type1pair type1pair;		    PickUp_type1pair(hello, type1pair);		    rtparms.rtp_dest = sockbuild_in(0, type1pair.d1_dst);		    if (!inet_class_valid(rtparms.rtp_dest)) {			continue;		    }		    rtparms.rtp_preference = hello_preference;		    rtparms.rtp_metric = type1pair.d1_delay;				    /* Force delay to be valid */		    if (rtparms.rtp_metric > HELLO_UNREACHABLE) {			rtparms.rtp_metric = HELLO_UNREACHABLE;		    }		    /*		     *	Add the interface metric converted to a HELLO delay.		     */		    rtparms.rtp_metric += ifap->ifa_ps[tp->task_rtproto].ips_metric_in;		    rtparms.rtp_state = RTS_INTERIOR;		    		    rtparms.rtp_dest_mask = inet_mask_withif(rtparms.rtp_dest, ifap, &rtparms.rtp_state);		    if (!rtparms.rtp_dest_mask) {			/* Ignore zero subnet */			continue;		    }		    if (if_myaddr(ifap, rtparms.rtp_dest, rtparms.rtp_dest_mask)) {			/* Ignore route to interface or whole network */			continue;		    }		    rt = rt_locate(rtparms.rtp_state,				   rtparms.rtp_dest,				   rtparms.rtp_dest_mask,				   RTPROTO_BIT(tp->task_rtproto));		    if (!rt) {			rt_head *rth;	    			/* No route installed.  See if we are announcing another route */			rt = rt_locate(RTS_NETROUTE,				       rtparms.rtp_dest,				       rtparms.rtp_dest_mask,				       RTPROTO_BIT_ANY);			if (rt &&			    (rth = rt->rt_head) &&			    rth->rth_n_announce &&			    (rt == rth->rth_active || rt == rth->rth_holddown)) {			    /* We are announcing this route */			    register target *tlp;			    /* HELLO won't announce an active route if one in holddown */			    /* so check the holddown route first */			    rt = rth->rth_holddown;			    if (!rt) {				rt = rth->rth_active;			    }			    TARGET_LIST(tlp, &hello_targets) {				if (BIT_TEST(tlp->target_flags, TARGETF_SUPPLY) &&				    rtbit_isset(rt, tlp->target_rtbit)) {				    /* We are sending to this target */				    td_entry *tdp;				    TD_TSI_GET(tlp, rth, tdp);				    if (BIT_TEST(tdp->td_flags, TDF_HOLDDOWN|TDF_POISON) ||					tdp->td_metric < rtparms.rtp_metric) {					/* We are announcing this route from another protocol */					break;				    }				}			    } TARGET_LIST_END(tlp, &hello_targets) ;			    if (tlp) {				/* Announced via another protocol, ignore this route */				continue;			    }			}	    			/* New route */			if (rtparms.rtp_metric < HELLO_UNREACHABLE &&			    import(rtparms.rtp_dest,				   rtparms.rtp_dest_mask,				   hello_import_list,				   ifap->ifa_ps[tp->task_rtproto].ips_import,				   rtparms.rtp_gwp->gw_import,				   &rtparms.rtp_preference,				   ifap,				   (void_t) 0)) {			    /* Allocate space for the hysterisis */			    rtparms.rtp_rtd = task_block_alloc(hello_win_block_index);			    			    hello_win_init(rtparms.rtp_rtd, rtparms.rtp_metric);			    /* Add new route */			    rt = rt_add(&rtparms);			    if (!rt) {				task_block_free(hello_win_block_index, rtparms.rtp_rtd);				rtparms.rtp_rtd = (void_t) 0;			    }			} else {			    BIT_SET(rtparms.rtp_gwp->gw_flags, GWF_IMPORT);			}		    } else if (sockaddrcmp_in(RT_ROUTER(rt), rtparms.rtp_router)) {			/* same route */			if (rtparms.rtp_metric >= HELLO_UNREACHABLE) {			    /* Now unreachable -  Delete route */			    hello_win_add(rt->rt_data, HELLO_UNREACHABLE);			    rt_delete(rt);			} else if (METRIC_DIFF(rt->rt_metric, rtparms.rtp_metric) >= HELLO_HYST(rt->rt_metric)) {			    /* Better metric */			    if ((rt = rt_change(rt,						rtparms.rtp_metric,						rtparms.rtp_metric2,						rtparms.rtp_tag,						rt->rt_preference,						rt->rt_preference2,						rt->rt_n_gw, rt->rt_routers))) {				hello_win_add(rt->rt_data, (metric_t) rtparms.rtp_metric);				rt_refresh(rt);			    }			} else {			    /* No change */			    rt_refresh(rt);			}		    } else if (((rtparms.rtp_metric < rt->rt_metric				 && METRIC_DIFF(rtparms.rtp_metric, rt->rt_metric) >= HELLO_HYST(rt->rt_metric))				|| (rt_age(rt) > (HELLO_T_EXPIRE / 2)				    && rt->rt_metric == rtparms.rtp_metric))			       && import(rtparms.rtp_dest,					 rtparms.rtp_dest_mask,					 hello_import_list,					 ifap->ifa_ps[tp->task_rtproto].ips_import,					 rtparms.rtp_gwp->gw_import,					 &rtparms.rtp_preference,					 ifap,					 (void_t) 0)) {			/* Better metric or same metric and old route has */			/* not been refreshed */			hello_win_add(rt->rt_data, HELLO_UNREACHABLE);			rt_delete(rt);			/* Allocate space for the hysterisis */			rtparms.rtp_rtd = task_block_alloc(hello_win_block_index);			    			hello_win_init(rtparms.rtp_rtd, rtparms.rtp_metric);			/* Add new route */			rt = rt_add(&rtparms);			if (!rt) {			    task_block_free(hello_win_block_index, rtparms.rtp_rtd);			    rtparms.rtp_rtd = (void_t) 0;			}		    }		}			/* for each advertized net */		break;	    default:		trace_log_tp(tp,			     0,			     LOG_ERR,			     ("hello_recv: invalid type %d",			      hm_hdr.hm_type));		BIT_SET(rtparms.rtp_gwp->gw_flags, GWF_FORMAT);		/* Force end of packet */		hello = end;	    } /* switch (mh->hm_type) */	} 	/* while not end of packet */	rt_close(tp, rtparms.rtp_gwp, (int) hm_hdr.hm_count, NULL);    }}/* Send HELLO updates to all targets on the list *//*ARGSUSED*/static voidhello_supply __PF2(tlp, target *,		   flash_update, int){    byte *packet = task_get_send_buffer(byte *);    byte *start = packet + Size_hellohdr + Size_hm_hdr;    byte *fillp = start;    register td_entry *tdp;    size_t maxsize = 0;    int changes = 0;	    /* Open the routing table in case a holddown is over */    rt_open(tlp->target_task);    TD_LIST(tdp, &tlp->target_td) {	int cleanup = 0;	struct type1pair type1pair;	if (flash_update) {	    if (!BIT_TEST(tdp->td_flags, TDF_CHANGED)) {		/* End of changes for this target */		    		break;	    }	} else {	    if (BIT_TEST(tdp->td_flags, TDF_HOLDDOWN|TDF_POISON)		&& !--tdp->td_metric) {		/* Holddown is over - queue it to be released */		cleanup++;	    }	}	if (BIT_TEST(tdp->td_flags, TDF_CHANGED)) {	    BIT_RESET(tdp->td_flags, TDF_CHANGED);	}		if (fillp > Size_type1pair + packet + tlp->target_ifap->ifa_mtu) {	    hello_send(tlp,		       packet,		       fillp,		       &maxsize);	    fillp = start;	}	/* Put this entry in the packet */	type1pair.d1_delay = BIT_TEST(tdp->td_flags, TDF_HOLDDOWN|TDF_POISON) ? HELLO_UNREACHABLE : tdp->td_metric;	type1pair.d1_offset = 0;	/* should be signed clock offset */	type1pair.d1_dst = sock2ip(tdp->td_rt->rt_dest);	/* struct copy */	PutDown_type1pair(fillp, type1pair);	if (cleanup) {	    if (TRACE_TP(tlp->target_task, TR_POLICY)) {		if (!changes) {		    trace_only_tp(tlp->target_task,				  TRC_NL_BEFORE,				  ("hello_supply: Policy for target %A",				   *tlp->target_dst));		}		trace_only_tp(tlp->target_task,			      0,			      ("\t%A/%A %s ended",			       tdp->td_rt->rt_dest,			       tdp->td_rt->rt_dest_mask,			       BIT_TEST(tdp->td_flags, TDF_POISON) ? "poison" : "holddown"));	    }	    changes++;	    TD_CLEANUP(tlp, tdp, TRUE);	}    } TD_LIST_END(tdp, &tlp->target_td) ;    /* Send any packets with data remaining in them */    if (fillp > start) {	hello_send(tlp,		   packet,		   fillp,		   &maxsize);	fillp = start;    }    if (TRACE_TP(tlp->target_task, TR_POLICY)	|| changes) {	trace_only_tp(tlp->target_task,		      0,		      (NULL));    }        rt_close(tlp->target_task, (gw_entry *) 0, 0, NULL);}/* *	send HELLO packets *//*ARGSUSED*/static voidhello_job __PF2(tip, task_timer *,		interval, time_t){    target *tlp;        TARGET_LIST(tlp, &hello_targets) {	if (BIT_TEST(tlp->target_flags, TARGETF_SUPPLY)) {	    hello_supply(tlp, FALSE);	}    } TARGET_LIST_END(tlp, &hello_targets);    /* Indicate that flash updates are possible as soon as the timer fires */    task_timer_set(hello_timer_flash, HELLO_T_FLASH, (time_t) 0);    BIT_RESET(hello_flags, HELLOF_NOFLASH|HELLOF_FLASHDUE);}/* *	send a flash update packet *//*ARGSUSED*/static voidhello_do_flash __PF2(tip, task_timer *,		     interval, time_t){    task *tp = tip->task_timer_task;        if (BIT_TEST(hello_flags, HELLOF_FLASHDUE)) {	target *tlp;	/* Do a flash update */	trace_tp(tp,		 TR_TASK,		 0,		 ("hello_do_flash: Doing flash update for HELLO"));	TARGET_LIST(tlp, &hello_targets) {	    if (BIT_TEST(tlp->target_flags, TARGETF_SUPPLY)) {		hello_supply(tlp, TRUE);	    }	} TARGET_LIST_END(tlp, &hello_targets);	trace_tp(tp,		 TR_TASK,		 0,		 ("hello_do_flash: Flash update done"));	/* Indicate no flash update is due */	BIT_RESET(hello_flags, HELLOF_FLASHDUE);	/* Schedule the next flash update */	if (time_sec + HELLO_T_MIN + HELLO_T_MAX < hello_timer_update->task_timer_next_time) {	    /* We can squeeze another flash update in before the full update */	    task_timer_set(tip, HELLO_T_FLASH, (time_t) 0);	} else {	    /* The next flash update will be scheduled after the full update */	    task_timer_reset(tip);	    BIT_SET(hello_flags, HELLOF_NOFLASH);	}    } else {	/* The next flash update can happen immediately */	task_timer_reset(tip);    }}/* *	Schedule or do a flash update */static voidhello_need_flash __PF1(tp, task *){    task_timer *tip = hello_timer_flash;    if (!tip) {	BIT_RESET(hello_flags, HELLOF_FLASHDUE);	return;    }    /* Indicate we need a flash update */    BIT_SET(hello_flags, HELLOF_FLASHDUE);    /* And see if we can do it now */    if (!tip->task_timer_next_time	&& !BIT_TEST(hello_flags, HELLOF_NOFLASH)) {	/* Do it now */	hello_do_flash(tip, (time_t) 0);    }}/* *	Evaluate policy for changed routes. */static inthello_policy __PF3(tp, task *,		   tlp, target *,		   change_list, rt_list *){    if_addr *ifap = tlp->target_ifap;    u_long if_net = inet_net_natural(ifap->ifa_addr);    int same_net = if_net == inet_net_natural(ifap->ifa_addr_local);    int changes = 0;    int logged = 0;    rt_head *rth;    RT_LIST(rth, change_list, rt_head) {	register rt_entry *new_rt = rth->rth_active;	adv_results result;	td_entry *tdp;	int exportable = FALSE;	int changed = 0;	int move_bit = 0;	int holddown = 0;	int poison = 0;	int set_metric = 0;	TD_TSI_GET(tlp, rth, tdp);	/* See if there is a new route and if it can be announced */	if ((new_rt = rth->rth_active)) {	    	    if (socktype(new_rt->rt_dest) != AF_INET) {		goto no_export;	    }	    	    if (BIT_TEST(new_rt->rt_state, RTS_NOADVISE|RTS_PENDING|RTS_GROUP)) {		/* Absolutely not */		goto no_export;	    }	    if (RT_IFAP(new_rt) == ifap &&		new_rt->rt_gwp->gw_proto == RTPROTO_DIRECT) {		/* Do not send interface routes back to the same interface */		goto no_export;	    }	    /* Host routes go everywhere, subnets and nets may need to be restricted */	    if (new_rt->rt_dest_mask != inet_mask_host) {		sockaddr_un *natural_mask = inet_mask_natural(new_rt->rt_dest);		if (new_rt->rt_dest_mask > natural_mask) {		    /* This is a subnet */		    if (!same_net			|| (sock2ip(rth->rth_dest) & sock2ip(natural_mask)) != if_net) {			/* Only send subnets to interfaces of the same network */			goto no_export;		    }		    if (rth->rth_dest_mask != ifap->ifa_netmask) {			/* Only send subnets that have the same mask */			goto no_export;		    }		} else if (sock2ip(rth->rth_dest) == if_net) {		    /* Do not send the whole net to a subnet */		    goto no_export;		}	    }	    if ((new_rt->rt_gwp->gw_proto == tp->task_rtproto) && (ifap == RT_IFAP(new_rt))) {		/* Split horizon */		goto no_export;	    }

⌨️ 快捷键说明

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