diff options
Diffstat (limited to 'usr.sbin/altq/libaltq/parser.c')
-rw-r--r-- | usr.sbin/altq/libaltq/parser.c | 769 |
1 files changed, 306 insertions, 463 deletions
diff --git a/usr.sbin/altq/libaltq/parser.c b/usr.sbin/altq/libaltq/parser.c index 2fb0a65351d..22d1e2cdeae 100644 --- a/usr.sbin/altq/libaltq/parser.c +++ b/usr.sbin/altq/libaltq/parser.c @@ -1,32 +1,36 @@ -/* $OpenBSD: parser.c,v 1.4 2001/08/16 12:59:43 kjc Exp $ */ -/* $KAME: parser.c,v 1.12 2001/08/16 10:39:13 kjc Exp $ */ -/******************************************************************* - - Copyright (c) 1996 by the University of Southern California - All rights reserved. - - Permission to use, copy, modify, and distribute this software and its - documentation in source and binary forms for any purpose and without - fee is hereby granted, provided that both the above copyright notice - and this permission notice appear in all copies. and that any - documentation, advertising materials, and other materials related to - such distribution and use acknowledge that the software was developed - in part by the University of Southern California, Information - Sciences Institute. The name of the University may not be used to - endorse or promote products derived from this software without - specific prior written permission. - - THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about - the suitability of this software for any purpose. THIS SOFTWARE IS - PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, - INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - - Other copyrights might apply to parts of this software and are so - noted when applicable. - -********************************************************************/ +/* $OpenBSD: parser.c,v 1.5 2002/02/13 08:21:45 kjc Exp $ */ +/* $KAME: parser.c,v 1.13 2002/02/12 10:14:01 kjc Exp $ */ +/* + * Copyright (C) 1999-2002 + * Sony Computer Science Laboratories, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY SONY CSL AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL SONY CSL OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include <sys/param.h> +#include <sys/socket.h> +#include <net/if.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> @@ -36,11 +40,7 @@ #include <ctype.h> #include <errno.h> #include <syslog.h> -#include <sys/socket.h> #include <netdb.h> -#include <net/if.h> -#include <netinet/in.h> -#include <arpa/inet.h> #include <altq/altq.h> #include <altq/altq_cdnr.h> @@ -49,17 +49,10 @@ #include "altq_qop.h" #include "qop_cdnr.h" -#define show_help(op) printf(cmd_tab[op].cmd_help) - -/* - * Forward & External Declarations - */ static int is_qdisc_name(const char *); static int qdisc_interface_parser(const char *, const char *, int, char **); static int qdisc_class_parser(const char *, const char *, const char *, - const char *, int, char **); - -static int pfxcmp(const char *, const char *); + const char *, int, char **); static int next_word(char **, char *); static int do_cmd(int, char *); @@ -82,18 +75,10 @@ static int rio_parser(char *); static int conditioner_parser(char *); static int tc_action_parser(char *, char **, struct tc_action *); -/* - * Globals - */ -#define MAX_NFLWDS 64 -#define MAX_T 64 - -int TNO = 1; /* Current Thread number */ -int line_no = 0; -int filter_dontwarn; - -static char if_names[MAX_T][IFNAMSIZ]; -static struct if_nameindex *if_namelist = NULL; +#define MAX_LINE 1024 +#define MAX_WORD 64 +#define MAX_ARGS 64 +#define MAX_ACTIONS 16 #ifndef MAX #define MAX(a,b) (((a)>(b))?(a):(b)) @@ -101,70 +86,143 @@ static struct if_nameindex *if_namelist = NULL; #ifndef MIN #define MIN(a,b) (((a)<(b))?(a):(b)) #endif +#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) + +int line_no = 0; +int filter_dontwarn; -enum op_codes { - /* order must be same as entries cmd_tab[].cmd_op below!! */ - OP_HELP = 1, OP_QUIT, - OP_IFACE, OP_CLASS, OP_FILTER, - OP_ALTQ, OP_DEL, +static char curifname[IFNAMSIZ]; +static struct if_nameindex *if_namelist = NULL; + +struct cmd_tab { + const char *cmd; + int (*parser)(char *); + const char *help; +} cmd_tab[] = { + {"help", NULL, "help | ?"}, + {"quit", NULL, "quit"}, + {"interface", interface_parser, "interface if_name [bandwidth bps] [cbq|hfsc]"}, + {"class", class_parser, "class discipline if_name class_name [parent]"}, + {"filter", filter_parser, "filter if_name class_name [name filt_name] dst [netmask #] dport src [netmask #] sport proto [tos # [tosmask #] [gpi #] [dontwarn]"}, + {"altq", ctl_parser, "altq if_name {enable|disable}"}, + {"delete", delete_parser, "delete if_name class_name [filter_name]"}, #ifdef INET6 - OP_FILTER6, + {"filter6", filter6_parser, "filter6 if_name class_name [name filt_name] dst[/prefix] dport src[/prefix] sport proto [flowlabel #][tclass # [tclassmask #]][gpi #] [dontwarn]"}, #endif - OP_RED, OP_RIO, - OP_CDNR, - OP_NULL, OP_BUG + {"red", red_parser, "red th_min th_max inv_pmax"}, + {"rio", rio_parser, "rio low_th_min low_th_max low_inv_pmax med_th_min med_th_max med_inv_pmax high_th_min high_th_max high_inv_pmax"}, + {"conditioner", conditioner_parser, "conditioner if_name cdnr_name <tc_action>"}, + {"debug", NULL, "debug"}, + {NULL, NULL, NULL} /* termination */ }; -/* Following table MUST match enum order of op_codes ! +/* + * read one line from the specified stream. if it's a command, + * execute the command. + * returns 1 if OK, 0 if error or EOF. */ -struct cmds { - char *cmd_verb; - int cmd_op; - char *cmd_help; -} cmd_tab[] = { - - { "?", OP_HELP, "Commands are:\n" }, - { "help", OP_HELP, " help | ?\n" }, - { "quit", OP_QUIT, " quit\n" }, - { "interface", OP_IFACE, " interface if_name [bandwidth bps] [cbq|hfsc]\n" }, - { "class", OP_CLASS, " class discipline if_name class_name [parent]\n" }, - { "filter", OP_FILTER, " filter if_name class_name [name filt_name] dst [netmask #] dport src [netmask #] sport proto [tos # [tosmask #] [gpi #] [dontwarn]\n" }, - { "altq", OP_ALTQ, " disc if_name {enable|disable}\n" }, - { "delete", OP_DEL, " delete if_name class_name\n" }, -#ifdef INET6 - { "filter6", OP_FILTER6, " filter6 if_name class_name [name filt_name] dst[/prefix] dport src[/prefix] sport proto [flowlabel #][tclass # [tclassmask #]][gpi #] [dontwarn]\n" }, -#endif - { "red", OP_RED, " red th_min th_max inv_pmax\n" }, - { "rio", OP_RIO, " rio low_th_min low_th_max low_inv_pmax med_th_min med_th_max med_inv_pmax high_th_min high_th_max high_inv_pmax\n" }, - { "conditioner", OP_CDNR, " conditioner if_name cdnr_name <tc_action>\n" }, - { "bug", OP_BUG, " bug (On/Off)\n" }, - { "", OP_NULL, "" } /* MUST BE LAST IN CMD TABLE */ -}; +do_command(FILE *fp) +{ + char cmd_line[MAX_LINE], cmd[MAX_WORD], *cp; + struct cmd_tab *tp; + int len, rval; -static int + /* + * read a line from the stream and make it a null-terminated string + */ + cp = cmd_line; +read_line: + if (fgets(cp, &cmd_line[MAX_LINE] - cp, fp) == NULL) + /* EOF or error */ + return(0); + line_no++; + + /* null-terminate the line */ + if ((len = strlen(cmd_line)) > 0) { + cp = cmd_line + len - 1; + if (*cp == '\n') { + /* if escaped newline, read next line */ + if (len > 1 && *(cp - 1) == '\\') + goto read_line; + *cp = '\0'; + } else if (!feof(fp)) + err(1, "LINE %d too long!", line_no); + } + /* trim comments */ + if ((cp = strchr(cmd_line, '#')) != NULL) + *cp = '\0'; + + cp = cmd_line; + if ((len = next_word(&cp, cmd)) == 0) + /* no command in this line */ + return (1); + + /* fnind the corresponding parser */ + rval = 0; + for (tp = cmd_tab; tp->cmd != NULL; tp++) + if (strncmp(cmd, tp->cmd, len) == 0) + break; + + if (tp->cmd == NULL) { + if (fp == stdin) { + printf(" ?? %s\n", cmd); + rval = 1; + } else + LOG(LOG_ERR, 0, "unknown command: %s", cmd); + return (rval); + } + + if (tp->parser != NULL) + rval = (*tp->parser)(cp); + else { + /* handle other commands */ + if (strcmp(tp->cmd, "quit") == 0) + rval = 0; + else if (strcmp(tp->cmd, "help") == 0 || + strcmp(tp->cmd, "?") == 0) { + for (tp = cmd_tab; tp->cmd != NULL; tp++) + printf("%s\n", tp->help); + rval = 1; + } else if (strcmp(tp->cmd, "debug") == 0) { + if (m_debug & DEBUG_ALTQ) { + /* turn off verbose */ + l_debug = LOG_INFO; + m_debug &= ~DEBUG_ALTQ; + } else { + /* turn on verbose */ + l_debug = LOG_DEBUG; + m_debug |= DEBUG_ALTQ; + } + rval = 1; + } + } + return (rval); +} + +static int is_qdisc_name(const char *qname) { struct qdisc_parser *qp; - + for (qp = qdisc_parser; qp->qname != NULL; qp++) if (strncmp(qp->qname, qname, strlen(qp->qname)) == 0) return (1); return (0); } -static int +static int qdisc_interface_parser(const char * qname, const char *ifname, int argc, char **argv) { struct qdisc_parser *qp; - + for (qp = qdisc_parser; qp->qname != NULL; qp++) if (strncmp(qp->qname, qname, strlen(qp->qname)) == 0) return (*qp->interface_parser)(ifname, argc, argv); return (0); } -static int +static int qdisc_class_parser(const char *qname, const char *ifname, const char *class_name, const char *parent_name, int argc, char **argv) @@ -180,15 +238,13 @@ qdisc_class_parser(const char *qname, const char *ifname, return (0); } if ((ifinfo = ifname2ifinfo(ifname)) == NULL) { - LOG(LOG_ERR, 0, - "no such interface, line %d", line_no); + LOG(LOG_ERR, 0, "no such interface"); return (0); } if (strncmp(ifinfo->qdisc->qname, qname, strlen(ifinfo->qdisc->qname)) != 0) { LOG(LOG_ERR, 0, - "qname doesn't match the interface, line %d", - line_no); + "qname doesn't match the interface"); return (0); } return (*qp->class_parser)(ifname, class_name, @@ -197,222 +253,67 @@ qdisc_class_parser(const char *qname, const char *ifname, return (0); } - /* - * Read the config file to learn about tunnel vifs and non-default phyint - * parameters. + * read the config file */ int qcmd_config(void) { - FILE *f; - int i, rc = 1; + FILE *fp; + int i, rval; if (if_namelist != NULL) if_freenameindex(if_namelist); if_namelist = if_nameindex(); - - for (i = 0; i < MAX_T; i++) - if_names[i][0] = '\0'; + curifname[0] = '\0'; LOG(LOG_INFO, 0, "ALTQ config file is %s", altqconfigfile); - f = fopen(altqconfigfile, "r"); - if (f == NULL) { + fp = fopen(altqconfigfile, "r"); + if (fp == NULL) { LOG(LOG_ERR, errno, "can't open %s", altqconfigfile, 0); return (QOPERR_INVAL); } line_no = 0; - while (rc) - rc = DoCommand(altqconfigfile, f); - - (void) fclose(f); - line_no = 0; - return (0); -} - -/* - * Do_Command(): Top-level routine to read the next line from a given - * file and execute the command it contains. - * returns 1 if OK, 0 if EOF. - */ -int -DoCommand(char *infile, FILE *infp) -{ - char cmd_line[256], cmd_op[80]; - struct cmds *cmdp; - char *cp; - int rc; - - if (fgets(cmd_line, sizeof(cmd_line), infp) == NULL) - /* EOF */ - return(0); - line_no++; - - /* check escaped newline */ - while ((cp = strrchr(cmd_line, '\\')) != NULL && cp[1] == '\n') { - if (fgets(cp, &cmd_line[256] - cp, infp) != NULL) - line_no++; - } - - /* remove trailing NL */ - cp = cmd_line + strlen(cmd_line) - 1; - if (*cp == '\n') - *cp = '\0'; - else if (!feof(infp)) { - printf("LINE %d > 255 CHARS: %s.\n", line_no, cmd_line); - exit(1); - } - /*** printf("DoCommand: %s\n", cmd_line); ***/ - - if (cmd_line[0] == '#') { /* Comment, skip this line */ - return(1); - } - cp = cmd_line; - if (!next_word(&cp, cmd_op)) - return(1); - if (cmd_op[0] == 'T') { - TNO = atoi(&cmd_op[1]); - if (!next_word(&cp, cmd_op)) - return(1); - } - cmdp = cmd_tab; - while ((cmdp->cmd_op != OP_NULL) && pfxcmp(cmd_op, cmdp->cmd_verb)) - cmdp++; - - if (cmdp->cmd_op == OP_NULL) { - if (cmd_op[0]) - printf(" ?? %s\n", cmd_op); - return(1); - } - rc = do_cmd(cmdp->cmd_op, cp); - if (rc == 0) { - if (infile) { - /* error in the config file. cleanup and exit. */ - LOG(LOG_ERR, 0, "config failed. exiting..."); - (void) qcmd_destroyall(); - (void) fclose(infp); - exit(1); - } else { - /* interactive mode */ - printf("error: usage :"); - show_help(cmdp->cmd_op); - } - } - return(1); -} + while (rval) + rval = do_command(fp); + if (!feof(fp)) { + LOG(LOG_ERR, 0, "Error in %s, line %d. config failed.", + altqconfigfile, line_no); + (void) qcmd_destroyall(); + rval = QOPERR_INVAL; + } else + rval = 0; -/* - * Prefix string comparison: Return 0 if s1 string is prefix of s2 string, 1 - * otherwise. - */ -static int -pfxcmp(const char *s1, const char *s2) -{ - while (*s1) - if (*s1++ != *s2++) - return (1); - return (0); + (void)fclose(fp); + line_no = 0; + return (rval); } -/* - * Skip leading blanks, then copy next word (delimited by blank or zero, but - * no longer than 63 bytes) into buffer b, set scan pointer to following - * non-blank (or end of string), and return 1. If there is no non-blank text, - * set scan ptr to point to 0 byte and return 0. - */ static int next_word(char **cpp, char *b) { - char *tp; - size_t L; - - *cpp += strspn(*cpp, " \t"); - if (**cpp == '\0' || **cpp == '\n' || **cpp == '#') - return(0); - - tp = strpbrk(*cpp, " \t\n#"); - L = MIN((tp)?(tp-*cpp):strlen(*cpp), 63); - strncpy(b, *cpp, L); - *(b + L) = '\0'; - *cpp += L; - *cpp += strspn(*cpp, " \t"); - return (1); -} + char *cp; + int i; -/* - * do_cmd executes a command input. - * returns 1 if OK, 0 if an error occurs. - */ -static int -do_cmd(int op, char *cmdbuf) -{ - int i, rval = 0; - - switch (op) { - case OP_HELP: - for (i = 0; i < OP_NULL; i++) - show_help(i); - rval = 1; - break; - case OP_QUIT: - qcmd_destroyall(); - exit(0); - break; - case OP_IFACE: - rval = interface_parser(cmdbuf); - break; - case OP_CLASS: - rval = class_parser(cmdbuf); - break; - case OP_FILTER: - rval = filter_parser(cmdbuf); - break; - case OP_ALTQ: - rval = ctl_parser(cmdbuf); - break; - case OP_DEL: - rval = delete_parser(cmdbuf); - break; -#ifdef INET6 - case OP_FILTER6: - rval = filter6_parser(cmdbuf); - break; -#endif - case OP_RED: - rval = red_parser(cmdbuf); - break; - case OP_RIO: - rval = rio_parser(cmdbuf); - break; - case OP_CDNR: - rval = conditioner_parser(cmdbuf); - break; - case OP_BUG: - if (m_debug & DEBUG_ALTQ) { - /* turn off verbose */ - l_debug = LOG_INFO; - m_debug &= ~DEBUG_ALTQ; - } else { - /* turn on verbose */ - l_debug = LOG_DEBUG; - m_debug |= DEBUG_ALTQ; - } - break; - default: - printf("command %d not supported\n", op); - rval = 0; - break; + cp = *cpp; + while (*cp == ' ' || *cp == '\t') + cp++; + for (i = 0; i < MAX_WORD - 1; i++) { + if (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '\0') + break; + *b++ = *cp++; } - return(rval); + *b = '\0'; + *cpp = cp; + return (i); } -#define EQUAL(s1, s2) (strcmp((s1), (s2)) == 0) - -char *cur_ifname(void) +char * +cur_ifname(void) { - return (if_names[TNO]); + return (curifname); } u_int @@ -429,7 +330,7 @@ get_ifindex(const char *ifname) static int get_ifname(char **cpp, char **ifnamep) { - char w[128], *ocp; + char w[MAX_WORD], *ocp; struct if_nameindex *ifnp; ocp = *cpp; @@ -437,16 +338,16 @@ get_ifname(char **cpp, char **ifnamep) for (ifnp = if_namelist; ifnp->if_name != NULL; ifnp++) if (strcmp(w, ifnp->if_name) == 0) { /* if_name found. advance the word pointer */ - *cpp = ocp; - strlcpy(if_names[TNO], w, sizeof(if_names[TNO])); - *ifnamep = if_names[TNO]; + *cpp = ocp; + strlcpy(curifname, w, sizeof(curifname)); + *ifnamep = curifname; return (1); } /* this is not interface name. use one in the context. */ - if (if_names[TNO][0] == 0) + if (curifname[0] == '\0') return (0); - *ifnamep = if_names[TNO]; + *ifnamep = curifname; return (1); } @@ -454,9 +355,9 @@ get_ifname(char **cpp, char **ifnamep) static int get_addr(char **cpp, struct in_addr *addr, struct in_addr *mask) { - char w[128], *ocp; + char w[MAX_WORD], *ocp; struct in_addr tmp; - + addr->s_addr = 0; mask->s_addr = 0xffffffff; @@ -467,13 +368,11 @@ get_addr(char **cpp, struct in_addr *addr, struct in_addr *mask) /* try gethostbyname */ struct hostent *h; - if ((h = gethostbyname(w)) == NULL - || h->h_addrtype != AF_INET || h->h_length != 4) + if ((h = gethostbyname(w)) == NULL || + h->h_addrtype != AF_INET || h->h_length != 4) return (0); - bcopy(h->h_addr, &tmp, (size_t)h->h_length); } - addr->s_addr = tmp.s_addr; /* check if netmask option is present */ @@ -481,12 +380,11 @@ get_addr(char **cpp, struct in_addr *addr, struct in_addr *mask) if (next_word(&ocp, w) && EQUAL(w, "netmask")) { if (!next_word(&ocp, w)) return (0); - if (inet_aton((char *)w, (struct in_addr *)&tmp) != 1) return (0); mask->s_addr = tmp.s_addr; - *cpp = ocp; + *cpp = ocp; return (1); } /* no netmask option */ @@ -499,7 +397,7 @@ get_port(const char *name, u_int16_t *port_no) { struct servent *s; u_int16_t num; - + if (isdigit(name[0])) { num = (u_int16_t)strtol(name, NULL, 0); *port_no = htons(num); @@ -517,7 +415,7 @@ static int get_proto(const char *name, int *proto_no) { struct protoent *p; - + if (isdigit(name[0])) { *proto_no = (int)strtol(name, NULL, 0); return (1); @@ -533,7 +431,7 @@ get_proto(const char *name, int *proto_no) static int get_fltr_opts(char **cpp, char *fltr_name, size_t len, int *ruleno) { - char w[128], *ocp; + char w[MAX_WORD], *ocp; ocp = *cpp; while (next_word(&ocp, w)) { @@ -559,88 +457,78 @@ get_fltr_opts(char **cpp, char *fltr_name, size_t len, int *ruleno) static int interface_parser(char *cmdbuf) { - char w[256], *ap, *cp = cmdbuf; - char *ifname, *argv[64], qdisc_name[64]; - int argc, rval; + char w[MAX_WORD], *ap, *cp = cmdbuf; + char *ifname, *argv[MAX_ARGS], qdisc_name[MAX_WORD]; + int argc; if (!get_ifname(&cp, &ifname)) { - LOG(LOG_ERR, 0, "missing interface name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing interface name"); return (0); } - /* - * Create argment list & look for scheduling discipline options. - */ - snprintf(qdisc_name, sizeof(qdisc_name), "null"); + /* create argment list & look for scheduling discipline options. */ + sprintf(qdisc_name, "null"); argc = 0; ap = w; while (next_word(&cp, ap)) { if (is_qdisc_name(ap)) - strlcpy(qdisc_name, ap, sizeof(qdisc_name)); + strcpy(qdisc_name, ap); argv[argc] = ap; ap += strlen(ap) + 1; argc++; + if (argc >= MAX_ARGS) { + LOG(LOG_ERR, 0, "too many args"); + return (0); + } } - rval = qdisc_interface_parser(qdisc_name, ifname, argc, argv); - if (rval == 0) { - LOG(LOG_ERR, 0, "Error in %s, line %d", - altqconfigfile, line_no); - return (0); - } - return (1); + return qdisc_interface_parser(qdisc_name, ifname, argc, argv); } + static int -class_parser(char *cmdbuf) +class_parser(char *cmdbuf) { - char w[256], *cp = cmdbuf; - char *ifname, qdisc_name[128], class_name[128], parent_name[128]; + char w[MAX_WORD], *cp = cmdbuf; + char *ifname, qdisc_name[MAX_WORD]; + char class_name[MAX_WORD], parent_name[MAX_WORD]; char *clname = class_name; char *parent = NULL; - char *argv[64], *ap; + char *argv[MAX_ARGS], *ap; int argc, rval; /* get scheduling class */ if (!next_word(&cp, qdisc_name)) { - LOG(LOG_ERR, 0, "missing scheduling discipline in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing discipline"); return (0); } if (!is_qdisc_name(qdisc_name)) { - LOG(LOG_ERR, 0, - "unknown scheduling discipline '%s' in %s, line %d", - qdisc_name, altqconfigfile, line_no); + LOG(LOG_ERR, 0, "unknown discipline '%s'", qdisc_name); return (0); } /* get interface name */ if (!get_ifname(&cp, &ifname)) { - LOG(LOG_ERR, 0, "missing interface name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing interface name"); return (0); } /* get class name */ if (!next_word(&cp, class_name)) { - LOG(LOG_ERR, 0, "missing class name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing class name"); return (0); } /* get parent name */ if (!next_word(&cp, parent_name)) { - LOG(LOG_ERR, 0, "missing parent class in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing parent class"); return (0); } - if (!EQUAL(parent_name, "null") && !EQUAL(parent_name, "NULL")) { + if (!EQUAL(parent_name, "null") && !EQUAL(parent_name, "NULL")) parent = parent_name; - } else { + else parent = NULL; - } ap = w; argc = 0; @@ -648,24 +536,22 @@ class_parser(char *cmdbuf) argv[argc] = ap; ap += strlen(ap) + 1; argc++; + if (argc >= MAX_ARGS) { + LOG(LOG_ERR, 0, "too many args"); + return (0); + } } - rval = qdisc_class_parser(qdisc_name, ifname, clname, parent, - argc, argv); - if (rval == 0) { - LOG(LOG_ERR, 0, "can't add class '%s' on interface '%s'", - clname, ifname); - return (0); - } - - return (1); + return qdisc_class_parser(qdisc_name, ifname, clname, parent, + argc, argv); } static int -filter_parser(char *cmdbuf) +filter_parser(char *cmdbuf) { - char w[128], *cp = cmdbuf; - char *ifname, class_name[64], fltr_name[64], *flname = NULL; + char w[MAX_WORD], *cp = cmdbuf; + char *ifname, class_name[MAX_WORD], fltr_name[MAX_WORD]; + char *flname = NULL; struct flow_filter sfilt; int protocol; u_char tos, tosmask; @@ -677,24 +563,19 @@ filter_parser(char *cmdbuf) sfilt.ff_flow.fi_family = AF_INET; if (!get_ifname(&cp, &ifname)) { - LOG(LOG_ERR, 0, "missing interface name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing interface name in filter command"); return (0); } if (!next_word(&cp, class_name)) { - LOG(LOG_ERR, 0, - "missing class name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing class name in filter command"); return (0); } fltr_name[0] = '\0'; ruleno = 0; if (!get_fltr_opts(&cp, &fltr_name[0], sizeof(fltr_name), &ruleno)) { - LOG(LOG_ERR, 0, - "bad filter option in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter option"); return (0); } if (fltr_name[0] != '\0') @@ -703,53 +584,43 @@ filter_parser(char *cmdbuf) /* get filter destination Address */ if (!get_addr(&cp, &sfilt.ff_flow.fi_dst, &sfilt.ff_mask.mask_dst)) { - LOG(LOG_ERR, 0, - "bad filter destination address in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter destination address"); return (0); } /* get filter destination port */ if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, - "missing filter destination port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing filter destination port"); return (0); } if (!get_port(w, &sfilt.ff_flow.fi_dport)) { - LOG(LOG_ERR, 0, "bad filter destination port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter destination port"); return (0); } - + /* get filter source address */ if (!get_addr(&cp, &sfilt.ff_flow.fi_src, &sfilt.ff_mask.mask_src)) { - LOG(LOG_ERR, 0, "bad filter source address in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter source address"); return (0); } /* get filter source port */ if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing filter source port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing filter source port"); return (0); } if (!get_port(w, &sfilt.ff_flow.fi_sport)) { - LOG(LOG_ERR, 0, "bad filter source port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter source port"); return (0); } /* get filter protocol id */ if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing filter protocol id in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing filter protocol"); return (0); } if (!get_proto(w, &protocol)) { - LOG(LOG_ERR, 0, "bad protocol in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad protocol"); return (0); } sfilt.ff_flow.fi_proto = protocol; @@ -758,7 +629,7 @@ filter_parser(char *cmdbuf) if (EQUAL(w, "tos")) { tos = 0; tosmask = 0xff; - + if (next_word(&cp, w)) { tos = (u_char)strtol(w, NULL, 0); if (next_word(&cp, w)) { @@ -768,8 +639,8 @@ filter_parser(char *cmdbuf) } } } - sfilt.ff_flow.fi_tos = tos; - sfilt.ff_mask.mask_tos = tosmask; + sfilt.ff_flow.fi_tos = tos; + sfilt.ff_mask.mask_tos = tosmask; } else if (EQUAL(w, "gpi")) { if (next_word(&cp, w)) { sfilt.ff_flow.fi_gpi = @@ -793,7 +664,6 @@ filter_parser(char *cmdbuf) class_name, ifname); return (0); } - return (1); } @@ -801,8 +671,9 @@ filter_parser(char *cmdbuf) static int filter6_parser(char *cmdbuf) { - char w[128], *cp = cmdbuf; - char *ifname, class_name[128], fltr_name[64], *flname = NULL; + char w[MAX_WORD], *cp = cmdbuf; + char *ifname, class_name[MAX_WORD], fltr_name[MAX_WORD]; + char *flname = NULL; struct flow_filter6 sfilt; int protocol; u_char tclass, tclassmask; @@ -814,23 +685,19 @@ filter6_parser(char *cmdbuf) sfilt.ff_flow6.fi6_family = AF_INET6; if (!get_ifname(&cp, &ifname)) { - LOG(LOG_ERR, 0, "missing interface name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing interface name"); return (0); } if (!next_word(&cp, class_name)) { - LOG(LOG_ERR, 0, "missing class name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing class name"); return (0); } fltr_name[0] = '\0'; ruleno = 0; if (!get_fltr_opts(&cp, &fltr_name[0], sizeof(fltr_name), &ruleno)) { - LOG(LOG_ERR, 0, - "bad filter option in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter option"); return (0); } if (fltr_name[0] != '\0') @@ -840,56 +707,47 @@ filter6_parser(char *cmdbuf) /* get filter destination address */ if (!get_ip6addr(&cp, &sfilt.ff_flow6.fi6_dst, &sfilt.ff_mask6.mask6_dst)) { - LOG(LOG_ERR, 0, "bad destination address in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad destination address"); return (0); } /* get filter destination port */ if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, - "missing filter destination port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing filter destination port"); return (0); } if (!get_port(w, &sfilt.ff_flow6.fi6_dport)) { - LOG(LOG_ERR, 0, "bad filter destination port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter destination port"); return (0); } /* get filter source address */ if (!get_ip6addr(&cp, &sfilt.ff_flow6.fi6_src, &sfilt.ff_mask6.mask6_src)) { - LOG(LOG_ERR, 0, "bad source address in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad source address"); return (0); } /* get filter source port */ if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing filter source port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing filter source port"); return (0); } if (!get_port(w, &sfilt.ff_flow6.fi6_sport)) { - LOG(LOG_ERR, 0, "bad filter source port in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad filter source port"); return (0); } /* get filter protocol id */ if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing filter protocol id in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing filter protocol"); return (0); } if (!get_proto(w, &protocol)) { - LOG(LOG_ERR, 0, "bad protocol in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad protocol"); return (0); } - sfilt.ff_flow6.fi6_proto = protocol; + sfilt.ff_flow6.fi6_proto = protocol; while (next_word(&cp, w)) { if (EQUAL(w, "tclass")) { @@ -946,7 +804,7 @@ filter6_parser(char *cmdbuf) static int get_ip6addr(char **cpp, struct in6_addr *addr, struct in6_addr *mask) { - char w[128], *prefix; + char w[MAX_WORD], *prefix; u_char *cp; int len; @@ -998,11 +856,11 @@ get_ip6addr(char **cpp, struct in6_addr *addr, struct in6_addr *mask) static int ctl_parser(char *cmdbuf) { - char w[128], *cp = cmdbuf; + char w[MAX_WORD], *cp = cmdbuf; char *ifname; int state; int rval; - + if (!get_ifname(&cp, &ifname)) { printf("missing interface name in %s, line %d", altqconfigfile, line_no); @@ -1033,27 +891,35 @@ ctl_parser(char *cmdbuf) return (1); } - static int delete_parser(char *cmdbuf) { char *cp = cmdbuf; - char *ifname, class_name[128]; + char *ifname, class_name[MAX_WORD], filter_name[MAX_WORD]; int ret; - + if (!get_ifname(&cp, &ifname)) { - printf("missing interface name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing interface name"); return (0); } if (!next_word(&cp, class_name)) { - LOG(LOG_ERR, 0, - "missing class name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing class name"); return (0); } + /* check if filter is specified */ + if (next_word(&cp, filter_name)) { + ret = qcmd_delete_filter(ifname, class_name, filter_name); + if (ret) { + LOG(LOG_ERR, 0, + "can't delete filter '%s' on interface '%s'", + filter_name, ifname); + return (0); + } + return (1); + } + ret = qcmd_delete_class(ifname, class_name); if (ret) { LOG(LOG_ERR, 0, @@ -1068,7 +934,7 @@ delete_parser(char *cmdbuf) static int red_parser(char *cmdbuf) { - char w[128], *cp = cmdbuf; + char w[MAX_WORD], *cp = cmdbuf; int th_min, th_max, inv_pmax; if (!next_word(&cp, w)) @@ -1091,15 +957,14 @@ red_parser(char *cmdbuf) return (1); bad: - LOG(LOG_ERR, 0, "bad red parameter in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad red parameter"); return (0); } static int rio_parser(char *cmdbuf) { - char w[128], *cp = cmdbuf; + char w[MAX_WORD], *cp = cmdbuf; int i; struct redparams params[RIO_NDROPPREC]; @@ -1125,28 +990,25 @@ rio_parser(char *cmdbuf) return (1); bad: - LOG(LOG_ERR, 0, "bad rio parameter in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "bad rio parameter"); return (0); } static int conditioner_parser(char *cmdbuf) { - char cdnr_name[128], *cp = cmdbuf; + char cdnr_name[MAX_WORD], *cp = cmdbuf; char *ifname; - struct tc_action action[64]; - + struct tc_action action[MAX_ACTIONS]; + if (!get_ifname(&cp, &ifname)) { - LOG(LOG_ERR, 0, "missing interface name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing interface name"); return (0); } /* get conditioner name */ if (!next_word(&cp, cdnr_name)) { - LOG(LOG_ERR, 0, "missing cdnr name in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing cdnr name"); return (0); } @@ -1166,7 +1028,7 @@ static int tc_action_parser(char *ifname, char **cpp, struct tc_action *action) { char *cp, *start, *end; - char type[128], w[128]; + char type[MAX_WORD], w[MAX_WORD]; int depth, i; struct tb_profile profile[2]; @@ -1176,8 +1038,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) */ start = strchr(*cpp, '<'); if (start == NULL) { - LOG(LOG_ERR, 0, "conditioner action missing in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "conditioner action missing"); return (0); } depth = 1; @@ -1186,8 +1047,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) end = strpbrk(cp, "<>"); if (end == NULL) { LOG(LOG_ERR, 0, - "conditioner action delimiter mismatch in %s, line %d", - altqconfigfile, line_no); + "conditioner action delimiter mismatch"); return (0); } if (*end == '<') @@ -1205,9 +1065,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) } if (!next_word(&cp, type)) { - LOG(LOG_ERR, 0, - "missing conditioner action type in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing conditioner action type"); return (0); } @@ -1217,16 +1075,14 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) if (EQUAL(type, "conditioner")) { if (!next_word(&cp, w)) { LOG(LOG_ERR, 0, - "missing conditioner name in %s, line %d", - altqconfigfile, line_no); + "missing conditioner name"); return (0); } action->tca_code = TCACODE_HANDLE; action->tca_handle = cdnr_name2handle(ifname, w); if (action->tca_handle == CDNR_NULL_HANDLE) { LOG(LOG_ERR, 0, - "wrong conditioner name %s in %s, line %d", - w, altqconfigfile, line_no); + "wrong conditioner name %s", w); return (0); } } else if (EQUAL(type, "pass")) { @@ -1235,22 +1091,19 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) action->tca_code = TCACODE_DROP; } else if (EQUAL(type, "mark")) { if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing dscp in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing dscp"); return (0); } action->tca_code = TCACODE_MARK; action->tca_dscp = (u_int8_t)strtol(w, NULL, 0); } else if (EQUAL(type, "tbmeter")) { if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing tb profile in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[0].rate = atobps(w); if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing tb profile in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[0].depth = atobytes(w); @@ -1267,16 +1120,12 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) for (i=0; i<2; i++) { if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, - "missing tb profile in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[i].rate = atobps(w); if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, - "missing tb profile in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing tb profile"); return (0); } profile[i].depth = atobytes(w); @@ -1301,24 +1150,21 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) return (0); } else if (EQUAL(type, "tswtcm")) { u_int32_t cmtd_rate, peak_rate, avg_interval; - + if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing cmtd rate in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing cmtd rate"); return (0); } cmtd_rate = atobps(w); if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing peak rate in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing peak rate"); return (0); } peak_rate = atobps(w); if (!next_word(&cp, w)) { - LOG(LOG_ERR, 0, "missing avg interval in %s, line %d", - altqconfigfile, line_no); + LOG(LOG_ERR, 0, "missing avg interval"); return (0); } avg_interval = (u_int32_t)strtoul(w, NULL, 0); @@ -1336,9 +1182,7 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) != 0) return (0); } else { - LOG(LOG_ERR, 0, - "Unkown action type %s in %s, line %d", - type, altqconfigfile, line_no); + LOG(LOG_ERR, 0, "unkown action type %s"); return (0); } @@ -1346,4 +1190,3 @@ tc_action_parser(char *ifname, char **cpp, struct tc_action *action) return (1); } - |