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

📄 route.c

📁 vxworks下的实现网络TCPIP协议的原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    != 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.	     */	    for (ia = in_ifaddr; ia; ia = ia->ia_next)		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       if(req==RTM_ADD)	   return (rtrequestAddEqui(&pORE->rt_dst, pNetMask, &pORE->rt_gateway, 			            pORE->rt_flags, M2_ipRouteProto_other, NULL));       else	   return (rtrequestDelEqui(&pORE->rt_dst, pNetMask, &pORE->rt_gateway,			            pORE->rt_flags, M2_ipRouteProto_other, NULL));}#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 = 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))			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 = 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:		R_Malloc(rt, struct rtentry *, sizeof(ROUTE_ENTRY));		if (rt == 0)			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);		/* 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) ARP 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;		if (req == RTM_RESOLVE)			rt->rt_rmx = (*ret_nrt)->rt_rmx; /* copy metrics */		if (ifa->ifa_rtrequest)			ifa->ifa_rtrequest(req, rt, SA(ret_nrt ? *ret_nrt : 0));		if (ret_nrt) {			*ret_nrt = rt;			rt->rt_refcnt++;		}		rt->rt_mod = tickGet(); 	/* last modified */		rtmodified++;		break;	}bad:	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.  * If so, the host-specific entry is added after the ARP 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 ARP entries will prevent the addition of     * matching host routes. Delete the ARP 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. */        pTwinRt = (struct rtentry *)pNode;        if (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 an ARP 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);    }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;	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)			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;	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);			}		}	}       if(cmd==RTM_ADD)	   error=rtrequestAddEqui(dst, ifa->ifa_netmask, ifa->ifa_addr, 	   		          flags | ifa->ifa_flags, M2_ipRouteProto_local, 				  (ROUTE_ENTRY**)&nrt);       if(cmd==RTM_DELETE)	   error=rtrequestDelEqui(dst, ifa->ifa_netmask, ifa->ifa_addr,			          flags | ifa->ifa_flags, M2_ipRouteProto_local, 				  (ROUTE_ENTRY**)&nrt);	if (m)		(void) m_free(m);	if (cmd == RTM_DELETE && error == 0 && (rt = nrt)) {        	if (_rtNewAddrMsgHook)                     (*_rtNewAddrMsgHook) (cmd, ifa, error, nrt);		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)                    (*_rtNewAddrMsgHook) (cmd, ifa, error, nrt);	}	return (error);}

⌨️ 快捷键说明

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