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

📄 ipr.c

📁 minux操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!oroute)	{		DBLOCK(1, printf("ip[%d]: got a ttl exceeded for ",			port_nr);			writeIpAddr(dest); printf("but no route present\n"));		return;	}	new_dist= oroute->ort_dist * 2;	if (new_dist > IP_DEF_TTL)	{		new_dist= oroute->ort_dist+1;		if (new_dist >= IP_DEF_TTL)		{			DBLOCK(1, printf("ip[%d]: got a ttl exceeded for ",				port_nr);				writeIpAddr(dest);				printf(" but dist is %d\n",				oroute->ort_dist));			return;		}	}	result= ipr_add_oroute(port_nr, dest, netmask, oroute->ort_gateway, 		timeout, new_dist, oroute->ort_mtu, FALSE, 0, NULL);	assert(result == NW_OK);}PUBLIC void ipr_mtu(port_nr, dest, mtu, timeout)int port_nr;ipaddr_t dest;u16_t mtu;time_t timeout;{	oroute_t *oroute;	int result;	oroute= oroute_find_ent(port_nr, dest);	if (!oroute)	{		DBLOCK(1, printf("ip[%d]: got a mtu exceeded for ",			port_nr);			writeIpAddr(dest); printf("but no route present\n"));		return;	}	if (mtu <  IP_MIN_MTU)		return;	if (oroute->ort_mtu && mtu >= oroute->ort_mtu)		return;		/* Only decrease mtu */	result= ipr_add_oroute(port_nr, dest, HTONL(0xffffffff),		oroute->ort_gateway, timeout, oroute->ort_dist, mtu,		FALSE, 0, NULL);	assert(result == NW_OK);}PUBLIC int ipr_get_oroute(ent_no, route_ent)int ent_no;nwio_route_t *route_ent;{	oroute_t *oroute;	if (ent_no<0 || ent_no>= OROUTE_NR)		return ENOENT;	oroute= &oroute_table[ent_no];	if ((oroute->ort_flags & ORTF_INUSE) && oroute->ort_exp_tim &&					oroute->ort_exp_tim < get_time())	{		oroute_del(oroute);		oroute->ort_flags &= ~ORTF_INUSE;	}	route_ent->nwr_ent_no= ent_no;	route_ent->nwr_ent_count= OROUTE_NR;	route_ent->nwr_dest= oroute->ort_dest;	route_ent->nwr_netmask= oroute->ort_subnetmask;	route_ent->nwr_gateway= oroute->ort_gateway;	route_ent->nwr_dist= oroute->ort_dist;	route_ent->nwr_flags= NWRF_EMPTY;	if (oroute->ort_flags & ORTF_INUSE)	{		route_ent->nwr_flags |= NWRF_INUSE;		if (oroute->ort_flags & ORTF_STATIC)			route_ent->nwr_flags |= NWRF_STATIC;	}	route_ent->nwr_pref= oroute->ort_pref;	route_ent->nwr_mtu= oroute->ort_mtu;	route_ent->nwr_ifaddr= ip_get_ifaddr(oroute->ort_port);	return NW_OK;}PRIVATE oroute_t *oroute_find_ent(port_nr, dest)int port_nr;ipaddr_t dest;{	int hash;	oroute_hash_t *oroute_hash;	oroute_hash_t tmp_hash;	oroute_t *oroute, *bestroute;	time_t currtim;	unsigned long hash_tmp;	u32_t tmp_mask;	currtim= get_time();	hash= hash_oroute(port_nr, dest, hash_tmp);	oroute_hash= &oroute_hash_table[hash][0];	if (oroute_hash[0].orh_addr == dest)		oroute= oroute_hash[0].orh_route;	else if (oroute_hash[1].orh_addr == dest)	{		tmp_hash= oroute_hash[1];		oroute_hash[1]= oroute_hash[0];		oroute_hash[0]= tmp_hash;		oroute= tmp_hash.orh_route;	}	else if (oroute_hash[2].orh_addr == dest)	{		tmp_hash= oroute_hash[2];		oroute_hash[2]= oroute_hash[1];		oroute_hash[1]= oroute_hash[0];		oroute_hash[0]= tmp_hash;		oroute= tmp_hash.orh_route;	}	else if (oroute_hash[3].orh_addr == dest)	{		tmp_hash= oroute_hash[3];		oroute_hash[3]= oroute_hash[2];		oroute_hash[2]= oroute_hash[1];		oroute_hash[1]= oroute_hash[0];		oroute_hash[0]= tmp_hash;		oroute= tmp_hash.orh_route;	}	else		oroute= NULL;	if (oroute)	{		assert(oroute->ort_port == port_nr);		if (oroute->ort_exp_tim && oroute->ort_exp_tim<currtim)		{			oroute_del(oroute);			oroute->ort_flags &= ~ORTF_INUSE;		}		else			return oroute;	}	bestroute= NULL;	for (oroute= oroute_head; oroute; oroute= oroute->ort_nextnw)	{		if (((dest ^ oroute->ort_dest) & oroute->ort_subnetmask) != 0)			continue;		if (oroute->ort_port != port_nr)			continue;		if (!bestroute)		{			bestroute= oroute;			continue;		}		assert(oroute->ort_dest != bestroute->ort_dest);		/* Using two ntohl macros in one expression		 * is not allowed (tmp_l is modified twice)		 */		tmp_mask= ntohl(oroute->ort_subnetmask);		if (tmp_mask > ntohl(bestroute->ort_subnetmask))		{			bestroute= oroute;			continue;		}	}	if (bestroute == NULL)		return NULL;	oroute_hash[3]= oroute_hash[2];	oroute_hash[2]= oroute_hash[1];	oroute_hash[1]= oroute_hash[0];	oroute_hash[0].orh_addr= dest;	oroute_hash[0].orh_route= bestroute;	return bestroute;}PRIVATE void oroute_del(oroute)oroute_t *oroute;{	oroute_t *prev, *nw_route, *gw_route, *dist_route, *prev_route;	DBLOCK(0x10, 		printf("ip[%d]: deleting oroute to ", oroute->ort_port);		writeIpAddr(oroute->ort_dest);		printf("["); writeIpAddr(oroute->ort_subnetmask);		printf("] through ");		writeIpAddr(oroute->ort_gateway);		printf(	" timestamp %lds, timeout: %lds, distance %d pref %ld mtu %ld ",			(long)oroute->ort_timestamp/HZ,			(long)oroute->ort_exp_tim/HZ, oroute->ort_dist,			(long)oroute->ort_pref, (long)oroute->ort_mtu);		printf("flags 0x%x\n", oroute->ort_flags));	for (prev= NULL, nw_route= oroute_head; nw_route; 				prev= nw_route, nw_route= nw_route->ort_nextnw)	{		if (oroute->ort_port == nw_route->ort_port &&			oroute->ort_dest == nw_route->ort_dest &&			oroute->ort_subnetmask == nw_route->ort_subnetmask)		{			break;		}	}	assert(nw_route);	if (prev)		prev->ort_nextnw= nw_route->ort_nextnw;	else		oroute_head= nw_route->ort_nextnw;	prev_route= nw_route;	for (prev= NULL, gw_route= nw_route; gw_route; 				prev= gw_route, gw_route= gw_route->ort_nextgw)	{		if (oroute->ort_gateway == gw_route->ort_gateway)			break;	}	assert(gw_route);	if (prev)		prev->ort_nextgw= gw_route->ort_nextgw;	else		nw_route= gw_route->ort_nextgw;	for (prev= NULL, dist_route= gw_route; dist_route; 			prev= dist_route, dist_route= dist_route->ort_nextdist)	{		if (oroute == dist_route)			break;	}	assert(dist_route);	if (prev)		prev->ort_nextdist= dist_route->ort_nextdist;	else		gw_route= dist_route->ort_nextdist;	gw_route= sort_dists(gw_route);	if (gw_route != NULL)	{		gw_route->ort_nextgw= nw_route;		nw_route= gw_route;	}	nw_route= sort_gws(nw_route);	if (nw_route != NULL)	{		nw_route->ort_nextnw= oroute_head;		oroute_head= nw_route;	}	if (nw_route != prev_route)	{		oroute_uncache_nw(prev_route->ort_dest, 			prev_route->ort_subnetmask);	}}PRIVATE oroute_t *sort_dists(oroute)oroute_t *oroute;{	oroute_t *r, *prev, *best, *best_prev;	int best_dist, best_pref;	best= NULL;	best_dist= best_pref= 0;	best_prev= NULL;	for (prev= NULL, r= oroute; r; prev= r, r= r->ort_nextdist)	{		if (best == NULL)			;	/* Force assignment to best */		else if (r->ort_dist != best_dist)		{			if (r->ort_dist > best_dist)				continue;		}		else		{			if (r->ort_pref <= best_pref)				continue;		}		best= r;		best_prev= prev;		best_dist= r->ort_dist;		best_pref= r->ort_pref;	}	if (!best)	{		assert(oroute == NULL);		return oroute;	}	if (!best_prev)	{		assert(best == oroute);		return oroute;	}	best_prev->ort_nextdist= best->ort_nextdist;	best->ort_nextdist= oroute;	return best;}PRIVATE oroute_t *sort_gws(oroute)oroute_t *oroute;{	oroute_t *r, *prev, *best, *best_prev;	int best_dist, best_pref;	best= NULL;	best_dist= best_pref= 0;	best_prev= NULL;	for (prev= NULL, r= oroute; r; prev= r, r= r->ort_nextgw)	{		if (best == NULL)			;	/* Force assignment to best */		else if (r->ort_dist != best_dist)		{			if (r->ort_dist > best_dist)				continue;		}		else		{			if (r->ort_pref <= best_pref)				continue;		}		best= r;		best_prev= prev;		best_dist= r->ort_dist;		best_pref= r->ort_pref;	}	if (!best)	{		assert(oroute == NULL);		return oroute;	}	if (!best_prev)	{		assert(best == oroute);		return oroute;	}	best_prev->ort_nextgw= best->ort_nextgw;	best->ort_nextgw= oroute;	return best;}PRIVATE	void oroute_uncache_nw(dest, netmask)ipaddr_t dest;ipaddr_t netmask;{	int i, j;	oroute_hash_t *oroute_hash;	for (i= 0, oroute_hash= &oroute_hash_table[0][0];		i<OROUTE_HASH_NR; i++, oroute_hash += OROUTE_HASH_ASS_NR)	{		for (j= 0; j<OROUTE_HASH_ASS_NR; j++)		{			if (((oroute_hash[j].orh_addr ^ dest) & netmask) == 0)			{				oroute_hash[j].orh_addr= 0;				oroute_hash[j].orh_route= NULL;			}		}	}}/* * Input routing */PUBLIC int ipr_get_iroute(ent_no, route_ent)int ent_no;nwio_route_t *route_ent;{	iroute_t *iroute;	if (ent_no<0 || ent_no>= IROUTE_NR)		return ENOENT;	iroute= &iroute_table[ent_no];	route_ent->nwr_ent_no= ent_no;	route_ent->nwr_ent_count= IROUTE_NR;	route_ent->nwr_dest= iroute->irt_dest;	route_ent->nwr_netmask= iroute->irt_subnetmask;	route_ent->nwr_gateway= iroute->irt_gateway;	route_ent->nwr_dist= iroute->irt_dist;	route_ent->nwr_flags= NWRF_EMPTY;	if (iroute->irt_flags & IRTF_INUSE)	{		route_ent->nwr_flags |= NWRF_INUSE;		if (iroute->irt_flags & IRTF_STATIC)			route_ent->nwr_flags |= NWRF_STATIC;		if (iroute->irt_dist == IRTD_UNREACHABLE)			route_ent->nwr_flags |= NWRF_UNREACHABLE;	}	route_ent->nwr_pref= 0;	route_ent->nwr_mtu= iroute->irt_mtu;	route_ent->nwr_ifaddr= ip_get_ifaddr(iroute->irt_port);	return NW_OK;}PUBLIC int ipr_add_iroute(port_nr, dest, subnetmask, gateway, 	dist, mtu, static_route, iroute_p)int port_nr;ipaddr_t dest;ipaddr_t subnetmask;ipaddr_t gateway;int dist;int mtu;int static_route;iroute_t **iroute_p;{	int i;	iroute_t *iroute, *unused_route;	ip_port_t *ip_port;	ip_port= &ip_port_table[port_nr];	/* Check gateway */	if (((gateway ^ ip_port->ip_ipaddr) & ip_port->ip_subnetmask) != 0 &&		gateway != 0)	{		DBLOCK(1, printf("ip[%d] (ipr_add_iroute): invalid gateway: ",			port_nr);			writeIpAddr(gateway); printf("\n"));		return EINVAL;	}	unused_route= NULL;	if (static_route)	{		/* Static routes are not reused automatically, so we look 		 * for an unused entry.		 */		for(i= 0, iroute= iroute_table; i<IROUTE_NR; i++, iroute++)		{			if ((iroute->irt_flags & IRTF_INUSE) == 0)				break;		}		if (i != IROUTE_NR)			unused_route= iroute;	}	else	{		/* Try to track down any old routes, and look for an		 * unused one.		 */		for(i= 0, iroute= iroute_table; i<IROUTE_NR; i++, iroute++)		{			if ((iroute->irt_flags & IRTF_INUSE) == 0)			{				unused_route= iroute;				continue;			}			if ((iroute->irt_flags & IRTF_STATIC) != 0)				continue;			if (iroute->irt_port != port_nr ||				iroute->irt_dest != dest ||				iroute->irt_subnetmask != subnetmask ||				iroute->irt_gateway != gateway)			{				continue;			}			break;		}		if (i != IROUTE_NR)			unused_route= iroute;	}	if (unused_route == NULL)		return ENOMEM;	iroute= unused_route;	iroute->irt_port= port_nr;	iroute->irt_dest= dest;	iroute->irt_subnetmask= subnetmask;	iroute->irt_gateway= gateway;	iroute->irt_dist= dist;	iroute->irt_mtu= mtu;	iroute->irt_flags= IRTF_INUSE;	if (static_route)		iroute->irt_flags |= IRTF_STATIC;		iroute_uncache_nw(iroute->irt_dest, iroute->irt_subnetmask);	if (iroute_p != NULL)		*iroute_p= iroute;	return NW_OK;}PUBLIC int ipr_del_iroute(port_nr, dest, subnetmask, gateway, static_route)int port_nr;ipaddr_t dest;ipaddr_t subnetmask;ipaddr_t gateway;int static_route;{	int i;	iroute_t *iroute;	/* Try to track down any old routes, and look for an	 * unused one.	 */	for(i= 0, iroute= iroute_table; i<IROUTE_NR; i++, iroute++)	{		if ((iroute->irt_flags & IRTF_INUSE) == 0)			continue;		if (iroute->irt_port != port_nr ||			iroute->irt_dest != dest ||			iroute->irt_subnetmask != subnetmask ||			iroute->irt_gateway != gateway)		{			continue;		}		if (!!(iroute->irt_flags & IRTF_STATIC) != static_route)			continue;		break;	}	if (i == IROUTE_NR)		return ESRCH;	iroute_uncache_nw(iroute->irt_dest, iroute->irt_subnetmask);	iroute->irt_flags= IRTF_EMPTY;	return NW_OK;}PUBLIC void ipr_chk_itab(port_nr, addr, mask)int port_nr;ipaddr_t addr;ipaddr_t mask;{	int i;	iroute_t *iroute;	DBLOCK(1,		printf("ip[%d] (ipr_chk_itab): addr ", port_nr);		writeIpAddr(addr);		printf(" mask ");		writeIpAddr(mask);		printf("\n");	);	if (addr == 0)	{		/* Special hack to flush entries for an interface that		 * goes down.		 */		addr= mask= HTONL(0xffffffff);	}	for(i= 0, iroute= iroute_table; i<IROUTE_NR; i++, iroute++)	{		if ((iroute->irt_flags & IRTF_INUSE) == 0)			continue;		if (iroute->irt_port != port_nr)			continue;		if (iroute->irt_gateway == 0)		{			/* Special case: attached network. */			if (iroute->irt_subnetmask == mask &&				iroute->irt_dest == (addr & mask))			{				/* Nothing changed. */				continue;			}		}		if (((iroute->irt_gateway ^ addr) & mask) == 0)			continue;		DBLOCK(1, printf("ip[%d] (ipr_chk_itab): deleting route to ",				port_nr);		    writeIpAddr(iroute->irt_dest);		    printf(" gw ");		    writeIpAddr(iroute->irt_gateway);		    printf("\n"));		iroute_uncache_nw(iroute->irt_dest, iroute->irt_subnetmask);		iroute->irt_flags &= ~IRTF_INUSE;	}}PRIVATE	void iroute_uncache_nw(dest, netmask)ipaddr_t dest;ipaddr_t netmask;{	int i, j;	iroute_hash_t *iroute_hash;	for (i= 0, iroute_hash= &iroute_hash_table[0][0];		i<IROUTE_HASH_NR; i++, iroute_hash += IROUTE_HASH_ASS_NR)	{		for (j= 0; j<IROUTE_HASH_ASS_NR; j++)		{			if (((iroute_hash[j].irh_addr ^ dest) &				netmask) == 0)			{				iroute_hash[j].irh_addr= 0;				iroute_hash[j].irh_route= NULL;			}		}	}}/* * $PchId: ipr.c,v 1.23 2003/01/22 11:49:58 philip Exp $ */

⌨️ 快捷键说明

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