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

📄 rtsock.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: rtsock.c,v 1.2 1996/01/16 14:22:01 chris Exp $ *//* * Copyright (c) 1988, 1991 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)rtsock.c	7.18 (Berkeley) 6/27/91 */#include "param.h"#include "mbuf.h"#include "proc.h"#include "socket.h"#include "socketvar.h"#include "domain.h"#include "protosw.h"#include "af.h"#include "if.h"#include "route.h"#include "raw_cb.h"#include "machine/mtpr.h"#ifdef NO_DATAstruct sockaddr route_dst;struct sockaddr route_src;struct sockproto route_proto;#elsestruct sockaddr route_dst = { 2, PF_ROUTE, };struct sockaddr route_src = { 2, PF_ROUTE, };struct sockproto route_proto = { PF_ROUTE, };#endifroute_init (){#ifdef NO_DATA    route_dst.sa_len = route_src.sa_len = 2;    route_dst.sa_family = route_src.sa_family = PF_ROUTE;    route_proto.sp_family = PF_ROUTE;#endif    raw_init ();}/*ARGSUSED*/route_usrreq(so, req, m, nam, control)	register struct socket *so;	int req;	struct mbuf *m, *nam, *control;{	register int error = 0;	register struct rawcb *rp = sotorawcb(so);	int s;	if (req == PRU_ATTACH) {		MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);		if (so->so_pcb = (caddr_t)rp)			bzero(so->so_pcb, sizeof(*rp));	}	if (req == PRU_DETACH && rp) {		int af = rp->rcb_proto.sp_protocol;		if (af == AF_INET)			route_cb.ip_count--;		else if (af == AF_NS)			route_cb.ns_count--;		else if (af == AF_ISO)			route_cb.iso_count--;		route_cb.any_count--;	}	s = splnet();	error = raw_usrreq(so, req, m, nam, control);	rp = sotorawcb(so);	if (req == PRU_ATTACH && rp) {		int af = rp->rcb_proto.sp_protocol;		if (error) {			free((caddr_t)rp, M_PCB);			splx(s);			return (error);		}		if (af == AF_INET)			route_cb.ip_count++;		else if (af == AF_NS)			route_cb.ns_count++;		else if (af == AF_ISO)			route_cb.iso_count++;		rp->rcb_faddr = &route_src;		route_cb.any_count++;		soisconnected(so);		so->so_options |= SO_USELOOPBACK;	}	splx(s);	return (error);}#define ROUNDUP(a) \	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))/*ARGSUSED*/route_output(m, so)	register struct mbuf *m;	struct socket *so;{	register struct rt_msghdr *rtm = 0;	register struct rtentry *rt = 0;	struct rtentry *saved_nrt = 0;	struct sockaddr *dst = 0, *gate = 0, *netmask = 0, *genmask = 0;	struct sockaddr *ifpaddr = 0, *ifaaddr = 0;	caddr_t cp, lim;	int len, error = 0;	struct ifnet *ifp = 0;	struct ifaddr *ifa = 0;	struct ifaddr *ifaof_ifpforaddr(), *ifa_ifwithroute();#define senderr(e) { error = e; goto flush;}	if (m == 0 || m->m_len < sizeof(long))		return (ENOBUFS);	if ((m = m_pullup(m, sizeof(long))) == 0)		return (ENOBUFS);	if ((m->m_flags & M_PKTHDR) == 0)		panic("route_output");	len = m->m_pkthdr.len;	if (len < sizeof(*rtm) ||	    len != mtod(m, struct rt_msghdr *)->rtm_msglen)		senderr(EINVAL);	R_Malloc(rtm, struct rt_msghdr *, len);	if (rtm == 0)		senderr(ENOBUFS);	m_copydata(m, 0, len, (caddr_t)rtm);	if (rtm->rtm_version != RTM_VERSION)		senderr(EPROTONOSUPPORT);	rtm->rtm_pid = curproc->p_pid;	lim = len + (caddr_t) rtm;	cp = (caddr_t) (rtm + 1);	if (rtm->rtm_addrs & RTA_DST) {		dst = (struct sockaddr *)cp;		ADVANCE(cp, dst);	} else		senderr(EINVAL);	if ((rtm->rtm_addrs & RTA_GATEWAY) && cp < lim)  {		gate = (struct sockaddr *)cp;		ADVANCE(cp, gate);	}	if ((rtm->rtm_addrs & RTA_NETMASK) && cp < lim)  {		netmask = (struct sockaddr *)cp;		ADVANCE(cp, netmask);	}	if ((rtm->rtm_addrs & RTA_GENMASK) && cp < lim)  {		struct radix_node *t, *rn_addmask();		genmask = (struct sockaddr *)cp;		ADVANCE(cp, genmask);		t = rn_addmask(genmask, 1, 2);		if (t && Bcmp(genmask, t->rn_key, *(u_char *)genmask) == 0)			genmask = (struct sockaddr *)(t->rn_key);		else			senderr(ENOBUFS);	}	if ((rtm->rtm_addrs & RTA_IFP) && cp < lim)  {		ifpaddr = (struct sockaddr *)cp;		ADVANCE(cp, ifpaddr);	}	if ((rtm->rtm_addrs & RTA_IFA) && cp < lim)  {		ifaaddr = (struct sockaddr *)cp;	}	switch (rtm->rtm_type) {	case RTM_ADD:		if (gate == 0)			senderr(EINVAL);		error = rtrequest(RTM_ADD, dst, gate, netmask,					rtm->rtm_flags, &saved_nrt);		if (error == 0 && saved_nrt) {			rt_setmetrics(rtm->rtm_inits,				&rtm->rtm_rmx, &saved_nrt->rt_rmx);			saved_nrt->rt_refcnt--;			saved_nrt->rt_genmask = genmask;		}		break;	case RTM_DELETE:		error = rtrequest(RTM_DELETE, dst, gate, netmask,				rtm->rtm_flags, (struct rtentry **)0);		break;	case RTM_GET:	case RTM_CHANGE:	case RTM_LOCK:		rt = rtalloc1(dst, 0);		if (rt == 0)			senderr(ESRCH);		if (rtm->rtm_type != RTM_GET) {			if (Bcmp(dst, rt_key(rt), dst->sa_len) != 0)				senderr(ESRCH);			if (rt->rt_nodes->rn_dupedkey &&			    (netmask == 0 ||			     Bcmp(netmask, rt_mask(rt), netmask->sa_len)))				senderr(ETOOMANYREFS);		}		switch(rtm->rtm_type) {		case RTM_GET:			dst = rt_key(rt); len = sizeof(*rtm);			ADVANCE(len, dst);			rtm->rtm_addrs |= RTA_DST;			if (gate = rt->rt_gateway) {				ADVANCE(len, gate);				rtm->rtm_addrs |= RTA_GATEWAY;			} else				rtm->rtm_addrs &= ~RTA_GATEWAY;			if (netmask = rt_mask(rt)) {				ADVANCE(len, netmask);				rtm->rtm_addrs |= RTA_NETMASK;			} else				rtm->rtm_addrs &= ~RTA_NETMASK;			if (genmask = rt->rt_genmask) {				ADVANCE(len, genmask);				rtm->rtm_addrs |= RTA_GENMASK;			} else				rtm->rtm_addrs &= ~RTA_GENMASK;			if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {				if (rt->rt_ifp == 0)					goto badif;				for (ifa = rt->rt_ifp->if_addrlist;				    ifa && ifa->ifa_addr->sa_family != AF_LINK;				     ifa = ifa->ifa_next){}				if (ifa && rt->rt_ifa) {					ifpaddr = ifa->ifa_addr;					ADVANCE(len, ifpaddr);					ifaaddr = rt->rt_ifa->ifa_addr;					ADVANCE(len, ifaaddr);					rtm->rtm_addrs |= RTA_IFP | RTA_IFA;				} else {				badif:	ifpaddr = 0;					rtm->rtm_addrs &= ~(RTA_IFP | RTA_IFA);				}			}			if (len > rtm->rtm_msglen) {				struct rt_msghdr *new_rtm;				R_Malloc(new_rtm, struct rt_msghdr *, len);				if (new_rtm == 0)					senderr(ENOBUFS);				Bcopy(rtm, new_rtm, rtm->rtm_msglen);				Free(rtm); rtm = new_rtm;			}			rtm->rtm_msglen = len;			rtm->rtm_flags = rt->rt_flags;			rtm->rtm_rmx = rt->rt_rmx;			cp = (caddr_t) (1 + rtm);			len = ROUNDUP(dst->sa_len); 			Bcopy(dst, cp, len); cp += len;			if (gate) {			    len = ROUNDUP(gate->sa_len);			    Bcopy(gate, cp, len); cp += len;			}			if (netmask) {			    len = ROUNDUP(netmask->sa_len);			    Bcopy(netmask, cp, len); cp += len;			}			if (genmask) {			    len = ROUNDUP(genmask->sa_len);			    Bcopy(genmask, cp, len); cp += len;			}			if (ifpaddr) {			    len = ROUNDUP(ifpaddr->sa_len);			    Bcopy(ifpaddr, cp, len); cp += len;			    len = ROUNDUP(ifaaddr->sa_len);			    Bcopy(ifaaddr, cp, len); cp += len;			}			break;		case RTM_CHANGE:			if (gate &&			    (gate->sa_len > (len = rt->rt_gateway->sa_len)))				senderr(EDQUOT);			/* new gateway could require new ifaddr, ifp;			   flags may also be different; ifp may be specified			   by ll sockaddr when protocol address is ambiguous */			if (ifpaddr && (ifa = ifa_ifwithnet(ifpaddr)) &&			    (ifp = ifa->ifa_ifp))				ifa = ifaof_ifpforaddr(ifaaddr ? ifaaddr : gate,							ifp);			else if ((ifaaddr && (ifa = ifa_ifwithaddr(ifaaddr))) ||				 (ifa = ifa_ifwithroute(rt->rt_flags,							rt_key(rt), gate)))				ifp = ifa->ifa_ifp;			if (ifa) {				register struct ifaddr *oifa = rt->rt_ifa;				if (oifa != ifa) {				    if (oifa && oifa->ifa_rtrequest)					oifa->ifa_rtrequest(RTM_DELETE,								rt, gate);				    rt->rt_ifa = ifa;				    rt->rt_ifp = ifp;				}			}			if (gate)				Bcopy(gate, rt->rt_gateway, len);			rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,					&rt->rt_rmx);			if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest)			       rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, gate);			if (genmask)				rt->rt_genmask = genmask;			/*			 * Fall into			 */		case RTM_LOCK:			rt->rt_rmx.rmx_locks |=				(rtm->rtm_inits & rtm->rtm_rmx.rmx_locks);			rt->rt_rmx.rmx_locks &= ~(rtm->rtm_inits);			break;		}		goto cleanup;	default:		senderr(EOPNOTSUPP);	}

⌨️ 快捷键说明

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