X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..5353443c9cd32307ab4ce5d2e263522955d5d5dd:/bsd/net/rtsock.c diff --git a/bsd/net/rtsock.c b/bsd/net/rtsock.c index ae49c24c5..8a9742722 100644 --- a/bsd/net/rtsock.c +++ b/bsd/net/rtsock.c @@ -3,22 +3,19 @@ * * @APPLE_LICENSE_HEADER_START@ * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -149,11 +146,12 @@ rts_attach(struct socket *so, int proto, struct proc *p) */ s = splnet(); so->so_pcb = (caddr_t)rp; - error = raw_usrreqs.pru_attach(so, proto, p); + error = raw_attach(so, proto); /* don't use raw_usrreqs.pru_attach, it checks for SS_PRIV */ rp = sotorawcb(so); if (error) { splx(s); FREE(rp, M_PCB); + so->so_pcb = 0; return error; } switch(rp->rcb_proto.sp_protocol) { @@ -311,6 +309,7 @@ route_output(m, so) struct ifnet *ifp = 0; struct ifaddr *ifa = 0; struct proc *curproc = current_proc(); + int sendonlytoself = 0; #define senderr(e) { error = e; goto flush;} if (m == 0 || ((m->m_len < sizeof(long)) && @@ -334,6 +333,26 @@ route_output(m, so) dst = 0; senderr(EPROTONOSUPPORT); } + + /* + * Silent version of RTM_GET for Reachabiltiy APIs. We may change + * all RTM_GETs to be silent in the future, so this is private for now. + */ + if (rtm->rtm_type == RTM_GET_SILENT) { + if ((so->so_options & SO_USELOOPBACK) == 0) + senderr(EINVAL); + sendonlytoself = 1; + rtm->rtm_type = RTM_GET; + } + + /* + * Perform permission checking, only privileged sockets + * may perform operations other than RTM_GET + */ + if (rtm->rtm_type != RTM_GET && (so->so_state & SS_PRIV) == 0) { + dst = 0; + senderr(EPERM); + } rtm->rtm_pid = curproc->p_pid; info.rti_addrs = rtm->rtm_addrs; if (rt_xaddrs((caddr_t)(rtm + 1), len + (caddr_t)rtm, &info)) { @@ -566,15 +585,24 @@ flush: m_adj(m, rtm->rtm_msglen - m->m_pkthdr.len); Free(rtm); } - if (rp) - rp->rcb_proto.sp_family = 0; /* Avoid us */ - if (dst) - route_proto.sp_protocol = dst->sa_family; - if (m) - raw_input(m, &route_proto, &route_src, &route_dst); - if (rp) - rp->rcb_proto.sp_family = PF_ROUTE; - } + if (sendonlytoself && m) { + if (sbappendaddr(&so->so_rcv, &route_src, m, (struct mbuf*)0) == 0) { + m_freem(m); + error = ENOBUFS; + } else { + sorwakeup(so); + } + } else { + if (rp) + rp->rcb_proto.sp_family = 0; /* Avoid us */ + if (dst) + route_proto.sp_protocol = dst->sa_family; + if (m) + raw_input(m, &route_proto, &route_src, &route_dst); + if (rp) + rp->rcb_proto.sp_family = PF_ROUTE; + } + } return (error); }