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

📄 route.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
			*rtp = rt;		else			rtfree(rt);	}out:	if (error)		rtstat.rts_badredirect++;	else if (stat != NULL)		(*stat)++;	bzero((caddr_t)&info, sizeof(info));	info.rti_info[RTAX_DST] = dst;	info.rti_info[RTAX_GATEWAY] = gateway;	info.rti_info[RTAX_NETMASK] = netmask;	info.rti_info[RTAX_AUTHOR] = src;	rt_missmsg(RTM_REDIRECT, &info, flags, error);}/** Routing table ioctl interface.*/intrtioctl(req, data, p)	u_long req;	caddr_t data;	struct proc *p;{	return (EOPNOTSUPP);}struct ifaddr *ifa_ifwithroute(flags, dst, gateway)	int flags;	struct sockaddr	*dst, *gateway;{	register struct ifaddr *ifa;#ifdef IPSEC	/*	 * If the destination is a PF_KEY address, we'll look	 * for the existence of a encap interface number or address	 * in the options list of the gateway. By default, we'll return	 * enc0.	 */	if (dst && (dst->sa_family == PF_KEY))		return encap_findgwifa(gateway);#endif	if ((flags & RTF_GATEWAY) == 0) {		/*		 * If we are adding a route to an interface,		 * and the interface is a pt to pt link		 * we should search for the destination		 * as our clue to the interface.  Otherwise		 * we can use the local address.		 */		ifa = NULL;		if (flags & RTF_HOST) 			ifa = ifa_ifwithdstaddr(dst);		if (ifa == NULL)			ifa = ifa_ifwithaddr(gateway);	} else {		/*		 * If we are adding a route to a remote net		 * or host, the gateway may still be on the		 * other end of a pt to pt link.		 */		ifa = ifa_ifwithdstaddr(gateway);	}	if (ifa == NULL)		ifa = ifa_ifwithnet(gateway);	if (ifa == NULL) {		struct rtentry *rt = rtalloc1(gateway, 0);		if (rt == NULL)			return (NULL);		rt->rt_refcnt--;		/* The gateway must be local if the same address family. */		if (!(flags & RTF_TUNNEL) && (rt->rt_flags & RTF_GATEWAY) && 		    rt_key(rt)->sa_family == dst->sa_family)			return (0);		if ((ifa = rt->rt_ifa) == NULL)			return (NULL);	}	if (ifa->ifa_addr->sa_family != dst->sa_family) {		struct ifaddr *oifa = ifa;		ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);		if (ifa == NULL)			ifa = oifa;	}	return (ifa);}#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))intrtrequest(req, dst, gateway, netmask, flags, ret_nrt)	int req, flags;	struct sockaddr *dst, *gateway, *netmask;	struct rtentry **ret_nrt;{	int s = splsoftnet(); int error = 0;	register struct rtentry *rt;	register struct radix_node *rn;	register struct radix_node_head *rnh;	struct ifaddr *ifa;	struct sockaddr *ndst;#define senderr(x) { error = x ; goto bad; }	if ((rnh = rt_tables[dst->sa_family]) == 0)		senderr(EAFNOSUPPORT);	if (flags & RTF_HOST)		netmask = 0;	switch (req) {	case RTM_DELETE:		if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == NULL)			senderr(ESRCH);		if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))			panic ("rtrequest delete");		rt = (struct rtentry *)rn;		rt->rt_flags &= ~RTF_UP;		if (rt->rt_gwroute) {			rt = rt->rt_gwroute; RTFREE(rt);			(rt = (struct rtentry *)rn)->rt_gwroute = NULL;		}		if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)			ifa->ifa_rtrequest(RTM_DELETE, rt, SA(NULL));		rttrash++;		if (ret_nrt)			*ret_nrt = rt;		else if (rt->rt_refcnt <= 0) {			rt->rt_refcnt++;			rtfree(rt);		}		break;	case RTM_RESOLVE:		if (ret_nrt == NULL || (rt = *ret_nrt) == NULL)			senderr(EINVAL);		ifa = rt->rt_ifa;		flags = rt->rt_flags & ~RTF_CLONING;		gateway = rt->rt_gateway;		if ((netmask = rt->rt_genmask) == NULL)			flags |= RTF_HOST;		goto makeroute;	case RTM_ADD:		if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == NULL)			senderr(ENETUNREACH);	makeroute:		R_Malloc(rt, struct rtentry *, sizeof(*rt));		if (rt == NULL)			senderr(ENOBUFS);		Bzero(rt, sizeof(*rt));		rt->rt_flags = RTF_UP | flags;		if (rt_setgate(rt, dst, gateway)) {			Free(rt);			senderr(ENOBUFS);		}		ndst = rt_key(rt);		if (netmask) {			rt_maskedcopy(dst, ndst, netmask);		} else			Bcopy(dst, ndst, dst->sa_len);		rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,					rnh, rt->rt_nodes);		if (rn == NULL) {			if (rt->rt_gwroute)				rtfree(rt->rt_gwroute);			Free(rt_key(rt));			Free(rt);			senderr(EEXIST);		}		ifa->ifa_refcnt++;		rt->rt_ifa = ifa;		rt->rt_ifp = ifa->ifa_ifp;		if (req == RTM_RESOLVE) {			/*			 * Copy both metrics and a back pointer to the cloned			 * route's parent.			 */			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */			rt->rt_parent = *ret_nrt;	 /* Back ptr. to parent. */		}		if (ifa->ifa_rtrequest)			ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : NULL));		if (ret_nrt) {			*ret_nrt = rt;			rt->rt_refcnt++;		}#ifdef INET6		/* If we have a v4_in_v4 or a v4_in_v6 tunnel route		 * then do some tunnel state (e.g. security state)		 * initialization.		 *		 * Since IPV6 packets flow down this path, we don't		 * want it using ipv4_tunnelsetup(rt) (since they		 * have their own ipv6_tunnel_parent/child()		 * routines which are called ipv6_rtrequest().)		 *		 * Thus, we check to see if the packet is to a v4		 * destination.		 */		if (dst->sa_family == AF_INET && (rt->rt_flags & RTF_TUNNEL))			ipv4_tunnelsetup(rt);#endif /* INET6 */		break;	}bad:	splx(s);	return (error);}/* * Set up any tunnel states (e.g. security) information * for v4_in_v4 or v4_in_v6 tunnel routes. */#ifdef INET6voidipv4_tunnelsetup(rt)	register struct rtentry *rt;{	/* XXX */}#endifintrt_setgate(rt0, dst, gate)	struct rtentry *rt0;	struct sockaddr *dst, *gate;{	caddr_t new, old;	int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len);	register struct rtentry *rt = rt0;	if (rt->rt_gateway == NULL || glen > ROUNDUP(rt->rt_gateway->sa_len)) {		old = (caddr_t)rt_key(rt);		R_Malloc(new, caddr_t, dlen + glen);		if (new == NULL)			return 1;		rt->rt_nodes->rn_key = new;	} else {		new = rt->rt_nodes->rn_key;		old = NULL;	}	Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen);	if (old) {		Bcopy(dst, new, dlen);		Free(old);	}	if (rt->rt_gwroute != NULL) {		rt = rt->rt_gwroute;		RTFREE(rt);		rt = rt0;		rt->rt_gwroute = NULL;	}	if (rt->rt_flags & RTF_GATEWAY) {		rt->rt_gwroute = rtalloc1(gate, 1);	}	return 0;}voidrt_maskedcopy(src, dst, netmask)	struct sockaddr *src, *dst, *netmask;{	register u_char *cp1 = (u_char *)src;	register u_char *cp2 = (u_char *)dst;	register u_char *cp3 = (u_char *)netmask;	u_char *cplim = cp2 + *cp3;	u_char *cplim2 = cp2 + *cp1;	*cp2++ = *cp1++; *cp2++ = *cp1++; /* copies sa_len & sa_family */	cp3 += 2;	if (cplim > cplim2)		cplim = cplim2;	while (cp2 < cplim)		*cp2++ = *cp1++ & *cp3++;	if (cp2 < cplim2)		bzero((caddr_t)cp2, (unsigned)(cplim2 - cp2));}/* * Set up a routing table entry, normally * for an interface. */intrtinit(ifa, cmd, flags)	register struct ifaddr *ifa;	int cmd, flags;{	register struct rtentry *rt;	register struct sockaddr *dst;	register struct sockaddr *deldst;	struct mbuf *m = NULL;	struct rtentry *nrt = NULL;	int error;	dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;	if (cmd == RTM_DELETE) {		if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {			m = m_get(M_WAIT, MT_SONAME);			deldst = mtod(m, struct sockaddr *);			rt_maskedcopy(dst, deldst, ifa->ifa_netmask);			dst = deldst;		}		if ((rt = rtalloc1(dst, 0)) != NULL) {			rt->rt_refcnt--;			if (rt->rt_ifa != ifa) {				if (m != NULL)					(void) m_free(m);				return (flags & RTF_HOST ? EHOSTUNREACH							: ENETUNREACH);			}		}	}	error = rtrequest(cmd, dst, ifa->ifa_addr, ifa->ifa_netmask,			flags | ifa->ifa_flags, &nrt);	if (m != NULL)		(void) m_free(m);	if (cmd == RTM_DELETE && error == 0 && (rt = nrt) != NULL) {		rt_newaddrmsg(cmd, ifa, error, nrt);		if (rt->rt_refcnt <= 0) {			rt->rt_refcnt++;			rtfree(rt);		}	}	if (cmd == RTM_ADD && error == 0 && (rt = nrt) != NULL) {		rt->rt_refcnt--;#ifdef INET6		/* Initialize Path MTU for IPv6 interface route */		if (ifa->ifa_addr->sa_family == AF_INET6 &&		    !rt->rt_rmx.rmx_mtu)			rt->rt_rmx.rmx_mtu = ifa->ifa_ifp->if_mtu;#endif /* INET6 */		if (rt->rt_ifa != ifa) {			printf("rtinit: wrong ifa (%p) was (%p)\n",			       ifa, rt->rt_ifa);			if (rt->rt_ifa->ifa_rtrequest)				rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt,				    SA(NULL));			IFAFREE(rt->rt_ifa);			rt->rt_ifa = ifa;			rt->rt_ifp = ifa->ifa_ifp;			ifa->ifa_refcnt++;			if (ifa->ifa_rtrequest)				ifa->ifa_rtrequest(RTM_ADD, rt, SA(NULL));		}		rt_newaddrmsg(cmd, ifa, error, nrt);	}	return (error);}

⌨️ 快捷键说明

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