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