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

📄 rtsock.c

📁 vxworks下的实现网络TCPIP协议的原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		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. */static 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. */static 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. */static 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;	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;			int 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;			netmask = rt_mask(rt);			dst = sa = rt_key(rt);			gate = rt->rt_gateway;			if ((m = rt_msg1(cmd, &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);	}}/* * 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));	for (ifp = ifnet; ifp; ifp = ifp->if_next) {		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;	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)	    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;	}    }

⌨️ 快捷键说明

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