static int ds_ip6tset_line(struct dataset *ds, char *s, struct dsctx *dsc) { struct dsdata *dsd = ds->ds_dsd; int bits, excl; ip6oct_t addr[IP6ADDR_FULL]; if (*s == ':') { if (!dsd->def_rr) { unsigned rrl; const char *rr; if (!(rrl = parse_a_txt(s, &rr, def_rr, dsc))) return 1; if (!(dsd->def_rr = mp_dmemdup(ds->ds_mp, rr, rrl))) return 0; } return 1; } excl = *s == '!'; if (excl) { ++s; SKIPSPACE(s); } bits = ip6prefix(s, addr, &s); if (bits < 0 || (*s && !ISSPACE(*s) && !ISCOMMENT(*s) && *s != ':')) { dswarn(dsc, "invalid address"); return 1; } if (bits != (excl ? 128 : 64)) { dswarn(dsc, "invalid address for %s (should be %d bits)", excl ? "exclusion" : "regular entry", excl ? 128 : 64); return 1; } if (excl) { if (dsd->e_cnt >= dsd->e_alc) { struct ip6full *e = dsd->e; unsigned alc = dsd->e_alc ? dsd->e_alc << 1 : dsd->e_hnt ? dsd->e_hnt : 64; e = trealloc(struct ip6full, e, alc); if (!e) return 0; dsd->e = e; dsd->e_alc = alc; } memcpy(&(dsd->e[dsd->e_cnt++]), addr, sizeof(*dsd->e)); } else { if (dsd->a_cnt >= dsd->a_alc) {
/* Return pointer to first char c or ';' comment in given string, or pointer to null at end of string if neither found. ';' must be prefixed by a whitespace character to register as a comment. The quoted char will be ignored. */ static char* find_char_or_comment(const char* s, char c) { int dquoted = 0, squoted = 0; // double quoated, single quoted char prev = 0; while (*s && (*s != c && !ISCOMMENT(*s) || dquoted || squoted) ) { // was_whitespace = isspace((unsigned char)(*s)); if( '\"' == *s && prev!= '\\') dquoted = ! dquoted; else if( '\'' == *s && prev!= '\\') squoted = ! squoted; prev = *s; s++; } return (char*)s; }
static int ds_ip4set_line(struct dataset *ds, char *s, struct dsctx *dsc) { struct dsdata *dsd = ds->ds_dsd; ip4addr_t a, b; const char *rr; unsigned rrl; int not; int bits; if (*s == ':') { if (!(rrl = parse_a_txt(s, &rr, def_rr, dsc))) return 1; if (!(dsd->def_rr = mp_dmemdup(ds->ds_mp, rr, rrl))) return 0; return 1; } if (*s == '!') { not = 1; ++s; SKIPSPACE(s); } else not = 0; if ((bits = ip4range(s, &a, &b, &s)) <= 0 || (*s && !ISSPACE(*s) && !ISCOMMENT(*s) && *s != ':')) { dswarn(dsc, "invalid address"); return 1; } if (accept_in_cidr) a &= ip4mask(bits); else if (a & ~ip4mask(bits)) { dswarn(dsc, "invalid range (non-zero host part)"); return 1; } if (dsc->dsc_ip4maxrange && dsc->dsc_ip4maxrange <= (b - a)) { dswarn(dsc, "too large range (%u) ignored (%u max)", b - a + 1, dsc->dsc_ip4maxrange); return 1; } if (not) rr = NULL; else { SKIPSPACE(s); if (!*s || ISCOMMENT(*s)) rr = dsd->def_rr; else if (!(rrl = parse_a_txt(s, &rr, dsd->def_rr, dsc))) return 1; else if (!(rr = mp_dmemdup(ds->ds_mp, rr, rrl))) return 0; } /*XXX some comments about funny ip4range_expand et al */ #define fn(idx,start,count) ds_ip4set_addent(dsd, idx, start, count, rr) /* helper macro for ip4range_expand: * deal with last octet, shifting a and b when done */ #define ip4range_expand_octet(bits) \ if ((a | 255u) >= b) { \ if (b - a == 255u) \ return fn((bits>>3)+1, a<<bits, 1); \ else \ return fn(bits>>3, a<<bits, b - a + 1); \ } \ if (a & 255u) { \ if (!fn(bits>>3, a<<bits, 256u - (a & 255u))) \ return 0; \ a = (a >> 8) + 1; \ } \ else \ a >>= 8; \ if ((b & 255u) != 255u) { \ if (!fn((bits>>3), (b & ~255u)<<bits, (b&255u)+1)) \ return 0; \ b = (b >> 8) - 1; \ } \ else \ b >>= 8 ip4range_expand_octet(0); ip4range_expand_octet(8); ip4range_expand_octet(16); return fn(3, a << 24, b - a + 1); }
static void parseconfigline (char *buf, unsigned int line, zconf_t *z) { char *end, *val, *p; char *tag; unsigned int len, found; zconf_para_t *c; assert (buf[0] != '\0'); p = &buf[strlen(buf)-1]; /* Chop off white space at eol */ while ( p >= buf && isspace (*p) ) *p-- = '\0'; for (p = buf; isspace (*p); p++ ) /* Ignore leading white space */ ; /* Ignore comments and emtpy lines */ if ( *p == '\0' || ISCOMMENT (p) ) return; tag = p; /* Get the end of the first argument */ end = &buf[strlen(buf)-1]; while ( p < end && !ISDELIM (*p) ) /* Skip until delim */ p++; *p++ = '\0'; /* Terminate this argument */ dbg_val1 ("Parsing \"%s\"\n", tag); while ( p < end && ISDELIM (*p) ) /* Skip delim chars */ p++; val = p; /* Start of the value */ dbg_val1 ("\tgot value \"%s\"\n", val); /* If starting with quote, skip until next quote */ if ( *p == '"' || *p == '\'' ) { p++; /* Find next quote */ while ( p <= end && *p && *p != *val ) p++; *p = '\0'; val++; /* Skip the first quote */ } else /* Otherwise check if there is any comment char at the end */ { while ( p < end && *p && !ISCOMMENT(p) ) p++; if ( ISCOMMENT (p) ) { do /* Chop off white space before comment */ *p-- = '\0'; while ( p >= val && isspace (*p) ); } } /* Otherwise it is already terminated above */ found = 0; c = confpara; while ( !found && c->type != CONF_END ) { len = strlen (c->label); if ( strcasecmp (tag, c->label) == 0 ) { char **str; char quantity; long lval; found = 1; switch ( c->type ) { case CONF_LEVEL: case CONF_FACILITY: case CONF_STRING: str = (char **)c->var; *str = strdup (val); str_untaint (*str); /* remove "bad" characters */ break; case CONF_INT: sscanf (val, "%d", (int *)c->var); break; case CONF_TIMEINT: quantity = 'd'; sscanf (val, "%ld%c", &lval, &quantity); if ( quantity == 'm' ) lval *= MINSEC; else if ( quantity == 'h' ) lval *= HOURSEC; else if ( quantity == 'd' ) lval *= DAYSEC; else if ( quantity == 'w' ) lval *= WEEKSEC; else if ( quantity == 'y' ) lval *= YEARSEC; (*(long *)c->var) = lval; break; case CONF_ALGO: if ( strcasecmp (val, "rsa") == 0 || strcasecmp (val, "rsamd5") == 0 ) *((int *)c->var) = DK_ALGO_RSA; else if ( strcasecmp (val, "dsa") == 0 ) *((int *)c->var) = DK_ALGO_DSA; else if ( strcasecmp (val, "rsasha1") == 0 ) *((int *)c->var) = DK_ALGO_RSASHA1; else if ( strcasecmp (val, "nsec3dsa") == 0 || strcasecmp (val, "n3dsa") == 0 ) *((int *)c->var) = DK_ALGO_NSEC3DSA; else if ( strcasecmp (val, "nsec3rsasha1") == 0 || strcasecmp (val, "n3rsasha1") == 0 ) *((int *)c->var) = DK_ALGO_NSEC3RSASHA1; else error ("Illegal algorithm \"%s\" " "in line %d.\n" , val, line); break; case CONF_SERIAL: if ( strcasecmp (val, "unixtime") == 0 ) *((serial_form_t *)c->var) = Unixtime; else if ( strcasecmp (val, "incremental") == 0 ) *((serial_form_t *)c->var) = Incremental; else error ("Illegal serial no format \"%s\" " "in line %d.\n" , val, line); break; case CONF_BOOL: *((int *)c->var) = ISTRUE (val); break; default: fatal ("Illegal configuration type in line %d.\n", line); } } c++; } if ( !found ) error ("Unknown configuration statement: %s \"%s\"\n", tag, val); return; }