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

Reply via email to