summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2001-06-25 10:14:08 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2001-06-25 10:14:08 +0000
commit24bc6fabf20d8b9e03f638db44cfc5ddd78be20c (patch)
tree96c049c3fd5a687e03d169c51c6cf53dcc40d89f /sbin
parent5fe78cac127e8b90faf921100c0a53547f135f56 (diff)
catch up, might have introduced bugs, but there is a next pass...
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/pfctl.c4
-rw-r--r--sbin/pfctl/pfctl_parser.c151
2 files changed, 94 insertions, 61 deletions
diff --git a/sbin/pfctl/pfctl.c b/sbin/pfctl/pfctl.c
index 35864f46493..9586094faf0 100644
--- a/sbin/pfctl/pfctl.c
+++ b/sbin/pfctl/pfctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl.c,v 1.7 2001/06/25 09:44:32 deraadt Exp $ */
+/* $OpenBSD: pfctl.c,v 1.8 2001/06/25 10:14:07 deraadt Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -49,7 +49,7 @@
void printerror(char *);
void usage(char *);
char *load_file(char *, size_t *);
-int main(int, char *[]);
+int main(int, char *[]);
void
printerror(char *s)
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 122a24dd530..dcb12ca6ed2 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.6 2001/06/25 09:44:32 deraadt Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.7 2001/06/25 10:14:07 deraadt Exp $ */
/*
* Copyright (c) 2001, Daniel Hartmeier
@@ -34,6 +34,9 @@
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
#include <net/pfvar.h>
#include <stdio.h>
@@ -41,6 +44,8 @@
#include <string.h>
#include <ctype.h>
#include <netdb.h>
+#include <stdarg.h>
+#include <errno.h>
#include "pfctl_parser.h"
@@ -58,6 +63,19 @@ u_int32_t rule_mask (u_int8_t);
char *tcpflags = "FSRPAU";
+int
+error(int n, char *fmt, ...)
+{
+ extern char *__progname;
+ va_list ap;
+
+ va_start(ap, fmt);
+ fprintf(stderr, "%s: line %d", __progname, n);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ return (0);
+}
+
void
print_addr(u_int32_t a)
{
@@ -411,13 +429,24 @@ u_int16_t
rule_port(char *w, u_int8_t p)
{
struct servent *s;
-
- if (isdigit(*w))
- return (htons(atoi(w)));
- s = getservbyname(w, p == IPPROTO_TCP ? "tcp" : "udp");
- if (s == NULL)
+ u_long ul;
+ char *ep;
+
+ errno = 0;
+ ul = strtoul(w, &ep, 10);
+ if (*w == '\0' || *ep != '\0') {
+ s = getservbyname(w, p == IPPROTO_TCP ? "tcp" : "udp");
+ if (s == NULL)
+ return (0);
+ return (s->s_port);
+ }
+ if (errno == ERANGE && ul == ULONG_MAX)
return (0);
- return (s->s_port);
+ if (ul > USHRT_MAX) {
+ errno = ERANGE;
+ return (0);
+ }
+ return (htons(ul));
}
u_int32_t
@@ -444,8 +473,7 @@ parse_rule(int n, char *l, struct pf_rule *r)
else if (!strcmp(w, "block"))
r->action = 1;
else {
- fprintf(stderr, "error on line %d: expected pass/block, got %s\n",
- n, w);
+ error(n, "expected pass/block, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -462,8 +490,7 @@ parse_rule(int n, char *l, struct pf_rule *r)
else if (!strcmp(w, "out"))
r->direction = 1;
else {
- fprintf(stderr, "error on line %d: expected in/out, got %s\n",
- n, w);
+ error(n, "expected in/out, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -493,8 +520,7 @@ parse_rule(int n, char *l, struct pf_rule *r)
w = next_word(&l);
p = getprotobyname(w);
if (p == NULL) {
- fprintf(stderr, "error on line %d: unknown protocol %s\n",
- n, w);
+ error(n, "unknown protocol %s\n", w);
return (0);
}
r->proto = p->p_proto;
@@ -521,7 +547,7 @@ parse_rule(int n, char *l, struct pf_rule *r)
else if (*w == '/')
r->src.mask = rule_mask(next_number(&w));
else {
- fprintf(stderr, "error on line %d: expected /, got '%c'\n", n, *w);
+ error(n, "expected /, got '%c'\n", *w);
return (0);
}
w = next_word(&l);
@@ -551,7 +577,8 @@ parse_rule(int n, char *l, struct pf_rule *r)
w = next_word(&l);
if (r->src.port_op == 1) {
if (strcmp(w, "<>") && strcmp(w, "><")) {
- fprintf(stderr, "error on line %d: expected <>/><, got %s\n", n, w);
+ error(n, "expected <>/><, got %s\n",
+ w);
return (0);
}
w = next_word(&l);
@@ -562,8 +589,7 @@ parse_rule(int n, char *l, struct pf_rule *r)
/* destination address */
if (strcmp(w, "to")) {
- fprintf(stderr, "error on line %d: expected to, got %s\n",
- n, w);
+ error(n, "expected to, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -580,7 +606,7 @@ parse_rule(int n, char *l, struct pf_rule *r)
else if (*w == '/')
r->dst.mask = rule_mask(next_number(&w));
else {
- fprintf(stderr, "error on line %d: expected /, got '%c'\n", n, *w);
+ error(n, "expected /, got '%c'\n", *w);
return (0);
}
w = next_word(&l);
@@ -610,7 +636,8 @@ parse_rule(int n, char *l, struct pf_rule *r)
w = next_word(&l);
if (r->dst.port_op == 1) {
if (strcmp(w, "<>") && strcmp(w, "><")) {
- fprintf(stderr, "error on line %d: expected <>/><, got %s\n", n, w);
+ error(n, "expected <>/><, got %s\n",
+ w);
return (0);
}
w = next_word(&l);
@@ -619,20 +646,17 @@ parse_rule(int n, char *l, struct pf_rule *r)
}
}
- }
- else {
- fprintf(stderr, "error on line %d: expected all/from, got %s\n",
- n, w);
+ } else {
+ error(n, "expected all/from, got %s\n", w);
return (0);
}
/* flags */
if (!strcmp(w, "flags")) {
if (r->proto != IPPROTO_TCP) {
- fprintf(stderr, "error on line %d: flags only valid for proto tcp\n", n);
+ error(n, "flags only valid for proto tcp\n");
return (0);
- }
- else {
+ } else {
w = next_word(&l);
r->flags = next_flags(&w);
r->flagset = next_flags(&w);
@@ -643,17 +667,38 @@ parse_rule(int n, char *l, struct pf_rule *r)
/* icmp type/code */
if (!strcmp(w, "icmp-type")) {
if (r->proto != IPPROTO_ICMP) {
- fprintf(stderr,
- "error on line %d: icmp-type only valid for proto icmp\n", n);
+ error(n, "icmp-type only valid for proto icmp\n");
return (0);
- }
- else {
+ } else {
+ u_long ul;
+ char *ep;
+
w = next_word(&l);
- r->type = atoi(w)+1;
+
+ errno = 0;
+ ul = strtoul(w, &ep, 10);
+ if (w[0] == '\0' || *ep != '\0' ||
+ (errno == ERANGE && ul == ULONG_MAX) ||
+ ul > ICMP_MAXTYPE) {
+ error(n, "icmp-type type wrong\n");
+ return (0);
+ }
+ r->type = ul+1;
+
w = next_word(&l);
if (!strcmp(w, "code")) {
w = next_word(&l);
- r->code = atoi(w) + 1;
+
+ errno = 0;
+ ul = strtoul(w, &ep, 10);
+ if ((w[0] == '\0' || *ep != '\0') ||
+ (errno == ERANGE && ul == ULONG_MAX) ||
+ ul > 255) {
+ error(n, "icmp-type code wrong\n");
+ return (0);
+ }
+
+ r->code = ul + 1;
w = next_word(&l);
}
}
@@ -665,16 +710,15 @@ parse_rule(int n, char *l, struct pf_rule *r)
if (!strcmp(w, "state")) {
w = next_word(&l);
r->keep_state = 1;
- }
- else {
- fprintf(stderr, "error on line %d: expected state, got %s\n", n, w);
+ } else {
+ error(n, "expected state, got %s\n", w);
return (0);
}
}
/* no further options expected */
while (*w) {
- fprintf(stderr, "error on line %d: unexpected %s\n", n, w);
+ error(n, "unexpected %s\n", w);
w = next_word(&l);
}
@@ -691,8 +735,7 @@ parse_nat(int n, char *l, struct pf_nat *nat)
/* nat */
if (strcmp(w, "nat" )) {
- fprintf(stderr,
- "error on line %d: expected nat, got %s\n", n, w);
+ error(n, "expected nat, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -712,16 +755,14 @@ parse_nat(int n, char *l, struct pf_nat *nat)
else if (*w == '/')
nat->smask = rule_mask(next_number(&w));
else {
- fprintf(stderr,
- "error on line %d: expected /, got '%c'\n", n, *w);
+ error(n, "expected /, got '%c'\n", *w);
return (0);
}
w = next_word(&l);
/* -> */
if (strcmp(w, "->")) {
- fprintf(stderr,
- "error on line %d: expected ->, got %s\n", n, w);
+ error(n, "expected ->, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -740,9 +781,7 @@ parse_nat(int n, char *l, struct pf_nat *nat)
else if (!strcmp(w, "icmp"))
nat->proto = IPPROTO_ICMP;
else {
- fprintf(stderr,
- "error on line %d: expected tcp/udp/icmp, got %s\n",
- n, w);
+ error(n, "expected tcp/udp/icmp, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -750,7 +789,7 @@ parse_nat(int n, char *l, struct pf_nat *nat)
/* no further options expected */
while (*w) {
- fprintf(stderr, "error on line %d: unexpected %s\n", n, w);
+ error(n, "unexpected %s\n", w);
w = next_word(&l);
}
@@ -767,8 +806,7 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr)
/* rdr */
if (strcmp(w, "rdr" )) {
- fprintf(stderr,
- "error on line %d: expected rdr, got %s\n", n, w);
+ error(n, "expected rdr, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -788,15 +826,14 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr)
else if (*w == '/')
rdr->dmask = rule_mask(next_number(&w));
else {
- fprintf(stderr,
- "error on line %d: expected /, got '%c'\n", n, *w);
+ error(n, "expected /, got '%c'\n", *w);
return (0);
}
w = next_word(&l);
/* external port */
if (strcmp(w, "port")) {
- fprintf(stderr, "error on line %d: expected port, got %s\n", n, w);
+ error(n, "expected port, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -805,8 +842,7 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr)
/* -> */
if (strcmp(w, "->")) {
- fprintf(stderr,
- "error on line %d: expected ->, got %s\n", n, w);
+ error(n, "expected ->, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -817,8 +853,7 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr)
/* internal port */
if (strcmp(w, "port")) {
- fprintf(stderr,
- "error on line %d: expected port, got %s\n", n, w);
+ error(n, "expected port, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -833,9 +868,7 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr)
else if (!strcmp(w, "udp"))
rdr->proto = IPPROTO_UDP;
else {
- fprintf(stderr,
- "error on line %d: expected tcp/udp, got %s\n",
- n, w);
+ error(n, "expected tcp/udp, got %s\n", w);
return (0);
}
w = next_word(&l);
@@ -843,7 +876,7 @@ parse_rdr(int n, char *l, struct pf_rdr *rdr)
/* no further options expected */
while (*w) {
- fprintf(stderr, "error on line %d: unexpected %s\n", n, w);
+ error(n, "unexpected %s\n", w);
w = next_word(&l);
}