2 Unix SMB/CIFS implementation.
4 DNS query too for Samba with socketwrapper support
6 Copyright (C) 2012 Kai Blin <kai@samba.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "lib/util/samba_util.h"
26 #include "librpc/ndr/libndr.h"
27 #include "librpc/gen_ndr/ndr_dns.h"
28 #include "libcli/dns/libdns.h"
30 static void usage(void)
32 printf("Usage: samba-dig <dns-server-ip> <data> <record-type>\n\n");
35 static struct dns_name_packet
*make_name_packet(TALLOC_CTX
*mem_ctx
,
38 struct dns_name_packet
*packet
= talloc_zero(mem_ctx
,
39 struct dns_name_packet
);
44 packet
->id
= random();
45 packet
->operation
|= operation
| DNS_FLAG_RECURSION_DESIRED
;
50 #define QTYPE_MAP(type) if (strncmp(type_string, #type , strlen( #type )) == 0) \
51 return DNS_QTYPE_ ## type ;
53 static enum dns_qtype
parse_qtype(const char *type_string
)
63 static struct dns_name_question
*make_question(TALLOC_CTX
*mem_ctx
,
67 struct dns_name_question
*question
= talloc(mem_ctx
,
68 struct dns_name_question
);
69 if (question
== NULL
) {
73 question
->name
= talloc_strdup(question
, name
);
74 question
->question_type
= type
;
75 question
->question_class
= DNS_QCLASS_IN
;
80 int main(int argc
, char **argv
)
82 TALLOC_CTX
*mem_ctx
= talloc_init("samba-dig");
83 struct tevent_context
*ev
;
84 struct dns_name_packet
*dns_packet
, *in_packet
;
85 struct dns_name_question
*question
;
87 enum ndr_err_code ndr_err
;
88 struct tevent_req
*req
;
98 ev
= tevent_context_init(mem_ctx
);
99 setup_logging("samba-dig", DEBUG_STDERR
);
100 debug_parse_levels("1");
102 DEBUG(1,("Querying %s for %s %s\n", argv
[1], argv
[2], argv
[3]));
104 dns_packet
= make_name_packet(mem_ctx
, DNS_OPCODE_QUERY
);
106 type
= parse_qtype(argv
[3]);
108 DEBUG(0, ("Invalid DNS_QTYPE %s\n", argv
[3]));
113 question
= make_question(dns_packet
, argv
[2], type
);
115 dns_packet
->qdcount
= 1;
116 dns_packet
->questions
= question
;
117 NDR_PRINT_DEBUG(dns_name_packet
, dns_packet
);
119 ndr_err
= ndr_push_struct_blob(&out
, mem_ctx
, dns_packet
,
120 (ndr_push_flags_fn_t
)ndr_push_dns_name_packet
);
121 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
122 DEBUG(0, ("Failed to marshall dns_name_packet: %d\n", ndr_err
));
127 req
= dns_udp_request_send(mem_ctx
, ev
, argv
[1], out
.data
, out
.length
);
129 DEBUG(0, ("Failed to allocate memory for tevent_req\n"));
133 if (!tevent_req_poll(req
, ev
)) {
134 DEBUG(0, ("Error sending dns request\n"));
138 w_err
= dns_udp_request_recv(req
, mem_ctx
, &in
.data
, &in
.length
);
139 if (!W_ERROR_IS_OK(w_err
)) {
140 DEBUG(0, ("Error receiving dns request: %s\n", win_errstr(w_err
)));
145 in_packet
= talloc(mem_ctx
, struct dns_name_packet
);
147 ndr_err
= ndr_pull_struct_blob(&in
, in_packet
, in_packet
,
148 (ndr_pull_flags_fn_t
)ndr_pull_dns_name_packet
);
149 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
150 DEBUG(0, ("Failed to unmarshall dns_name_packet: %d\n", ndr_err
));
155 NDR_PRINT_DEBUG(dns_name_packet
, in_packet
);
158 talloc_free(mem_ctx
);