aboutsummaryrefslogtreecommitdiff
path: root/sbin/ip6fw/ip6fw.c
diff options
context:
space:
mode:
authorHajimu UMEMOTO <ume@FreeBSD.org>2001-01-20 22:40:39 +0000
committerHajimu UMEMOTO <ume@FreeBSD.org>2001-01-20 22:40:39 +0000
commitdd9d139453b0bbb5ba173e52dc7f72e6720ed510 (patch)
treee60b52975b668ad478193b2cad42f47274287f39 /sbin/ip6fw/ip6fw.c
parent6c0bea350e27e00fbbe177be6de0c26cc59ecbd1 (diff)
Notes
Diffstat (limited to 'sbin/ip6fw/ip6fw.c')
-rw-r--r--sbin/ip6fw/ip6fw.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/sbin/ip6fw/ip6fw.c b/sbin/ip6fw/ip6fw.c
index 9c3a7e5aa096..c6307344f336 100644
--- a/sbin/ip6fw/ip6fw.c
+++ b/sbin/ip6fw/ip6fw.c
@@ -37,6 +37,7 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
+#include <errno.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -410,18 +411,25 @@ list(ac, av)
int ac;
char **av;
{
- struct ip6_fw *r;
- struct ip6_fw rules[1024];
+ struct ip6_fw *r, *rules;
int l,i;
unsigned long rulenum;
- int bytes;
+ int nalloc, bytes, maxbytes;
- /* extract rules from kernel */
- memset(rules,0,sizeof rules);
- bytes = sizeof rules;
- i = getsockopt(s, IPPROTO_IPV6, IPV6_FW_GET, rules, &bytes);
- if (i < 0)
- err(2,"getsockopt(IPV6_FW_GET)");
+ /* extract rules from kernel, resizing array as necessary */
+ rules = NULL;
+ nalloc = sizeof *rules;
+ bytes = nalloc;
+ maxbytes = 65536 * sizeof *rules;
+ while (bytes >= nalloc) {
+ nalloc = nalloc * 2 + 200;
+ bytes = nalloc;
+ if ((rules = realloc(rules, bytes)) == NULL)
+ err(2, "realloc");
+ i = getsockopt(s, IPPROTO_IPV6, IPV6_FW_GET, rules, &bytes);
+ if ((i < 0 && errno != EINVAL) || nalloc > maxbytes)
+ err(2, "getsockopt(IPV6_FW_GET)");
+ }
if (!ac) {
/* display all rules */
for (r = rules, l = bytes; l >= sizeof rules[0];