static knot_dname_t *synth_ptrname(const char *addr_str, synth_template_t *tpl) { /* PTR right-hand value is [prefix][address][zone] */ char ptrname[KNOT_DNAME_MAXLEN] = {'\0'}; int prefix_len = strlen(tpl->prefix); int addr_len = strlen(addr_str); int zone_len = strlen(tpl->zone); /* Check required space (zone requires extra leading dot). */ if (prefix_len + addr_len + zone_len + 1 >= KNOT_DNAME_MAXLEN) { return NULL; } /* Write prefix string. */ memcpy(ptrname, tpl->prefix, prefix_len); int written = prefix_len; /* Write address with substituted separator to '-'. */ char sep = str_separator(tpl->subnet.ss.ss_family); memcpy(ptrname + written, addr_str, addr_len); str_subst(ptrname + written, addr_len, sep, '-'); written += addr_len; /* Write zone name. */ ptrname[written] = '.'; written += 1; memcpy(ptrname + written, tpl->zone, zone_len); /* Convert to domain name. */ return knot_dname_from_str(ptrname); }
static const response* parse_addr_arg(void) { unsigned i; char term; int quoted; if (!str_truncate(&addr, 0)) return &resp_oom; if (!str_truncate(¶ms, 0)) return &resp_oom; addr.len = 0; if ((i = str_findfirst(&arg, LBRACE) + 1) != 0) term = RBRACE; else { term = SPACE; if ((i = str_findfirst(&arg, COLON) + 1) == 0) if ((i = str_findfirst(&arg, SPACE) + 1) == 0) return &resp_badaddr; while (i < arg.len && arg.s[i] == SPACE) ++i; } for (quoted = 0; i < arg.len && (quoted || arg.s[i] != term); ++i) { switch (arg.s[i]) { case QUOTE: quoted = !quoted; break; case ESCAPE: ++i; /* fall through */ default: if (!str_catc(&addr, arg.s[i])) return &resp_oom; } } ++i; if (i > arg.len) return &resp_badaddr; while (i < arg.len && arg.s[i] == SPACE) ++i; if (!str_copyb(¶ms, arg.s+i, arg.len-i)) return &resp_oom; str_subst(¶ms, ' ', 0); /* strip source routing */ if (addr.s[0] == AT && (i = str_findfirst(&addr, COLON) + 1) != 0) str_lcut(&addr, i); return 0; }
static int forward_addr_parse(struct query_data *qdata, synth_template_t *tpl, char *addr_str) { /* Find prefix label count (additive to prefix length). */ const knot_dname_t *addr_label = qdata->name; /* Mismatch if label shorter/equal than prefix. */ int prefix_len = strlen(tpl->prefix); if (addr_label == NULL || addr_label[0] <= prefix_len) { return KNOT_EINVAL; } int addr_len = *addr_label - prefix_len; memcpy(addr_str, addr_label + 1 + prefix_len, addr_len); /* Restore correct address format. */ char sep = str_separator(tpl->subnet.ss.ss_family); str_subst(addr_str, addr_len, '-', sep); return KNOT_EOK; }