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

📄 route.c

📁 VXWORKS 源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		break;	}bad:#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */        if (error)            {            WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_CRITICAL, 28, 7,                             WV_NETEVENT_RTREQ_BADROUTE,                             error,                              ((struct sockaddr_in *)dst)->sin_addr.s_addr,                              ((struct sockaddr_in *)gateway)->sin_addr.s_addr,                              ((struct sockaddr_in *)netmask)->sin_addr.s_addr)            }#endif  /* INCLUDE_WVNET */#endif	splx(s);	return (error);} /*   * This routine is called when adding a host-specific route to  * the routing tree fails. That failure can occur because an  * ARP entry for the destination already exists in the tree.  * Alternatively, a cloned entry to a remote destination (for  * path MTU results) might already exist. In either case, the  * host-specific entry is added after the existing entry is removed.  */struct radix_node * routeSwap    (    struct radix_node_head * 	pNodeHead,    struct rtentry * 		pRoute,    struct sockaddr * 		pDest,    struct sockaddr * 		pNetmask    )    {    struct radix_node * 	pNode;    struct rtentry * 		pTwinRt;    struct ifaddr * 		pIfAddr;    struct rtentry * 		pArpRt;    struct radix_node_head * 	pTwinHead;    struct sockaddr * 		pTwinKey;    /*     * Existing entries will prevent the addition of     * matching host routes. Delete the entry and try     * to add the host route again. The search is based     * on the rtalloc1() routine.     */    pNode = rn_search ((caddr_t)pDest, pNodeHead->rnh_treetop);    if ( (pNode->rn_flags & RNF_ROOT) == 0)        {        /* Check leaf node for ARP information or existing child route. */        pTwinRt = (struct rtentry *)pNode;        if ( (pTwinRt->rt_flags & RTF_CLONED) ||                (pTwinRt->rt_flags & RTF_LLINFO &&                 pTwinRt->rt_flags & RTF_HOST &&                 pTwinRt->rt_gateway &&                 pTwinRt->rt_gateway->sa_family == AF_LINK))            {            /* Mimic RTM_DELETE case from rtrequest() routine. */            pTwinKey = (struct sockaddr *)rt_key (pTwinRt);            pTwinHead = rt_tables [pTwinKey->sa_family];            if (pTwinHead)                {                pNode = pTwinHead->rnh_deladdr (pTwinKey, 0, pTwinHead);                if (pNode)                    {                    pArpRt = (struct rtentry *)pNode;                    pArpRt->rt_flags &= ~RTF_UP;                    if (pArpRt->rt_gwroute)                        {                        pArpRt = pArpRt->rt_gwroute;                        RTFREE (pArpRt);                        pArpRt = (struct rtentry *)pNode;                        pArpRt->rt_gwroute = 0;                        }                    pIfAddr = pArpRt->rt_ifa;                    if (pIfAddr && pIfAddr->ifa_rtrequest)                        pIfAddr->ifa_rtrequest (RTM_DELETE, pArpRt, SA(0));                    rttrash++;                    if (pArpRt->rt_refcnt <= 0)                        {                        pArpRt->rt_refcnt++;                        rtfree (pArpRt);                        }                    rtmodified++;                    }                }    /* RTM_DELETE completed. */            pNode = pNodeHead->rnh_addaddr ( (caddr_t)pDest, (caddr_t)pNetmask,                                             pNodeHead, pRoute->rt_nodes);            }  /* End ARP entry replacement. */        else            {            /*             * Matching node was not a host entry. Reset node reference.             */            pNode = 0;            }        }    /* End handling for RNF_ROOT != 0 */    else        {        /*          * No valid entry found: remove reference to leftmost/rightmost node.         */        pNode = 0;        }    return (pNode);    }/* * The rt_fixchange() routine adjusts the routing tree after adding a new * network route. If the system inserts the route between an older network * route and the corresponding (cloned) host routes, the new route might * incorporate existing cloned entries. This routine removes those (obsolete) * cloned routes. Unfortunately, it also needlessly examines a subtree and * removes valid cloned routes when adding a new (less specific) route above * a pre-existing entry. Since those routes will be regenerated if still in * use, this (wasteful) behavior does not prevent correct operation. */static intrt_fixchange(rn, vp)        struct radix_node *rn;        void *vp;{        struct rtentry *rt = (struct rtentry *)rn;        struct rtentry *rt0 = vp;        struct radix_node_head *rnh = rt_tables [AF_INET];        u_char *xk1, *xm1, *xk2;        int i, len;        if (!rt->rt_parent)     /* Ignore uncloned entries. */            return 0;        /*         * Check if the network number of the route entry matches         * the destination of the new route.         */        len = min (rt_key (rt0)->sa_len, rt_key (rt)->sa_len);        xk1 = (u_char *)rt_key (rt0);        xm1 = (u_char *)rt_mask (rt0);        xk2 = (u_char *)rt_key (rt);        for (i = rnh->rnh_treetop->rn_off; i < len; i++) {                if ((xk2[i] & xm1[i]) != xk1[i]) {                        return 0;                }        }        /* Remove the cloned route which is part of the new route's network. */        return rtrequest(RTM_DELETE, rt_key(rt), (struct sockaddr *)0,                         rt_mask(rt), rt->rt_flags, (struct rtentry **)0);}/* * The rt_fixdelete() routine removes any cloned routes (for storing path * MTU information) when the original route to the remote destination is * deleted or the gateway is changed. It has no affect on cloned entries * containing ARP information. */int rt_fixdelete(rn, vp)        struct radix_node *rn;        void *vp;{        struct rtentry *rt = (struct rtentry *)rn;        struct rtentry *rt0 = vp;        if (rt->rt_parent == rt0 && !(rt->rt_flags & RTF_LLINFO)) {                return rtrequest(RTM_DELETE, rt_key(rt),                                 (struct sockaddr *)0, rt_mask(rt),                                 rt->rt_flags, (struct rtentry **)0);        }        return 0;}intrt_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;        /*	 * Prevent addition of a host route with destination equal to         * the gateway. Addition of such a route can cause infinite	 * recursion while doing a route search using rtalloc which might	 * result in stack overflow in tNetTask.	 */	if (((rt0->rt_flags & (RTF_HOST | RTF_GATEWAY | RTF_LLINFO)) ==	     (RTF_HOST | RTF_GATEWAY)) && (dst->sa_len == gate->sa_len) &&	     (((struct sockaddr_in *) dst)->sin_addr.s_addr ==	      ((struct sockaddr_in *) gate)->sin_addr.s_addr))	    return 1;	if (rt->rt_gateway == 0 || glen > ROUNDUP(rt->rt_gateway->sa_len)) {		old = (caddr_t)rt_key(rt);		R_Malloc(new, caddr_t, dlen + glen);		if (new == 0)                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */                    WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 23, 3,                                     WV_NETEVENT_RTSET_NOBUFS)#endif  /* INCLUDE_WVNET */#endif                   return 1;                   }		rt->rt_nodes->rn_key = new;	} else {		new = rt->rt_nodes->rn_key;		old = 0;	}	Bcopy(gate, (rt->rt_gateway = (struct sockaddr *)(new + dlen)), glen);	if (old) {		Bcopy(dst, new, dlen);		Free(old);	}	if (rt->rt_gwroute) {		rt = rt->rt_gwroute; RTFREE(rt);		rt = rt0; rt->rt_gwroute = 0;	}	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 = 0;	struct rtentry *nrt = 0;	int error=0;	dst = flags & RTF_HOST ? ifa->ifa_dstaddr : ifa->ifa_addr;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_VERBOSE, 35, 15,                         WV_NETEVENT_RTINIT_START, cmd,                          ((struct sockaddr_in *)dst)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif	if (cmd == RTM_DELETE) {		if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) {			m = mBufClGet(M_WAIT, MT_SONAME, CL_SIZE_128, TRUE);			if (m == (struct mbuf *) NULL)			    {			    return (ENOBUFS);			    }			deldst = mtod(m, struct sockaddr *);			rt_maskedcopy(dst, deldst, ifa->ifa_netmask);			dst = deldst;		}		if ((rt = rtalloc1(dst, 0))) {			rt->rt_refcnt--;			if (rt->rt_ifa != ifa) {				if (m)					(void) m_free(m);				return (flags & RTF_HOST ? EHOSTUNREACH							: ENETUNREACH);			}		}	}        /*         * Create the new route using the default weight value or delete         * the matching entry. In either case, do not report the change         * since the later hook generates both types of messages.         */       if(cmd==RTM_ADD)	   error=rtrequestAddEqui(dst, ifa->ifa_netmask, ifa->ifa_addr, 	   		          flags | ifa->ifa_flags,                                  M2_ipRouteProto_local, 0, FALSE, FALSE,				  (ROUTE_ENTRY**)&nrt);       if(cmd==RTM_DELETE)	   error=rtrequestDelEqui(dst, ifa->ifa_netmask, ifa->ifa_addr,			          flags | ifa->ifa_flags,                                  M2_ipRouteProto_local, FALSE, FALSE,				  (ROUTE_ENTRY**)&nrt);	if (m)		(void) m_free(m);	if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) {        	if (rtNewAddrMsgHook) #ifdef ROUTER_STACK                    (*rtNewAddrMsgHook) (cmd, ifa, nrt);#else                    (*rtNewAddrMsgHook) (cmd, ifa, error, nrt);#endif /* ROUTER_STACK */		if (rt->rt_refcnt <= 0) {			rt->rt_refcnt++;			rtfree(rt);		}	}	if (cmd == RTM_ADD && error == 0 && (rt = nrt)) {		rt->rt_refcnt--;		if (rt->rt_ifa != ifa) {			logMsg("rtinit: wrong ifa (%x) was (%x)\n", (int) ifa,				(int) rt->rt_ifa, 0, 0, 0, 0);			if (rt->rt_ifa->ifa_rtrequest)			    rt->rt_ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));			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(0));		}		if (rtNewAddrMsgHook)#ifdef ROUTER_STACK                    (*rtNewAddrMsgHook) (cmd, ifa, nrt);#else                    (*rtNewAddrMsgHook) (cmd, ifa, error, nrt);#endif /* ROUTER_STACK */	}	return (error);}#ifdef RTALLOC_DEBUG/********************************************************************************* routeEntryDebugShow - print an entry of the routing table** This routine prints a routing table entry, displaying its mask, protocol,* and type of service.** RETURNS: OK or ERROR.** NOMANUAL*/LOCAL int routeEntryDebugShow    (    struct radix_node * rn              /* pointer to the node structure */    )    {    FAST struct sockaddr *      destAddr = NULL;    FAST struct sockaddr *      gateAddr;    FAST struct rtentry *       pRt;    char                        aStr [INET_ADDR_LEN];    uint32_t                    mask;    FAST UCHAR *                pChr;     pRt = (struct rtentry *)rn;    destAddr = rt_key(pRt);             /* get the destination address */    gateAddr = pRt->rt_gateway;         /* get the gateway address */    /*  arp entries */    /*if ((gateAddr->sa_family == AF_LINK) && (pRt->rt_flags & RTF_HOST))        return (0);*/    /* print destination internet address */    inet_ntoa_b (((struct sockaddr_in *)destAddr)->sin_addr, aStr);    printf ("if_name: %s%d\n",  pRt->rt_ifp->if_name, pRt->rt_ifp->if_unit);    printf ("destination: %-16s\n", (destAddr->sa_family == AF_INET) ?                      aStr : "not AF_INET\n");    /* print netmask */    if (rt_mask (pRt) == NULL)        {        mask = 0xffffffff;        }    else        {        mask = ((struct sockaddr_in *) rt_mask (pRt))->sin_addr.s_addr;        mask = ntohl (mask);        }    printf ("mask: %-10lx\n", mask);    /* print the gateway address which: internet or linklevel */    if (gateAddr->sa_family == AF_LINK)        {        if ( ((struct sockaddr_dl *)gateAddr)->sdl_alen == 6)            {            pChr = (UCHAR *)(LLADDR((struct sockaddr_dl *)gateAddr));            printf ("ARP ROUTE: %02x:%02x:%02x:%02x:%02x:%-6x\n",                pChr[0], pChr[1], pChr[2], pChr[3], pChr[4], pChr[5]);            }        else if ( ((struct sockaddr_dl *)gateAddr)->sdl_alen == 0)            {            printf("ARP Interface Route Entry\n");            }        else            {            printf("Unknown Entry\n");            return(0);            }        }    else        {        inet_ntoa_b (((struct sockaddr_in *)gateAddr)->sin_addr, aStr);        printf ("Gateway: %-20s \n", aStr);        }    /* print type of service */    printf ("tos: %-5x\n", TOS_GET (destAddr));    printf ("flags: ");    if (pRt->rt_flags & RTF_UP)        printf("U");    if (pRt->rt_flags & RTF_HOST)        printf("H");    if (pRt->rt_flags & RTF_LLINFO)        printf("L");    if (pRt->rt_flags & RTF_CLONING)        printf("C ");    if (pRt->rt_flags & RTF_STATIC)        printf("S");    if (pRt->rt_flags & RTF_GATEWAY)        {        printf("G");        if (pRt->rt_gwroute)            printf(": Gateway route entry = %p ", pRt->rt_gwroute);        }    printf ("\n");    printf ("refCnt: %-7d\n",   pRt->rt_refcnt);    printf ("rt_use: %-7ld\n",  pRt->rt_use);    printf ("proto: %-5d\n",  RT_PROTO_GET (destAddr));    return (0);    }#endif /* RTALLOC_DEBUG */

⌨️ 快捷键说明

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