FreeBSD Bugzilla – Attachment 80960 Details for
Bug 116009
[ipfw] [patch] Ignore errors when loading ruleset from file + rule replacement command
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 75.60 KB, created by
Alter
on 2007-09-02 11:00:06 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
Alter
Created:
2007-09-02 11:00:06 UTC
Size:
75.60 KB
patch
obsolete
>*** ipfw2.orig.c Sat Sep 1 11:04:54 2007 >--- ipfw2.c Sat Sep 1 22:09:31 2007 >*************** >*** 73,124 **** > show_sets, /* display rule sets */ > test_only, /* only check syntax */ > comment_only, /* only print action and comment */ >! verbose; > > #define IP_MASK_ALL 0xffffffff >- /* >- * the following macro returns an error message if we run out of >- * arguments. >- */ >- #define NEED1(msg) {if (!ac) errx(EX_USAGE, msg);} > >! #define GET_UINT_ARG(arg, min, max, tok, s_x) do { \ >! if (!ac) \ >! errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \ >! if (_substrcmp(*av, "tablearg") == 0) { \ >! arg = IP_FW_TABLEARG; \ >! break; \ >! } \ >! \ >! { \ >! long val; \ >! char *end; \ >! \ >! val = strtol(*av, &end, 10); \ >! \ >! if (!isdigit(**av) || *end != '\0' || (val == 0 && errno == EINVAL)) \ >! errx(EX_DATAERR, "%s: invalid argument: %s", \ >! match_value(s_x, tok), *av); \ >! \ >! if (errno == ERANGE || val < min || val > max) \ >! errx(EX_DATAERR, "%s: argument is out of range (%u..%u): %s", \ >! match_value(s_x, tok), min, max, *av); \ >! \ >! if (val == IP_FW_TABLEARG) \ >! errx(EX_DATAERR, "%s: illegal argument value: %s", \ >! match_value(s_x, tok), *av); \ >! arg = val; \ >! } \ >! } while (0) > >- #define PRINT_UINT_ARG(str, arg) do { \ >- if (str != NULL) \ >- printf("%s",str); \ >- if (arg == IP_FW_TABLEARG) \ >- printf("tablearg"); \ >- else \ >- printf("%u", (uint32_t)arg); \ >- } while (0) > > /* > * _s_x is a structure that stores a string <-> token pairs, used in >--- 73,85 ---- > show_sets, /* display rule sets */ > test_only, /* only check syntax */ > comment_only, /* only print action and comment */ >! verbose, >! ignore_errors; > > #define IP_MASK_ALL 0xffffffff > >! #define EX_BREAK 1 > > > /* > * _s_x is a structure that stores a string <-> token pairs, used in >*************** >*** 133,138 **** >--- 94,194 ---- > int x; > }; > >+ /* Some forward declarations */ >+ static char const * >+ match_value(struct _s_x *p, int value); >+ >+ static int >+ _substrcmp(const char *str1, const char* str2); >+ >+ int my_errx(int code, char* fmt, ...) >+ { >+ va_list args; >+ va_start(args, fmt); >+ >+ if(!ignore_errors) >+ verrx(code, fmt, args); >+ >+ vwarnx(fmt, args); >+ >+ va_end(args); >+ return code; >+ } >+ >+ int my_err(int code, char* fmt, ...) >+ { >+ va_list args; >+ va_start(args, fmt); >+ >+ if(!ignore_errors) >+ verr(code, fmt, args); >+ >+ vwarn(fmt, args); >+ >+ va_end(args); >+ return code; >+ } >+ >+ /* >+ * the following macro returns an error message if we run out of >+ * arguments. >+ */ >+ #define NEED1(msg) {if (!ac) { return my_errx(EX_USAGE, msg); } } >+ >+ int >+ _GET_UINT_ARG(char *av[], uint16_t* arg, long min, long max, int tok, struct _s_x* s_x) >+ { >+ if (_substrcmp(*av, "tablearg") == 0) { >+ (*arg) = IP_FW_TABLEARG; >+ return EX_BREAK; >+ } >+ >+ { >+ long val; >+ char *end; >+ >+ val = strtol(*av, &end, 10); >+ >+ if (!isdigit(**av) || *end != '\0' || (val == 0 && errno == EINVAL)) { >+ return my_errx(EX_DATAERR, "%s: invalid argument: %s", >+ match_value(s_x, tok), *av); >+ } >+ >+ if (errno == ERANGE || val < min || val > max) { >+ return my_errx(EX_DATAERR, "%s: argument is out of range (%u..%u): %s", >+ match_value(s_x, tok), min, max, *av); >+ } >+ >+ if (val == IP_FW_TABLEARG) { >+ return my_errx(EX_DATAERR, "%s: illegal argument value: %s", >+ match_value(s_x, tok), *av); >+ } >+ (*arg) = val; >+ } >+ return EX_OK; >+ } >+ >+ #define GET_UINT_ARG(arg, min, max, tok, s_x) do { \ >+ int r; \ >+ if (!ac) { \ >+ return my_errx(EX_USAGE, "%s: missing argument", match_value(s_x, tok)); \ >+ } \ >+ r = _GET_UINT_ARG(av, &arg, min, max, tok, s_x); \ >+ if(r == EX_BREAK) \ >+ break; \ >+ if(r != EX_OK) \ >+ return r; \ >+ } while(0) >+ >+ #define PRINT_UINT_ARG(str, arg) do { \ >+ if (str != NULL) \ >+ printf("%s",str); \ >+ if (arg == IP_FW_TABLEARG) \ >+ printf("tablearg"); \ >+ else \ >+ printf("%u", (uint32_t)arg); \ >+ } while (0) >+ > static struct _s_x f_tcpflags[] = { > { "syn", TH_SYN }, > { "fin", TH_FIN }, >*************** >*** 488,495 **** > > if (s == -1) > s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); >! if (s < 0) >! err(EX_UNAVAILABLE, "socket"); > > if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || > optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || >--- 544,553 ---- > > if (s == -1) > s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW); >! if (s < 0) { >! my_errx(EX_UNAVAILABLE, "socket"); >! return -1; >! } > > if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || > optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || >*************** >*** 724,746 **** > static TAILQ_HEAD(, pf_altq) altq_entries = > TAILQ_HEAD_INITIALIZER(altq_entries); > >! static void > altq_set_enabled(int enabled) > { > int pffd; > > pffd = open("/dev/pf", O_RDWR); >! if (pffd == -1) >! err(EX_UNAVAILABLE, >! "altq support opening pf(4) control device"); > if (enabled) { >! if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST) >! err(EX_UNAVAILABLE, "enabling altq"); > } else { >! if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT) >! err(EX_UNAVAILABLE, "disabling altq"); > } > close(pffd); > } > > static void >--- 782,807 ---- > static TAILQ_HEAD(, pf_altq) altq_entries = > TAILQ_HEAD_INITIALIZER(altq_entries); > >! static int > altq_set_enabled(int enabled) > { > int pffd; > > pffd = open("/dev/pf", O_RDWR); >! if (pffd == -1) { >! return my_err(EX_UNAVAILABLE, "altq support opening pf(4) control device"); >! } > if (enabled) { >! if (ioctl(pffd, DIOCSTARTALTQ) != 0 && errno != EEXIST) { >! return my_err(EX_UNAVAILABLE, "enabling altq"); >! } > } else { >! if (ioctl(pffd, DIOCSTOPALTQ) != 0 && errno != ENOENT) { >! return my_err(EX_UNAVAILABLE, "disabling altq"); >! } > } > close(pffd); >+ return EX_OK; > } > > static void >*************** >*** 776,783 **** > if (pfioc.altq.qid == 0) > continue; > altq = malloc(sizeof(*altq)); >! if (altq == NULL) > err(EX_OSERR, "malloc"); > *altq = pfioc.altq; > TAILQ_INSERT_TAIL(&altq_entries, altq, entries); > } >--- 837,845 ---- > if (pfioc.altq.qid == 0) > continue; > altq = malloc(sizeof(*altq)); >! if (altq == NULL) { > err(EX_OSERR, "malloc"); >+ } > *altq = pfioc.altq; > TAILQ_INSERT_TAIL(&altq_entries, altq, entries); > } >*************** >*** 785,791 **** > } > > static u_int32_t >! altq_name_to_qid(const char *name) > { > struct pf_altq *altq; > >--- 847,853 ---- > } > > static u_int32_t >! altq_name_to_qid(const char *name, u_int32_t *qid) > { > struct pf_altq *altq; > >*************** >*** 793,801 **** > TAILQ_FOREACH(altq, &altq_entries, entries) > if (strcmp(name, altq->qname) == 0) > break; >! if (altq == NULL) >! errx(EX_DATAERR, "altq has no queue named `%s'", name); >! return altq->qid; > } > > static const char * >--- 855,866 ---- > TAILQ_FOREACH(altq, &altq_entries, entries) > if (strcmp(name, altq->qname) == 0) > break; >! if (altq == NULL) { >! warn("altq has no queue named `%s'", name); >! return EX_DATAERR; >! } >! (*qid) = altq->qid; >! return EX_OK; > } > > static const char * >*************** >*** 812,821 **** > return altq->qname; > } > >! static void > fill_altq_qid(u_int32_t *qid, const char *av) > { >! *qid = altq_name_to_qid(av); > } > > /* >--- 877,886 ---- > return altq->qname; > } > >! static int > fill_altq_qid(u_int32_t *qid, const char *av) > { >! return altq_name_to_qid(av, qid); > } > > /* >*************** >*** 858,865 **** > av = s + 1; > } > if (i > 0) { >! if (i + 1 > F_LEN_MASK) >! errx(EX_DATAERR, "too many ports/ranges\n"); > cmd->o.len |= i + 1; /* leave F_NOT and F_OR untouched */ > } > return (i); >--- 923,932 ---- > av = s + 1; > } > if (i > 0) { >! if (i + 1 > F_LEN_MASK) { >! my_errx(EX_DATAERR, "too many ports/ranges\n"); >! return 0; >! } > cmd->o.len |= i + 1; /* leave F_NOT and F_OR untouched */ > } > return (i); >*************** >*** 885,891 **** > { NULL, 0 } > }; > >! static void > fill_reject_code(u_short *codep, char *str) > { > int val; >--- 952,958 ---- > { NULL, 0 } > }; > >! static int > fill_reject_code(u_short *codep, char *str) > { > int val; >*************** >*** 894,903 **** > val = strtoul(str, &s, 0); > if (s == str || *s != '\0' || val >= 0x100) > val = match_token(icmpcodes, str); >! if (val < 0) >! errx(EX_DATAERR, "unknown ICMP unreachable code ``%s''", str); > *codep = val; >! return; > } > > static void >--- 961,971 ---- > val = strtoul(str, &s, 0); > if (s == str || *s != '\0' || val >= 0x100) > val = match_token(icmpcodes, str); >! if (val < 0) { >! return my_errx(EX_DATAERR, "unknown ICMP unreachable code ``%s''", str); >! } > *codep = val; >! return EX_OK; > } > > static void >*************** >*** 919,925 **** > { NULL, 0 } > }; > >! static void > fill_unreach6_code(u_short *codep, char *str) > { > int val; >--- 987,993 ---- > { NULL, 0 } > }; > >! static int > fill_unreach6_code(u_short *codep, char *str) > { > int val; >*************** >*** 928,937 **** > val = strtoul(str, &s, 0); > if (s == str || *s != '\0' || val >= 0x100) > val = match_token(icmp6codes, str); >! if (val < 0) >! errx(EX_DATAERR, "unknown ICMPv6 unreachable code ``%s''", str); > *codep = val; >! return; > } > > static void >--- 996,1006 ---- > val = strtoul(str, &s, 0); > if (s == str || *s != '\0' || val >= 0x100) > val = match_token(icmp6codes, str); >! if (val < 0) { >! return my_errx(EX_DATAERR, "unknown ICMPv6 unreachable code ``%s''", str); >! } > *codep = val; >! return EX_OK; > } > > static void >*************** >*** 1108,1114 **** > } > } > >! static void > fill_icmptypes(ipfw_insn_u32 *cmd, char *av) > { > uint8_t type; >--- 1177,1183 ---- > } > } > >! static int > fill_icmptypes(ipfw_insn_u32 *cmd, char *av) > { > uint8_t type; >*************** >*** 1120,1135 **** > > type = strtoul(av, &av, 0); > >! if (*av != ',' && *av != '\0') >! errx(EX_DATAERR, "invalid ICMP type"); > >! if (type > 31) >! errx(EX_DATAERR, "ICMP type out of range"); > > cmd->d[0] |= 1 << type; > } > cmd->o.opcode = O_ICMPTYPE; > cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32); > } > > static void >--- 1189,1207 ---- > > type = strtoul(av, &av, 0); > >! if (*av != ',' && *av != '\0') { >! return my_errx(EX_DATAERR, "invalid ICMP type"); >! } > >! if (type > 31) { >! return my_errx(EX_DATAERR, "ICMP type out of range"); >! } > > cmd->d[0] |= 1 << type; > } > cmd->o.opcode = O_ICMPTYPE; > cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32); >+ return EX_OK; > } > > static void >*************** >*** 1201,1207 **** > } > } > >! static void > fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av) > { > uint8_t type; >--- 1273,1279 ---- > } > } > >! static int > fill_icmp6types(ipfw_insn_icmp6 *cmd, char *av) > { > uint8_t type; >*************** >*** 1211,1230 **** > if (*av == ',') > av++; > type = strtoul(av, &av, 0); >! if (*av != ',' && *av != '\0') >! errx(EX_DATAERR, "invalid ICMP6 type"); > /* > * XXX: shouldn't this be 0xFF? I can't see any reason why > * we shouldn't be able to filter all possiable values > * regardless of the ability of the rest of the kernel to do > * anything useful with them. > */ >! if (type > ICMP6_MAXTYPE) >! errx(EX_DATAERR, "ICMP6 type out of range"); > cmd->d[type / 32] |= ( 1 << (type % 32)); > } > cmd->o.opcode = O_ICMP6TYPE; > cmd->o.len |= F_INSN_SIZE(ipfw_insn_icmp6); > } > > >--- 1283,1305 ---- > if (*av == ',') > av++; > type = strtoul(av, &av, 0); >! if (*av != ',' && *av != '\0') { >! return my_errx(EX_DATAERR, "invalid ICMP6 type"); >! } > /* > * XXX: shouldn't this be 0xFF? I can't see any reason why > * we shouldn't be able to filter all possiable values > * regardless of the ability of the rest of the kernel to do > * anything useful with them. > */ >! if (type > ICMP6_MAXTYPE) { >! return my_errx(EX_DATAERR, "ICMP6 type out of range"); >! } > cmd->d[type / 32] |= ( 1 << (type % 32)); > } > cmd->o.opcode = O_ICMP6TYPE; > cmd->o.len |= F_INSN_SIZE(ipfw_insn_icmp6); >+ return EX_OK; > } > > >*************** >*** 1307,1313 **** > break; > > default: >! errx( EX_DATAERR, "invalid option for ipv6 exten header" ); > break; > } > } >--- 1382,1389 ---- > break; > > default: >! my_errx( EX_DATAERR, "invalid option for ipv6 exten header" ); >! return -1; > break; > } > } >*************** >*** 2308,2314 **** > * ipfw set move X to Y > * ipfw set move rule X to Y > */ >! static void > sets_handler(int ac, char *av[]) > { > uint32_t set_disable, masks[2]; >--- 2384,2390 ---- > * ipfw set move X to Y > * ipfw set move rule X to Y > */ >! static int > sets_handler(int ac, char *av[]) > { > uint32_t set_disable, masks[2]; >*************** >*** 2319,2335 **** > ac--; > av++; > >! if (!ac) >! errx(EX_USAGE, "set needs command"); > if (_substrcmp(*av, "show") == 0) { > void *data; > char const *msg; > > nbytes = sizeof(struct ip_fw); >! if ((data = calloc(1, nbytes)) == NULL) >! err(EX_OSERR, "calloc"); >! if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0) >! err(EX_OSERR, "getsockopt(IP_FW_GET)"); > bcopy(&((struct ip_fw *)data)->next_rule, > &set_disable, sizeof(set_disable)); > >--- 2395,2415 ---- > ac--; > av++; > >! if (!ac) { >! warn("set needs command"); >! return EX_USAGE; >! } > if (_substrcmp(*av, "show") == 0) { > void *data; > char const *msg; > > nbytes = sizeof(struct ip_fw); >! if ((data = calloc(1, nbytes)) == NULL) { >! my_err(EX_OSERR, "calloc"); >! } >! if (do_cmd(IP_FW_GET, data, (uintptr_t)&nbytes) < 0) { >! my_err(EX_OSERR, "getsockopt(IP_FW_GET)"); >! } > bcopy(&((struct ip_fw *)data)->next_rule, > &set_disable, sizeof(set_disable)); > >*************** >*** 2347,2360 **** > printf("\n"); > } else if (_substrcmp(*av, "swap") == 0) { > ac--; av++; >! if (ac != 2) >! errx(EX_USAGE, "set swap needs 2 set numbers\n"); > rulenum = atoi(av[0]); > new_set = atoi(av[1]); >! if (!isdigit(*(av[0])) || rulenum > RESVD_SET) >! errx(EX_DATAERR, "invalid set number %s\n", av[0]); >! if (!isdigit(*(av[1])) || new_set > RESVD_SET) >! errx(EX_DATAERR, "invalid set number %s\n", av[1]); > masks[0] = (4 << 24) | (new_set << 16) | (rulenum); > i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t)); > } else if (_substrcmp(*av, "move") == 0) { >--- 2427,2443 ---- > printf("\n"); > } else if (_substrcmp(*av, "swap") == 0) { > ac--; av++; >! if (ac != 2) { >! return my_errx(EX_USAGE, "set swap needs 2 set numbers\n"); >! } > rulenum = atoi(av[0]); > new_set = atoi(av[1]); >! if (!isdigit(*(av[0])) || rulenum > RESVD_SET) { >! return my_errx(EX_DATAERR, "invalid set number %s\n", av[0]); >! } >! if (!isdigit(*(av[1])) || new_set > RESVD_SET) { >! return my_errx(EX_DATAERR, "invalid set number %s\n", av[1]); >! } > masks[0] = (4 << 24) | (new_set << 16) | (rulenum); > i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t)); > } else if (_substrcmp(*av, "move") == 0) { >*************** >*** 2364,2378 **** > ac--; av++; > } else > cmd = 3; >! if (ac != 3 || _substrcmp(av[1], "to") != 0) >! errx(EX_USAGE, "syntax: set move [rule] X to Y\n"); > rulenum = atoi(av[0]); > new_set = atoi(av[2]); > if (!isdigit(*(av[0])) || (cmd == 3 && rulenum > RESVD_SET) || >! (cmd == 2 && rulenum == 65535) ) >! errx(EX_DATAERR, "invalid source number %s\n", av[0]); >! if (!isdigit(*(av[2])) || new_set > RESVD_SET) >! errx(EX_DATAERR, "invalid dest. set %s\n", av[1]); > masks[0] = (cmd << 24) | (new_set << 16) | (rulenum); > i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t)); > } else if (_substrcmp(*av, "disable") == 0 || >--- 2447,2464 ---- > ac--; av++; > } else > cmd = 3; >! if (ac != 3 || _substrcmp(av[1], "to") != 0) { >! return my_errx(EX_USAGE, "syntax: set move [rule] X to Y\n"); >! } > rulenum = atoi(av[0]); > new_set = atoi(av[2]); > if (!isdigit(*(av[0])) || (cmd == 3 && rulenum > RESVD_SET) || >! (cmd == 2 && rulenum == 65535) ) { >! return my_errx(EX_DATAERR, "invalid source number %s\n", av[0]); >! } >! if (!isdigit(*(av[2])) || new_set > RESVD_SET) { >! return my_errx(EX_DATAERR, "invalid dest. set %s\n", av[1]); >! } > masks[0] = (cmd << 24) | (new_set << 16) | (rulenum); > i = do_cmd(IP_FW_DEL, masks, sizeof(uint32_t)); > } else if (_substrcmp(*av, "disable") == 0 || >*************** >*** 2385,2417 **** > while (ac) { > if (isdigit(**av)) { > i = atoi(*av); >! if (i < 0 || i > RESVD_SET) >! errx(EX_DATAERR, > "invalid set number %d\n", i); > masks[which] |= (1<<i); > } else if (_substrcmp(*av, "disable") == 0) > which = 0; > else if (_substrcmp(*av, "enable") == 0) > which = 1; >! else >! errx(EX_DATAERR, > "invalid set command %s\n", *av); > av++; ac--; > } >! if ( (masks[0] & masks[1]) != 0 ) >! errx(EX_DATAERR, > "cannot enable and disable the same set\n"); >! > i = do_cmd(IP_FW_DEL, masks, sizeof(masks)); > if (i) > warn("set enable/disable: setsockopt(IP_FW_DEL)"); >! } else >! errx(EX_USAGE, "invalid set command %s\n", *av); > } > >! static void > sysctl_handler(int ac, char *av[], int which) > { > ac--; > av++; > >--- 2471,2508 ---- > while (ac) { > if (isdigit(**av)) { > i = atoi(*av); >! if (i < 0 || i > RESVD_SET) { >! return my_errx(EX_DATAERR, > "invalid set number %d\n", i); >+ } > masks[which] |= (1<<i); > } else if (_substrcmp(*av, "disable") == 0) > which = 0; > else if (_substrcmp(*av, "enable") == 0) > which = 1; >! else { >! return my_errx(EX_DATAERR, > "invalid set command %s\n", *av); >+ } > av++; ac--; > } >! if ( (masks[0] & masks[1]) != 0 ) { >! return my_errx(EX_DATAERR, > "cannot enable and disable the same set\n"); >! } > i = do_cmd(IP_FW_DEL, masks, sizeof(masks)); > if (i) > warn("set enable/disable: setsockopt(IP_FW_DEL)"); >! } else { >! return my_errx(EX_USAGE, "invalid set command %s\n", *av); >! } >! return EX_OK; > } > >! static int > sysctl_handler(int ac, char *av[], int which) > { >+ int r; > ac--; > av++; > >*************** >*** 2433,2442 **** > sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0, > &which, sizeof(which)); > } else if (_substrcmp(*av, "altq") == 0) { >! altq_set_enabled(which); > } else { > warnx("unrecognize enable/disable keyword: %s\n", *av); > } > } > > static void >--- 2524,2537 ---- > sysctlbyname("net.inet.ip.fw.dyn_keepalive", NULL, 0, > &which, sizeof(which)); > } else if (_substrcmp(*av, "altq") == 0) { >! r = altq_set_enabled(which); >! if(r != EX_OK) { >! return r; >! } > } else { > warnx("unrecognize enable/disable keyword: %s\n", *av); > } >+ return EX_OK; > } > > static void >*************** >*** 2680,2686 **** > * 1.2.3.4/26{1,6,5,4,23} set of addresses in a subnet > * We can have multiple comma-separated address/mask entries. > */ >! static void > fill_ip(ipfw_insn_ip *cmd, char *av) > { > int len = 0; >--- 2775,2781 ---- > * 1.2.3.4/26{1,6,5,4,23} set of addresses in a subnet > * We can have multiple comma-separated address/mask entries. > */ >! static int > fill_ip(ipfw_insn_ip *cmd, char *av) > { > int len = 0; >*************** >*** 2689,2699 **** > cmd->o.len &= ~F_LEN_MASK; /* zero len */ > > if (_substrcmp(av, "any") == 0) >! return; > > if (_substrcmp(av, "me") == 0) { > cmd->o.len |= F_INSN_SIZE(ipfw_insn); >! return; > } > > if (strncmp(av, "table(", 6) == 0) { >--- 2784,2794 ---- > cmd->o.len &= ~F_LEN_MASK; /* zero len */ > > if (_substrcmp(av, "any") == 0) >! return EX_OK; > > if (_substrcmp(av, "me") == 0) { > cmd->o.len |= F_INSN_SIZE(ipfw_insn); >! return EX_OK; > } > > if (strncmp(av, "table(", 6) == 0) { >*************** >*** 2708,2714 **** > d[0] = strtoul(p, NULL, 0); > } else > cmd->o.len |= F_INSN_SIZE(ipfw_insn); >! return; > } > > while (av) { >--- 2803,2809 ---- > d[0] = strtoul(p, NULL, 0); > } else > cmd->o.len |= F_INSN_SIZE(ipfw_insn); >! return EX_OK; > } > > while (av) { >*************** >*** 2727,2746 **** > } else > md = '\0'; > >! if (lookup_host(av, (struct in_addr *)&d[0]) != 0) >! errx(EX_NOHOST, "hostname ``%s'' unknown", av); > switch (md) { > case ':': >! if (!inet_aton(p, (struct in_addr *)&d[1])) >! errx(EX_DATAERR, "bad netmask ``%s''", p); > break; > case '/': > masklen = atoi(p); > if (masklen == 0) > d[1] = htonl(0); /* mask */ >! else if (masklen > 32) >! errx(EX_DATAERR, "bad width ``%s''", p); >! else > d[1] = htonl(~0 << (32 - masklen)); > break; > case '{': /* no mask, assume /24 and put back the '{' */ >--- 2822,2843 ---- > } else > md = '\0'; > >! if (lookup_host(av, (struct in_addr *)&d[0]) != 0) { >! return my_errx(EX_NOHOST, "hostname ``%s'' unknown", av); >! } > switch (md) { > case ':': >! if (!inet_aton(p, (struct in_addr *)&d[1])) { >! return my_errx(EX_DATAERR, "bad netmask ``%s''", p); >! } > break; > case '/': > masklen = atoi(p); > if (masklen == 0) > d[1] = htonl(0); /* mask */ >! else if (masklen > 32) { >! return my_errx(EX_DATAERR, "bad width ``%s''", p); >! } else > d[1] = htonl(~0 << (32 - masklen)); > break; > case '{': /* no mask, assume /24 and put back the '{' */ >*************** >*** 2773,2782 **** > int low, high; > int i = contigmask((uint8_t *)&(d[1]), 32); > >! if (len > 0) >! errx(EX_DATAERR, "address set cannot be in a list"); >! if (i < 24 || i > 31) >! errx(EX_DATAERR, "invalid set with mask %d\n", i); > cmd->o.arg1 = 1<<(32-i); /* map length */ > d[0] = ntohl(d[0]); /* base addr in host format */ > cmd->o.opcode = O_IP_DST_SET; /* default */ >--- 2870,2881 ---- > int low, high; > int i = contigmask((uint8_t *)&(d[1]), 32); > >! if (len > 0) { >! return my_errx(EX_DATAERR, "address set cannot be in a list"); >! } >! if (i < 24 || i > 31) { >! return my_errx(EX_DATAERR, "invalid set with mask %d\n", i); >! } > cmd->o.arg1 = 1<<(32-i); /* map length */ > d[0] = ntohl(d[0]); /* base addr in host format */ > cmd->o.opcode = O_IP_DST_SET; /* default */ >*************** >*** 2798,2821 **** > int a = strtol(av, &s, 0); > > if (s == av) { /* no parameter */ >! if (*av != '}') >! errx(EX_DATAERR, "set not closed\n"); >! if (i != -1) >! errx(EX_DATAERR, "incomplete range %d-", i); > break; > } >! if (a < low || a > high) >! errx(EX_DATAERR, "addr %d out of range [%d-%d]\n", > a, low, high); > a -= low; > if (i == -1) /* no previous in range */ > i = a; > else { /* check that range is valid */ >! if (i > a) >! errx(EX_DATAERR, "invalid range %d-%d", > i+low, a+low); >! if (*s == '-') >! errx(EX_DATAERR, "double '-' in range"); > } > for (; i <= a; i++) > map[i/32] |= 1<<(i & 31); >--- 2897,2925 ---- > int a = strtol(av, &s, 0); > > if (s == av) { /* no parameter */ >! if (*av != '}') { >! return my_errx(EX_DATAERR, "set not closed\n"); >! } >! if (i != -1) { >! return my_errx(EX_DATAERR, "incomplete range %d-", i); >! } > break; > } >! if (a < low || a > high) { >! return my_errx(EX_DATAERR, "addr %d out of range [%d-%d]\n", > a, low, high); >+ } > a -= low; > if (i == -1) /* no previous in range */ > i = a; > else { /* check that range is valid */ >! if (i > a) { >! return my_errx(EX_DATAERR, "invalid range %d-%d", > i+low, a+low); >! } >! if (*s == '-') { >! return my_errx(EX_DATAERR, "double '-' in range"); >! } > } > for (; i <= a; i++) > map[i/32] |= 1<<(i & 31); >*************** >*** 2826,2832 **** > break; > av = s+1; > } >! return; > } > av = p; > if (av) /* then *av must be a ',' */ >--- 2930,2936 ---- > break; > av = s+1; > } >! return EX_OK; > } > av = p; > if (av) /* then *av must be a ',' */ >*************** >*** 2845,2856 **** > errx(EX_DATAERR, "not any never matches"); > } > /* else do nothing and skip this entry */ >! return; > } > /* A single IP can be stored in an optimized format */ > if (d[1] == IP_MASK_ALL && av == NULL && len == 0) { > cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32); >! return; > } > len += 2; /* two words... */ > d += 2; >--- 2949,2960 ---- > errx(EX_DATAERR, "not any never matches"); > } > /* else do nothing and skip this entry */ >! return EX_OK; > } > /* A single IP can be stored in an optimized format */ > if (d[1] == IP_MASK_ALL && av == NULL && len == 0) { > cmd->o.len |= F_INSN_SIZE(ipfw_insn_u32); >! return EX_OK; > } > len += 2; /* two words... */ > d += 2; >*************** >*** 2858,2863 **** >--- 2962,2968 ---- > if (len + 1 > F_LEN_MASK) > errx(EX_DATAERR, "address list too long"); > cmd->o.len |= len+1; >+ return EX_OK; > } > > >*************** >*** 3092,3098 **** > * helper function to process a set of flags and set bits in the > * appropriate masks. > */ >! static void > fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode, > struct _s_x *flags, char *p) > { >--- 3197,3203 ---- > * helper function to process a set of flags and set bits in the > * appropriate masks. > */ >! static int > fill_flags(ipfw_insn *cmd, enum ipfw_opcodes opcode, > struct _s_x *flags, char *p) > { >*************** >*** 3113,3130 **** > *q++ = '\0'; > val = match_token(flags, p); > if (val <= 0) >! errx(EX_DATAERR, "invalid flag %s", p); > *which |= (uint8_t)val; > p = q; > } > cmd->opcode = opcode; > cmd->len = (cmd->len & (F_NOT | F_OR)) | 1; > cmd->arg1 = (set & 0xff) | ( (clear & 0xff) << 8); > } > > >! static void >! delete(int ac, char *av[]) > { > uint32_t rulenum; > struct dn_pipe p; >--- 3218,3236 ---- > *q++ = '\0'; > val = match_token(flags, p); > if (val <= 0) >! return my_errx(EX_DATAERR, "invalid flag %s", p); > *which |= (uint8_t)val; > p = q; > } > cmd->opcode = opcode; > cmd->len = (cmd->len & (F_NOT | F_OR)) | 1; > cmd->arg1 = (set & 0xff) | ( (clear & 0xff) << 8); >+ return EX_OK; > } > > >! static int >! delete(int ac, char *av[], int replace) > { > uint32_t rulenum; > struct dn_pipe p; >*************** >*** 3159,3172 **** > rulenum = (i & 0xffff) | (do_set << 24); > i = do_cmd(IP_FW_DEL, &rulenum, sizeof rulenum); > if (i) { >! exitval = EX_UNAVAILABLE; >! warn("rule %u: setsockopt(IP_FW_DEL)", >! rulenum); > } > } > } >! if (exitval != EX_OK) > exit(exitval); > } > > >--- 3265,3281 ---- > rulenum = (i & 0xffff) | (do_set << 24); > i = do_cmd(IP_FW_DEL, &rulenum, sizeof rulenum); > if (i) { >! if(!replace) { >! exitval = EX_UNAVAILABLE; >! warn("rule %u: setsockopt(IP_FW_DEL)", >! rulenum); >! } > } > } > } >! if (exitval != EX_OK && !ignore_errors) > exit(exitval); >+ return exitval; > } > > >*************** >*** 3177,3183 **** > * Interface names containing '*', '?', or '[' are assumed to be shell > * patterns which match interfaces. > */ >! static void > fill_iface(ipfw_insn_if *cmd, char *arg) > { > cmd->name[0] = '\0'; >--- 3286,3292 ---- > * Interface names containing '*', '?', or '[' are assumed to be shell > * patterns which match interfaces. > */ >! static int > fill_iface(ipfw_insn_if *cmd, char *arg) > { > cmd->name[0] = '\0'; >*************** >*** 3190,3199 **** > strlcpy(cmd->name, arg, sizeof(cmd->name)); > cmd->p.glob = strpbrk(arg, "*?[") != NULL ? 1 : 0; > } else if (!inet_aton(arg, &cmd->p.ip)) >! errx(EX_DATAERR, "bad ip address ``%s''", arg); > } > >! static void > config_pipe(int ac, char **av) > { > struct dn_pipe p; >--- 3299,3309 ---- > strlcpy(cmd->name, arg, sizeof(cmd->name)); > cmd->p.glob = strpbrk(arg, "*?[") != NULL ? 1 : 0; > } else if (!inet_aton(arg, &cmd->p.ip)) >! return my_errx(EX_DATAERR, "bad ip address ``%s''", arg); >! return EX_OK; > } > >! static int > config_pipe(int ac, char **av) > { > struct dn_pipe p; >*************** >*** 3325,3331 **** > goto end_mask; > } > if (ac < 1) >! errx(EX_USAGE, "mask: value missing"); > if (*av[0] == '/') { > a = strtoul(av[0]+1, &end, 0); > if (pa6 == NULL) >--- 3435,3441 ---- > goto end_mask; > } > if (ac < 1) >! return my_errx(EX_USAGE, "mask: value missing"); > if (*av[0] == '/') { > a = strtoul(av[0]+1, &end, 0); > if (pa6 == NULL) >*************** >*** 3336,3358 **** > *p32 = a; > else if (p16 != NULL) { > if (a > 0xFFFF) >! errx(EX_DATAERR, > "port mask must be 16 bit"); > *p16 = (uint16_t)a; > } else if (p20 != NULL) { > if (a > 0xfffff) >! errx(EX_DATAERR, > "flow_id mask must be 20 bit"); > *p20 = (uint32_t)a; > } else if (pa6 != NULL) { > if (a < 0 || a > 128) >! errx(EX_DATAERR, > "in6addr invalid mask len"); > else > n2mask(pa6, a); > } else { > if (a > 0xFF) >! errx(EX_DATAERR, > "proto mask must be 8 bit"); > p.fs.flow_mask.proto = (uint8_t)a; > } >--- 3446,3468 ---- > *p32 = a; > else if (p16 != NULL) { > if (a > 0xFFFF) >! return my_errx(EX_DATAERR, > "port mask must be 16 bit"); > *p16 = (uint16_t)a; > } else if (p20 != NULL) { > if (a > 0xfffff) >! return my_errx(EX_DATAERR, > "flow_id mask must be 20 bit"); > *p20 = (uint32_t)a; > } else if (pa6 != NULL) { > if (a < 0 || a > 128) >! return my_errx(EX_DATAERR, > "in6addr invalid mask len"); > else > n2mask(pa6, a); > } else { > if (a > 0xFF) >! return my_errx(EX_DATAERR, > "proto mask must be 8 bit"); > p.fs.flow_mask.proto = (uint8_t)a; > } >*************** >*** 3375,3381 **** > if ((end = strsep(&av[0], "/"))) { > double w_q = strtod(end, NULL); > if (w_q > 1 || w_q <= 0) >! errx(EX_DATAERR, "0 < w_q <= 1"); > p.fs.w_q = (int) (w_q * (1 << SCALE_RED)); > } > if ((end = strsep(&av[0], "/"))) { >--- 3485,3491 ---- > if ((end = strsep(&av[0], "/"))) { > double w_q = strtod(end, NULL); > if (w_q > 1 || w_q <= 0) >! return my_errx(EX_DATAERR, "0 < w_q <= 1"); > p.fs.w_q = (int) (w_q * (1 << SCALE_RED)); > } > if ((end = strsep(&av[0], "/"))) { >*************** >*** 3391,3397 **** > if ((end = strsep(&av[0], "/"))) { > double max_p = strtod(end, NULL); > if (max_p > 1 || max_p <= 0) >! errx(EX_DATAERR, "0 < max_p <= 1"); > p.fs.max_p = (int)(max_p * (1 << SCALE_RED)); > } > ac--; av++; >--- 3501,3507 ---- > if ((end = strsep(&av[0], "/"))) { > double max_p = strtod(end, NULL); > if (max_p > 1 || max_p <= 0) >! return my_errx(EX_DATAERR, "0 < max_p <= 1"); > p.fs.max_p = (int)(max_p * (1 << SCALE_RED)); > } > ac--; av++; >*************** >*** 3404,3410 **** > case TOK_BW: > NEED1("bw needs bandwidth or interface\n"); > if (do_pipe != 1) >! errx(EX_DATAERR, "bandwidth only valid for pipes"); > /* > * set clocking interface or bandwidth value > */ >--- 3514,3520 ---- > case TOK_BW: > NEED1("bw needs bandwidth or interface\n"); > if (do_pipe != 1) >! return my_errx(EX_DATAERR, "bandwidth only valid for pipes"); > /* > * set clocking interface or bandwidth value > */ >*************** >*** 3429,3442 **** > _substrcmp2(end, "by", "bytes") == 0) > p.bandwidth *= 8; > if (p.bandwidth < 0) >! errx(EX_DATAERR, "bandwidth too large"); > } > ac--; av++; > break; > > case TOK_DELAY: > if (do_pipe != 1) >! errx(EX_DATAERR, "delay only valid for pipes"); > NEED1("delay needs argument 0..10000ms\n"); > p.delay = strtoul(av[0], NULL, 0); > ac--; av++; >--- 3539,3552 ---- > _substrcmp2(end, "by", "bytes") == 0) > p.bandwidth *= 8; > if (p.bandwidth < 0) >! return my_errx(EX_DATAERR, "bandwidth too large"); > } > ac--; av++; > break; > > case TOK_DELAY: > if (do_pipe != 1) >! return my_errx(EX_DATAERR, "delay only valid for pipes"); > NEED1("delay needs argument 0..10000ms\n"); > p.delay = strtoul(av[0], NULL, 0); > ac--; av++; >*************** >*** 3444,3450 **** > > case TOK_WEIGHT: > if (do_pipe == 1) >! errx(EX_DATAERR,"weight only valid for queues"); > NEED1("weight needs argument 0..100\n"); > p.fs.weight = strtoul(av[0], &end, 0); > ac--; av++; >--- 3554,3560 ---- > > case TOK_WEIGHT: > if (do_pipe == 1) >! return my_errx(EX_DATAERR,"weight only valid for queues"); > NEED1("weight needs argument 0..100\n"); > p.fs.weight = strtoul(av[0], &end, 0); > ac--; av++; >*************** >*** 3452,3484 **** > > case TOK_PIPE: > if (do_pipe == 1) >! errx(EX_DATAERR,"pipe only valid for queues"); > NEED1("pipe needs pipe_number\n"); > p.fs.parent_nr = strtoul(av[0], &end, 0); > ac--; av++; > break; > > default: >! errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]); > } > } > if (do_pipe == 1) { > if (p.pipe_nr == 0) >! errx(EX_DATAERR, "pipe_nr must be > 0"); > if (p.delay > 10000) >! errx(EX_DATAERR, "delay must be < 10000"); > } else { /* do_pipe == 2, queue */ > if (p.fs.parent_nr == 0) >! errx(EX_DATAERR, "pipe must be > 0"); > if (p.fs.weight >100) >! errx(EX_DATAERR, "weight must be <= 100"); > } > if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) { > if (p.fs.qsize > 1024*1024) >! errx(EX_DATAERR, "queue size must be < 1MB"); > } else { > if (p.fs.qsize > 100) >! errx(EX_DATAERR, "2 <= queue size <= 100"); > } > if (p.fs.flags_fs & DN_IS_RED) { > size_t len; >--- 3562,3594 ---- > > case TOK_PIPE: > if (do_pipe == 1) >! return my_errx(EX_DATAERR,"pipe only valid for queues"); > NEED1("pipe needs pipe_number\n"); > p.fs.parent_nr = strtoul(av[0], &end, 0); > ac--; av++; > break; > > default: >! return my_errx(EX_DATAERR, "unrecognised option ``%s''", av[-1]); > } > } > if (do_pipe == 1) { > if (p.pipe_nr == 0) >! return my_errx(EX_DATAERR, "pipe_nr must be > 0"); > if (p.delay > 10000) >! return my_errx(EX_DATAERR, "delay must be < 10000"); > } else { /* do_pipe == 2, queue */ > if (p.fs.parent_nr == 0) >! return my_errx(EX_DATAERR, "pipe must be > 0"); > if (p.fs.weight >100) >! return my_errx(EX_DATAERR, "weight must be <= 100"); > } > if (p.fs.flags_fs & DN_QSIZE_IS_BYTES) { > if (p.fs.qsize > 1024*1024) >! return my_errx(EX_DATAERR, "queue size must be < 1MB"); > } else { > if (p.fs.qsize > 100) >! return my_errx(EX_DATAERR, "2 <= queue size <= 100"); > } > if (p.fs.flags_fs & DN_IS_RED) { > size_t len; >*************** >*** 3488,3522 **** > int t; > > if (p.fs.min_th >= p.fs.max_th) >! errx(EX_DATAERR, "min_th %d must be < than max_th %d", > p.fs.min_th, p.fs.max_th); > if (p.fs.max_th == 0) >! errx(EX_DATAERR, "max_th must be > 0"); > > len = sizeof(int); > if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth", > &lookup_depth, &len, NULL, 0) == -1) > >! errx(1, "sysctlbyname(\"%s\")", > "net.inet.ip.dummynet.red_lookup_depth"); > if (lookup_depth == 0) >! errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth" > " must be greater than zero"); > > len = sizeof(int); > if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size", > &avg_pkt_size, &len, NULL, 0) == -1) > >! errx(1, "sysctlbyname(\"%s\")", > "net.inet.ip.dummynet.red_avg_pkt_size"); > if (avg_pkt_size == 0) >! errx(EX_DATAERR, > "net.inet.ip.dummynet.red_avg_pkt_size must" > " be greater than zero"); > > len = sizeof(struct clockinfo); > if (sysctlbyname("kern.clockrate", &ck, &len, NULL, 0) == -1) >! errx(1, "sysctlbyname(\"%s\")", "kern.clockrate"); > > /* > * Ticks needed for sending a medium-sized packet. >--- 3598,3632 ---- > int t; > > if (p.fs.min_th >= p.fs.max_th) >! return my_errx(EX_DATAERR, "min_th %d must be < than max_th %d", > p.fs.min_th, p.fs.max_th); > if (p.fs.max_th == 0) >! return my_errx(EX_DATAERR, "max_th must be > 0"); > > len = sizeof(int); > if (sysctlbyname("net.inet.ip.dummynet.red_lookup_depth", > &lookup_depth, &len, NULL, 0) == -1) > >! return my_errx(1, "sysctlbyname(\"%s\")", > "net.inet.ip.dummynet.red_lookup_depth"); > if (lookup_depth == 0) >! return my_errx(EX_DATAERR, "net.inet.ip.dummynet.red_lookup_depth" > " must be greater than zero"); > > len = sizeof(int); > if (sysctlbyname("net.inet.ip.dummynet.red_avg_pkt_size", > &avg_pkt_size, &len, NULL, 0) == -1) > >! return my_errx(1, "sysctlbyname(\"%s\")", > "net.inet.ip.dummynet.red_avg_pkt_size"); > if (avg_pkt_size == 0) >! return my_errx(EX_DATAERR, > "net.inet.ip.dummynet.red_avg_pkt_size must" > " be greater than zero"); > > len = sizeof(struct clockinfo); > if (sysctlbyname("kern.clockrate", &ck, &len, NULL, 0) == -1) >! return my_errx(1, "sysctlbyname(\"%s\")", "kern.clockrate"); > > /* > * Ticks needed for sending a medium-sized packet. >*************** >*** 3549,3555 **** > } > i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p); > if (i) >! err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE"); > } > > static void >--- 3659,3666 ---- > } > i = do_cmd(IP_DUMMYNET_CONFIGURE, &p, sizeof p); > if (i) >! return my_err(1, "setsockopt(%s)", "IP_DUMMYNET_CONFIGURE"); >! return EX_OK; > } > > static void >*************** >*** 3601,3607 **** > /* > * Takes arguments and copies them into a comment > */ >! static void > fill_comment(ipfw_insn *cmd, int ac, char **av) > { > int i, l; >--- 3712,3718 ---- > /* > * Takes arguments and copies them into a comment > */ >! static int > fill_comment(ipfw_insn *cmd, int ac, char **av) > { > int i, l; >*************** >*** 3614,3622 **** > for (i = 0, l = 0; i < ac; i++) > l += strlen(av[i]) + 1; > if (l == 0) >! return; > if (l > 84) >! errx(EX_DATAERR, > "comment too long (max 80 chars)"); > l = 1 + (l+3)/4; > cmd->len = (cmd->len & (F_NOT | F_OR)) | l; >--- 3725,3733 ---- > for (i = 0, l = 0; i < ac; i++) > l += strlen(av[i]) + 1; > if (l == 0) >! return EX_OK; > if (l > 84) >! return my_errx(EX_DATAERR, > "comment too long (max 80 chars)"); > l = 1 + (l+3)/4; > cmd->len = (cmd->len & (F_NOT | F_OR)) | l; >*************** >*** 3626,3631 **** >--- 3737,3743 ---- > *p++ = ' '; > } > *(--p) = '\0'; >+ return EX_OK; > } > > /* >*************** >*** 3640,3645 **** >--- 3752,3759 ---- > cmd->arg1 = arg; > } > >+ #define INV_INSN ((ipfw_insn *)(-1)) >+ > /* > * Fetch and add the MAC address and type, with masks. This generates one or > * two microinstructions, and returns the pointer to the last one. >*************** >*** 3649,3656 **** > { > ipfw_insn_mac *mac; > >! if (ac < 2) >! errx(EX_DATAERR, "MAC dst src"); > > cmd->opcode = O_MACADDR2; > cmd->len = (cmd->len & (F_NOT | F_OR)) | F_INSN_SIZE(ipfw_insn_mac); >--- 3763,3772 ---- > { > ipfw_insn_mac *mac; > >! if (ac < 2) { >! my_errx(EX_DATAERR, "MAC dst src"); >! return INV_INSN; >! } > > cmd->opcode = O_MACADDR2; > cmd->len = (cmd->len & (F_NOT | F_OR)) | F_INSN_SIZE(ipfw_insn_mac); >*************** >*** 3664,3671 **** > static ipfw_insn * > add_mactype(ipfw_insn *cmd, int ac, char *av) > { >! if (ac < 1) >! errx(EX_DATAERR, "missing MAC type"); > if (strcmp(av, "any") != 0) { /* we have a non-null type */ > fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE); > cmd->opcode = O_MAC_TYPE; >--- 3780,3789 ---- > static ipfw_insn * > add_mactype(ipfw_insn *cmd, int ac, char *av) > { >! if (ac < 1) { >! my_errx(EX_DATAERR, "missing MAC type"); >! return INV_INSN; >! } > if (strcmp(av, "any") != 0) { /* we have a non-null type */ > fill_newports((ipfw_insn_u16 *)cmd, av, IPPROTO_ETHERTYPE); > cmd->opcode = O_MAC_TYPE; >*************** >*** 3738,3744 **** > static ipfw_insn * > add_srcip(ipfw_insn *cmd, char *av) > { >! fill_ip((ipfw_insn_ip *)cmd, av); > if (cmd->opcode == O_IP_DST_SET) /* set */ > cmd->opcode = O_IP_SRC_SET; > else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */ >--- 3856,3863 ---- > static ipfw_insn * > add_srcip(ipfw_insn *cmd, char *av) > { >! if(fill_ip((ipfw_insn_ip *)cmd, av) != EX_OK) >! return NULL; > if (cmd->opcode == O_IP_DST_SET) /* set */ > cmd->opcode = O_IP_SRC_SET; > else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */ >*************** >*** 3755,3761 **** > static ipfw_insn * > add_dstip(ipfw_insn *cmd, char *av) > { >! fill_ip((ipfw_insn_ip *)cmd, av); > if (cmd->opcode == O_IP_DST_SET) /* set */ > ; > else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */ >--- 3874,3881 ---- > static ipfw_insn * > add_dstip(ipfw_insn *cmd, char *av) > { >! if(fill_ip((ipfw_insn_ip *)cmd, av) != EX_OK) >! return NULL; > if (cmd->opcode == O_IP_DST_SET) /* set */ > ; > else if (cmd->opcode == O_IP_DST_LOOKUP) /* table */ >*************** >*** 3846,3852 **** > * various match patterns, log/altq actions, and the actual action. > * > */ >! static void > add(int ac, char *av[]) > { > /* >--- 3966,3972 ---- > * various match patterns, log/altq actions, and the actual action. > * > */ >! static int > add(int ac, char *av[]) > { > /* >*************** >*** 3870,3875 **** >--- 3990,3996 ---- > size_t len; > > int i; >+ int r; > > int open_par = 0; /* open parenthesis ( */ > >*************** >*** 3898,3905 **** > /* [set N] -- set number (0..RESVD_SET), optional */ > if (ac > 1 && _substrcmp(*av, "set") == 0) { > int set = strtoul(av[1], NULL, 10); >! if (set < 0 || set > RESVD_SET) >! errx(EX_DATAERR, "illegal set %s", av[1]); > rule->set = set; > av += 2; ac -= 2; > } >--- 4019,4028 ---- > /* [set N] -- set number (0..RESVD_SET), optional */ > if (ac > 1 && _substrcmp(*av, "set") == 0) { > int set = strtoul(av[1], NULL, 10); >! if (set < 0 || set > RESVD_SET) { >! warn("illegal set %s", av[1]); >! return EX_DATAERR; >! } > rule->set = set; > av += 2; ac -= 2; > } >*************** >*** 3909,3915 **** > match_prob = strtod(av[1], NULL); > > if (match_prob <= 0 || match_prob > 1) >! errx(EX_DATAERR, "illegal match prob. %s", av[1]); > av += 2; ac -= 2; > } > >--- 4032,4038 ---- > match_prob = strtod(av[1], NULL); > > if (match_prob <= 0 || match_prob > 1) >! return my_errx(EX_DATAERR, "illegal match prob. %s", av[1]); > av += 2; ac -= 2; > } > >*************** >*** 3951,3964 **** > case TOK_UNREACH: > action->opcode = O_REJECT; > NEED1("missing reject code"); >! fill_reject_code(&action->arg1, *av); > ac--; av++; > break; > > case TOK_UNREACH6: > action->opcode = O_UNREACH6; > NEED1("missing unreach code"); >! fill_unreach6_code(&action->arg1, *av); > ac--; av++; > break; > >--- 4074,4093 ---- > case TOK_UNREACH: > action->opcode = O_REJECT; > NEED1("missing reject code"); >! r = fill_reject_code(&action->arg1, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > break; > > case TOK_UNREACH6: > action->opcode = O_UNREACH6; > NEED1("missing unreach code"); >! r = fill_unreach6_code(&action->arg1, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > break; > >*************** >*** 3990,4000 **** > action->opcode = O_TEE; > chkarg: > if (!ac) >! errx(EX_USAGE, "missing argument for %s", *(av - 1)); > if (isdigit(**av)) { > action->arg1 = strtoul(*av, NULL, 10); > if (action->arg1 <= 0 || action->arg1 >= IP_FW_TABLEARG) >! errx(EX_DATAERR, "illegal argument for %s", > *(av - 1)); > } else if (_substrcmp(*av, TABLEARG) == 0) { > action->arg1 = IP_FW_TABLEARG; >--- 4119,4129 ---- > action->opcode = O_TEE; > chkarg: > if (!ac) >! return my_errx(EX_USAGE, "missing argument for %s", *(av - 1)); > if (isdigit(**av)) { > action->arg1 = strtoul(*av, NULL, 10); > if (action->arg1 <= 0 || action->arg1 >= IP_FW_TABLEARG) >! return my_errx(EX_DATAERR, "illegal argument for %s", > *(av - 1)); > } else if (_substrcmp(*av, TABLEARG) == 0) { > action->arg1 = IP_FW_TABLEARG; >*************** >*** 4005,4013 **** > if (s != NULL) > action->arg1 = ntohs(s->s_port); > else >! errx(EX_DATAERR, "illegal divert/tee port"); > } else >! errx(EX_DATAERR, "illegal argument for %s", *(av - 1)); > ac--; av++; > break; > >--- 4134,4142 ---- > if (s != NULL) > action->arg1 = ntohs(s->s_port); > else >! return my_errx(EX_DATAERR, "illegal divert/tee port"); > } else >! return my_errx(EX_DATAERR, "illegal argument for %s", *(av - 1)); > ac--; av++; > break; > >*************** >*** 4033,4039 **** > *(s++) = '\0'; > i = strtoport(s, &end, 0 /* base */, 0 /* proto */); > if (s == end) >! errx(EX_DATAERR, > "illegal forwarding port ``%s''", s); > p->sa.sin_port = (u_short)i; > } >--- 4162,4168 ---- > *(s++) = '\0'; > i = strtoport(s, &end, 0 /* base */, 0 /* proto */); > if (s == end) >! return my_errx(EX_DATAERR, > "illegal forwarding port ``%s''", s); > p->sa.sin_port = (u_short)i; > } >*************** >*** 4049,4055 **** > break; > > default: >! errx(EX_DATAERR, "invalid action %s\n", av[-1]); > } > action = next_cmd(action); > >--- 4178,4184 ---- > break; > > default: >! return my_errx(EX_DATAERR, "invalid action %s\n", av[-1]); > } > action = next_cmd(action); > >*************** >*** 4069,4075 **** > int l; > > if (have_log) >! errx(EX_DATAERR, > "log cannot be specified more than once"); > have_log = (ipfw_insn *)c; > cmd->len = F_INSN_SIZE(ipfw_insn_log); >--- 4198,4204 ---- > int l; > > if (have_log) >! return my_errx(EX_DATAERR, > "log cannot be specified more than once"); > have_log = (ipfw_insn *)c; > cmd->len = F_INSN_SIZE(ipfw_insn_log); >*************** >*** 4079,4085 **** > NEED1("logamount requires argument"); > l = atoi(*av); > if (l < 0) >! errx(EX_DATAERR, > "logamount must be positive"); > c->max_log = l; > ac--; av++; >--- 4208,4214 ---- > NEED1("logamount requires argument"); > l = atoi(*av); > if (l < 0) >! return my_errx(EX_DATAERR, > "logamount must be positive"); > c->max_log = l; > ac--; av++; >*************** >*** 4087,4093 **** > len = sizeof(c->max_log); > if (sysctlbyname("net.inet.ip.fw.verbose_limit", > &c->max_log, &len, NULL, 0) == -1) >! errx(1, "sysctlbyname(\"%s\")", > "net.inet.ip.fw.verbose_limit"); > } > } >--- 4216,4222 ---- > len = sizeof(c->max_log); > if (sysctlbyname("net.inet.ip.fw.verbose_limit", > &c->max_log, &len, NULL, 0) == -1) >! return my_errx(1, "sysctlbyname(\"%s\")", > "net.inet.ip.fw.verbose_limit"); > } > } >*************** >*** 4099,4110 **** > > NEED1("missing altq queue name"); > if (have_altq) >! errx(EX_DATAERR, > "altq cannot be specified more than once"); > have_altq = (ipfw_insn *)a; > cmd->len = F_INSN_SIZE(ipfw_insn_altq); > cmd->opcode = O_ALTQ; >! fill_altq_qid(&a->qid, *av); > ac--; av++; > } > break; >--- 4228,4242 ---- > > NEED1("missing altq queue name"); > if (have_altq) >! return my_errx(EX_DATAERR, > "altq cannot be specified more than once"); > have_altq = (ipfw_insn *)a; > cmd->len = F_INSN_SIZE(ipfw_insn_altq); > cmd->opcode = O_ALTQ; >! r = fill_altq_qid(&a->qid, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > } > break; >*************** >*** 4114,4120 **** > uint16_t tag; > > if (have_tag) >! errx(EX_USAGE, "tag and untag cannot be " > "specified more than once"); > GET_UINT_ARG(tag, 1, 65534, i, rule_action_params); > have_tag = cmd; >--- 4246,4252 ---- > uint16_t tag; > > if (have_tag) >! return my_errx(EX_USAGE, "tag and untag cannot be " > "specified more than once"); > GET_UINT_ARG(tag, 1, 65534, i, rule_action_params); > have_tag = cmd; >*************** >*** 4124,4130 **** > } > > default: >! abort(); > } > cmd = next_cmd(cmd); > } >--- 4256,4263 ---- > } > > default: >! //abort(); >! return EX_SOFTWARE; > } > cmd = next_cmd(cmd); > } >*************** >*** 4135,4141 **** > #define OR_START(target) \ > if (ac && (*av[0] == '(' || *av[0] == '{')) { \ > if (open_par) \ >! errx(EX_USAGE, "nested \"(\" not allowed\n"); \ > prev = NULL; \ > open_par = 1; \ > if ( (av[0])[1] == '\0') { \ >--- 4268,4274 ---- > #define OR_START(target) \ > if (ac && (*av[0] == '(' || *av[0] == '{')) { \ > if (open_par) \ >! return my_errx(EX_USAGE, "nested \"(\" not allowed\n"); \ > prev = NULL; \ > open_par = 1; \ > if ( (av[0])[1] == '\0') { \ >*************** >*** 4155,4167 **** > open_par = 0; \ > ac--; av++; \ > } else \ >! errx(EX_USAGE, "missing \")\"\n"); \ > } > > #define NOT_BLOCK \ > if (ac && _substrcmp(*av, "not") == 0) { \ > if (cmd->len & F_NOT) \ >! errx(EX_USAGE, "double \"not\" not allowed\n"); \ > cmd->len |= F_NOT; \ > ac--; av++; \ > } >--- 4288,4300 ---- > open_par = 0; \ > ac--; av++; \ > } else \ >! return my_errx(EX_USAGE, "missing \")\"\n"); \ > } > > #define NOT_BLOCK \ > if (ac && _substrcmp(*av, "not") == 0) { \ > if (cmd->len & F_NOT) \ >! return my_errx(EX_USAGE, "double \"not\" not allowed\n"); \ > cmd->len |= F_NOT; \ > ac--; av++; \ > } >*************** >*** 4169,4175 **** > #define OR_BLOCK(target) \ > if (ac && _substrcmp(*av, "or") == 0) { \ > if (prev == NULL || open_par == 0) \ >! errx(EX_DATAERR, "invalid OR block"); \ > prev->len |= F_OR; \ > ac--; av++; \ > goto target; \ >--- 4302,4308 ---- > #define OR_BLOCK(target) \ > if (ac && _substrcmp(*av, "or") == 0) { \ > if (prev == NULL || open_par == 0) \ >! return my_errx(EX_DATAERR, "invalid OR block"); \ > prev->len |= F_OR; \ > ac--; av++; \ > goto target; \ >*************** >*** 4188,4201 **** > NEED1("missing protocol"); > if (_substrcmp(*av, "MAC") == 0 || > _substrcmp(*av, "mac") == 0) { > ac--; av++; /* the "MAC" keyword */ >! add_mac(cmd, ac, av); /* exits in case of errors */ > cmd = next_cmd(cmd); > ac -= 2; av += 2; /* dst-mac and src-mac */ > NOT_BLOCK; > NEED1("missing mac type"); >! if (add_mactype(cmd, ac, av[0])) > cmd = next_cmd(cmd); > ac--; av++; /* any or mac-type */ > goto read_options; > } >--- 4321,4345 ---- > NEED1("missing protocol"); > if (_substrcmp(*av, "MAC") == 0 || > _substrcmp(*av, "mac") == 0) { >+ >+ ipfw_insn * insn; >+ > ac--; av++; /* the "MAC" keyword */ >! insn = add_mac(cmd, ac, av); /* exits in case of errors if ignore_errors=0 */ >! if(insn == INV_INSN || !insn) { >! return EX_DATAERR; >! } > cmd = next_cmd(cmd); > ac -= 2; av += 2; /* dst-mac and src-mac */ > NOT_BLOCK; > NEED1("missing mac type"); >! insn = add_mactype(cmd, ac, av[0]); >! if(insn == INV_INSN) { >! return EX_DATAERR; >! } >! if(insn) { > cmd = next_cmd(cmd); >+ } > ac--; av++; /* any or mac-type */ > goto read_options; > } >*************** >*** 4214,4220 **** > cmd = next_cmd(cmd); > } > } else if (first_cmd != cmd) { >! errx(EX_DATAERR, "invalid protocol ``%s''", *av); > } else > goto read_options; > OR_BLOCK(get_proto); >--- 4358,4364 ---- > cmd = next_cmd(cmd); > } > } else if (first_cmd != cmd) { >! return my_errx(EX_DATAERR, "invalid protocol ``%s''", *av); > } else > goto read_options; > OR_BLOCK(get_proto); >*************** >*** 4223,4229 **** > * "from", mandatory > */ > if (!ac || _substrcmp(*av, "from") != 0) >! errx(EX_USAGE, "missing ``from''"); > ac--; av++; > > /* >--- 4367,4373 ---- > * "from", mandatory > */ > if (!ac || _substrcmp(*av, "from") != 0) >! return my_errx(EX_USAGE, "missing ``from''"); > ac--; av++; > > /* >*************** >*** 4239,4245 **** > cmd = next_cmd(cmd); > } > } else >! errx(EX_USAGE, "bad source address %s", *av); > OR_BLOCK(source_ip); > > /* >--- 4383,4389 ---- > cmd = next_cmd(cmd); > } > } else >! return my_errx(EX_USAGE, "bad source address %s", *av); > OR_BLOCK(source_ip); > > /* >*************** >*** 4259,4265 **** > * "to", mandatory > */ > if (!ac || _substrcmp(*av, "to") != 0) >! errx(EX_USAGE, "missing ``to''"); > av++; ac--; > > /* >--- 4403,4409 ---- > * "to", mandatory > */ > if (!ac || _substrcmp(*av, "to") != 0) >! return my_errx(EX_USAGE, "missing ``to''"); > av++; ac--; > > /* >*************** >*** 4275,4281 **** > cmd = next_cmd(cmd); > } > } else >! errx( EX_USAGE, "bad destination address %s", *av); > OR_BLOCK(dest_ip); > > /* >--- 4419,4425 ---- > cmd = next_cmd(cmd); > } > } else >! return my_errx( EX_USAGE, "bad destination address %s", *av); > OR_BLOCK(dest_ip); > > /* >*************** >*** 4303,4315 **** > while (ac) { > char *s; > ipfw_insn_u32 *cmd32; /* alias for cmd */ > > s = *av; > cmd32 = (ipfw_insn_u32 *)cmd; > > if (*s == '!') { /* alternate syntax for NOT */ > if (cmd->len & F_NOT) >! errx(EX_USAGE, "double \"not\" not allowed\n"); > cmd->len = F_NOT; > s++; > } >--- 4447,4460 ---- > while (ac) { > char *s; > ipfw_insn_u32 *cmd32; /* alias for cmd */ >+ ipfw_insn * insn; > > s = *av; > cmd32 = (ipfw_insn_u32 *)cmd; > > if (*s == '!') { /* alternate syntax for NOT */ > if (cmd->len & F_NOT) >! return my_errx(EX_USAGE, "double \"not\" not allowed\n"); > cmd->len = F_NOT; > s++; > } >*************** >*** 4318,4342 **** > switch(i) { > case TOK_NOT: > if (cmd->len & F_NOT) >! errx(EX_USAGE, "double \"not\" not allowed\n"); > cmd->len = F_NOT; > break; > > case TOK_OR: > if (open_par == 0 || prev == NULL) >! errx(EX_USAGE, "invalid \"or\" block\n"); > prev->len |= F_OR; > break; > > case TOK_STARTBRACE: > if (open_par) >! errx(EX_USAGE, "+nested \"(\" not allowed\n"); > open_par = 1; > break; > > case TOK_ENDBRACE: > if (!open_par) >! errx(EX_USAGE, "+missing \")\"\n"); > open_par = 0; > prev = NULL; > break; >--- 4463,4487 ---- > switch(i) { > case TOK_NOT: > if (cmd->len & F_NOT) >! return my_errx(EX_USAGE, "double \"not\" not allowed\n"); > cmd->len = F_NOT; > break; > > case TOK_OR: > if (open_par == 0 || prev == NULL) >! return my_errx(EX_USAGE, "invalid \"or\" block\n"); > prev->len |= F_OR; > break; > > case TOK_STARTBRACE: > if (open_par) >! return my_errx(EX_USAGE, "+nested \"(\" not allowed\n"); > open_par = 1; > break; > > case TOK_ENDBRACE: > if (!open_par) >! return my_errx(EX_USAGE, "+missing \")\"\n"); > open_par = 0; > prev = NULL; > break; >*************** >*** 4375,4381 **** > case TOK_VIA: > NEED1("recv, xmit, via require interface name" > " or address"); >! fill_iface((ipfw_insn_if *)cmd, av[0]); > ac--; av++; > if (F_LEN(cmd) == 0) /* not a valid address */ > break; >--- 4520,4529 ---- > case TOK_VIA: > NEED1("recv, xmit, via require interface name" > " or address"); >! r = fill_iface((ipfw_insn_if *)cmd, av[0]); >! if(r != EX_OK) >! return r; >! > ac--; av++; > if (F_LEN(cmd) == 0) /* not a valid address */ > break; >*************** >*** 4389,4401 **** > > case TOK_ICMPTYPES: > NEED1("icmptypes requires list of types"); >! fill_icmptypes((ipfw_insn_u32 *)cmd, *av); > av++; ac--; > break; > > case TOK_ICMP6TYPES: > NEED1("icmptypes requires list of types"); >! fill_icmp6types((ipfw_insn_icmp6 *)cmd, *av); > av++; ac--; > break; > >--- 4537,4555 ---- > > case TOK_ICMPTYPES: > NEED1("icmptypes requires list of types"); >! r = fill_icmptypes((ipfw_insn_u32 *)cmd, *av); >! if(r != EX_OK) >! return r; >! > av++; ac--; > break; > > case TOK_ICMP6TYPES: > NEED1("icmptypes requires list of types"); >! r = fill_icmp6types((ipfw_insn_icmp6 *)cmd, *av); >! if(r != EX_OK) >! return r; >! > av++; ac--; > break; > >*************** >*** 4403,4409 **** > NEED1("ipttl requires TTL"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_IPTTL)) >! errx(EX_DATAERR, "invalid ipttl %s", *av); > } else > fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0)); > ac--; av++; >--- 4557,4563 ---- > NEED1("ipttl requires TTL"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_IPTTL)) >! return my_errx(EX_DATAERR, "invalid ipttl %s", *av); > } else > fill_cmd(cmd, O_IPTTL, 0, strtoul(*av, NULL, 0)); > ac--; av++; >*************** >*** 4413,4419 **** > NEED1("ipid requires id"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_IPID)) >! errx(EX_DATAERR, "invalid ipid %s", *av); > } else > fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0)); > ac--; av++; >--- 4567,4573 ---- > NEED1("ipid requires id"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_IPID)) >! return my_errx(EX_DATAERR, "invalid ipid %s", *av); > } else > fill_cmd(cmd, O_IPID, 0, strtoul(*av, NULL, 0)); > ac--; av++; >*************** >*** 4423,4429 **** > NEED1("iplen requires length"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_IPLEN)) >! errx(EX_DATAERR, "invalid ip len %s", *av); > } else > fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0)); > ac--; av++; >--- 4577,4583 ---- > NEED1("iplen requires length"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_IPLEN)) >! return my_errx(EX_DATAERR, "invalid ip len %s", *av); > } else > fill_cmd(cmd, O_IPLEN, 0, strtoul(*av, NULL, 0)); > ac--; av++; >*************** >*** 4444,4456 **** > > case TOK_IPOPTS: > NEED1("missing argument for ipoptions"); >! fill_flags(cmd, O_IPOPT, f_ipopts, *av); > ac--; av++; > break; > > case TOK_IPTOS: > NEED1("missing argument for iptos"); >! fill_flags(cmd, O_IPTOS, f_iptos, *av); > ac--; av++; > break; > >--- 4598,4616 ---- > > case TOK_IPOPTS: > NEED1("missing argument for ipoptions"); >! r = fill_flags(cmd, O_IPOPT, f_ipopts, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > break; > > case TOK_IPTOS: > NEED1("missing argument for iptos"); >! r = fill_flags(cmd, O_IPTOS, f_iptos, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > break; > >*************** >*** 4465,4471 **** > uid = strtoul(*av, &end, 0); > pwd = (*end == '\0') ? getpwuid(uid) : getpwnam(*av); > if (pwd == NULL) >! errx(EX_DATAERR, "uid \"%s\" nonexistent", *av); > cmd32->d[0] = pwd->pw_uid; > cmd->len |= F_INSN_SIZE(ipfw_insn_u32); > ac--; av++; >--- 4625,4631 ---- > uid = strtoul(*av, &end, 0); > pwd = (*end == '\0') ? getpwuid(uid) : getpwnam(*av); > if (pwd == NULL) >! return my_errx(EX_DATAERR, "uid \"%s\" nonexistent", *av); > cmd32->d[0] = pwd->pw_uid; > cmd->len |= F_INSN_SIZE(ipfw_insn_u32); > ac--; av++; >*************** >*** 4483,4489 **** > gid = strtoul(*av, &end, 0); > grp = (*end == '\0') ? getgrgid(gid) : getgrnam(*av); > if (grp == NULL) >! errx(EX_DATAERR, "gid \"%s\" nonexistent", *av); > cmd32->d[0] = grp->gr_gid; > cmd->len |= F_INSN_SIZE(ipfw_insn_u32); > ac--; av++; >--- 4643,4649 ---- > gid = strtoul(*av, &end, 0); > grp = (*end == '\0') ? getgrgid(gid) : getgrnam(*av); > if (grp == NULL) >! return my_errx(EX_DATAERR, "gid \"%s\" nonexistent", *av); > cmd32->d[0] = grp->gr_gid; > cmd->len |= F_INSN_SIZE(ipfw_insn_u32); > ac--; av++; >*************** >*** 4499,4505 **** > cmd->opcode = O_JAIL; > jid = (int)strtol(*av, &end, 0); > if (jid < 0 || *end != '\0') >! errx(EX_DATAERR, "jail requires prison ID"); > cmd32->d[0] = (uint32_t)jid; > cmd->len |= F_INSN_SIZE(ipfw_insn_u32); > ac--; av++; >--- 4659,4665 ---- > cmd->opcode = O_JAIL; > jid = (int)strtol(*av, &end, 0); > if (jid < 0 || *end != '\0') >! return my_errx(EX_DATAERR, "jail requires prison ID"); > cmd32->d[0] = (uint32_t)jid; > cmd->len |= F_INSN_SIZE(ipfw_insn_u32); > ac--; av++; >*************** >*** 4519,4525 **** > NEED1("tcpdatalen requires length"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_TCPDATALEN)) >! errx(EX_DATAERR, "invalid tcpdata len %s", *av); > } else > fill_cmd(cmd, O_TCPDATALEN, 0, > strtoul(*av, NULL, 0)); >--- 4679,4685 ---- > NEED1("tcpdatalen requires length"); > if (strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_TCPDATALEN)) >! return my_errx(EX_DATAERR, "invalid tcpdata len %s", *av); > } else > fill_cmd(cmd, O_TCPDATALEN, 0, > strtoul(*av, NULL, 0)); >*************** >*** 4528,4534 **** > > case TOK_TCPOPTS: > NEED1("missing argument for tcpoptions"); >! fill_flags(cmd, O_TCPOPTS, f_tcpopts, *av); > ac--; av++; > break; > >--- 4688,4697 ---- > > case TOK_TCPOPTS: > NEED1("missing argument for tcpoptions"); >! r = fill_flags(cmd, O_TCPOPTS, f_tcpopts, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > break; > >*************** >*** 4551,4566 **** > case TOK_TCPFLAGS: > NEED1("missing argument for tcpflags"); > cmd->opcode = O_TCPFLAGS; >! fill_flags(cmd, O_TCPFLAGS, f_tcpflags, *av); > ac--; av++; > break; > > case TOK_KEEPSTATE: > if (open_par) >! errx(EX_USAGE, "keep-state cannot be part " > "of an or block"); > if (have_state) >! errx(EX_USAGE, "only one of keep-state " > "and limit is allowed"); > have_state = cmd; > fill_cmd(cmd, O_KEEP_STATE, 0, 0); >--- 4714,4732 ---- > case TOK_TCPFLAGS: > NEED1("missing argument for tcpflags"); > cmd->opcode = O_TCPFLAGS; >! r = fill_flags(cmd, O_TCPFLAGS, f_tcpflags, *av); >! if(r != EX_OK) >! return r; >! > ac--; av++; > break; > > case TOK_KEEPSTATE: > if (open_par) >! return my_errx(EX_USAGE, "keep-state cannot be part " > "of an or block"); > if (have_state) >! return my_errx(EX_USAGE, "only one of keep-state " > "and limit is allowed"); > have_state = cmd; > fill_cmd(cmd, O_KEEP_STATE, 0, 0); >*************** >*** 4571,4580 **** > int val; > > if (open_par) >! errx(EX_USAGE, > "limit cannot be part of an or block"); > if (have_state) >! errx(EX_USAGE, "only one of keep-state and" > "limit is allowed"); > have_state = cmd; > >--- 4737,4746 ---- > int val; > > if (open_par) >! return my_errx(EX_USAGE, > "limit cannot be part of an or block"); > if (have_state) >! return my_errx(EX_USAGE, "only one of keep-state and" > "limit is allowed"); > have_state = cmd; > >*************** >*** 4590,4596 **** > } > > if (c->limit_mask == 0) >! errx(EX_USAGE, "limit: missing limit mask"); > > GET_UINT_ARG(c->conn_limit, 1, 65534, TOK_LIMIT, > rule_options); >--- 4756,4762 ---- > } > > if (c->limit_mask == 0) >! return my_errx(EX_USAGE, "limit: missing limit mask"); > > GET_UINT_ARG(c->conn_limit, 1, 65534, TOK_LIMIT, > rule_options); >*************** >*** 4604,4610 **** > if (add_proto(cmd, *av, &proto)) { > ac--; av++; > } else >! errx(EX_DATAERR, "invalid protocol ``%s''", > *av); > break; > >--- 4770,4776 ---- > if (add_proto(cmd, *av, &proto)) { > ac--; av++; > } else >! return my_errx(EX_DATAERR, "invalid protocol ``%s''", > *av); > break; > >*************** >*** 4642,4648 **** > add_ports(cmd, *av, proto, O_IP_SRCPORT)) { > ac--; av++; > } else >! errx(EX_DATAERR, "invalid source port %s", *av); > break; > > case TOK_DSTPORT: >--- 4808,4814 ---- > add_ports(cmd, *av, proto, O_IP_SRCPORT)) { > ac--; av++; > } else >! return my_errx(EX_DATAERR, "invalid source port %s", *av); > break; > > case TOK_DSTPORT: >*************** >*** 4651,4670 **** > add_ports(cmd, *av, proto, O_IP_DSTPORT)) { > ac--; av++; > } else >! errx(EX_DATAERR, "invalid destination port %s", > *av); > break; > > case TOK_MAC: >! if (add_mac(cmd, ac, av)) { > ac -= 2; av += 2; > } > break; > > case TOK_MACTYPE: > NEED1("missing mac type"); >! if (!add_mactype(cmd, ac, *av)) >! errx(EX_DATAERR, "invalid mac type %s", *av); > ac--; av++; > break; > >--- 4817,4842 ---- > add_ports(cmd, *av, proto, O_IP_DSTPORT)) { > ac--; av++; > } else >! return my_errx(EX_DATAERR, "invalid destination port %s", > *av); > break; > > case TOK_MAC: >! insn = add_mac(cmd, ac, av); >! if(insn == INV_INSN) { >! return EX_DATAERR; >! } >! if(insn) { > ac -= 2; av += 2; > } > break; > > case TOK_MACTYPE: > NEED1("missing mac type"); >! insn = add_mactype(cmd, ac, *av); >! if(insn == INV_INSN || !insn) { >! return my_errx(EX_DATAERR, "invalid mac type %s", *av); >! } > ac--; av++; > break; > >*************** >*** 4693,4712 **** > break; > > case TOK_EXT6HDR: >! fill_ext6hdr( cmd, *av ); > ac--; av++; > break; > > case TOK_FLOWID: > if (proto != IPPROTO_IPV6 ) >! errx( EX_USAGE, "flow-id filter is active " > "only for ipv6 protocol\n"); > fill_flow6( (ipfw_insn_u32 *) cmd, *av ); > ac--; av++; > break; > > case TOK_COMMENT: >! fill_comment(cmd, ac, av); > av += ac; > ac = 0; > break; >--- 4865,4888 ---- > break; > > case TOK_EXT6HDR: >! r = fill_ext6hdr( cmd, *av ); >! if(r == -1) >! return EX_DATAERR; > ac--; av++; > break; > > case TOK_FLOWID: > if (proto != IPPROTO_IPV6 ) >! return my_errx( EX_USAGE, "flow-id filter is active " > "only for ipv6 protocol\n"); > fill_flow6( (ipfw_insn_u32 *) cmd, *av ); > ac--; av++; > break; > > case TOK_COMMENT: >! r = fill_comment(cmd, ac, av); >! if(r != EX_OK) >! return r; > av += ac; > ac = 0; > break; >*************** >*** 4714,4720 **** > case TOK_TAGGED: > if (ac > 0 && strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_TAGGED)) >! errx(EX_DATAERR, "tagged: invalid tag" > " list: %s", *av); > } > else { >--- 4890,4896 ---- > case TOK_TAGGED: > if (ac > 0 && strpbrk(*av, "-,")) { > if (!add_ports(cmd, *av, 0, O_TAGGED)) >! return my_errx(EX_DATAERR, "tagged: invalid tag" > " list: %s", *av); > } > else { >*************** >*** 4728,4734 **** > break; > > default: >! errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s); > } > if (F_LEN(cmd) > 0) { /* prepare to advance */ > prev = cmd; >--- 4904,4910 ---- > break; > > default: >! return my_errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s); > } > if (F_LEN(cmd) > 0) { /* prepare to advance */ > prev = cmd; >*************** >*** 4821,4833 **** > > rule->cmd_len = (uint32_t *)dst - (uint32_t *)(rule->cmd); > i = (char *)dst - (char *)rule; >! if (do_cmd(IP_FW_ADD, rule, (uintptr_t)&i) == -1) >! err(EX_UNAVAILABLE, "getsockopt(%s)", "IP_FW_ADD"); > if (!do_quiet) > show_ipfw(rule, 0, 0); > } > >! static void > zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */) > { > int rulenum; >--- 4997,5013 ---- > > rule->cmd_len = (uint32_t *)dst - (uint32_t *)(rule->cmd); > i = (char *)dst - (char *)rule; >! if (do_cmd(IP_FW_ADD, rule, (uintptr_t)&i) == -1) { >! warn("getsockopt(%s)", "IP_FW_ADD"); >! return EX_UNAVAILABLE; >! } > if (!do_quiet) > show_ipfw(rule, 0, 0); >+ >+ return EX_OK; > } > >! static int > zero(int ac, char *av[], int optname /* IP_FW_ZERO or IP_FW_RESETLOG */) > { > int rulenum; >*************** >*** 4839,4850 **** > if (!ac) { > /* clear all entries */ > if (do_cmd(optname, NULL, 0) < 0) >! err(EX_UNAVAILABLE, "setsockopt(IP_FW_%s)", name); > if (!do_quiet) > printf("%s.\n", optname == IP_FW_ZERO ? > "Accounting cleared":"Logging counts reset"); > >! return; > } > > while (ac) { >--- 5019,5030 ---- > if (!ac) { > /* clear all entries */ > if (do_cmd(optname, NULL, 0) < 0) >! return my_err(EX_UNAVAILABLE, "setsockopt(IP_FW_%s)", name); > if (!do_quiet) > printf("%s.\n", optname == IP_FW_ZERO ? > "Accounting cleared":"Logging counts reset"); > >! return EX_OK; > } > > while (ac) { >*************** >*** 4862,4875 **** > optname == IP_FW_ZERO ? > "cleared" : "logging count reset"); > } else { >! errx(EX_USAGE, "invalid rule number ``%s''", *av); > } > } >! if (failed != EX_OK) > exit(failed); > } > >! static void > flush(int force) > { > int cmd = do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH; >--- 5042,5056 ---- > optname == IP_FW_ZERO ? > "cleared" : "logging count reset"); > } else { >! return my_errx(EX_USAGE, "invalid rule number ``%s''", *av); > } > } >! if (failed != EX_OK && !ignore_errors) > exit(failed); >+ return EX_OK; > } > >! static int > flush(int force) > { > int cmd = do_pipe ? IP_DUMMYNET_FLUSH : IP_FW_FLUSH; >*************** >*** 4890,4899 **** > return; > } > if (do_cmd(cmd, NULL, 0) < 0) >! err(EX_UNAVAILABLE, "setsockopt(IP_%s_FLUSH)", > do_pipe ? "DUMMYNET" : "FW"); > if (!do_quiet) > printf("Flushed all %s.\n", do_pipe ? "pipes" : "rules"); > } > > /* >--- 5071,5081 ---- > return; > } > if (do_cmd(cmd, NULL, 0) < 0) >! return my_err(EX_UNAVAILABLE, "setsockopt(IP_%s_FLUSH)", > do_pipe ? "DUMMYNET" : "FW"); > if (!do_quiet) > printf("Flushed all %s.\n", do_pipe ? "pipes" : "rules"); >+ return EX_OK; > } > > /* >*************** >*** 4916,4922 **** > * ipfw table N flush > * ipfw table N list > */ >! static void > table_handler(int ac, char *av[]) > { > ipfw_table_entry ent; >--- 5098,5104 ---- > * ipfw table N flush > * ipfw table N list > */ >! static int > table_handler(int ac, char *av[]) > { > ipfw_table_entry ent; >*************** >*** 4931,4954 **** > ent.tbl = atoi(*av); > ac--; av++; > } else >! errx(EX_USAGE, "table number required"); > NEED1("table needs command"); > if (_substrcmp(*av, "add") == 0 || > _substrcmp(*av, "delete") == 0) { > do_add = **av == 'a'; > ac--; av++; > if (!ac) >! errx(EX_USAGE, "IP address required"); > p = strchr(*av, '/'); > if (p) { > *p++ = '\0'; > ent.masklen = atoi(p); > if (ent.masklen > 32) >! errx(EX_DATAERR, "bad width ``%s''", p); > } else > ent.masklen = 32; > if (lookup_host(*av, (struct in_addr *)&ent.addr) != 0) >! errx(EX_NOHOST, "hostname ``%s'' unknown", *av); > ac--; av++; > if (do_add && ac) > ent.value = strtoul(*av, NULL, 0); >--- 5113,5136 ---- > ent.tbl = atoi(*av); > ac--; av++; > } else >! return my_errx(EX_USAGE, "table number required"); > NEED1("table needs command"); > if (_substrcmp(*av, "add") == 0 || > _substrcmp(*av, "delete") == 0) { > do_add = **av == 'a'; > ac--; av++; > if (!ac) >! return my_errx(EX_USAGE, "IP address required"); > p = strchr(*av, '/'); > if (p) { > *p++ = '\0'; > ent.masklen = atoi(p); > if (ent.masklen > 32) >! return my_errx(EX_DATAERR, "bad width ``%s''", p); > } else > ent.masklen = 32; > if (lookup_host(*av, (struct in_addr *)&ent.addr) != 0) >! return my_errx(EX_NOHOST, "hostname ``%s'' unknown", *av); > ac--; av++; > if (do_add && ac) > ent.value = strtoul(*av, NULL, 0); >*************** >*** 4958,4996 **** > &ent, sizeof(ent)) < 0) { > /* If running silent, don't bomb out on these errors. */ > if (!(do_quiet && (errno == (do_add ? EEXIST : ESRCH)))) >! err(EX_OSERR, "setsockopt(IP_FW_TABLE_%s)", > do_add ? "ADD" : "DEL"); > /* In silent mode, react to a failed add by deleting */ > if (do_add) { > do_cmd(IP_FW_TABLE_DEL, &ent, sizeof(ent)); > if (do_cmd(IP_FW_TABLE_ADD, > &ent, sizeof(ent)) < 0) >! err(EX_OSERR, > "setsockopt(IP_FW_TABLE_ADD)"); > } > } > } else if (_substrcmp(*av, "flush") == 0) { > if (do_cmd(IP_FW_TABLE_FLUSH, &ent.tbl, sizeof(ent.tbl)) < 0) >! err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)"); > } else if (_substrcmp(*av, "list") == 0) { > a = ent.tbl; > l = sizeof(a); > if (do_cmd(IP_FW_TABLE_GETSIZE, &a, (uintptr_t)&l) < 0) >! err(EX_OSERR, "getsockopt(IP_FW_TABLE_GETSIZE)"); > l = sizeof(*tbl) + a * sizeof(ipfw_table_entry); > tbl = malloc(l); > if (tbl == NULL) >! err(EX_OSERR, "malloc"); > tbl->tbl = ent.tbl; > if (do_cmd(IP_FW_TABLE_LIST, tbl, (uintptr_t)&l) < 0) >! err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)"); > for (a = 0; a < tbl->cnt; a++) { > printf("%s/%u %u\n", > inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr), > tbl->ent[a].masklen, tbl->ent[a].value); > } > } else >! errx(EX_USAGE, "invalid table command %s", *av); > } > > /* >--- 5140,5179 ---- > &ent, sizeof(ent)) < 0) { > /* If running silent, don't bomb out on these errors. */ > if (!(do_quiet && (errno == (do_add ? EEXIST : ESRCH)))) >! return my_err(EX_OSERR, "setsockopt(IP_FW_TABLE_%s)", > do_add ? "ADD" : "DEL"); > /* In silent mode, react to a failed add by deleting */ > if (do_add) { > do_cmd(IP_FW_TABLE_DEL, &ent, sizeof(ent)); > if (do_cmd(IP_FW_TABLE_ADD, > &ent, sizeof(ent)) < 0) >! return my_err(EX_OSERR, > "setsockopt(IP_FW_TABLE_ADD)"); > } > } > } else if (_substrcmp(*av, "flush") == 0) { > if (do_cmd(IP_FW_TABLE_FLUSH, &ent.tbl, sizeof(ent.tbl)) < 0) >! return my_err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)"); > } else if (_substrcmp(*av, "list") == 0) { > a = ent.tbl; > l = sizeof(a); > if (do_cmd(IP_FW_TABLE_GETSIZE, &a, (uintptr_t)&l) < 0) >! return my_err(EX_OSERR, "getsockopt(IP_FW_TABLE_GETSIZE)"); > l = sizeof(*tbl) + a * sizeof(ipfw_table_entry); > tbl = malloc(l); > if (tbl == NULL) >! return my_err(EX_OSERR, "malloc"); > tbl->tbl = ent.tbl; > if (do_cmd(IP_FW_TABLE_LIST, tbl, (uintptr_t)&l) < 0) >! return my_err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)"); > for (a = 0; a < tbl->cnt; a++) { > printf("%s/%u %u\n", > inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr), > tbl->ent[a].masklen, tbl->ent[a].value); > } > } else >! return my_errx(EX_USAGE, "invalid table command %s", *av); >! return EX_OK; > } > > /* >*************** >*** 5095,5101 **** > save_av = av; > > optind = optreset = 0; >! while ((ch = getopt(ac, av, "abcdefhnNqs:STtv")) != -1) > switch (ch) { > case 'a': > do_acct = 1; >--- 5278,5284 ---- > save_av = av; > > optind = optreset = 0; >! while ((ch = getopt(ac, av, "abcdefhinNqs:STtv")) != -1) > switch (ch) { > case 'a': > do_acct = 1; >*************** >*** 5127,5132 **** >--- 5310,5319 ---- > help(); > break; /* NOTREACHED */ > >+ case 'i': >+ ignore_errors = 1; >+ break; >+ > case 'n': > test_only = 1; > break; >*************** >*** 5211,5218 **** > else if (do_pipe && _substrcmp(*av, "config") == 0) > config_pipe(ac, av); > else if (_substrcmp(*av, "delete") == 0) >! delete(ac, av); >! else if (_substrcmp(*av, "flush") == 0) > flush(do_force); > else if (_substrcmp(*av, "zero") == 0) > zero(ac, av, IP_FW_ZERO); >--- 5398,5408 ---- > else if (do_pipe && _substrcmp(*av, "config") == 0) > config_pipe(ac, av); > else if (_substrcmp(*av, "delete") == 0) >! delete(ac, av, 0); >! else if (_substrcmp(*av, "replace") == 0) { >! delete(ac, av, 1); >! add(ac, av); >! } else if (_substrcmp(*av, "flush") == 0) > flush(do_force); > else if (_substrcmp(*av, "zero") == 0) > zero(ac, av, IP_FW_ZERO); >*************** >*** 5252,5258 **** > > filename = av[ac-1]; > >! while ((c = getopt(ac, av, "cfNnp:qS")) != -1) { > switch(c) { > case 'c': > do_compact = 1; >--- 5447,5453 ---- > > filename = av[ac-1]; > >! while ((c = getopt(ac, av, "cfiNnp:qS")) != -1) { > switch(c) { > case 'c': > do_compact = 1; >*************** >*** 5260,5265 **** >--- 5455,5464 ---- > > case 'f': > do_force = 1; >+ break; >+ >+ case 'i': >+ ignore_errors = 1; > break; > > case 'N':
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 116009
: 80960