On Fri, 19 Jan 2007, Daniel Hartmeier wrote: > On Fri, Jan 19, 2007 at 07:20:11PM +0100, Xavier ROUX wrote: > > > int_lan = "172.16.1.0/24" > > rel_int_lan = "172.16.2.0/24" > > rel_ext_lan = "172.16.3.0/24" > > > > lans = "{" $int_lan $rel_int_lan $rel_ext_lan "}" > > > > I obtain this error: > > > > # pfctl -nf /etc/pf.conf > > /etc/pf.conf:48: syntax error > > /etc/pf.conf:83: macro 'lans' not defined > > > > Could you give me the correct syntax? > > Basically, it can't be done, due to the way the parser deals with macros > and strings.
I just updated this diff that was more then 4 years old. It never was pretty, and still isn't, but it _does_ get the job done, without "{", "'{'", etc. tricks [EMAIL PROTECTED] $ cat test int_lan = "172.16.1.0/24" rel_int_lan = "172.16.2.0/24" rel_ext_lan = "172.16.3.0/24" lans = "$int_lan $rel_int_lan $rel_ext_lan" pass in from { $lans } [EMAIL PROTECTED] $ obj/pfctl -nvvf test int_lan = "172.16.1.0/24" rel_int_lan = "172.16.2.0/24" rel_ext_lan = "172.16.3.0/24" lans = "$int_lan $rel_int_lan $rel_ext_lan" @0 pass in inet from 172.16.1.0/24 to any flags S/SA keep state @1 pass in inet from 172.16.2.0/24 to any flags S/SA keep state @2 pass in inet from 172.16.3.0/24 to any flags S/SA keep state -- Cam Index: parse.y =================================================================== RCS file: /cvs/src/sbin/pfctl/parse.y,v retrieving revision 1.516 diff -u -p -u -r1.516 parse.y --- parse.y 7 Nov 2006 01:12:01 -0000 1.516 +++ parse.y 19 Jan 2007 21:31:00 -0000 @@ -5228,22 +5228,18 @@ parse_rules(FILE *input, struct pfctl *x int symset(const char *nam, const char *val, int persist) { - struct sym *sym; + struct sym *osym, *sym; + size_t rlen; + const char *i; + char *n, *p0, *p, *r, *tok; - for (sym = TAILQ_FIRST(&symhead); sym && strcmp(nam, sym->nam); - sym = TAILQ_NEXT(sym, entries)) - ; /* nothing */ - - if (sym != NULL) { - if (sym->persist == 1) - return (0); - else { - free(sym->nam); - free(sym->val); - TAILQ_REMOVE(&symhead, sym, entries); - free(sym); - } + TAILQ_FOREACH(osym, &symhead, entries) { + if (strcmp(nam, osym->nam) == 0) + break; } + if (osym != NULL && osym->persist == 1) + return (0); + if ((sym = calloc(1, sizeof(*sym))) == NULL) return (-1); @@ -5258,10 +5254,76 @@ symset(const char *nam, const char *val, free(sym); return (-1); } + + p0 = p = malloc(strlen(val) + 1); + if (p0 == NULL) { + free(sym->nam); + free(sym); + return (-1); + } + + for (i = val; *i != '\0'; i++) { + if (*i != '$') { + /* Just copy. */ + *p++ = *i; + } else { + /* Found a macro: copy it and try to expand. */ + i++; + *p++ = '\0'; + + tok = p; + while (isalnum(*i) || *i == '_') + *p++ = *i++; + i--; + if (tok == p) { + yyerror("spurious $"); + goto error; + } + *p = '\0'; + p = tok - 1; /* rewind */ + + r = symget(tok); + if (r == NULL) { + yyerror("macro '%s' not defined", tok); + goto error; + } + /* + * Reallocate space to be able to hold: + * 1. what we have so far (p0), + * 2. the expanded macro (r), and + * 3. what's left of the source string (i). + */ + rlen = strlen(r); + n = realloc(p0, (p - p0) + rlen + strlen(i) + 1); + if (n == NULL) + goto error; + /* Move pointers into new storage. */ + p = n + (p - p0); + p0 = n; + /* Concatenate expanded macro. */ + if (strlcpy(p, r, rlen + 1) != rlen) + goto error; + p += rlen; + } + } + *p = '\0'; + + if (osym != NULL) { + free(osym->nam); + free(osym->val); + TAILQ_REMOVE(&symhead, osym, entries); + free(osym); + } + sym->val = p0; sym->used = 0; sym->persist = persist; TAILQ_INSERT_TAIL(&symhead, sym, entries); return (0); +error: + free(sym->nam); + free(sym); + free(p0); + return (-1); } int