summaryrefslogtreecommitdiffstats
path: root/tools/ippool_y.y
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ippool_y.y')
-rw-r--r--tools/ippool_y.y520
1 files changed, 520 insertions, 0 deletions
diff --git a/tools/ippool_y.y b/tools/ippool_y.y
new file mode 100644
index 0000000..4aa5108
--- /dev/null
+++ b/tools/ippool_y.y
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2001-2006 by Darren Reed.
+ *
+ * See the IPFILTER.LICENCE file for details on licencing.
+ */
+%{
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#if defined(BSD) && (BSD >= 199306)
+# include <sys/cdefs.h>
+#endif
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#if __FreeBSD_version >= 300000
+# include <net/if_var.h>
+#endif
+#include <netinet/in.h>
+
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <ctype.h>
+#include <unistd.h>
+
+#include "ipf.h"
+#include "netinet/ip_lookup.h"
+#include "netinet/ip_pool.h"
+#include "netinet/ip_htable.h"
+#include "ippool_l.h"
+#include "kmem.h"
+
+#define YYDEBUG 1
+#define YYSTACKSIZE 0x00ffffff
+
+extern int yyparse __P((void));
+extern int yydebug;
+extern FILE *yyin;
+
+static iphtable_t ipht;
+static iphtent_t iphte;
+static ip_pool_t iplo;
+static ioctlfunc_t poolioctl = NULL;
+static char poolname[FR_GROUPLEN];
+
+static iphtent_t *add_htablehosts __P((char *));
+static ip_pool_node_t *add_poolhosts __P((char *));
+
+%}
+
+%union {
+ char *str;
+ u_32_t num;
+ struct in_addr addr;
+ struct alist_s *alist;
+ struct in_addr adrmsk[2];
+ iphtent_t *ipe;
+ ip_pool_node_t *ipp;
+ union i6addr ip6;
+}
+
+%token <num> YY_NUMBER YY_HEX
+%token <str> YY_STR
+%token YY_COMMENT
+%token YY_CMP_EQ YY_CMP_NE YY_CMP_LE YY_CMP_GE YY_CMP_LT YY_CMP_GT
+%token YY_RANGE_OUT YY_RANGE_IN
+%token <ip6> YY_IPV6
+
+%token IPT_IPF IPT_NAT IPT_COUNT IPT_AUTH IPT_IN IPT_OUT
+%token IPT_TABLE IPT_GROUPMAP IPT_HASH
+%token IPT_ROLE IPT_TYPE IPT_TREE
+%token IPT_GROUP IPT_SIZE IPT_SEED IPT_NUM IPT_NAME
+%type <num> role table inout
+%type <ipp> ipftree range addrlist
+%type <adrmsk> addrmask
+%type <ipe> ipfgroup ipfhash hashlist hashentry
+%type <ipe> groupentry setgrouplist grouplist
+%type <addr> ipaddr mask ipv4
+%type <str> number setgroup
+
+%%
+file: line
+ | assign
+ | file line
+ | file assign
+ ;
+
+line: table role ipftree eol { iplo.ipo_unit = $2;
+ iplo.ipo_list = $3;
+ load_pool(&iplo, poolioctl);
+ resetlexer();
+ }
+ | table role ipfhash eol { ipht.iph_unit = $2;
+ ipht.iph_type = IPHASH_LOOKUP;
+ load_hash(&ipht, $3, poolioctl);
+ resetlexer();
+ }
+ | groupmap role number ipfgroup eol
+ { ipht.iph_unit = $2;
+ strncpy(ipht.iph_name, $3,
+ sizeof(ipht.iph_name));
+ ipht.iph_type = IPHASH_GROUPMAP;
+ load_hash(&ipht, $4, poolioctl);
+ resetlexer();
+ }
+ | YY_COMMENT
+ ;
+
+eol: ';'
+ ;
+
+assign: YY_STR assigning YY_STR ';' { set_variable($1, $3);
+ resetlexer();
+ free($1);
+ free($3);
+ yyvarnext = 0;
+ }
+ ;
+
+assigning:
+ '=' { yyvarnext = 1; }
+ ;
+
+table: IPT_TABLE { bzero((char *)&ipht, sizeof(ipht));
+ bzero((char *)&iphte, sizeof(iphte));
+ bzero((char *)&iplo, sizeof(iplo));
+ *ipht.iph_name = '\0';
+ iplo.ipo_flags = IPHASH_ANON;
+ iplo.ipo_name[0] = '\0';
+ }
+ ;
+
+groupmap:
+ IPT_GROUPMAP inout { bzero((char *)&ipht, sizeof(ipht));
+ bzero((char *)&iphte, sizeof(iphte));
+ *ipht.iph_name = '\0';
+ ipht.iph_unit = IPHASH_GROUPMAP;
+ ipht.iph_flags = $2;
+ }
+ ;
+
+inout: IPT_IN { $$ = FR_INQUE; }
+ | IPT_OUT { $$ = FR_OUTQUE; }
+ ;
+role:
+ IPT_ROLE '=' IPT_IPF { $$ = IPL_LOGIPF; }
+ | IPT_ROLE '=' IPT_NAT { $$ = IPL_LOGNAT; }
+ | IPT_ROLE '=' IPT_AUTH { $$ = IPL_LOGAUTH; }
+ | IPT_ROLE '=' IPT_COUNT { $$ = IPL_LOGCOUNT; }
+ ;
+
+ipftree:
+ IPT_TYPE '=' IPT_TREE number start addrlist end
+ { strncpy(iplo.ipo_name, $4,
+ sizeof(iplo.ipo_name));
+ $$ = $6;
+ }
+ ;
+
+ipfhash:
+ IPT_TYPE '=' IPT_HASH number hashopts start hashlist end
+ { strncpy(ipht.iph_name, $4,
+ sizeof(ipht.iph_name));
+ $$ = $7;
+ }
+ ;
+
+ipfgroup:
+ setgroup hashopts start grouplist end
+ { iphtent_t *e;
+ for (e = $4; e != NULL;
+ e = e->ipe_next)
+ if (e->ipe_group[0] == '\0')
+ strncpy(e->ipe_group,
+ $1,
+ FR_GROUPLEN);
+ $$ = $4;
+ }
+ | hashopts start setgrouplist end { $$ = $3; }
+ ;
+
+number: IPT_NUM '=' YY_NUMBER { sprintf(poolname, "%u", $3);
+ $$ = poolname;
+ }
+ | IPT_NAME '=' YY_STR { $$ = $3; }
+ | { $$ = ""; }
+ ;
+
+setgroup:
+ IPT_GROUP '=' YY_STR { char tmp[FR_GROUPLEN+1];
+ strncpy(tmp, $3, FR_GROUPLEN);
+ $$ = strdup(tmp);
+ }
+ | IPT_GROUP '=' YY_NUMBER { char tmp[FR_GROUPLEN+1];
+ sprintf(tmp, "%u", $3);
+ $$ = strdup(tmp);
+ }
+ ;
+
+hashopts:
+ | size
+ | seed
+ | size seed
+ ;
+
+addrlist:
+ next { $$ = NULL; }
+ | range next addrlist { $1->ipn_next = $3; $$ = $1; }
+ | range next { $$ = $1; }
+ ;
+
+grouplist:
+ next { $$ = NULL; }
+ | groupentry next grouplist { $$ = $1; $1->ipe_next = $3; }
+ | addrmask next grouplist { $$ = calloc(1, sizeof(iphtent_t));
+ bcopy((char *)&($1[0]),
+ (char *)&($$->ipe_addr),
+ sizeof($$->ipe_addr));
+ bcopy((char *)&($1[1]),
+ (char *)&($$->ipe_mask),
+ sizeof($$->ipe_mask));
+ $$->ipe_next = $3;
+ }
+ | groupentry next { $$ = $1; }
+ | addrmask next { $$ = calloc(1, sizeof(iphtent_t));
+ bcopy((char *)&($1[0]),
+ (char *)&($$->ipe_addr),
+ sizeof($$->ipe_addr));
+ bcopy((char *)&($1[1]),
+ (char *)&($$->ipe_mask),
+ sizeof($$->ipe_mask));
+ }
+ ;
+
+setgrouplist:
+ next { $$ = NULL; }
+ | groupentry next { $$ = $1; }
+ | groupentry next setgrouplist { $1->ipe_next = $3; $$ = $1; }
+ ;
+
+groupentry:
+ addrmask ',' setgroup { $$ = calloc(1, sizeof(iphtent_t));
+ bcopy((char *)&($1[0]),
+ (char *)&($$->ipe_addr),
+ sizeof($$->ipe_addr));
+ bcopy((char *)&($1[1]),
+ (char *)&($$->ipe_mask),
+ sizeof($$->ipe_mask));
+ strncpy($$->ipe_group, $3,
+ FR_GROUPLEN);
+ free($3);
+ }
+ | YY_STR { $$ = add_htablehosts($1); }
+ ;
+
+range: addrmask { $$ = calloc(1, sizeof(*$$));
+ $$->ipn_info = 0;
+ $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
+ $$->ipn_addr.adf_addr.in4.s_addr = $1[0].s_addr;
+ $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
+ $$->ipn_mask.adf_addr.in4.s_addr = $1[1].s_addr;
+ }
+ | '!' addrmask { $$ = calloc(1, sizeof(*$$));
+ $$->ipn_info = 1;
+ $$->ipn_addr.adf_len = sizeof($$->ipn_addr);
+ $$->ipn_addr.adf_addr.in4.s_addr = $2[0].s_addr;
+ $$->ipn_mask.adf_len = sizeof($$->ipn_mask);
+ $$->ipn_mask.adf_addr.in4.s_addr = $2[1].s_addr;
+ }
+ | YY_STR { $$ = add_poolhosts($1); }
+
+hashlist:
+ next { $$ = NULL; }
+ | hashentry next { $$ = $1; }
+ | hashentry next hashlist { $1->ipe_next = $3; $$ = $1; }
+ ;
+
+hashentry:
+ addrmask { $$ = calloc(1, sizeof(iphtent_t));
+ bcopy((char *)&($1[0]),
+ (char *)&($$->ipe_addr),
+ sizeof($$->ipe_addr));
+ bcopy((char *)&($1[1]),
+ (char *)&($$->ipe_mask),
+ sizeof($$->ipe_mask));
+ }
+ | YY_STR { $$ = add_htablehosts($1); }
+ ;
+
+addrmask:
+ ipaddr '/' mask { $$[0] = $1; $$[1].s_addr = $3.s_addr;
+ yyexpectaddr = 0;
+ }
+ | ipaddr { $$[0] = $1; $$[1].s_addr = 0xffffffff;
+ yyexpectaddr = 0;
+ }
+ ;
+
+ipaddr: ipv4 { $$ = $1; }
+ | YY_NUMBER { $$.s_addr = htonl($1); }
+ ;
+
+mask: YY_NUMBER { ntomask(4, $1, (u_32_t *)&$$.s_addr); }
+ | ipv4 { $$ = $1; }
+ ;
+
+start: '{' { yyexpectaddr = 1; }
+ ;
+
+end: '}' { yyexpectaddr = 0; }
+ ;
+
+next: ';' { yyexpectaddr = 1; }
+ ;
+
+size: IPT_SIZE '=' YY_NUMBER { ipht.iph_size = $3; }
+ ;
+
+seed: IPT_SEED '=' YY_NUMBER { ipht.iph_seed = $3; }
+ ;
+
+ipv4: YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER '.' YY_NUMBER
+ { if ($1 > 255 || $3 > 255 || $5 > 255 || $7 > 255) {
+ yyerror("Invalid octet string for IP address");
+ return 0;
+ }
+ $$.s_addr = ($1 << 24) | ($3 << 16) | ($5 << 8) | $7;
+ $$.s_addr = htonl($$.s_addr);
+ }
+ ;
+%%
+static wordtab_t yywords[] = {
+ { "auth", IPT_AUTH },
+ { "count", IPT_COUNT },
+ { "group", IPT_GROUP },
+ { "group-map", IPT_GROUPMAP },
+ { "hash", IPT_HASH },
+ { "in", IPT_IN },
+ { "ipf", IPT_IPF },
+ { "name", IPT_NAME },
+ { "nat", IPT_NAT },
+ { "number", IPT_NUM },
+ { "out", IPT_OUT },
+ { "role", IPT_ROLE },
+ { "seed", IPT_SEED },
+ { "size", IPT_SIZE },
+ { "table", IPT_TABLE },
+ { "tree", IPT_TREE },
+ { "type", IPT_TYPE },
+ { NULL, 0 }
+};
+
+
+int ippool_parsefile(fd, filename, iocfunc)
+int fd;
+char *filename;
+ioctlfunc_t iocfunc;
+{
+ FILE *fp = NULL;
+ char *s;
+
+ yylineNum = 1;
+ (void) yysettab(yywords);
+
+ s = getenv("YYDEBUG");
+ if (s)
+ yydebug = atoi(s);
+ else
+ yydebug = 0;
+
+ if (strcmp(filename, "-")) {
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "fopen(%s) failed: %s\n", filename,
+ STRERROR(errno));
+ return -1;
+ }
+ } else
+ fp = stdin;
+
+ while (ippool_parsesome(fd, fp, iocfunc) == 1)
+ ;
+ if (fp != NULL)
+ fclose(fp);
+ return 0;
+}
+
+
+int ippool_parsesome(fd, fp, iocfunc)
+int fd;
+FILE *fp;
+ioctlfunc_t iocfunc;
+{
+ char *s;
+ int i;
+
+ poolioctl = iocfunc;
+
+ if (feof(fp))
+ return 0;
+ i = fgetc(fp);
+ if (i == EOF)
+ return 0;
+ if (ungetc(i, fp) == EOF)
+ return 0;
+ if (feof(fp))
+ return 0;
+ s = getenv("YYDEBUG");
+ if (s)
+ yydebug = atoi(s);
+ else
+ yydebug = 0;
+
+ yyin = fp;
+ yyparse();
+ return 1;
+}
+
+
+static iphtent_t *
+add_htablehosts(url)
+char *url;
+{
+ iphtent_t *htop, *hbot, *h;
+ alist_t *a, *hlist;
+
+ if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
+ hlist = load_url(url);
+ } else {
+ use_inet6 = 0;
+
+ hlist = calloc(1, sizeof(*hlist));
+ if (hlist == NULL)
+ return NULL;
+
+ if (gethost(url, &hlist->al_addr) == -1)
+ yyerror("Unknown hostname");
+ }
+
+ hbot = NULL;
+ htop = NULL;
+
+ for (a = hlist; a != NULL; a = a->al_next) {
+ h = calloc(1, sizeof(*h));
+ if (h == NULL)
+ break;
+
+ bcopy((char *)&a->al_addr, (char *)&h->ipe_addr,
+ sizeof(h->ipe_addr));
+ bcopy((char *)&a->al_mask, (char *)&h->ipe_mask,
+ sizeof(h->ipe_mask));
+
+ if (hbot != NULL)
+ hbot->ipe_next = h;
+ else
+ htop = h;
+ hbot = h;
+ }
+
+ alist_free(hlist);
+
+ return htop;
+}
+
+
+static ip_pool_node_t *
+add_poolhosts(url)
+char *url;
+{
+ ip_pool_node_t *ptop, *pbot, *p;
+ alist_t *a, *hlist;
+
+ if (!strncmp(url, "file://", 7) || !strncmp(url, "http://", 7)) {
+ hlist = load_url(url);
+ } else {
+ use_inet6 = 0;
+
+ hlist = calloc(1, sizeof(*hlist));
+ if (hlist == NULL)
+ return NULL;
+
+ if (gethost(url, &hlist->al_addr) == -1)
+ yyerror("Unknown hostname");
+ }
+
+ pbot = NULL;
+ ptop = NULL;
+
+ for (a = hlist; a != NULL; a = a->al_next) {
+ p = calloc(1, sizeof(*p));
+ if (p == NULL)
+ break;
+
+ p->ipn_addr.adf_len = 8;
+ p->ipn_mask.adf_len = 8;
+
+ p->ipn_info = a->al_not;
+
+ bcopy((char *)&a->al_addr, (char *)&p->ipn_addr.adf_addr,
+ sizeof(p->ipn_addr.adf_addr));
+ bcopy((char *)&a->al_mask, (char *)&p->ipn_mask.adf_addr,
+ sizeof(p->ipn_mask.adf_addr));
+
+ if (pbot != NULL)
+ pbot->ipn_next = p;
+ else
+ ptop = p;
+ pbot = p;
+ }
+
+ alist_free(hlist);
+
+ return ptop;
+}
OpenPOWER on IntegriCloud