summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/parse.c
diff options
context:
space:
mode:
authorcy <cy@FreeBSD.org>2013-07-19 05:41:57 +0000
committercy <cy@FreeBSD.org>2013-07-19 05:41:57 +0000
commit672af8808c0e7c15f330b401482f9271c2eb3fa6 (patch)
tree225b5acf68c01bc6a260b386c2b2dbf4fa2839e3 /contrib/ipfilter/parse.c
parent71e82d94e82560b20789833f60056506de34de8b (diff)
downloadFreeBSD-src-672af8808c0e7c15f330b401482f9271c2eb3fa6.zip
FreeBSD-src-672af8808c0e7c15f330b401482f9271c2eb3fa6.tar.gz
As per the developers handbook (5.3.1 step 1), prepare the vendor trees for
import of new ipfilter vendor sources by flattening them. To keep the tags consistent with dist, the tags are also flattened. Approved by: glebius (Mentor)
Diffstat (limited to 'contrib/ipfilter/parse.c')
-rw-r--r--contrib/ipfilter/parse.c1510
1 files changed, 0 insertions, 1510 deletions
diff --git a/contrib/ipfilter/parse.c b/contrib/ipfilter/parse.c
deleted file mode 100644
index 0d8a617..0000000
--- a/contrib/ipfilter/parse.c
+++ /dev/null
@@ -1,1510 +0,0 @@
-/*
- * Copyright (C) 1993-2001 by Darren Reed.
- *
- * See the IPFILTER.LICENCE file for details on licencing.
- */
-#if defined(__sgi) && (IRIX > 602)
-# include <sys/ptimers.h>
-#endif
-#include <sys/types.h>
-#if !defined(__SVR4) && !defined(__svr4__)
-#include <strings.h>
-#else
-#include <sys/byteorder.h>
-#endif
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
-#include <net/if.h>
-#if __FreeBSD_version >= 300000
-# include <net/if_var.h>
-#endif
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <stddef.h>
-#include <netdb.h>
-#include <arpa/nameser.h>
-#include <arpa/inet.h>
-#include <resolv.h>
-#include <ctype.h>
-#include <syslog.h>
-#include "ip_compat.h"
-#include "ip_fil.h"
-#include "ipf.h"
-#include "facpri.h"
-
-#if !defined(lint)
-static const char sccsid[] = "@(#)parse.c 1.44 6/5/96 (C) 1993-2000 Darren Reed";
-static const char rcsid[] = "@(#)$IPFilter: parse.c,v 2.8 1999/12/28 10:49:46 darrenr Exp $";
-#endif
-
-extern struct ipopt_names ionames[], secclass[];
-extern int opts;
-extern int use_inet6;
-
-int addicmp __P((char ***, struct frentry *, int));
-int extras __P((char ***, struct frentry *, int));
-
-int icmpcode __P((char *)), addkeep __P((char ***, struct frentry *, int));
-int to_interface __P((frdest_t *, char *, int));
-void print_toif __P((char *, frdest_t *));
-void optprint __P((u_short *, u_long, u_long));
-int loglevel __P((char **, u_int *, int));
-void printlog __P((frentry_t *));
-void printifname __P((char *, char *, void *));
-
-extern char *proto;
-extern char flagset[];
-extern u_char flags[];
-
-
-/* parse()
- *
- * parse a line read from the input filter rule file
- *
- * status:
- * < 0 error
- * = 0 OK
- * > 0 programmer error
- */
-struct frentry *parse(line, linenum, status)
-char *line;
-int linenum;
-int *status; /* good, bad, or indifferent */
-{
- static struct frentry fil;
- char *cps[31], **cpp, *endptr, *s;
- struct protoent *p = NULL;
- int i, cnt = 1, j, ch;
- u_int k;
-
- *status = 100; /* default to error */
-
- while (*line && isspace(*line))
- line++;
- if (!*line) {
- *status = 0;
- return NULL;
- }
-
- bzero((char *)&fil, sizeof(fil));
- fil.fr_mip.fi_v = 0xf;
- fil.fr_ip.fi_v = use_inet6 ? 6 : 4;
- fil.fr_loglevel = 0xffff;
-
- /*
- * break line up into max of 20 segments
- */
- if (opts & OPT_DEBUG)
- fprintf(stderr, "parse [%s]\n", line);
- for (i = 0, *cps = strtok(line, " \b\t\r\n"); cps[i] && i < 30; cnt++)
- cps[++i] = strtok(NULL, " \b\t\r\n");
- cps[i] = NULL;
-
- if (cnt < 3) {
- fprintf(stderr, "%d: not enough segments in line\n", linenum);
- *status = -1;
- return NULL;
- }
-
- cpp = cps;
- /*
- * The presence of an '@' followed by a number gives the position in
- * the current rule list to insert this one.
- */
- if (**cpp == '@')
- fil.fr_hits = (U_QUAD_T)atoi(*cpp++ + 1) + 1;
-
-
- /*
- * Check the first keyword in the rule and any options that are
- * expected to follow it.
- */
- if (!strcasecmp("block", *cpp)) {
- fil.fr_flags |= FR_BLOCK;
- if (!strncasecmp(*(cpp+1), "return-icmp-as-dest", 19) &&
- (i = 19))
- fil.fr_flags |= FR_FAKEICMP;
- else if (!strncasecmp(*(cpp+1), "return-icmp", 11) && (i = 11))
- fil.fr_flags |= FR_RETICMP;
- if (fil.fr_flags & FR_RETICMP) {
- cpp++;
- if (strlen(*cpp) == i) {
- if (*(cpp + 1) && **(cpp +1) == '(') {
- cpp++;
- i = 0;
- } else
- i = -1;
- }
-
- /*
- * The ICMP code is not required to follow in ()'s
- */
- if ((i >= 0) && (*(*cpp + i) == '(')) {
- i++;
- j = icmpcode(*cpp + i);
- if (j == -1) {
- fprintf(stderr,
- "%d: unrecognised icmp code %s\n",
- linenum, *cpp + 20);
- *status = -1;
- return NULL;
- }
- fil.fr_icode = j;
- }
- } else if (!strcasecmp(*(cpp+1), "return-rst")) {
- fil.fr_flags |= FR_RETRST;
- cpp++;
- }
- } else if (!strcasecmp("count", *cpp)) {
- fil.fr_flags |= FR_ACCOUNT;
- } else if (!strcasecmp("pass", *cpp)) {
- fil.fr_flags |= FR_PASS;
- } else if (!strcasecmp("nomatch", *cpp)) {
- fil.fr_flags |= FR_NOMATCH;
- } else if (!strcasecmp("auth", *cpp)) {
- fil.fr_flags |= FR_AUTH;
- if (!strncasecmp(*(cpp+1), "return-rst", 10)) {
- fil.fr_flags |= FR_RETRST;
- cpp++;
- }
- } else if (!strcasecmp("preauth", *cpp)) {
- fil.fr_flags |= FR_PREAUTH;
- } else if (!strcasecmp("skip", *cpp)) {
- cpp++;
- if (ratoui(*cpp, &k, 0, UINT_MAX))
- fil.fr_skip = k;
- else {
- fprintf(stderr, "%d: integer must follow skip\n",
- linenum);
- *status = -1;
- return NULL;
- }
- } else if (!strcasecmp("log", *cpp)) {
- fil.fr_flags |= FR_LOG;
- if (!strcasecmp(*(cpp+1), "body")) {
- fil.fr_flags |= FR_LOGBODY;
- cpp++;
- }
- if (!strcasecmp(*(cpp+1), "first")) {
- fil.fr_flags |= FR_LOGFIRST;
- cpp++;
- }
- if (*cpp && !strcasecmp(*(cpp+1), "or-block")) {
- fil.fr_flags |= FR_LOGORBLOCK;
- cpp++;
- }
- if (!strcasecmp(*(cpp+1), "level")) {
- cpp++;
- if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1) {
- /* NB loglevel prints its own error message */
- *status = -1;
- return NULL;
- }
- cpp++;
- }
- } else {
- /*
- * Doesn't start with one of the action words
- */
- fprintf(stderr, "%d: unknown keyword (%s)\n", linenum, *cpp);
- *status = -1;
- return NULL;
- }
- if (!*++cpp) {
- fprintf(stderr, "%d: missing 'in'/'out' keyword\n", linenum);
- *status = -1;
- return NULL;
- }
-
- /*
- * Get the direction for filtering. Impose restrictions on direction
- * if blocking with returning ICMP or an RST has been requested.
- */
- if (!strcasecmp("in", *cpp))
- fil.fr_flags |= FR_INQUE;
- else if (!strcasecmp("out", *cpp)) {
- fil.fr_flags |= FR_OUTQUE;
- if (fil.fr_flags & FR_RETICMP) {
- fprintf(stderr,
- "%d: Can only use return-icmp with 'in'\n",
- linenum);
- *status = -1;
- return NULL;
- } else if (fil.fr_flags & FR_RETRST) {
- fprintf(stderr,
- "%d: Can only use return-rst with 'in'\n",
- linenum);
- *status = -1;
- return NULL;
- }
- }
- if (!*++cpp) {
- fprintf(stderr, "%d: missing source specification\n", linenum);
- *status = -1;
- return NULL;
- }
-
- if (!strcasecmp("log", *cpp)) {
- if (!*++cpp) {
- fprintf(stderr, "%d: missing source specification\n",
- linenum);
- *status = -1;
- return NULL;
- }
- if (fil.fr_flags & FR_PASS)
- fil.fr_flags |= FR_LOGP;
- else if (fil.fr_flags & FR_BLOCK)
- fil.fr_flags |= FR_LOGB;
- if (*cpp && !strcasecmp(*cpp, "body")) {
- fil.fr_flags |= FR_LOGBODY;
- cpp++;
- }
- if (*cpp && !strcasecmp(*cpp, "first")) {
- fil.fr_flags |= FR_LOGFIRST;
- cpp++;
- }
- if (*cpp && !strcasecmp(*cpp, "or-block")) {
- if (!(fil.fr_flags & FR_PASS)) {
- fprintf(stderr,
- "%d: or-block must be used with pass\n",
- linenum);
- *status = -1;
- return NULL;
- }
- fil.fr_flags |= FR_LOGORBLOCK;
- cpp++;
- }
- if (*cpp && !strcasecmp(*cpp, "level")) {
- if (loglevel(cpp, &fil.fr_loglevel, linenum) == -1) {
- *status = -1;
- return NULL;
- }
- cpp++;
- cpp++;
- }
- }
-
- if (*cpp && !strcasecmp("quick", *cpp)) {
- if (fil.fr_skip != 0) {
- fprintf(stderr, "%d: cannot use skip with quick\n",
- linenum);
- *status = -1;
- return NULL;
- }
- cpp++;
- fil.fr_flags |= FR_QUICK;
- }
-
- /*
- * Parse rule options that are available if a rule is tied to an
- * interface.
- */
- *fil.fr_ifname = '\0';
- *fil.fr_oifname = '\0';
- if (*cpp && !strcasecmp(*cpp, "on")) {
- if (!*++cpp) {
- fprintf(stderr, "%d: interface name missing\n",
- linenum);
- *status = -1;
- return NULL;
- }
-
- s = index(*cpp, ',');
- if (s != NULL) {
- *s++ = '\0';
- (void)strncpy(fil.fr_ifnames[1], s, IFNAMSIZ - 1);
- fil.fr_ifnames[1][IFNAMSIZ - 1] = '\0';
- } else
- strcpy(fil.fr_ifnames[1], "*");
-
- (void)strncpy(fil.fr_ifnames[0], *cpp, IFNAMSIZ - 1);
- fil.fr_ifnames[0][IFNAMSIZ - 1] = '\0';
-
- cpp++;
- if (!*cpp) {
- if ((fil.fr_flags & FR_RETMASK) == FR_RETRST) {
- fprintf(stderr,
- "%d: %s can only be used with TCP\n",
- linenum, "return-rst");
- *status = -1;
- return NULL;
- }
- *status = 0;
- return &fil;
- }
-
- if (*cpp) {
- if (!strcasecmp(*cpp, "dup-to") && *(cpp + 1)) {
- cpp++;
- if (to_interface(&fil.fr_dif, *cpp, linenum)) {
- *status = -1;
- return NULL;
- }
- cpp++;
- }
- if (*cpp && !strcasecmp(*cpp, "to") && *(cpp + 1)) {
- cpp++;
- if (to_interface(&fil.fr_tif, *cpp, linenum)) {
- *status = -1;
- return NULL;
- }
- cpp++;
- } else if (*cpp && !strcasecmp(*cpp, "fastroute")) {
- if (!(fil.fr_flags & FR_INQUE)) {
- fprintf(stderr,
- "can only use %s with 'in'\n",
- "fastroute");
- *status = -1;
- return NULL;
- }
- fil.fr_flags |= FR_FASTROUTE;
- cpp++;
- }
- }
-
- /*
- * Set the "other" interface name. Lets you specify both
- * inbound and outbound interfaces for state rules. Do not
- * prevent both interfaces from being the same.
- */
- strcpy(fil.fr_ifnames[3], "*");
- if ((*cpp != NULL) && (*(cpp + 1) != NULL) &&
- ((((fil.fr_flags & FR_INQUE) != 0) &&
- (strcasecmp(*cpp, "out-via") == 0)) ||
- (((fil.fr_flags & FR_OUTQUE) != 0) &&
- (strcasecmp(*cpp, "in-via") == 0)))) {
- cpp++;
-
- s = index(*cpp, ',');
- if (s != NULL) {
- *s++ = '\0';
- (void)strncpy(fil.fr_ifnames[3], s,
- IFNAMSIZ - 1);
- fil.fr_ifnames[3][IFNAMSIZ - 1] = '\0';
- }
-
- (void)strncpy(fil.fr_ifnames[2], *cpp, IFNAMSIZ - 1);
- fil.fr_ifnames[2][IFNAMSIZ - 1] = '\0';
- cpp++;
- } else
- strcpy(fil.fr_ifnames[2], "*");
- }
- if (*cpp && !strcasecmp(*cpp, "tos")) {
- if (!*++cpp) {
- fprintf(stderr, "%d: tos missing value\n", linenum);
- *status = -1;
- return NULL;
- }
- fil.fr_tos = strtol(*cpp, NULL, 0);
- fil.fr_mip.fi_tos = 0xff;
- cpp++;
- }
-
- if (*cpp && !strcasecmp(*cpp, "ttl")) {
- if (!*++cpp) {
- fprintf(stderr, "%d: ttl missing hopcount value\n",
- linenum);
- *status = -1;
- return NULL;
- }
- if (ratoi(*cpp, &i, 0, 255))
- fil.fr_ttl = i;
- else {
- fprintf(stderr, "%d: invalid ttl (%s)\n",
- linenum, *cpp);
- *status = -1;
- return NULL;
- }
- fil.fr_mip.fi_ttl = 0xff;
- cpp++;
- }
-
- /*
- * check for "proto <protoname>" only decode udp/tcp/icmp as protoname
- */
- proto = NULL;
- if (*cpp && !strcasecmp(*cpp, "proto")) {
- if (!*++cpp) {
- fprintf(stderr, "%d: protocol name missing\n", linenum);
- *status = -1;
- return NULL;
- }
- proto = *cpp++;
- if (!strcasecmp(proto, "tcp/udp")) {
- fil.fr_ip.fi_fl |= FI_TCPUDP;
- fil.fr_mip.fi_fl |= FI_TCPUDP;
- } else if (use_inet6 && !strcasecmp(proto, "icmp")) {
- fprintf(stderr,
-"%d: use proto ipv6-icmp with IPv6 (or use proto 1 if you really mean icmp)\n",
- linenum);
- } else {
- if (!(p = getprotobyname(proto)) && !isdigit(*proto)) {
- fprintf(stderr,
- "%d: unknown protocol (%s)\n",
- linenum, proto);
- *status = -1;
- return NULL;
- }
- if (p)
- fil.fr_proto = p->p_proto;
- else if (isdigit(*proto)) {
- i = (int)strtol(proto, &endptr, 0);
- if (*endptr != '\0' || i < 0 || i > 255) {
- fprintf(stderr,
- "%d: unknown protocol (%s)\n",
- linenum, proto);
- *status = -1;
- return NULL;
- }
- fil.fr_proto = i;
- }
- fil.fr_mip.fi_p = 0xff;
- }
- }
- if ((fil.fr_proto != IPPROTO_TCP) &&
- ((fil.fr_flags & FR_RETMASK) == FR_RETRST)) {
- fprintf(stderr, "%d: %s can only be used with TCP\n",
- linenum, "return-rst");
- *status = -1;
- return NULL;
- }
-
- /*
- * get the from host and bit mask to use against packets
- */
-
- if (!*cpp) {
- fprintf(stderr, "%d: missing source specification\n", linenum);
- *status = -1;
- return NULL;
- }
- if (!strcasecmp(*cpp, "all")) {
- cpp++;
- if (!*cpp) {
- *status = 0;
- return &fil;
- }
- } else {
- if (strcasecmp(*cpp, "from")) {
- fprintf(stderr, "%d: unexpected keyword (%s) - from\n",
- linenum, *cpp);
- *status = -1;
- return NULL;
- }
- if (!*++cpp) {
- fprintf(stderr, "%d: missing host after from\n",
- linenum);
- *status = -1;
- return NULL;
- }
- if (!strcmp(*cpp, "!")) {
- fil.fr_flags |= FR_NOTSRCIP;
- if (!*++cpp) {
- fprintf(stderr,
- "%d: missing host after from\n",
- linenum);
- *status = -1;
- return NULL;
- }
- } else if (**cpp == '!') {
- fil.fr_flags |= FR_NOTSRCIP;
- (*cpp)++;
- }
- ch = 0;
- if (hostmask(&cpp, (u_32_t *)&fil.fr_src,
- (u_32_t *)&fil.fr_smsk, &fil.fr_sport, &ch,
- &fil.fr_stop, linenum)) {
- *status = -1;
- return NULL;
- }
-
- if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
- (fil.fr_proto != IPPROTO_UDP) &&
- !(fil.fr_ip.fi_fl & FI_TCPUDP)) {
- fprintf(stderr,
- "%d: cannot use port and neither tcp or udp\n",
- linenum);
- *status = -1;
- return NULL;
- }
-
- fil.fr_scmp = ch;
- if (!*cpp) {
- fprintf(stderr, "%d: missing to fields\n", linenum);
- *status = -1;
- return NULL;
- }
-
- /*
- * do the same for the to field (destination host)
- */
- if (strcasecmp(*cpp, "to")) {
- fprintf(stderr, "%d: unexpected keyword (%s) - to\n",
- linenum, *cpp);
- *status = -1;
- return NULL;
- }
- if (!*++cpp) {
- fprintf(stderr, "%d: missing host after to\n", linenum);
- *status = -1;
- return NULL;
- }
- ch = 0;
- if (!strcmp(*cpp, "!")) {
- fil.fr_flags |= FR_NOTDSTIP;
- if (!*++cpp) {
- fprintf(stderr,
- "%d: missing host after from\n",
- linenum);
- *status = -1;
- return NULL;
- }
- } else if (**cpp == '!') {
- fil.fr_flags |= FR_NOTDSTIP;
- (*cpp)++;
- }
- if (hostmask(&cpp, (u_32_t *)&fil.fr_dst,
- (u_32_t *)&fil.fr_dmsk, &fil.fr_dport, &ch,
- &fil.fr_dtop, linenum)) {
- *status = -1;
- return NULL;
- }
- if ((ch != 0) && (fil.fr_proto != IPPROTO_TCP) &&
- (fil.fr_proto != IPPROTO_UDP) &&
- !(fil.fr_ip.fi_fl & FI_TCPUDP)) {
- fprintf(stderr,
- "%d: cannot use port and neither tcp or udp\n",
- linenum);
- *status = -1;
- return NULL;
- }
-
- fil.fr_dcmp = ch;
- }
-
- /*
- * check some sanity, make sure we don't have icmp checks with tcp
- * or udp or visa versa.
- */
- if (fil.fr_proto && (fil.fr_dcmp || fil.fr_scmp) &&
- fil.fr_proto != IPPROTO_TCP && fil.fr_proto != IPPROTO_UDP) {
- fprintf(stderr, "%d: port operation on non tcp/udp\n", linenum);
- *status = -1;
- return NULL;
- }
- if (fil.fr_icmp && fil.fr_proto != IPPROTO_ICMP) {
- fprintf(stderr, "%d: icmp comparisons on wrong protocol\n",
- linenum);
- *status = -1;
- return NULL;
- }
-
- if (!*cpp) {
- *status = 0;
- return &fil;
- }
-
- if (*cpp && !strcasecmp(*cpp, "flags")) {
- if (!*++cpp) {
- fprintf(stderr, "%d: no flags present\n", linenum);
- *status = -1;
- return NULL;
- }
- fil.fr_tcpf = tcp_flags(*cpp, &fil.fr_tcpfm, linenum);
- cpp++;
- }
-
- /*
- * extras...
- */
- if ((fil.fr_v == 4) && *cpp && (!strcasecmp(*cpp, "with") ||
- !strcasecmp(*cpp, "and")))
- if (extras(&cpp, &fil, linenum)) {
- *status = -1;
- return NULL;
- }
-
- /*
- * icmp types for use with the icmp protocol
- */
- if (*cpp && !strcasecmp(*cpp, "icmp-type")) {
- if (fil.fr_proto != IPPROTO_ICMP &&
- fil.fr_proto != IPPROTO_ICMPV6) {
- fprintf(stderr,
- "%d: icmp with wrong protocol (%d)\n",
- linenum, fil.fr_proto);
- *status = -1;
- return NULL;
- }
- if (addicmp(&cpp, &fil, linenum)) {
- *status = -1;
- return NULL;
- }
- fil.fr_icmp = htons(fil.fr_icmp);
- fil.fr_icmpm = htons(fil.fr_icmpm);
- }
-
- /*
- * Keep something...
- */
- while (*cpp && !strcasecmp(*cpp, "keep"))
- if (addkeep(&cpp, &fil, linenum)) {
- *status = -1;
- return NULL;
- }
-
- /*
- * This is here to enforce the old interface binding behaviour.
- * That is, "on X" is equivalent to "<dir> on X <!dir>-via -,X"
- */
- if (fil.fr_flags & FR_KEEPSTATE) {
- if (*fil.fr_ifnames[0] && !*fil.fr_ifnames[3]) {
- bcopy(fil.fr_ifnames[0], fil.fr_ifnames[3],
- sizeof(fil.fr_ifnames[3]));
- strncpy(fil.fr_ifnames[2], "*",
- sizeof(fil.fr_ifnames[3]));
- }
- }
-
- /*
- * head of a new group ?
- */
- if (*cpp && !strcasecmp(*cpp, "head")) {
- if (fil.fr_skip != 0) {
- fprintf(stderr, "%d: cannot use skip with head\n",
- linenum);
- *status = -1;
- return NULL;
- }
- if (!*++cpp) {
- fprintf(stderr, "%d: head without group #\n", linenum);
- *status = -1;
- return NULL;
- }
- if (ratoui(*cpp, &k, 0, UINT_MAX))
- fil.fr_grhead = (u_32_t)k;
- else {
- fprintf(stderr, "%d: invalid group (%s)\n",
- linenum, *cpp);
- *status = -1;
- return NULL;
- }
- cpp++;
- }
-
- /*
- * head of a new group ?
- */
- if (*cpp && !strcasecmp(*cpp, "group")) {
- if (!*++cpp) {
- fprintf(stderr, "%d: group without group #\n",
- linenum);
- *status = -1;
- return NULL;
- }
- if (ratoui(*cpp, &k, 0, UINT_MAX))
- fil.fr_group = k;
- else {
- fprintf(stderr, "%d: invalid group (%s)\n",
- linenum, *cpp);
- *status = -1;
- return NULL;
- }
- cpp++;
- }
-
- /*
- * leftovers...yuck
- */
- if (*cpp && **cpp) {
- fprintf(stderr, "%d: unknown words at end: [", linenum);
- for (; *cpp; cpp++)
- fprintf(stderr, "%s ", *cpp);
- fprintf(stderr, "]\n");
- *status = -1;
- return NULL;
- }
-
- /*
- * lazy users...
- */
- if ((fil.fr_tcpf || fil.fr_tcpfm) && fil.fr_proto != IPPROTO_TCP) {
- fprintf(stderr, "%d: TCP protocol not specified\n", linenum);
- *status = -1;
- return NULL;
- }
- if (!(fil.fr_ip.fi_fl & FI_TCPUDP) && (fil.fr_proto != IPPROTO_TCP) &&
- (fil.fr_proto != IPPROTO_UDP) && (fil.fr_dcmp || fil.fr_scmp)) {
- if (!fil.fr_proto) {
- fil.fr_ip.fi_fl |= FI_TCPUDP;
- fil.fr_mip.fi_fl |= FI_TCPUDP;
- } else {
- fprintf(stderr,
- "%d: port comparisons for non-TCP/UDP\n",
- linenum);
- *status = -1;
- return NULL;
- }
- }
-/*
- if ((fil.fr_flags & FR_KEEPFRAG) &&
- (!(fil.fr_ip.fi_fl & FI_FRAG) || !(fil.fr_ip.fi_fl & FI_FRAG))) {
- fprintf(stderr,
- "%d: must use 'with frags' with 'keep frags'\n",
- linenum);
- *status = -1;
- return NULL;
- }
-*/
- *status = 0;
- return &fil;
-}
-
-
-int loglevel(cpp, facpri, linenum)
-char **cpp;
-u_int *facpri;
-int linenum;
-{
- int fac, pri;
- char *s;
-
- fac = 0;
- pri = 0;
- if (!*++cpp) {
- fprintf(stderr, "%d: %s\n", linenum,
- "missing identifier after level");
- return -1;
- }
-
- s = index(*cpp, '.');
- if (s) {
- *s++ = '\0';
- fac = fac_findname(*cpp);
- if (fac == -1) {
- fprintf(stderr, "%d: %s %s\n", linenum,
- "Unknown facility", *cpp);
- return -1;
- }
- pri = pri_findname(s);
- if (pri == -1) {
- fprintf(stderr, "%d: %s %s\n", linenum,
- "Unknown priority", s);
- return -1;
- }
- } else {
- pri = pri_findname(*cpp);
- if (pri == -1) {
- fprintf(stderr, "%d: %s %s\n", linenum,
- "Unknown priority", *cpp);
- return -1;
- }
- }
- *facpri = fac|pri;
- return 0;
-}
-
-
-int to_interface(fdp, to, linenum)
-frdest_t *fdp;
-char *to;
-int linenum;
-{
- char *s;
-
- s = index(to, ':');
- fdp->fd_ifp = NULL;
- if (s) {
- *s++ = '\0';
- if (hostnum((u_32_t *)&fdp->fd_ip, s, linenum) == -1)
- return -1;
- }
- (void) strncpy(fdp->fd_ifname, to, sizeof(fdp->fd_ifname) - 1);
- fdp->fd_ifname[sizeof(fdp->fd_ifname) - 1] = '\0';
- return 0;
-}
-
-
-void print_toif(tag, fdp)
-char *tag;
-frdest_t *fdp;
-{
- printf("%s %s%s", tag, fdp->fd_ifname,
- (fdp->fd_ifp || (long)fdp->fd_ifp == -1) ? "" : "(!)");
-#ifdef USE_INET6
- if (use_inet6 && IP6_NOTZERO(&fdp->fd_ip6.in6)) {
- char ipv6addr[80];
-
- inet_ntop(AF_INET6, &fdp->fd_ip6, ipv6addr,
- sizeof(fdp->fd_ip6));
- printf(":%s", ipv6addr);
- } else
-#endif
- if (fdp->fd_ip.s_addr)
- printf(":%s", inet_ntoa(fdp->fd_ip));
- putchar(' ');
-}
-
-
-/*
- * deal with extra bits on end of the line
- */
-int extras(cp, fr, linenum)
-char ***cp;
-struct frentry *fr;
-int linenum;
-{
- u_short secmsk;
- u_long opts;
- int notopt;
- char oflags;
-
- opts = 0;
- secmsk = 0;
- notopt = 0;
- (*cp)++;
- if (!**cp)
- return -1;
-
- while (**cp && (!strncasecmp(**cp, "ipopt", 5) ||
- !strcasecmp(**cp, "not") || !strncasecmp(**cp, "opt", 3) ||
- !strncasecmp(**cp, "frag", 4) || !strcasecmp(**cp, "no") ||
- !strcasecmp(**cp, "short"))) {
- if (***cp == 'n' || ***cp == 'N') {
- notopt = 1;
- (*cp)++;
- continue;
- } else if (***cp == 'i' || ***cp == 'I') {
- if (!notopt)
- fr->fr_ip.fi_fl |= FI_OPTIONS;
- fr->fr_mip.fi_fl |= FI_OPTIONS;
- goto nextopt;
- } else if (***cp == 'f' || ***cp == 'F') {
- if (!notopt)
- fr->fr_ip.fi_fl |= FI_FRAG;
- fr->fr_mip.fi_fl |= FI_FRAG;
- goto nextopt;
- } else if (***cp == 'o' || ***cp == 'O') {
- if (!*(*cp + 1)) {
- fprintf(stderr,
- "%d: opt missing arguements\n",
- linenum);
- return -1;
- }
- (*cp)++;
- if (!(opts = optname(cp, &secmsk, linenum)))
- return -1;
- oflags = FI_OPTIONS;
- } else if (***cp == 's' || ***cp == 'S') {
- if (fr->fr_tcpf) {
- fprintf(stderr,
- "%d: short cannot be used with TCP flags\n",
- linenum);
- return -1;
- }
-
- if (!notopt)
- fr->fr_ip.fi_fl |= FI_SHORT;
- fr->fr_mip.fi_fl |= FI_SHORT;
- goto nextopt;
- } else
- return -1;
-
- if (!notopt || !opts)
- fr->fr_mip.fi_fl |= oflags;
- if (notopt) {
- if (!secmsk) {
- fr->fr_mip.fi_optmsk |= opts;
- } else {
- fr->fr_mip.fi_optmsk |= (opts & ~0x0100);
- }
- } else {
- fr->fr_mip.fi_optmsk |= opts;
- }
- fr->fr_mip.fi_secmsk |= secmsk;
-
- if (notopt) {
- fr->fr_ip.fi_fl &= (~oflags & 0xf);
- fr->fr_ip.fi_optmsk &= ~opts;
- fr->fr_ip.fi_secmsk &= ~secmsk;
- } else {
- fr->fr_ip.fi_fl |= oflags;
- fr->fr_ip.fi_optmsk |= opts;
- fr->fr_ip.fi_secmsk |= secmsk;
- }
-nextopt:
- notopt = 0;
- opts = 0;
- oflags = 0;
- secmsk = 0;
- (*cp)++;
- }
- return 0;
-}
-
-
-u_32_t optname(cp, sp, linenum)
-char ***cp;
-u_short *sp;
-int linenum;
-{
- struct ipopt_names *io, *so;
- u_long msk = 0;
- u_short smsk = 0;
- char *s;
- int sec = 0;
-
- for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) {
- for (io = ionames; io->on_name; io++)
- if (!strcasecmp(s, io->on_name)) {
- msk |= io->on_bit;
- break;
- }
- if (!io->on_name) {
- fprintf(stderr, "%d: unknown IP option name %s\n",
- linenum, s);
- return 0;
- }
- if (!strcasecmp(s, "sec-class"))
- sec = 1;
- }
-
- if (sec && !*(*cp + 1)) {
- fprintf(stderr, "%d: missing security level after sec-class\n",
- linenum);
- return 0;
- }
-
- if (sec) {
- (*cp)++;
- for (s = strtok(**cp, ","); s; s = strtok(NULL, ",")) {
- for (so = secclass; so->on_name; so++)
- if (!strcasecmp(s, so->on_name)) {
- smsk |= so->on_bit;
- break;
- }
- if (!so->on_name) {
- fprintf(stderr,
- "%d: no such security level: %s\n",
- linenum, s);
- return 0;
- }
- }
- if (smsk)
- *sp = smsk;
- }
- return msk;
-}
-
-
-#ifdef __STDC__
-void optprint(u_short *sec, u_long optmsk, u_long optbits)
-#else
-void optprint(sec, optmsk, optbits)
-u_short *sec;
-u_long optmsk, optbits;
-#endif
-{
- u_short secmsk = sec[0], secbits = sec[1];
- struct ipopt_names *io, *so;
- char *s;
-
- s = " opt ";
- for (io = ionames; io->on_name; io++)
- if ((io->on_bit & optmsk) &&
- ((io->on_bit & optmsk) == (io->on_bit & optbits))) {
- if ((io->on_value != IPOPT_SECURITY) ||
- (!secmsk && !secbits)) {
- printf("%s%s", s, io->on_name);
- if (io->on_value == IPOPT_SECURITY)
- io++;
- s = ",";
- }
- }
-
-
- if (secmsk & secbits) {
- printf("%ssec-class", s);
- s = " ";
- for (so = secclass; so->on_name; so++)
- if ((secmsk & so->on_bit) &&
- ((so->on_bit & secmsk) == (so->on_bit & secbits))) {
- printf("%s%s", s, so->on_name);
- s = ",";
- }
- }
-
- if ((optmsk && (optmsk != optbits)) ||
- (secmsk && (secmsk != secbits))) {
- s = " ";
- printf(" not opt");
- if (optmsk != optbits) {
- for (io = ionames; io->on_name; io++)
- if ((io->on_bit & optmsk) &&
- ((io->on_bit & optmsk) !=
- (io->on_bit & optbits))) {
- if ((io->on_value != IPOPT_SECURITY) ||
- (!secmsk && !secbits)) {
- printf("%s%s", s, io->on_name);
- s = ",";
- if (io->on_value ==
- IPOPT_SECURITY)
- io++;
- } else
- io++;
- }
- }
-
- if (secmsk != secbits) {
- printf("%ssec-class", s);
- s = " ";
- for (so = secclass; so->on_name; so++)
- if ((so->on_bit & secmsk) &&
- ((so->on_bit & secmsk) !=
- (so->on_bit & secbits))) {
- printf("%s%s", s, so->on_name);
- s = ",";
- }
- }
- }
-}
-
-char *icmptypes[] = {
- "echorep", (char *)NULL, (char *)NULL, "unreach", "squench",
- "redir", (char *)NULL, (char *)NULL, "echo", "routerad",
- "routersol", "timex", "paramprob", "timest", "timestrep",
- "inforeq", "inforep", "maskreq", "maskrep", "END"
-};
-
-/*
- * set the icmp field to the correct type if "icmp" word is found
- */
-int addicmp(cp, fp, linenum)
-char ***cp;
-struct frentry *fp;
-int linenum;
-{
- char **t;
- int i;
-
- (*cp)++;
- if (!**cp)
- return -1;
-
- if (isdigit(***cp)) {
- if (!ratoi(**cp, &i, 0, 255)) {
- fprintf(stderr,
- "%d: Invalid icmp-type (%s) specified\n",
- linenum, **cp);
- return -1;
- }
- } else if (fp->fr_proto == IPPROTO_ICMPV6) {
- fprintf(stderr, "%d: Unknown ICMPv6 type (%s) specified, %s",
- linenum, **cp, "(use numeric value instead)\n");
- return -1;
- } else {
- for (t = icmptypes, i = 0; ; t++, i++) {
- if (!*t)
- continue;
- if (!strcasecmp("END", *t)) {
- i = -1;
- break;
- }
- if (!strcasecmp(*t, **cp))
- break;
- }
- if (i == -1) {
- fprintf(stderr,
- "%d: Invalid icmp-type (%s) specified\n",
- linenum, **cp);
- return -1;
- }
- }
- fp->fr_icmp = (u_short)(i << 8);
- fp->fr_icmpm = (u_short)0xff00;
- (*cp)++;
- if (!**cp)
- return 0;
-
- if (**cp && strcasecmp("code", **cp))
- return 0;
- (*cp)++;
- if (isdigit(***cp)) {
- if (!ratoi(**cp, &i, 0, 255)) {
- fprintf(stderr,
- "%d: Invalid icmp code (%s) specified\n",
- linenum, **cp);
- return -1;
- }
- } else {
- i = icmpcode(**cp);
- if (i == -1) {
- fprintf(stderr,
- "%d: Invalid icmp code (%s) specified\n",
- linenum, **cp);
- return -1;
- }
- }
- i &= 0xff;
- fp->fr_icmp |= (u_short)i;
- fp->fr_icmpm = (u_short)0xffff;
- (*cp)++;
- return 0;
-}
-
-
-#define MAX_ICMPCODE 15
-
-char *icmpcodes[] = {
- "net-unr", "host-unr", "proto-unr", "port-unr", "needfrag",
- "srcfail", "net-unk", "host-unk", "isolate", "net-prohib",
- "host-prohib", "net-tos", "host-tos", "filter-prohib", "host-preced",
- "preced-cutoff", NULL };
-/*
- * Return the number for the associated ICMP unreachable code.
- */
-int icmpcode(str)
-char *str;
-{
- char *s;
- int i, len;
-
- if ((s = strrchr(str, ')')))
- *s = '\0';
- if (isdigit(*str)) {
- if (!ratoi(str, &i, 0, 255))
- return -1;
- else
- return i;
- }
- len = strlen(str);
- for (i = 0; icmpcodes[i]; i++)
- if (!strncasecmp(str, icmpcodes[i], MIN(len,
- strlen(icmpcodes[i])) ))
- return i;
- return -1;
-}
-
-
-/*
- * set the icmp field to the correct type if "icmp" word is found
- */
-int addkeep(cp, fp, linenum)
-char ***cp;
-struct frentry *fp;
-int linenum;
-{
- char *s;
-
- (*cp)++;
- if (!**cp) {
- fprintf(stderr, "%d: Missing keyword after keep\n",
- linenum);
- return -1;
- }
-
- if (strcasecmp(**cp, "state") == 0)
- fp->fr_flags |= FR_KEEPSTATE;
- else if (strncasecmp(**cp, "frag", 4) == 0)
- fp->fr_flags |= FR_KEEPFRAG;
- else if (strcasecmp(**cp, "state-age") == 0) {
- if (fp->fr_ip.fi_p == IPPROTO_TCP) {
- fprintf(stderr, "%d: cannot use state-age with tcp\n",
- linenum);
- return -1;
- }
- if ((fp->fr_flags & FR_KEEPSTATE) == 0) {
- fprintf(stderr, "%d: state-age with no 'keep state'\n",
- linenum);
- return -1;
- }
- (*cp)++;
- if (!**cp) {
- fprintf(stderr, "%d: state-age with no arg\n",
- linenum);
- return -1;
- }
- fp->fr_age[0] = atoi(**cp);
- s = index(**cp, '/');
- if (s != NULL) {
- s++;
- fp->fr_age[1] = atoi(s);
- } else
- fp->fr_age[1] = fp->fr_age[0];
- } else {
- fprintf(stderr, "%d: Unrecognised state keyword \"%s\"\n",
- linenum, **cp);
- return -1;
- }
- (*cp)++;
- return 0;
-}
-
-
-void printifname(format, name, ifp)
-char *format, *name;
-void *ifp;
-{
- printf("%s%s", format, name);
- if ((ifp == NULL) && strcmp(name, "-") && strcmp(name, "*"))
- printf("(!)");
-}
-
-
-/*
- * print the filter structure in a useful way
- */
-void printfr(fp)
-struct frentry *fp;
-{
- struct protoent *p;
- u_short sec[2];
- char *s;
- u_char *t;
- int pr;
-
- if (fp->fr_flags & FR_PASS)
- printf("pass");
- if (fp->fr_flags & FR_NOMATCH)
- printf("nomatch");
- else if (fp->fr_flags & FR_BLOCK) {
- printf("block");
- if (fp->fr_flags & FR_RETICMP) {
- if ((fp->fr_flags & FR_RETMASK) == FR_FAKEICMP)
- printf(" return-icmp-as-dest");
- else if ((fp->fr_flags & FR_RETMASK) == FR_RETICMP)
- printf(" return-icmp");
- if (fp->fr_icode) {
- if (fp->fr_icode <= MAX_ICMPCODE)
- printf("(%s)",
- icmpcodes[(int)fp->fr_icode]);
- else
- printf("(%d)", fp->fr_icode);
- }
- } else if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
- printf(" return-rst");
- } else if ((fp->fr_flags & FR_LOGMASK) == FR_LOG) {
- printlog(fp);
- } else if (fp->fr_flags & FR_ACCOUNT)
- printf("count");
- else if (fp->fr_flags & FR_AUTH) {
- printf("auth");
- if ((fp->fr_flags & FR_RETMASK) == FR_RETRST)
- printf(" return-rst");
- } else if (fp->fr_flags & FR_PREAUTH)
- printf("preauth");
- else if (fp->fr_skip)
- printf("skip %hu", fp->fr_skip);
-
- if (fp->fr_flags & FR_OUTQUE)
- printf(" out ");
- else
- printf(" in ");
-
- if (((fp->fr_flags & FR_LOGB) == FR_LOGB) ||
- ((fp->fr_flags & FR_LOGP) == FR_LOGP)) {
- printlog(fp);
- putchar(' ');
- }
-
- if (fp->fr_flags & FR_QUICK)
- printf("quick ");
-
- if (*fp->fr_ifname) {
- printifname("on ", fp->fr_ifname, fp->fr_ifa);
- if (*fp->fr_ifnames[1] && strcmp(fp->fr_ifnames[1], "*"))
- printifname(",", fp->fr_ifnames[1], fp->fr_ifas[1]);
- putchar(' ');
-
- if (*fp->fr_dif.fd_ifname)
- print_toif("dup-to", &fp->fr_dif);
- if (*fp->fr_tif.fd_ifname)
- print_toif("to", &fp->fr_tif);
- if (fp->fr_flags & FR_FASTROUTE)
- printf("fastroute ");
-
- if ((*fp->fr_ifnames[2] && strcmp(fp->fr_ifnames[2], "*")) ||
- (*fp->fr_ifnames[3] && strcmp(fp->fr_ifnames[3], "*"))) {
- if (fp->fr_flags & FR_OUTQUE)
- printf("in-via ");
- else
- printf("out-via ");
-
- if (*fp->fr_ifnames[2]) {
- printifname("", fp->fr_ifnames[2],
- fp->fr_ifas[2]);
- putchar(',');
- }
-
- if (*fp->fr_ifnames[3])
- printifname("", fp->fr_ifnames[3],
- fp->fr_ifas[3]);
- putchar(' ');
- }
- }
-
- if (fp->fr_mip.fi_tos)
- printf("tos %#x ", fp->fr_tos);
- if (fp->fr_mip.fi_ttl)
- printf("ttl %d ", fp->fr_ttl);
- if (fp->fr_ip.fi_fl & FI_TCPUDP) {
- printf("proto tcp/udp ");
- pr = -1;
- } else if ((pr = fp->fr_mip.fi_p)) {
- if ((p = getprotobynumber(fp->fr_proto)))
- printf("proto %s ", p->p_name);
- else
- printf("proto %d ", fp->fr_proto);
- }
-
- printf("from %s", fp->fr_flags & FR_NOTSRCIP ? "!" : "");
- printhostmask(fp->fr_v, (u_32_t *)&fp->fr_src.s_addr,
- (u_32_t *)&fp->fr_smsk.s_addr);
- if (fp->fr_scmp)
- printportcmp(pr, &fp->fr_tuc.ftu_src);
-
- printf(" to %s", fp->fr_flags & FR_NOTDSTIP ? "!" : "");
- printhostmask(fp->fr_v, (u_32_t *)&fp->fr_dst.s_addr,
- (u_32_t *)&fp->fr_dmsk.s_addr);
- if (fp->fr_dcmp)
- printportcmp(pr, &fp->fr_tuc.ftu_dst);
-
- if ((fp->fr_ip.fi_fl & ~FI_TCPUDP) ||
- (fp->fr_mip.fi_fl & ~FI_TCPUDP) ||
- fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk ||
- fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk) {
- printf(" with");
- if (fp->fr_ip.fi_optmsk || fp->fr_mip.fi_optmsk ||
- fp->fr_ip.fi_secmsk || fp->fr_mip.fi_secmsk) {
- sec[0] = fp->fr_mip.fi_secmsk;
- sec[1] = fp->fr_ip.fi_secmsk;
- optprint(sec,
- fp->fr_mip.fi_optmsk, fp->fr_ip.fi_optmsk);
- } else if (fp->fr_mip.fi_fl & FI_OPTIONS) {
- if (!(fp->fr_ip.fi_fl & FI_OPTIONS))
- printf(" not");
- printf(" ipopt");
- }
- if (fp->fr_mip.fi_fl & FI_SHORT) {
- if (!(fp->fr_ip.fi_fl & FI_SHORT))
- printf(" not");
- printf(" short");
- }
- if (fp->fr_mip.fi_fl & FI_FRAG) {
- if (!(fp->fr_ip.fi_fl & FI_FRAG))
- printf(" not");
- printf(" frag");
- }
- }
- if (fp->fr_proto == IPPROTO_ICMP && fp->fr_icmpm != 0) {
- int type = fp->fr_icmp, code;
-
- type = ntohs(fp->fr_icmp);
- code = type & 0xff;
- type /= 256;
- if (type < (sizeof(icmptypes) / sizeof(char *) - 1) &&
- icmptypes[type])
- printf(" icmp-type %s", icmptypes[type]);
- else
- printf(" icmp-type %d", type);
- if (ntohs(fp->fr_icmpm) & 0xff)
- printf(" code %d", code);
- }
- if (fp->fr_proto == IPPROTO_ICMPV6 && fp->fr_icmpm != 0) {
- int type = fp->fr_icmp, code;
-
- type = ntohs(fp->fr_icmp);
- code = type & 0xff;
- type /= 256;
- printf(" icmp-type %d", type);
- if (ntohs(fp->fr_icmpm) & 0xff)
- printf(" code %d", code);
- }
- if (fp->fr_proto == IPPROTO_TCP && (fp->fr_tcpf || fp->fr_tcpfm)) {
- printf(" flags ");
- if (fp->fr_tcpf & ~TCPF_ALL)
- printf("0x%x", fp->fr_tcpf);
- else
- for (s = flagset, t = flags; *s; s++, t++)
- if (fp->fr_tcpf & *t)
- (void)putchar(*s);
- if (fp->fr_tcpfm) {
- (void)putchar('/');
- if (fp->fr_tcpfm & ~TCPF_ALL)
- printf("0x%x", fp->fr_tcpfm);
- else
- for (s = flagset, t = flags; *s; s++, t++)
- if (fp->fr_tcpfm & *t)
- (void)putchar(*s);
- }
- }
-
- if (fp->fr_flags & FR_KEEPSTATE)
- printf(" keep state");
- if (fp->fr_flags & FR_KEEPFRAG)
- printf(" keep frags");
- if (fp->fr_age[0] != 0 || fp->fr_age[1]!= 0)
- printf(" state-age %u/%u", fp->fr_age[0], fp->fr_age[1]);
- if (fp->fr_grhead)
- printf(" head %d", fp->fr_grhead);
- if (fp->fr_group)
- printf(" group %d", fp->fr_group);
- (void)putchar('\n');
-}
-
-void binprint(fp)
-struct frentry *fp;
-{
- int i = sizeof(*fp), j = 0;
- u_char *s;
-
- for (s = (u_char *)fp; i; i--, s++) {
- j++;
- printf("%02x ", *s);
- if (j == 16) {
- printf("\n");
- j = 0;
- }
- }
- putchar('\n');
- (void)fflush(stdout);
-}
-
-
-void printlog(fp)
-frentry_t *fp;
-{
- char *s, *u;
-
- printf("log");
- if (fp->fr_flags & FR_LOGBODY)
- printf(" body");
- if (fp->fr_flags & FR_LOGFIRST)
- printf(" first");
- if (fp->fr_flags & FR_LOGORBLOCK)
- printf(" or-block");
- if (fp->fr_loglevel != 0xffff) {
- printf(" level ");
- if (fp->fr_loglevel & LOG_FACMASK) {
- s = fac_toname(fp->fr_loglevel);
- if (s == NULL)
- s = "!!!";
- } else
- s = "";
- u = pri_toname(fp->fr_loglevel);
- if (u == NULL)
- u = "!!!";
- if (*s)
- printf("%s.%s", s, u);
- else
- printf("%s", u);
- }
-}
OpenPOWER on IntegriCloud