X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/d7e50217d7adf6e52786a38bcaa4cd698cb9a79e..5353443c9cd32307ab4ce5d2e263522955d5d5dd:/bsd/net/rtsock.c?ds=inline

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);
 }