summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Stromberg <wilfried@cvs.openbsd.org>2001-09-15 23:23:41 +0000
committerPeter Stromberg <wilfried@cvs.openbsd.org>2001-09-15 23:23:41 +0000
commit0ea556316015d5c7204d780512ea86ee7a003549 (patch)
tree986efec64285b45310cee10709c349d9a0dd875c
parentc91dfed633051f95ae8a5b732220fb27d064939a (diff)
Implement return-icmp(number), return-icmp6(number)
Differentiate between return-icmp and return-icmp6, icmp-type and ipv6-icmp-type. ok dhartmei@
-rw-r--r--sbin/pfctl/parse.y29
-rw-r--r--sbin/pfctl/pfctl_parser.c46
2 files changed, 48 insertions, 27 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 15e3ac89392..84b50b08222 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.34 2001/09/15 21:49:19 dhartmei Exp $ */
+/* $OpenBSD: parse.y,v 1.35 2001/09/15 23:23:40 wilfried Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -242,22 +242,30 @@ blockspec : /* empty */ { $$.b2 = 0; $$.w = 0; }
$$.w = (ICMP6_DST_UNREACH << 8) |
ICMP6_DST_UNREACH_NOPORT;
}
+ | RETURNICMP '(' NUMBER ')' {
+ $$.w = (ICMP_UNREACH << 8) | $3;
+ $$.b2 = 0;
+ }
| RETURNICMP '(' STRING ')' {
struct icmpcodeent *p;
if ((p = geticmpcodebyname(ICMP_UNREACH, $3,
- IPPROTO_ICMP)) == NULL) {
+ AF_INET)) == NULL) {
yyerror("unknown icmp code %s", $3);
YYERROR;
}
$$.w = (p->type << 8) | p->code;
$$.b2 = 0;
}
+ | RETURNICMP6 '(' NUMBER ')' {
+ $$.w = (ICMP6_DST_UNREACH << 8) | $3;
+ $$.b2 = 0;
+ }
| RETURNICMP6 '(' STRING ')' {
struct icmpcodeent *p;
if ((p = geticmpcodebyname(ICMP6_DST_UNREACH, $3,
- IPPROTO_ICMPV6)) == NULL) {
+ AF_INET6)) == NULL) {
yyerror("unknown icmp code %s", $3);
YYERROR;
}
@@ -559,7 +567,7 @@ icmp_item : icmptype {
err(1, "icmp_item: malloc");
$$->type = $1;
if ((p = geticmpcodebyname($1, $3,
- IPPROTO_ICMP)) == NULL) {
+ AF_INET)) == NULL) {
yyerror("unknown icmp-code %s", $3);
YYERROR;
}
@@ -599,7 +607,7 @@ icmp6_item : icmp6type {
err(1, "icmp_item: malloc");
$$->type = $1;
if ((p = geticmpcodebyname($1, $3,
- IPPROTO_ICMPV6)) == NULL) {
+ AF_INET6)) == NULL) {
yyerror("unknown icmp6-code %s", $3);
YYERROR;
}
@@ -612,7 +620,7 @@ icmp6_item : icmp6type {
icmptype : STRING {
struct icmptypeent *p;
- if ((p = geticmptypebyname($1, IPPROTO_ICMP)) == NULL) {
+ if ((p = geticmptypebyname($1, AF_INET)) == NULL) {
yyerror("unknown icmp-type %s", $1);
YYERROR;
}
@@ -630,8 +638,7 @@ icmptype : STRING {
icmp6type : STRING {
struct icmptypeent *p;
- if ((p = geticmptypebyname($1,
- IPPROTO_ICMPV6)) == NULL) {
+ if ((p = geticmptypebyname($1, AF_INET6)) == NULL) {
yyerror("unknown ipv6-icmp-type %s", $1);
YYERROR;
}
@@ -953,6 +960,12 @@ rule_consistent(struct pf_rule *r)
yyerror("icmp version does not match address family");
problems++;
}
+ if (!(r->rule_flag & PFRULE_RETURNRST) && r->return_icmp &&
+ ((r->af != AF_INET6 && (r->return_icmp>>8) != ICMP_UNREACH) ||
+ (r->af == AF_INET6 && (r->return_icmp>>8) != ICMP6_DST_UNREACH))) {
+ yyerror("return-icmp version does not match address family");
+ problems++;
+ }
if (r->keep_state == PF_STATE_MODULATE && r->proto &&
r->proto != IPPROTO_TCP) {
yyerror("modulate state can only be applied to TCP rules");
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index 210adc9b861..0876836e906 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.49 2001/09/15 23:13:40 dhartmei Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.50 2001/09/15 23:23:40 wilfried Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -171,11 +171,11 @@ struct icmpcodeent icmp6_code[] = {
struct icmptypeent *
-geticmptypebynumber(u_int8_t type, u_int8_t proto)
+geticmptypebynumber(u_int8_t type, u_int8_t af)
{
unsigned i;
- if (proto == IPPROTO_ICMP) {
+ if (af != AF_INET6) {
for(i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); i++) {
if(type == icmp_type[i].type)
return (&icmp_type[i]);
@@ -191,11 +191,11 @@ geticmptypebynumber(u_int8_t type, u_int8_t proto)
}
struct icmptypeent *
-geticmptypebyname(char *w, u_int8_t proto)
+geticmptypebyname(char *w, u_int8_t af)
{
unsigned i;
- if (proto == IPPROTO_ICMP) {
+ if (af != AF_INET6) {
for(i=0; i < (sizeof (icmp_type) / sizeof(icmp_type[0])); i++) {
if(!strcmp(w, icmp_type[i].name))
return (&icmp_type[i]);
@@ -211,11 +211,11 @@ geticmptypebyname(char *w, u_int8_t proto)
}
struct icmpcodeent *
-geticmpcodebynumber(u_int8_t type, u_int8_t code, u_int8_t proto)
+geticmpcodebynumber(u_int8_t type, u_int8_t code, u_int8_t af)
{
unsigned i;
- if (proto == IPPROTO_ICMP) {
+ if (af != AF_INET6) {
for(i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); i++) {
if (type == icmp_code[i].type &&
code == icmp_code[i].code)
@@ -233,11 +233,11 @@ geticmpcodebynumber(u_int8_t type, u_int8_t code, u_int8_t proto)
}
struct icmpcodeent *
-geticmpcodebyname(u_long type, char *w, u_int8_t proto)
+geticmpcodebyname(u_long type, char *w, u_int8_t af)
{
unsigned i;
- if (proto == IPPROTO_ICMP) {
+ if (af != AF_INET6) {
for(i=0; i < (sizeof (icmp_code) / sizeof(icmp_code[0])); i++) {
if (type == icmp_code[i].type &&
!strcmp(w, icmp_code[i].name))
@@ -619,13 +619,17 @@ print_rule(struct pf_rule *r)
else if (r->return_icmp) {
struct icmpcodeent *ic;
- printf("return-icmp");
+ if (r->af != AF_INET6)
+ printf("return-icmp");
+ else
+ printf("return-icmp6");
ic = geticmpcodebynumber(r->return_icmp >> 8,
- r->return_icmp & 255, r->proto);
- if ((ic == NULL) || (ic->type != ICMP_UNREACH))
- printf("(%u,%u) ", r->return_icmp >> 8,
- r->return_icmp & 255);
- else if (ic->code != ICMP_UNREACH_PORT)
+ r->return_icmp & 255, r->af);
+
+ if (ic == NULL)
+ printf("(%u) ", r->return_icmp & 255);
+ else if ((r->af != AF_INET6 && ic->code != ICMP_UNREACH_PORT) ||
+ (r->af == AF_INET6 && ic->code != ICMP6_DST_UNREACH_NOPORT))
printf("(%s) ", ic->name);
else
printf(" ");
@@ -703,15 +707,19 @@ print_rule(struct pf_rule *r)
if (r->type) {
struct icmptypeent *p;
- p = geticmptypebynumber(r->type-1, r->proto);
+ p = geticmptypebynumber(r->type-1, r->af);
+ if (r->af != AF_INET6)
+ printf("icmp-type");
+ else
+ printf("ipv6-icmp-type");
if (p != NULL)
- printf("icmp-type %s ", p->name);
+ printf(" %s ", p->name);
else
- printf("icmp-type %u ", r->type-1);
+ printf(" %u ", r->type-1);
if (r->code) {
struct icmpcodeent *p;
- p = geticmpcodebynumber(r->type-1, r->code-1, r->proto);
+ p = geticmpcodebynumber(r->type-1, r->code-1, r->af);
if (p != NULL)
printf("code %s ", p->name);
else