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

📄 rtsock.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				Free(rtm); rtm = new_rtm;			}			(void)rt_msg2(rtm->rtm_type, &info, (caddr_t)rtm,				(struct walkarg *)0);			rtm->rtm_flags = rt->rt_flags;			rtm->rtm_rmx = rt->rt_rmx;			rtm->rtm_addrs = info.rti_addrs;			break;#ifdef ROUTER_STACK		case RTM_NEWCHANGE:                        /*                         * Use the exact match selected with the gateway                         * address, if available. Save the primary route                         * in case the change operation alters the weight.                         */                        if (pGateway)                            {                            saved_nrt = rt;                            rt = (struct rtentry *)pRoute;                            }                    /* Access the new gateway value for a route, if any. */                    gate = info.rti_info[RTAX_AUTHOR];#endif		case RTM_CHANGE:			if (gate && rt_setgate(rt, rt_key(rt), gate))				senderr(ENOSPC);#ifdef ROUTER_STACK       /* Only remove cloned routes when altering the primary entry. */                    if ( ((ROUTE_ENTRY *)rt)->primaryRouteFlag)                        {#endif /* ROUTER_STACK */                        if (gate && (rt_key(rt)->sa_family == AF_INET))                            {                            /*                             * Remove any cloned routes using the                             * (now obsolete) gateway.                             */                           if ( (rt->rt_flags & RTF_CLONING) && rt_mask (rt))                               rn_walksubtree (rnh, rt_key (rt), rt_mask (rt),                                               rt_fixdelete, rt);                           }#ifdef ROUTER_STACK    /* End of condition for cloned route removal */                        }#endif			/* new gateway could require new ifaddr, ifp;			   flags may also be different; ifp may be specified			   by ll sockaddr when protocol address is ambiguous */	if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) &&			    (ifp = ifa->ifa_ifp))		ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate, ifp);	else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) ||			 (ifa = ifa_ifwithroute(rt->rt_flags,						rt_key(rt), gate)))				ifp = ifa->ifa_ifp;			if (ifa) {				register struct ifaddr *oifa = rt->rt_ifa;				if (oifa != ifa) {				    if (oifa && oifa->ifa_rtrequest)					oifa->ifa_rtrequest(RTM_DELETE,								rt, gate);				    IFAFREE(rt->rt_ifa);				    rt->rt_ifa = ifa;				    ifa->ifa_refcnt++;				    rt->rt_ifp = ifp;				}			}#ifdef ROUTER_STACK    /*     * Note: Setting the metrics does not change the new weight     *       value for the selected route entry, since that     *       alteration could replace the current route before     *       completing all the changes required.     */#endif			rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,					&rt->rt_rmx);			if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)			       rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate);			if (genmask)				rt->rt_genmask = genmask;			/*			 * Fall into			 */		case RTM_LOCK:			rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);			rt->rt_rmx.rmx_locks |=				(rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);			break;		}#ifdef ROUTER_STACK                /*                 * Since a weight change could replace the primary route                 * visible to the IP forwarding process and the original                 * routing socket messages, reorganizing the routes must                 * wait until after all the prior changes so that any new                 * copy of the selected route is correct.                 */		switch(rtm->rtm_type) {		case RTM_CHANGE:		case RTM_NEWCHANGE:                    /* Do nothing if the weight did not change. */                    if ( (rtm->rtm_inits & RTV_WEIGHT) == 0)                        break;                    /*                     * Get the primary route to find the matching group                     * for an existing entry when updating the weight.                     */                    if (saved_nrt)                        {                        /*                         * The new change operation set a gateway to get                         * an exact match and saved the primary route.                         */                        pRoute = (ROUTE_ENTRY *)saved_nrt;                        }                    else                        {                        /*                         * The original change operation only modifies the                         * primary route. The new change operation also                         * alters that entry if no gateway is set.                         */                        pRoute = (ROUTE_ENTRY *)rt;                        }                    routeWeightUpdate (pRoute, protoId, (ROUTE_ENTRY *)rt,                                        gate, rtm->rtm_rmx.weight);                    if (saved_nrt)                        {                        /*                         * Release the reference to the primary route                         * if a specified gateway used an exact match.                         */                        rtfree (saved_nrt);                        }                    break;                }#endif /* ROUTER_STACK */		break;	default:		senderr(EOPNOTSUPP);	}flush:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        if (error)            {            WV_NET_EVENT_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 29, 4,                             WV_NETEVENT_RTOUTPUT_FAIL, WV_NET_SEND,                            so->so_fd, error)            }#endif  /* INCLUDE_WVNET */#endif	if (rtm) {		if (error)			rtm->rtm_errno = error;		else 			rtm->rtm_flags |= RTF_DONE;	}	if (rt)		rtfree(rt);    {	register struct rawcb *rp = 0;	/*	 * Check to see if we don't want our own messages.	 */	if ((so->so_options & SO_USELOOPBACK) == 0) {		if (route_cb.any_count <= 1) {			if (rtm)				Free(rtm);			m_freem(m);			return (error);		}		/* There is another listener, so construct message */		rp = sotorawcb(so);	}	if (rtm) {		m_copyback(m, 0, rtm->rtm_msglen, (caddr_t)rtm);		Free(rtm);	}	if (rp)		rp->rcb_proto.sp_family = 0; /* Avoid us */	if (dst)		route_proto.sp_protocol = dst->sa_family;	raw_input(m, &route_proto, &route_src, &route_dst);	if (rp)		rp->rcb_proto.sp_family = PF_ROUTE;    }	return (error);}static voidrt_setmetrics(which, in, out)	u_long which;	register struct rt_metrics *in, *out;{#define metric(f, e) if (which & (f)) out->e = in->e;	metric(RTV_RPIPE, rmx_recvpipe);	metric(RTV_SPIPE, rmx_sendpipe);	metric(RTV_SSTHRESH, rmx_ssthresh);	metric(RTV_RTT, rmx_rtt);	metric(RTV_RTTVAR, rmx_rttvar);	metric(RTV_HOPCOUNT, rmx_hopcount);	metric(RTV_MTU, rmx_mtu);	metric(RTV_EXPIRE, rmx_expire);#ifdef ROUTER_STACK    /*     * Set the values for the new additional metrics,     * except the weight, which must be postponed when     * altering that value.     */    metric(RTV_VALUE1, value1)    metric(RTV_VALUE2, value2)    metric(RTV_VALUE3, value3)    metric(RTV_VALUE4, value4)    metric(RTV_VALUE5, value5)    metric(RTV_ROUTETAG, routeTag)#endif /* ROUTER_STACK */#undef metric}#define ROUNDUP(a) \	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))static voidrt_xaddrs(cp, cplim, rtinfo)	register caddr_t cp, cplim;	register struct rt_addrinfo *rtinfo;{	register struct sockaddr *sa;	register int i;	bzero((char *)rtinfo->rti_info, sizeof(rtinfo->rti_info));	for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) {		if ((rtinfo->rti_addrs & (1 << i)) == 0)			continue;		rtinfo->rti_info[i] = sa = (struct sockaddr *)cp;		ADVANCE(cp, sa);	}}struct mbuf *rt_msg1(type, rtinfo)	int type;	register struct rt_addrinfo *rtinfo;{	register struct rt_msghdr *rtm;	register struct mbuf *m;	register int i;	register struct sockaddr *sa;	int len, dlen;	m = mHdrClGet(M_DONTWAIT, MT_DATA, CL_SIZE_128, TRUE);	if (m == 0)		return (m);	switch (type) {	case RTM_DELADDR:	case RTM_NEWADDR:		len = sizeof(struct ifa_msghdr);		break;	case RTM_IFINFO:		len = sizeof(struct if_msghdr);		break;	default:		len = sizeof(struct rt_msghdr);	}	if (len > m->m_extSize)		panic("rt_msg1");	m->m_pkthdr.len = m->m_len = len;	m->m_pkthdr.rcvif = 0;	rtm = mtod(m, struct rt_msghdr *);	bzero((caddr_t)rtm, len);	for (i = 0; i < RTAX_MAX; i++) {		if ((sa = rtinfo->rti_info[i]) == NULL)			continue;		rtinfo->rti_addrs |= (1 << i);		dlen = ROUNDUP(sa->sa_len);		m_copyback(m, len, dlen, (caddr_t)sa);		len += dlen;	}	if (m->m_pkthdr.len != len) {		m_freem(m);		return (NULL);	}	rtm->rtm_msglen = len;	rtm->rtm_version = RTM_VERSION;	rtm->rtm_type = type;	return (m);}static intrt_msg2(type, rtinfo, cp, w)	int type;	register struct rt_addrinfo *rtinfo;	caddr_t cp;	struct walkarg *w;{	register int i;	int len, dlen, second_time = 0;	caddr_t cp0;	rtinfo->rti_addrs = 0;again:	switch (type) {	case RTM_DELADDR:	case RTM_NEWADDR:		len = sizeof(struct ifa_msghdr);		break;	case RTM_IFINFO:		len = sizeof(struct if_msghdr);		break;	default:		len = sizeof(struct rt_msghdr);	}	if ((cp0 = cp))		cp += len;	for (i = 0; i < RTAX_MAX; i++) {		register struct sockaddr *sa;		if ((sa = rtinfo->rti_info[i]) == 0)			continue;		rtinfo->rti_addrs |= (1 << i);		dlen = ROUNDUP(sa->sa_len);		if (cp) {			bcopy((caddr_t)sa, cp, (unsigned)dlen);			cp += dlen;		}		len += dlen;	}	if (cp == 0 && w != NULL && !second_time) {		register struct walkarg *rw = w;		rw->w_needed += len;		if (rw->w_needed <= 0 && rw->w_where) {			if (rw->w_tmemsize < len) {				if (rw->w_tmem)				        {					FREE(rw->w_tmem, MT_RTABLE);					}				MALLOC(rw->w_tmem, caddr_t, len, MT_RTABLE,				       M_DONTWAIT); 				if (rw->w_tmem)					rw->w_tmemsize = len;			}			if (rw->w_tmem) {				cp = rw->w_tmem;				second_time = 1;				goto again;			} else				rw->w_where = 0;		}	}	if (cp) {		register struct rt_msghdr *rtm = (struct rt_msghdr *)cp0;		rtm->rtm_version = RTM_VERSION;		rtm->rtm_type = type;		rtm->rtm_msglen = len;	}	return (len);}/* * This routine is called to generate a message from the routing * socket indicating that a redirect has occured, a routing lookup * has failed, or that a protocol has detected timeouts to a particular * destination. */voidrt_missmsg(type, rtinfo, flags, error)	int type, flags, error;	register struct rt_addrinfo *rtinfo;{	register struct rt_msghdr *rtm;	register struct mbuf *m;	struct sockaddr *sa = rtinfo->rti_info[RTAX_DST];	if (route_cb.any_count == 0)		return;	m = rt_msg1(type, rtinfo);	if (m == 0)		return;	rtm = mtod(m, struct rt_msghdr *);	rtm->rtm_flags = RTF_DONE | flags;	rtm->rtm_errno = error;	rtm->rtm_addrs = rtinfo->rti_addrs;	route_proto.sp_protocol = sa ? sa->sa_family : 0;	raw_input(m, &route_proto, &route_src, &route_dst);}/* * This routine is called to generate a message from the routing * socket indicating that the status of a network interface has changed. */voidrt_ifmsg(ifp)	register struct ifnet *ifp;{	register struct if_msghdr *ifm;	struct mbuf *m;	struct rt_addrinfo info;	if (route_cb.any_count == 0)		return;	bzero((caddr_t)&info, sizeof(info));	m = rt_msg1(RTM_IFINFO, &info);	if (m == 0)		return;	ifm = mtod(m, struct if_msghdr *);	ifm->ifm_index = ifp->if_index;	ifm->ifm_flags = ifp->if_flags;	ifm->ifm_data = ifp->if_data;	ifm->ifm_addrs = 0;	route_proto.sp_protocol = 0;	raw_input(m, &route_proto, &route_src, &route_dst);}/* * This is called to generate messages from the routing socket * indicating a network interface has had addresses associated with it. * if we ever reverse the logic and replace messages TO the routing * socket indicate a request to configure interfaces, then it will * be unnecessary as the routing socket will automatically generate * copies of it. */voidrt_newaddrmsg(cmd, ifa, error, rt)	int cmd, error;	register struct ifaddr *ifa;	register struct rtentry *rt;{	struct rt_addrinfo info;	struct sockaddr *sa = NULL;	int pass;	struct mbuf *m = NULL;	struct ifnet *ifp = ifa->ifa_ifp;        int ncmd;	if (route_cb.any_count == 0)		return;	for (pass = 1; pass < 3; pass++) {		bzero((caddr_t)&info, sizeof(info));		if ((cmd == RTM_ADD && pass == 1) ||		    (cmd == RTM_DELETE && pass == 2)) {			register struct ifa_msghdr *ifam;			ncmd = cmd == RTM_ADD ? RTM_NEWADDR : RTM_DELADDR;			ifaaddr = sa = ifa->ifa_addr;			ifpaddr = ifp->if_addrlist->ifa_addr;			netmask = ifa->ifa_netmask;			brdaddr = ifa->ifa_dstaddr;			if ((m = rt_msg1(ncmd, &info)) == NULL)				continue;			ifam = mtod(m, struct ifa_msghdr *);			ifam->ifam_index = ifp->if_index;			ifam->ifam_metric = ifa->ifa_metric;			ifam->ifam_flags = ifa->ifa_flags;			ifam->ifam_addrs = info.rti_addrs;		}		if ((cmd == RTM_ADD && pass == 2) ||		    (cmd == RTM_DELETE && pass == 1)) {			register struct rt_msghdr *rtm;						if (rt == 0)				continue;                        ncmd = cmd;			netmask = rt_mask(rt);			dst = sa = rt_key(rt);			gate = rt->rt_gateway;#ifdef ROUTER_STACK                /* Use a different message type for additional routes. */                if ( ((ROUTE_ENTRY *)rt)->primaryRouteFlag == FALSE)                    {                    if (ncmd == RTM_ADD)                        ncmd = RTM_ADDEXTRA;                    else                        ncmd = RTM_DELEXTRA;                    }#endif /* ROUTER_STACK */			if ((m = rt_msg1(ncmd, &info)) == NULL)				continue;			rtm = mtod(m, struct rt_msghdr *);			rtm->rtm_index = ifp->if_index;			rtm->rtm_flags |= rt->rt_flags;			rtm->rtm_errno = error;			rtm->rtm_addrs = info.rti_addrs;		}		route_proto.sp_protocol = sa ? sa->sa_family : 0;		raw_input(m, &route_proto, &route_src, &route_dst);	}}

⌨️ 快捷键说明

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