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

📄 route.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
                         */                        error = rtrequestAddEqui (dst, netmask, gateway, flags,                                                  M2_ipRouteProto_icmp, 0,                                                  FALSE, FALSE, NULL);			/* error = rtrequest((int)RTM_ADD, dst, gateway,				    netmask, flags,				    (struct rtentry **)0);                        */			stat = &rtstat.rts_dynamic;		} else {			/*			 * Smash the current notion of the gateway to			 * this destination.  Should check about netmask!!!			 */			if (!(error = rt_setgate (rt, rt_key(rt), gateway)))			    {			    rt->rt_flags |= RTF_MODIFIED;			    flags |= RTF_MODIFIED;			    stat = &rtstat.rts_newgateway;			    rt->rt_mod = tickGet(); 	    /* last modified */			    rtmodified++; 			    }		}	} else		error = EHOSTUNREACH;done:	if (rt) {		if (rtp && !error)			*rtp = rt;		else			rtfree(rt);	}out:	if (error)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            WV_NET_MARKER_2 (NET_AUX_EVENT, WV_NET_CRITICAL, 27, 6,                             WV_NETEVENT_RTRESET_BADDEST,                             error,                              ((struct sockaddr_in *)gateway)->sin_addr.s_addr)#endif  /* INCLUDE_WVNET */#endif            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;        if (rtMissMsgHook)            (*rtMissMsgHook) (RTM_REDIRECT, &info, flags, error);#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_VERBOSE event */        WV_NET_MARKER_4 (NET_AUX_EVENT, WV_NET_VERBOSE, 34, 14,                         WV_NETEVENT_RTRESET_STATUS,                         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	return (error); }/** Routing table ioctl interface.** WRS MODS support for this function is being for backward compatibility.* This function has be moved else where because the routing code has * nothing to do with internet specific addresses since routing is independent* of the sockaddress family.*/intrtioctl(req, data)	int req;	caddr_t data;{	struct ortentry * pORE = NULL;	struct sockaddr netMask;	struct sockaddr * pNetMask = &netMask; 	register u_long i; 	register u_long net;	register struct in_ifaddr *ia;#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_INFO event */    WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 20, 12,                     WV_NETEVENT_RTIOCTL_START, req)#endif  /* INCLUDE_WVNET */#endif        if (req != SIOCADDRT && req != SIOCDELRT)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_ERROR event */            WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_ERROR, 37, 8,                             WV_NETEVENT_RTIOCTL_BADREQ, req)#endif  /* INCLUDE_WVNET */#endif            return (EINVAL);            }	pORE = (struct ortentry *)data;	/* BSD4.3 to BSD4.4 conversion */	if (req == SIOCADDRT)	    req = RTM_ADD;	else	    req = RTM_DELETE;	/* 	 * Set the netmask to the netmask of the interface address.	 * This has to be removed if provision is made with routeAdd	 * to add the network mask. 	 */	bzero ((caddr_t)&netMask, sizeof (struct sockaddr));	/* check for default gateway address */	if (((struct sockaddr_in *)(&pORE->rt_dst))->sin_addr.s_addr 	    != INADDR_ANY )	    {	    i = ntohl(((struct sockaddr_in*)&pORE->rt_dst)->sin_addr.s_addr);			    pNetMask->sa_family = AF_INET; 	    pNetMask->sa_len    = 8;	    if (IN_CLASSA(i))		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSA_NET);		net = i & IN_CLASSA_NET;		}	    else if (IN_CLASSB(i))		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSB_NET);		net = i & IN_CLASSB_NET;		}	    else if (IN_CLASSC(i))		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSC_NET);		net = i & IN_CLASSC_NET;		}	    else		{		((struct sockaddr_in *)pNetMask)->sin_addr.s_addr = 		    htonl(IN_CLASSD_NET);		net = i & IN_CLASSD_NET;		}	    /*	     * Check whether network is a subnet;	     * if so, return subnet number.	     */#ifdef VIRTUAL_STACK	    for (ia = _in_ifaddr; ia; ia = ia->ia_next)#else	    for (ia = in_ifaddr; ia; ia = ia->ia_next)#endif /* VIRTUAL_STACK */		if (net == ia->ia_net)		    ((struct sockaddr_in *)pNetMask)->sin_addr.s_addr =			htonl(ia->ia_subnetmask); 	    in_socktrim ((struct sockaddr_in *)pNetMask); 	    }       pORE->rt_flags |= RTF_GATEWAY;       if(pORE->rt_flags & RTF_HOST)	   pNetMask=0; #ifdef DEBUG       logMsg("rtIoctl:before rtrequestAddEqui/DelEqui\n",0,0,0,0,0,0);#endif        /*         * Add the requested route using the default weight value or delete         * the matching entry. In either case, report the change using both         * routing socket messages and direct callbacks.         */       if(req==RTM_ADD)	   return (rtrequestAddEqui (&pORE->rt_dst, pNetMask,                                     &pORE->rt_gateway, pORE->rt_flags,                                     M2_ipRouteProto_other, 0,                                     TRUE, TRUE, NULL));       else	   return (rtrequestDelEqui (&pORE->rt_dst, pNetMask,                                     &pORE->rt_gateway, pORE->rt_flags,                                     M2_ipRouteProto_other, TRUE, TRUE, NULL));}#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))int rt_fixdelete (struct radix_node *, void *);static int rt_fixchange (struct radix_node *, void *);intrtrequest(req, dst, gateway, netmask, flags, ret_nrt)	int req, flags;	struct sockaddr *dst, *gateway, *netmask;	struct rtentry **ret_nrt;{	int s = splnet(); 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(ESRCH);	if (flags & RTF_HOST)            {            netmask = 0;	    }        if (netmask)	    {	    TOS_SET (netmask, 0x1f);  /* set the 5 bits in the mask corresponding					 to the TOS bits */	    }	switch (req) {	case RTM_DELETE:		if ((rn = rnh->rnh_deladdr(dst, netmask, rnh)) == 0)			senderr(ESRCH);		if (rn->rn_flags & (RNF_ACTIVE | RNF_ROOT))                    {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */                    WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 22, 2,                                     WV_NETEVENT_RTREQ_PANIC)#endif  /* INCLUDE_WVNET */#endif                    panic ("rtrequest delete");                    }		rt = (struct rtentry *)rn;                /*                 * Search the appropriate subtree to remove any children                 * (created for path MTU results). This cleanup must occur                 * before clearing the RTF_UP flag or the system might                 * release the current node's memory prematurely if the                 * search deletes the last reference.                 */                if (dst->sa_family == AF_INET &&                    (rt->rt_flags & RTF_CLONING) && netmask)                    {                    rn_walksubtree (rnh, dst, netmask, rt_fixdelete, rt);                    }		rt->rt_flags &= ~RTF_UP;		if (rt->rt_gwroute) {			rt = rt->rt_gwroute; RTFREE(rt);			(rt = (struct rtentry *)rn)->rt_gwroute = 0;		}		if ((ifa = rt->rt_ifa) && ifa->ifa_rtrequest)			ifa->ifa_rtrequest(RTM_DELETE, rt, SA(0));		rttrash++;		if (ret_nrt)			*ret_nrt = rt;		else if (rt->rt_refcnt <= 0) {			rt->rt_refcnt++;			rtfree(rt);		}		rtmodified++;		break;	case RTM_RESOLVE:		if (ret_nrt == 0 || (rt = *ret_nrt) == 0)                        {#ifdef DEBUG                        logMsg("rtrequest: RTM_RESOLVE, EINVAL error\n",0,0,0,0,0,0);#endif			senderr(EINVAL);                        }		ifa = rt->rt_ifa;		flags = rt->rt_flags & ~RTF_CLONING;		gateway = rt->rt_gateway;		if ((netmask = rt->rt_genmask) == 0)			{			flags |= RTF_HOST;			}		goto makeroute;	case RTM_ADD:		if ((ifa = ifa_ifwithroute(flags, dst, gateway)) == 0)			senderr(ENETUNREACH);	makeroute:		/*		 * Check if the maximum ARP table size has been reached. This		 * test includes static ARP entries added using arpAdd() 		 * (RTM_ADD) and also dynamic ARP entries that might be cloned		 * from an existing route (RTM_RESOLVE). The check in 		 * arp_rtrequest() controls the creation of the llinfo_arp 		 * entry while this check ensures that the ARP rtentry 		 * structure is not created and is not added to the route tree.		 */		if ((gateway->sa_family == AF_LINK) && (arpMaxEntries != 0) &&		    (arp_inuse >= arpMaxEntries) && (arpEntryDelete () == ERROR))		    senderr (ENOBUFS);		R_Malloc(rt, struct rtentry *, sizeof(ROUTE_ENTRY));		if (rt == 0)			senderr(ENOBUFS);		Bzero(rt, sizeof (ROUTE_ENTRY));		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);            /* Set IP routes to create children (for path MTU results). */            if (ndst->sa_family == AF_INET &&                !IN_MULTICAST                    (ntohl ( ((struct sockaddr_in *)ndst)->sin_addr.s_addr)) &&                ! (rt->rt_flags & RTF_HOST))                {                if (((struct sockaddr_in *)netmask)->sin_addr.s_addr                          != 0xffffffff)                    {                    rt->rt_flags |= RTF_CLONING;                    }                }		rn = rnh->rnh_addaddr((caddr_t)ndst, (caddr_t)netmask,					rnh, rt->rt_nodes);		/* update proto field of rt entry, in the gateway sockaddr */		if ((req == RTM_ADD) && (gateway->sa_family == AF_INET))		    RT_PROTO_SET (ndst, RT_PROTO_GET (dst));                if (rn == 0 && (rt->rt_flags & RTF_HOST))                    {                    /* Replace matching (cloned) entry if possible. */                    rn = routeSwap (rnh, rt, ndst, netmask);                    }		if (rn == 0) {			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;                /*                 * Set the flags to ignore any new route associated                 * with a disabled interface. Enabling the interface                 * will clear the flags.                 */                if ( (rt->rt_ifp->if_flags & IFF_UP) == 0)                    {                    rt->rt_flags |= RTF_BLACKHOLE;                    rn->rn_flags |= RNF_BLACKHOLE;                    }		if (req == RTM_RESOLVE)                    {                    rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */                    rt->rt_parent = (*ret_nrt);   /* record source route */                    (*ret_nrt)->rt_refcnt++;                    rt->rt_flags |= RTF_CLONED;                                        /*                     * Mark the cloned route as a representative route                     * so that when it is deleted, Fastpath is called with                     * ROUTE_REP_DEL operation and the entry gets removed                     * from the Fastpath cache                     */                     ((ROUTE_ENTRY*)rt)->primaryRouteFlag = TRUE;                    }                if (rt->rt_ifp->if_type == IFT_PMP)                    {                    /*                     * Point-to-multipoint devices do not use a common                     * MTU value for all destinations or perform address                     * resolution, so cloning the interface route to store                     * that information is not necessary.                     */                    rt->rt_flags &= ~RTF_CLONING;                    }                /* Assign initial path MTU estimate, if enabled for route. */                if (!rt->rt_rmx.rmx_mtu && !(rt->rt_rmx.rmx_locks & RTV_MTU)                    && rt->rt_ifp)                    rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu;		if (ifa->ifa_rtrequest)			ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0));                if (ndst->sa_family == AF_INET)                    {                    /*                     * Remove any cloned routes which a new                     * network route overrides. Cloned routes		     * should not be deleted when adding the		     * default route.                     */                    if (!(rt->rt_flags & RTF_HOST) && rt_mask (rt) != 0 &&			((struct sockaddr_in *) ndst)->sin_addr.s_addr != 0)                        {                        rn_walksubtree (rnh, ndst, netmask, rt_fixchange, rt);                        }                    }		if (ret_nrt) {			*ret_nrt = rt;			rt->rt_refcnt++;		}		rt->rt_mod = tickGet(); 	/* last modified */		rtmodified++;		break;	}bad:        if (error)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_CRITICAL event */            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            }        else if (req != RTM_RESOLVE)            FORWARDING_CACHE_FLUSH();	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,

⌨️ 快捷键说明

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