diff options
author | Peter Stromberg <wilfried@cvs.openbsd.org> | 2001-09-15 23:23:41 +0000 |
---|---|---|
committer | Peter Stromberg <wilfried@cvs.openbsd.org> | 2001-09-15 23:23:41 +0000 |
commit | 0ea556316015d5c7204d780512ea86ee7a003549 (patch) | |
tree | 986efec64285b45310cee10709c349d9a0dd875c | |
parent | c91dfed633051f95ae8a5b732220fb27d064939a (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.y | 29 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 46 |
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 |