diff --git a/bin/dig/dig.c b/bin/dig/dig.c index e53ad5e29b..d3fc299bf5 100644 --- a/bin/dig/dig.c +++ b/bin/dig/dig.c @@ -1489,6 +1489,24 @@ plus_option(char *option, bool is_batchfile, dig_lookup_t *lookup) { break; case 'q': switch (cmd[1]) { + case 'i': /* qid */ + FULLCHECK("qid"); + if (!state) { + lookup->setqid = false; + lookup->qid = 0; + break; + } + if (value == NULL) { + goto need_value; + } + result = parse_uint(&num, value, MAXQID, "qid"); + if (result != ISC_R_SUCCESS) { + warn("Couldn't parse qid"); + goto exit_or_usage; + } + lookup->setqid = true; + lookup->qid = num; + break; case 'r': /* qr */ FULLCHECK("qr"); lookup->qr = state; diff --git a/bin/dig/dig.rst b/bin/dig/dig.rst index 3c899ceebc..b14c7e751c 100644 --- a/bin/dig/dig.rst +++ b/bin/dig/dig.rst @@ -426,6 +426,10 @@ abbreviation is unambiguous; for example, ``+cd`` is equivalent to mandatory. Responses to padded queries may also be padded, but only if the query uses TCP or DNS COOKIE. +``+qid=value`` + + Specify the query ID to use when sending queries. + ``+[no]qr`` Toggles the display of the query message as it is sent. By default, the query is not printed. diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c index 0384d7ccad..a12ff40019 100644 --- a/bin/dig/dighost.c +++ b/bin/dig/dighost.c @@ -677,6 +677,8 @@ make_empty_lookup(void) { looknew->tcflag = false; looknew->print_unknown_format = false; looknew->zflag = false; + looknew->setqid = false; + looknew->qid = 0; looknew->ns_search_only = false; looknew->origin = NULL; looknew->tsigctx = NULL; @@ -820,6 +822,8 @@ clone_lookup(dig_lookup_t *lookold, bool servers) { looknew->tcflag = lookold->tcflag; looknew->print_unknown_format = lookold->print_unknown_format; looknew->zflag = lookold->zflag; + looknew->setqid = lookold->setqid; + looknew->qid = lookold->qid; looknew->ns_search_only = lookold->ns_search_only; looknew->tcp_mode = lookold->tcp_mode; looknew->tcp_mode_set = lookold->tcp_mode_set; @@ -2298,6 +2302,11 @@ setup_lookup(dig_lookup_t *lookup) { lookup->sendmsg->flags |= 0x0040U; } + if (lookup->setqid) { + debug("set QID"); + lookup->sendmsg->id = lookup->qid; + } + dns_message_addname(lookup->sendmsg, lookup->name, DNS_SECTION_QUESTION); diff --git a/bin/dig/dighost.h b/bin/dig/dighost.h index 9b482ce3de..15585d460a 100644 --- a/bin/dig/dighost.h +++ b/bin/dig/dighost.h @@ -60,6 +60,8 @@ #define MAXPORT 0xffff /*% Max serial number */ #define MAXSERIAL 0xffffffff +/*% Max query ID */ +#define MAXQID 0xffff /*% Default TCP Timeout */ #define TCP_TIMEOUT 10 @@ -108,9 +110,10 @@ struct dig_lookup { tcp_keepalive, header_only, ednsneg, mapped, print_unknown_format, multiline, nottl, noclass, onesoa, use_usec, nocrypto, ttlunits, idnin, idnout, expandaaaa, qr, - accept_reply_unexpected_src; /*% print replies from + accept_reply_unexpected_src, /*% print replies from * unexpected * sources. */ + setqid; /*% use a speciied query ID */ char textname[MXNAME]; /*% Name we're going to be * looking up */ char cmdline[MXNAME]; @@ -157,6 +160,7 @@ struct dig_lookup { dns_opcode_t opcode; int rrcomments; unsigned int eoferr; + uint16_t qid; }; /*% The dig_query structure */ diff --git a/bin/dig/nslookup.c b/bin/dig/nslookup.c index 17d8515268..08ee5e36d9 100644 --- a/bin/dig/nslookup.c +++ b/bin/dig/nslookup.c @@ -788,6 +788,8 @@ addlookup(char *opt) { lookup->aaonly = aaonly; lookup->retries = tries; lookup->udpsize = 0; + lookup->setqid = false; + lookup->qid = 0; lookup->comments = comments; if (lookup->rdtype == dns_rdatatype_any && !tcpmode_set) { lookup->tcp_mode = true;