criteria, the whole cname is ignored. The cname must be unique, but it
is permissable to have more than one cname pointing to the same target.
.TP
+.B --dns-rr=<name>,<RR-number>,[<hex data>]
+Return an arbitrary DNS Resource Record. The number is the type of the
+record (which is always in the C_IN class). The value of the record is
+given by the hex data, which may be of the for 01:23:45 or 01 23 45 or
+012345 or any mixture of these.
+.TP
.B --interface-name=<name>,<interface>
Return a DNS record associating the name with the primary address on
the given interface. This flag specifies an A record for the given
#define LOPT_DUID 307
#define LOPT_HOST_REC 308
#define LOPT_TFTP_LC 309
+#define LOPT_RR 310
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
{ "srv-host", 1, 0, 'W' },
{ "localise-queries", 0, 0, 'y' },
{ "txt-record", 1, 0, 'Y' },
+ { "dns-rr", 1, 0, LOPT_RR },
{ "enable-dbus", 0, 0, '1' },
{ "bootp-dynamic", 2, 0, '3' },
{ "dhcp-mac", 1, 0, '4' },
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
{ LOPT_HOST_REC, ARG_DUP, "<name>,<address>", gettext_noop("Specify host (A/AAAA and PTR) records"), NULL },
+ { LOPT_RR, ARG_DUP, "<name>,<RR-number>,[<data>]", gettext_noop("Specify arbitrary DNS resource record"), NULL },
{ 0, 0, NULL, NULL, NULL }
};
}
if (len == -1)
+
problem = _("bad hex constant");
else if ((new->clid = opt_malloc(len)))
{
}
break;
}
-
+
+ case LOPT_RR: /* dns-rr */
+ {
+ struct txt_record *new;
+ size_t len;
+ char *data;
+ int val;
+
+ comma = split(arg);
+ data = split(comma);
+
+ new = opt_malloc(sizeof(struct txt_record));
+ new->next = daemon->rr;
+ daemon->rr = new;
+
+ if (!atoi_check(comma, &val) ||
+ !(new->name = canonicalise_opt(arg)) ||
+ (data && (len = parse_hex(data, (unsigned char *)data, -1, NULL, NULL)) == -1))
+ {
+ problem = _("bad RR record");
+ break;
+ }
+
+ new->class = val;
+ new->len = 0;
+
+ if (data)
+ {
+ new->txt=opt_malloc(len);
+ new->len = len;
+ memcpy(new->txt, data, len);
+ }
+
+ break;
+ }
+
case 'Y': /* --txt-record */
{
struct txt_record *new;
case 't':
usval = va_arg(ap, int);
sval = va_arg(ap, char *);
- memcpy(p, sval, usval);
+ if (usval != 0)
+ memcpy(p, sval, usval);
p += usval;
break;
if (qclass == C_IN)
{
+ struct txt_record *t;
+
+ for (t = daemon->rr; t; t = t->next)
+ if ((t->class == qtype || qtype == T_ANY) && hostname_isequal(name, t->name))
+ {
+ ans = 1;
+ if (!dryrun)
+ {
+ log_query(F_CONFIG | F_RRNAME, name, NULL, "<RR>");
+ if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ daemon->local_ttl, NULL,
+ t->class, C_IN, "t", t->len, t->txt))
+ anscount ++;
+ }
+ }
+
if (qtype == T_PTR || qtype == T_ANY)
{
/* see if it's w.z.y.z.in-addr.arpa format */
while (maxlen == -1 || i < maxlen)
{
- for (r = in; *r != 0 && *r != ':' && *r != '-'; r++)
+ for (r = in; *r != 0 && *r != ':' && *r != '-' && *r != ' '; r++)
if (*r != '*' && !isxdigit((unsigned char)*r))
return -1;
else
{
*r = 0;
- mask = mask << 1;
if (strcmp(in, "*") == 0)
- mask |= 1;
+ {
+ mask = (mask << 1) | 1;
+ i++;
+ }
else
- out[i] = strtol(in, NULL, 16);
- i++;
+ {
+ int j, bytes = (1 + (r - in))/2;
+ for (j = 0; j < bytes; j++)
+ {
+ char sav;
+ if (j < bytes - 1)
+ {
+ sav = in[(j+1)*2];
+ in[(j+1)*2] = 0;
+ }
+ out[i] = strtol(&in[j*2], NULL, 16);
+ mask = mask << 1;
+ i++;
+ if (j < bytes - 1)
+ in[(j+1)*2] = sav;
+ }
+ }
}
}
in = r+1;