Module Name:    src
Committed By:   christos
Date:           Thu Nov 29 02:06:18 UTC 2012

Modified Files:
        src/sbin/sysctl: sysctl.c

Log Message:
add a handler for the reserved port sysctl variable.


To generate a diff of this commit:
cvs rdiff -u -r1.143 -r1.144 src/sbin/sysctl/sysctl.c

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

Modified files:

Index: src/sbin/sysctl/sysctl.c
diff -u src/sbin/sysctl/sysctl.c:1.143 src/sbin/sysctl/sysctl.c:1.144
--- src/sbin/sysctl/sysctl.c:1.143	Sat Jun  2 17:38:09 2012
+++ src/sbin/sysctl/sysctl.c	Wed Nov 28 21:06:17 2012
@@ -1,4 +1,4 @@
-/*	$NetBSD: sysctl.c,v 1.143 2012/06/02 21:38:09 dsl Exp $ */
+/*	$NetBSD: sysctl.c,v 1.144 2012/11/29 02:06:17 christos Exp $ */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -68,10 +68,12 @@ __COPYRIGHT("@(#) Copyright (c) 1993\
 #if 0
 static char sccsid[] = "@(#)sysctl.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: sysctl.c,v 1.143 2012/06/02 21:38:09 dsl Exp $");
+__RCSID("$NetBSD: sysctl.c,v 1.144 2012/11/29 02:06:17 christos Exp $");
 #endif
 #endif /* not lint */
 
+#define FD_SETSIZE 0x10000
+#include <sys/fd_set.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
@@ -171,6 +173,7 @@ static void proc_limit(HANDLER_PROTO);
 static void machdep_diskinfo(HANDLER_PROTO);
 #endif /* CPU_DISKINFO */
 static void mode_bits(HANDLER_PROTO);
+static void reserve(HANDLER_PROTO);
 
 static const struct handlespec {
 	const char *ps_re;
@@ -210,7 +213,7 @@ static const struct handlespec {
 	{ "/net/(inet|inet6)/[^/]+/stats",	printother, NULL, "netstat"},
 	{ "/net/bpf/(stats|peers)",		printother, NULL, "netstat"},
 
-	{ "/net/inet.*/tcp.*/deb.*",		printother, NULL, "trpt" },
+	{ "/net/inet.*/ip.*/anonportalgo/reserve", reserve, reserve, NULL },
 
 	{ "/net/ns/spp/deb.*",			printother, NULL, "trsp" },
 
@@ -2685,3 +2688,96 @@ mode_bits(HANDLER_ARGS)
 		}
 	}
 }
+
+static char *
+bitmask_print(const fd_set *o)
+{
+	char *s, *os;
+
+	s = os = NULL;
+	for (size_t i = 0; i < FD_SETSIZE; i++)
+		if (FD_ISSET(i, o)) {
+			int rv;
+
+			if (os)
+			    	rv = asprintf(&s, "%s,%zu", os, i);
+			else
+			    	rv = asprintf(&s, "%zu", i);
+			if (rv == -1)
+				err(1, "");
+			free(os);
+			os = s;
+		}
+	if (s == NULL && (s = strdup("")) == NULL)
+		err(1, "");
+	return s;
+}
+
+static void
+bitmask_scan(const void *v, fd_set *o)
+{
+	char *s = strdup(v);
+	if (s == NULL)
+		err(1, "");
+	FD_ZERO(o);
+	for (s = strtok(s, ","); s; s = strtok(NULL, ",")) {
+		char *e;
+		errno = 0;
+		unsigned long l = strtoul(s, &e, 0);
+		if ((l == ULONG_MAX && errno == ERANGE) || s == e || *e)
+			errx(1, "Invalid port: %s", s);
+		if (l >= FD_SETSIZE)
+			errx(1, "Port out of range: %s", s);
+		FD_SET(l, o);
+	}
+}
+
+
+static void
+reserve(HANDLER_ARGS)
+{
+	int rc;
+	size_t osz, nsz;
+	fd_set o, n;
+
+	if (fn)
+		trim_whitespace(value, 3);
+
+	osz = sizeof(o);
+	if (value) {
+		bitmask_scan(value, &n);
+		value = (char *)&n;
+		nsz = sizeof(n);
+	} else
+		nsz = 0;
+
+	rc = prog_sysctl(name, namelen, &o, &osz, value, nsz);
+	if (rc == -1) {
+		sysctlerror(value == NULL);
+		return;
+	}
+
+	if (value && qflag)
+		return;
+
+	if (rflag || xflag)
+		display_struct(pnode, sname, &o, sizeof(o),
+		    value ? DISPLAY_OLD : DISPLAY_VALUE);
+	else {
+		char *s = bitmask_print(&o);
+		display_string(pnode, sname, s, strlen(s),
+		    value ? DISPLAY_OLD : DISPLAY_VALUE);
+		free(s);
+	}
+
+	if (value) {
+		if (rflag || xflag)
+			display_struct(pnode, sname, &n, sizeof(n),
+			    DISPLAY_NEW);
+		else {
+			char *s = bitmask_print(&n);
+			display_string(pnode, sname, s, strlen(s), DISPLAY_NEW);
+			free(s);
+		}
+	}
+}

Reply via email to