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

📄 rtsock.c

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 C
📖 第 1 页 / 共 2 页
字号:
		len -= mlen;		mlen += off;		off = 0;		totlen += mlen;		if (len == 0)			break;		if (m->m_next == 0) {			n = m_get(M_DONTWAIT, m->m_type);			if (n == 0)				break;			n->m_len = min(MLEN, 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;}static struct mbuf *rt_msg1(type, rtinfo)	int type;	register struct rt_addrinfo *rtinfo;{	register struct rt_msghdr *rtm;	register struct mbuf *m;	register int i;	register struct sockaddr *sa;	int len, dlen;	m = m_gethdr(M_DONTWAIT, MT_DATA);	if (m == 0)		return (m);	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 (len > MHLEN)		panic("rt_msg1");	m->m_pkthdr.len = m->m_len = len;	m->m_pkthdr.rcvif = 0;	rtm = mtod(m, struct rt_msghdr *);	bzero((caddr_t)rtm, len);	for (i = 0; i < RTAX_MAX; i++) {		if ((sa = rtinfo->rti_info[i]) == NULL)			continue;		rtinfo->rti_addrs |= (1 << i);		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) != NULL)		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, M_RTABLE);				rw->w_tmem = (caddr_t) malloc(len, M_RTABLE,							      M_NOWAIT);				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. */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. */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. */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.tqh_first->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);	}}#ifndef PMON/* * This is used in dumping the kernel table via sysctl(). */intsysctl_dumpentry(rn, v)	struct radix_node *rn;	register void *v;{	register struct walkarg *w = v;	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.tqh_first->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)) != 0)			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.tqh_first; ifp != 0; ifp = ifp->if_list.tqe_next) {		if (w->w_arg && w->w_arg != ifp->if_index)			continue;		ifa = ifp->if_addrlist.tqh_first;		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;			error = copyout((caddr_t)ifm, w->w_where, len);			if (error)				return (error);			w->w_where += len;		}		while ((ifa = ifa->ifa_list.tqe_next) != NULL) {			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;				error = copyout(w->w_tmem, w->w_where, len);				if (error)					return (error);				w->w_where += len;			}		}		ifaaddr = netmask = brdaddr = 0;	}	return (0);}#endifintsysctl_rtable(name, namelen, where, given, new, newlen)	int	*name;	u_int	namelen;	void 	*where;	size_t	*given;	void	*new;	size_t	newlen;{#ifdef PMON	int	error = EINVAL;#else	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 = splsoftnet();	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, M_RTABLE);	w.w_needed += w.w_given;	if (where) {		*given = w.w_where - (caddr_t) where;		if (*given < w.w_needed)			return (ENOMEM);	} else {		*given = (11 * w.w_needed) / 10;	}#endif	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,  raw_init,	0,		0,		0,  sysctl_rtable,}};struct domain routedomain =    { PF_ROUTE, "route", route_init, 0, 0,      routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] };

⌨️ 快捷键说明

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