Module Name:    src
Committed By:   christos
Date:           Thu Nov 29 02:07:21 UTC 2012

Modified Files:
        src/sys/netinet: ip_input.c portalgo.c portalgo.h
        src/sys/netinet6: ip6_input.c

Log Message:
Add a new sysctl to mark ports as reserved, so that they are not used in
the anonymous or reserved port allocation.


To generate a diff of this commit:
cvs rdiff -u -r1.302 -r1.303 src/sys/netinet/ip_input.c
cvs rdiff -u -r1.1 -r1.2 src/sys/netinet/portalgo.c \
    src/sys/netinet/portalgo.h
cvs rdiff -u -r1.140 -r1.141 src/sys/netinet6/ip6_input.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet/ip_input.c
diff -u src/sys/netinet/ip_input.c:1.302 src/sys/netinet/ip_input.c:1.303
--- src/sys/netinet/ip_input.c:1.302	Mon Jun 25 11:28:39 2012
+++ src/sys/netinet/ip_input.c	Wed Nov 28 21:07:20 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip_input.c,v 1.302 2012/06/25 15:28:39 christos Exp $	*/
+/*	$NetBSD: ip_input.c,v 1.303 2012/11/29 02:07:20 christos Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -91,7 +91,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.302 2012/06/25 15:28:39 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.303 2012/11/29 02:07:20 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -1906,7 +1906,13 @@ sysctl_net_inet_ip_setup(struct sysctllo
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_STRING, "selected",
 		       SYSCTL_DESCR("selected algorithm"),
-		       sysctl_portalgo_selected, 0, NULL, PORTALGO_MAXLEN,
+		       sysctl_portalgo_selected4, 0, NULL, PORTALGO_MAXLEN,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, &portalgo_node, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_STRUCT, "reserve",
+		       SYSCTL_DESCR("bitmap of reserved ports"),
+		       sysctl_portalgo_reserve4, 0, NULL, 0,
 		       CTL_CREATE, CTL_EOL);
 }
 

Index: src/sys/netinet/portalgo.c
diff -u src/sys/netinet/portalgo.c:1.1 src/sys/netinet/portalgo.c:1.2
--- src/sys/netinet/portalgo.c:1.1	Mon Jun 25 11:28:39 2012
+++ src/sys/netinet/portalgo.c	Wed Nov 28 21:07:20 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: portalgo.c,v 1.1 2012/06/25 15:28:39 christos Exp $	*/
+/*	$NetBSD: portalgo.c,v 1.2 2012/11/29 02:07:20 christos Exp $	*/
 
 /*
  * Copyright 2011 Vlad Balan
@@ -34,10 +34,12 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: portalgo.c,v 1.1 2012/06/25 15:28:39 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: portalgo.c,v 1.2 2012/11/29 02:07:20 christos Exp $");
 
 #include "opt_inet.h"
 
+#define FD_SETSIZE 0x10000
+#include <sys/fd_set.h>
 #include <sys/param.h>
 #include <sys/errno.h>
 #include <sys/kauth.h>
@@ -87,9 +89,11 @@ static bool portalgo_debug = true;
 
 #ifdef INET
 static int inet4_portalgo = PORTALGO_BSD;
+static fd_set inet4_reserve;
 #endif
 #ifdef INET6
 static int inet6_portalgo = PORTALGO_BSD;
+static fd_set inet6_reserve;
 #endif
 
 typedef struct {
@@ -250,6 +254,9 @@ check_suitable_port(uint16_t port, struc
 		struct inpcb *pcb;
 		struct sockaddr_in sin;
 
+		if (FD_ISSET(port, &inet4_reserve))
+			return false;
+
 		sin.sin_addr = inp->inp_laddr;
 		pcb = in_pcblookup_port(table, sin.sin_addr, htons(port), 1,
 		    &vestigial);
@@ -292,6 +299,9 @@ check_suitable_port(uint16_t port, struc
 		struct sockaddr_in6 sin6;
 		void *t;
 
+		if (FD_ISSET(port, &inet6_reserve))
+			return false;
+
 		sin6.sin6_addr = in6p->in6p_laddr;
 		so = in6p->in6p_socket;
 
@@ -853,10 +863,10 @@ portalgo_algo_index_select(struct inpcb_
 
 /*
  * The sysctl hook that is supposed to check that we are picking one
- * of the valid algorithms. IPv4.
+ * of the valid algorithms.
  */
 static int
-sysctl_portalgo_helper(SYSCTLFN_ARGS, int *algo)
+sysctl_portalgo_selected(SYSCTLFN_ARGS, int *algo)
 {
 	struct sysctlnode node;
 	int error;
@@ -891,23 +901,64 @@ sysctl_portalgo_helper(SYSCTLFN_ARGS, in
 	return error;
 }
 
+static int
+sysctl_portalgo_reserve(SYSCTLFN_ARGS, fd_set *bt)
+{
+	struct sysctlnode node;
+	int error;
+
+	DPRINTF("%s called\n", __func__);
+
+	node = *rnode;
+	node.sysctl_data = bt;
+	node.sysctl_size = sizeof(*bt);
+
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+
+	if (error || newp == NULL)
+		return error;
+
+#ifdef KAUTH_NETWORK_SOCKET_PORT_RESERVE
+	if (l != NULL && (error = kauth_authorize_system(l->l_cred,
+	    KAUTH_NETWORK_SOCKET, KAUTH_NETWORK_SOCKET_PORT_RESERVE, bt,
+	    NULL, NULL)) != 0)
+		return error;
+#endif
+	return error;
+}
+
+#ifdef INET
 /*
  * The sysctl hook that is supposed to check that we are picking one
  * of the valid algorithms.
  */
 int
-sysctl_portalgo_selected(SYSCTLFN_ARGS)
+sysctl_portalgo_selected4(SYSCTLFN_ARGS)
+{
+
+	return sysctl_portalgo_selected(SYSCTLFN_CALL(rnode), &inet4_portalgo);
+}
+
+int
+sysctl_portalgo_reserve4(SYSCTLFN_ARGS)
 {
 
-	return sysctl_portalgo_helper(SYSCTLFN_CALL(rnode), &inet4_portalgo);
+	return sysctl_portalgo_reserve(SYSCTLFN_CALL(rnode), &inet4_reserve);
 }
+#endif
 
 #ifdef INET6
 int
 sysctl_portalgo_selected6(SYSCTLFN_ARGS)
 {
 
-	return sysctl_portalgo_helper(SYSCTLFN_CALL(rnode), &inet6_portalgo);
+	return sysctl_portalgo_selected(SYSCTLFN_CALL(rnode), &inet6_portalgo);
+}
+
+int
+sysctl_portalgo_reserve6(SYSCTLFN_ARGS)
+{
+	return sysctl_portalgo_reserve(SYSCTLFN_CALL(rnode), &inet6_reserve);
 }
 #endif
 
Index: src/sys/netinet/portalgo.h
diff -u src/sys/netinet/portalgo.h:1.1 src/sys/netinet/portalgo.h:1.2
--- src/sys/netinet/portalgo.h:1.1	Mon Jun 25 11:28:39 2012
+++ src/sys/netinet/portalgo.h	Wed Nov 28 21:07:20 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: portalgo.h,v 1.1 2012/06/25 15:28:39 christos Exp $	*/
+/*	$NetBSD: portalgo.h,v 1.2 2012/11/29 02:07:20 christos Exp $	*/
 
 /*
  * Copyright 2011 Vlad Balan
@@ -35,8 +35,10 @@
 
 struct inpcb_hdr;
 int portalgo_randport(uint16_t *, struct inpcb_hdr *, kauth_cred_t);
-int sysctl_portalgo_selected(SYSCTLFN_ARGS);
+int sysctl_portalgo_selected4(SYSCTLFN_ARGS);
 int sysctl_portalgo_selected6(SYSCTLFN_ARGS);
+int sysctl_portalgo_reserve4(SYSCTLFN_ARGS);
+int sysctl_portalgo_reserve6(SYSCTLFN_ARGS);
 int sysctl_portalgo_available(SYSCTLFN_ARGS);
 int portalgo_algo_index_select(struct inpcb_hdr *, int);
 

Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.140 src/sys/netinet6/ip6_input.c:1.141
--- src/sys/netinet6/ip6_input.c:1.140	Mon Jun 25 11:28:40 2012
+++ src/sys/netinet6/ip6_input.c	Wed Nov 28 21:07:20 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.140 2012/06/25 15:28:40 christos Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.141 2012/11/29 02:07:20 christos Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.140 2012/06/25 15:28:40 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.141 2012/11/29 02:07:20 christos Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -1977,6 +1977,12 @@ sysctl_net_inet6_ip6_setup(struct sysctl
 		       SYSCTL_DESCR("selected algorithm"),
 	               sysctl_portalgo_selected6, 0, NULL, PORTALGO_MAXLEN,
 		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(clog, 0, &portalgo_node, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_STRUCT, "reserve",
+		       SYSCTL_DESCR("bitmap of reserved ports"),
+		       sysctl_portalgo_reserve6, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_INT, "neighborgcthresh",

Reply via email to