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

📄 rtsock.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
		 * I've seen this. route(1) can evidently generate these. 		 * This causes kernel to core dump.		 * for compatibility, If we see this, point to a safe address.		 */		if (sa->sa_len == 0) {			rtinfo->rti_info[i] = &sa_zero;			return (0); /* should be EINVAL but for compat */		}		/* accept it */		rtinfo->rti_info[i] = sa;		ADVANCE(cp, sa);	}	return (0);}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);	}	cp0 = cp;	if (cp0)		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;		if (rw->w_req) {			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;			}		}	}	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 = (u_short)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 = 0;	int pass;	struct mbuf *m = 0;	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, vw)	struct radix_node *rn;	void *vw;{	register struct walkarg *w = vw;	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;	size = rt_msg2(RTM_GET, &info, 0, w);	if (w->w_req && 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;		error = 0;		return (error);	}	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_req && w->w_tmem) {			register struct if_msghdr *ifm;			ifm = (struct if_msghdr *)w->w_tmem;			ifm->ifm_index = ifp->if_index;			ifm->ifm_flags = (u_short)ifp->if_flags;			ifm->ifm_data = ifp->if_data;			ifm->ifm_addrs = info.rti_addrs;			error = SYSCTL_OUT(w->w_req,(caddr_t)ifm, len);			if (error)				return (error);		}		while ((ifa = ifa->ifa_next) != 0) {			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_req && 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 = SYSCTL_OUT(w->w_req, w->w_tmem, len);				if (error)					return (error);			}		}		ifaaddr = netmask = brdaddr = 0;	}	return (0);}static intsysctl_rtsock(SYSCTL_HANDLER_ARGS){	int	*name = (int *)arg1;	u_int	namelen = arg2;	register struct radix_node_head *rnh;	int	i, s, error = EINVAL;	u_char  af;	struct	walkarg w;	name ++;	namelen--;	if (req->newptr)		return (EPERM);	if (namelen != 3)		return (EINVAL);	af = name[0];	Bzero(&w, sizeof(w));	w.w_op = name[1];	w.w_arg = name[2];	w.w_req = req;	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, M_RTABLE);	return (error);}SYSCTL_NODE(_net, PF_ROUTE, routetable, CTLFLAG_RD, sysctl_rtsock,"");/* * Definitions of protocols supported in the ROUTE domain. */extern struct domain routedomain;		/* or at least forward */static struct protosw routesw[] = {{ SOCK_RAW,	&routedomain,	0,		PR_ATOMIC|PR_ADDR,  0,		route_output,	raw_ctlinput,	0,  route_usrreq,  raw_init}};struct domain routedomain =    { PF_ROUTE, "route", route_init, 0, 0,      routesw, &routesw[sizeof(routesw)/sizeof(routesw[0])] };DOMAIN_SET(route);

⌨️ 快捷键说明

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