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

📄 rtsock.c

📁 the vxworks system kernel souce packeg.there may be something you need .
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * This is used in dumping the kernel table via sysctl(). */intsysctl_dumpentry(rn, w)	struct radix_node *rn;	register struct walkarg *w;{	register struct rtentry *rt = (struct rtentry *)rn;	int error = 0, size;	struct rt_addrinfo info;	if (w->w_op == NET_RT_FLAGS && !(rt->rt_flags & w->w_arg))		return 0;	bzero((caddr_t)&info, sizeof(info));	dst = rt_key(rt);	gate = rt->rt_gateway;	netmask = rt_mask(rt);	genmask = rt->rt_genmask;	if (rt->rt_ifp) {		ifpaddr = rt->rt_ifp->if_addrlist->ifa_addr;		ifaaddr = rt->rt_ifa->ifa_addr;		if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)			brdaddr = rt->rt_ifa->ifa_dstaddr;	}	size = rt_msg2(RTM_GET, &info, 0, w);	if (w->w_where && w->w_tmem) {		register struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;		rtm->rtm_flags = rt->rt_flags;		rtm->rtm_use = rt->rt_use;		rtm->rtm_rmx = rt->rt_rmx;		rtm->rtm_index = rt->rt_ifp->if_index;		rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0;		rtm->rtm_addrs = info.rti_addrs;		if ((error = copyout((caddr_t)rtm, w->w_where, size)))			w->w_where = NULL;		else			w->w_where += size;	}	return (error);}intsysctl_iflist(af, w)	int	af;	register struct	walkarg *w;{	register struct ifnet *ifp;	register struct ifaddr *ifa;	struct	rt_addrinfo info;	int	len, error = 0;	bzero((caddr_t)&info, sizeof(info));#ifdef VIRTUAL_STACK	for (ifp = _ifnet; ifp; ifp = ifp->if_next) {#else	for (ifp = ifnet; ifp; ifp = ifp->if_next) {#endif		if (w->w_arg && w->w_arg != ifp->if_index)			continue;		ifa = ifp->if_addrlist;		ifpaddr = ifa->ifa_addr;		len = rt_msg2(RTM_IFINFO, &info, (caddr_t)0, w);		ifpaddr = 0;		if (w->w_where && w->w_tmem) {			register struct if_msghdr *ifm;			ifm = (struct if_msghdr *)w->w_tmem;			ifm->ifm_index = ifp->if_index;			ifm->ifm_flags = ifp->if_flags;			ifm->ifm_data = ifp->if_data;			ifm->ifm_addrs = info.rti_addrs;			if ((error = copyout((caddr_t)ifm, w->w_where, len)))				return (error);			w->w_where += len;		}		while ((ifa = ifa->ifa_next)) {			if (af && af != ifa->ifa_addr->sa_family)				continue;			ifaaddr = ifa->ifa_addr;			netmask = ifa->ifa_netmask;			brdaddr = ifa->ifa_dstaddr;			len = rt_msg2(RTM_NEWADDR, &info, 0, w);			if (w->w_where && w->w_tmem) {				register struct ifa_msghdr *ifam;				ifam = (struct ifa_msghdr *)w->w_tmem;				ifam->ifam_index = ifa->ifa_ifp->if_index;				ifam->ifam_flags = ifa->ifa_flags;				ifam->ifam_metric = ifa->ifa_metric;				ifam->ifam_addrs = info.rti_addrs;				if ((error = copyout(w->w_tmem, w->w_where,                                                     len)))					return (error);				w->w_where += len;			}		}		ifaaddr = netmask = brdaddr = 0;	}	return (0);}intsysctl_rtable(name, namelen, where, given, new, newlen)	int	*name;	int	namelen;	caddr_t	where;	size_t	*given;	caddr_t	*new;	size_t	newlen;{	register struct radix_node_head *rnh;	int	i, s, error = EINVAL;	u_char  af;	struct	walkarg w;/* * XXX - This event does not usually occur: the sysctl_rtable() routine *       is typically only called by the Unix sysctl command which is not *       supported by VxWorks. It is also called by the RIP implementation *       as a legacy of the port from BSD, but that implementation detail *       is not of sufficient interest to include the event.#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /@ WV_NET_INFO event @/        if (namelen != 3)            {            WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 22, 7,                              WV_NETEVENT_ROUTEWALK_START, 0)            }        else            {            WV_NET_MARKER_1 (NET_AUX_EVENT, WV_NET_INFO, 22, 7,                              WV_NETEVENT_ROUTEWALK_START, name[1])            }#endif  /@ INCLUDE_WVNET @/#endif * XXX - end of unused event */	if (new)		return (EPERM);	if (namelen != 3)		return (EINVAL);	af = name[0];	Bzero(&w, sizeof(w));	w.w_where = where;	w.w_given = *given;	w.w_needed = 0 - w.w_given;	w.w_op = name[1];	w.w_arg = name[2];	s = splnet();	switch (w.w_op) {	case NET_RT_DUMP:	case NET_RT_FLAGS:		for (i = 1; i <= AF_MAX; i++)			if ((rnh = rt_tables[i]) && (af == 0 || af == i) &&			    (error = rnh->rnh_walktree(rnh,							sysctl_dumpentry, &w)))				break;		break;	case NET_RT_IFLIST:		error = sysctl_iflist(af, &w);	}	splx(s);	if (w.w_tmem){		FREE(w.w_tmem, MT_RTABLE);	}	w.w_needed += w.w_given;	if (where) {		*given = w.w_where - where;		if (*given < w.w_needed)			return (ENOMEM);	} else {		*given = (11 * w.w_needed) / 10;	}	return (error);}/* * Definitions of protocols supported in the ROUTE domain. */extern	struct domain routedomain;		/* or at least forward */struct protosw routesw[] = {{ SOCK_RAW,	&routedomain,	0,		PR_ATOMIC|PR_ADDR,  raw_input,	route_output,	raw_ctlinput,	0,  route_usrreq,  rtSockInit,	0,		0,		0,  sysctl_rtable,}};struct domain routedomain =    { PF_ROUTE, "route", 0, 0, 0,      routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] };/* * Copy data from a buffer back into the indicated mbuf chain, * starting "off" bytes from the beginning, extending the mbuf * chain if necessary. */static voidm_copyback(m0, off, len, cp)	struct	mbuf *m0;	register int off;	register int len;	caddr_t cp;{	register int mlen;	register struct mbuf *m = m0, *n;	int totlen = 0;	if (m0 == 0)		return;	while (off > (mlen = m->m_len)) {		off -= mlen;		totlen += mlen;		if (m->m_next == 0) {			n = m_getclr(M_DONTWAIT, m->m_type, CL_SIZE_128, TRUE);			if (n == 0)				goto out;			n->m_len = min(n->m_extSize, len + off);			m->m_next = n;		}		m = m->m_next;	}	while (len > 0) {		mlen = min (m->m_len - off, len);		bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);		cp += mlen;		len -= mlen;		mlen += off;		off = 0;		totlen += mlen;		if (len == 0)			break;		if (m->m_next == 0) {			n = mBufClGet(M_DONTWAIT, m->m_type, CL_SIZE_128, TRUE);			if (n == 0)				break;			n->m_len = min(n->m_extSize, len);			m->m_next = n;		}		m = m->m_next;	}out:	if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))		m->m_pkthdr.len = totlen;}/********************************************************************************* m_copydata - copy data from an mbuf chain into a buff* Copy data from an mbuf chain starting "off" bytes from the beginning,* continuing for "len" bytes, into the indicated buffer.*/static void m_copydata(m, off, len, cp)    register struct mbuf *m;    register int off;    register int len;    caddr_t cp;    {    register unsigned count;    if (off < 0 || len < 0)	panic("m_copydata");    while (off > 0)	{	if (m == 0)            {#ifdef WV_INSTRUMENTATION#ifdef INCLUDE_WVNET    /* WV_NET_EMERGENCY event */            WV_NET_MARKER_0 (NET_AUX_EVENT, WV_NET_EMERGENCY, 26, 3,                              WV_NETEVENT_COPYDATA_PANIC)#endif  /* INCLUDE_WVNET */#endif            panic("m_copydata");            }	if (off < m->m_len)	    break;	off -= m->m_len;	m = m->m_next;	}    while (len > 0)	{	if (m == 0)	    panic("m_copydata");	count = min(m->m_len - off, len);	bcopy(mtod(m, caddr_t) + off, cp, count);	len -= count;	cp += count;	off = 0;	m = m->m_next;	}    }#ifdef ROUTER_STACK/********************************************************************************* routeGatewayFetch - build a message which includes a list of gateways** This routine constructs a routing socket message which supplies each* next-hop router for all duplicate routes with a given destination and* netmask. When the <pMessage> parameter is NULL, the routine simply* counts the required length for the message. When that parameter provides* an actual value, the routine stores the appropriate information in* the supplied buffer. The RTAX_GATEWAY pointer for the resulting message* accesses a series of customized address structures which include the* protocol identifier and all additional metrics for each entry.** RETURNS: Length of message for all route entries** NOMANUAL*/LOCAL int routeGatewayFetch    (    struct rtentry * pRoute,     /* primary route for destination/netmask */    struct rt_msghdr * pMessage  /* list of routes for routing socket */    )    {    int length;    char * pBuffer;    struct sockaddr * pAddress = NULL;    struct sockaddr_gate * pGate;    int addrlen;    ROUTE_ENTRY * pGroup;    /* route entries for each protocol */    ROUTE_ENTRY * pMatch;    /* current route entry for message */    length = sizeof (struct rt_msghdr);    if (pMessage)        {        /* Fill in the initial message header. */        pMessage->rtm_version = RTM_VERSION;        pMessage->rtm_type = RTM_GETALL;        pMessage->rtm_flags = pRoute->rt_flags;        pMessage->rtm_addrs = RTA_DST | RTA_GATEWAY;        }    pAddress = rt_key (pRoute);    addrlen = ROUNDUP(pAddress->sa_len);    pBuffer = (char *)pMessage;    if (pBuffer)        {        /* Copy the destination address for the route entries. */        pBuffer += length;        bcopy ( (char *)pAddress, pBuffer, addrlen);        pBuffer += addrlen;        }    length += addrlen;    /*     * Find the length of all entries for the specified destination     * and netmask. Copy the relevant values if appropriate.     */    for (pGroup = (ROUTE_ENTRY *)pRoute; pGroup != NULL;                 pGroup = pGroup->diffNode.pFrwd)        {        for (pMatch = pGroup; pMatch != NULL; pMatch = pMatch->sameNode.pFrwd)            {            pAddress = ROUTE_ENTRY_GATEWAY (pMatch);            if (pAddress->sa_family == AF_LINK)                {                /*                 * The entry contains an ARP template. Use the                 * interface's IP address as the gateway value.                 */                pAddress = pMatch->rtEntry.rt_ifa->ifa_addr;                }            addrlen = ROUNDUP(sizeof (struct sockaddr_gate));            if (pBuffer)                {                /* Copy the gateway address for the route entry. */                pGate = (struct sockaddr_gate *)pBuffer;                pGate->gate_family = pAddress->sa_family;                pGate->gate_addr =                     ( (struct sockaddr_in *)pAddress)->sin_addr.s_addr;                /* Set length to reflect increased size for metrics. */                pGate->gate_len = sizeof (struct sockaddr_gate);                /* Copy additional information into gateway field. */                pGate->routeProto = RT_PROTO_GET (ROUTE_ENTRY_KEY (pMatch));                pGate->weight = pMatch->rtEntry.rt_rmx.weight;                pGate->value1 = pMatch->rtEntry.rt_rmx.value1;                pGate->value2 = pMatch->rtEntry.rt_rmx.value2;                pGate->value3 = pMatch->rtEntry.rt_rmx.value3;                pGate->value4 = pMatch->rtEntry.rt_rmx.value4;                pGate->value5 = pMatch->rtEntry.rt_rmx.value5;                pGate->routeTag = pMatch->rtEntry.rt_rmx.routeTag;                pBuffer += addrlen;                }            length += addrlen;            }        }    /* Copy any netmask information for the route. */    pAddress = rt_mask (pRoute);    if (pAddress)        {        addrlen = ROUNDUP(pAddress->sa_len);        if (pBuffer)            {            bcopy ( (char *)pAddress, pBuffer, addrlen);            pBuffer += addrlen;            /* Indicate that netmask information is present in the message. */            pMessage->rtm_addrs |= RTA_NETMASK;            }        length += addrlen;        }    if (pMessage)        {        /* Set the total message length. */        pMessage->rtm_msglen = length;        }    return (length);    }/********************************************************************************* routeMatch - find a unique entry within a set of duplicate routes** This routine searches the extended lists attached to the <pRoute>* primary route entry to find a matching route with the same next-hop* gateway as the <pGateway> argument and a creator which matches the* <protoId> value. That combination is unique for a particular destination* address and netmask. This routine allows routing sockets to retrieve* a duplicate route entry which is not visible to the IP forwarding process.** RETURNS: Pointer to existing route, or NULL if none.** NOMANUAL*/LOCAL ROUTE_ENTRY * routeMatch    (    struct rtentry * pRoute,    /* primary route for destination/netmask */    short protoId,              /* protocol identifer for matching route */    struct sockaddr * pGateway  /* next hop gateway for matching route */    )    {    ROUTE_ENTRY * pGroup;    /* route entries with matching protocol */    ROUTE_ENTRY * pMatch;    /* exact match for protocol and gateway */    if (protoId)        {        /* Find the list of entries for the specified protocol. */        for (pGroup = (ROUTE_ENTRY *)pRoute; pGroup != NULL;                 pGroup = pGroup->diffNode.pFrwd)            {            if (RT_PROTO_GET(ROUTE_ENTRY_KEY(pGroup)) == protoId)                break;            }        }    else        {        /* No protocol ID specified: use the initial group. */        pGroup = (ROUTE_ENTRY *)pRoute;        }    /* Find matching gateway if matching protocol found. */    for (pMatch = pGroup; pMatch != NULL; pMatch = pMatch->sameNode.pFrwd)        {        if (ROUTE_ENTRY_GATEWAY (pMatch)->sa_family == AF_LINK)            {            /*             * The gateway field contains an ARP template. The entry             * only matches for a search using the interface's IP address             * as the gateway.             */            if (SOCKADDR_IN (pMatch->rtEntry.rt_ifa->ifa_addr)                                    == SOCKADDR_IN (pGateway))                {                /* Matching route entry found - halt search. */                break;                }            }        else if (SOCKADDR_IN (ROUTE_ENTRY_GATEWAY (pMatch))                                    == SOCKADDR_IN (pGateway))            {            /* Matching route entry found - halt search. */            break;            }        }    return (pMatch);    }#endif /* ROUTER_STACK */

⌨️ 快捷键说明

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