summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorKenjiro Cho <kjc@cvs.openbsd.org>2002-02-13 08:21:46 +0000
committerKenjiro Cho <kjc@cvs.openbsd.org>2002-02-13 08:21:46 +0000
commita44854ca6d47ccf55b7711c935cd3bb4698d4b56 (patch)
tree7f238988769fb1abaac60099aa0b15fc600a5aa8 /usr.sbin
parent216d892966fcf0d3ba7355b2a6ce48d5d5c70fd6 (diff)
rewrite the parser code to get rid of the heritage
from rsvpd (rtap_cmds.c). replace the USC copyright by mine. it was OKed by the rsvp folks long time ago. this was the last USC copyright in the ALTQ related files. make "delete" command to accept filter name so that named filters can be deleted.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/altq/libaltq/altq_qop.h5
-rw-r--r--usr.sbin/altq/libaltq/parser.c769
2 files changed, 308 insertions, 466 deletions
diff --git a/usr.sbin/altq/libaltq/altq_qop.h b/usr.sbin/altq/libaltq/altq_qop.h
index 222bba6e0be..708a984e3d8 100644
--- a/usr.sbin/altq/libaltq/altq_qop.h
+++ b/usr.sbin/altq/libaltq/altq_qop.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: altq_qop.h,v 1.1 2001/06/27 18:23:23 kjc Exp $ */
+/* $OpenBSD: altq_qop.h,v 1.2 2002/02/13 08:21:45 kjc Exp $ */
/* $KAME: altq_qop.h,v 1.4 2000/10/18 09:15:18 kjc Exp $ */
/*
* Copyright (C) 1999-2000
@@ -124,8 +124,7 @@ struct fltrinfo {
int dontwarn; /* supress warning msg */
};
-int DoCommand(char *infile, FILE *infp);
-
+int do_command(FILE *infp);
int qcmd_enable(const char *ifname);
int qcmd_disable(const char *ifname);
int qcmd_delete_if(const char *ifname);
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);
}
-