1 /* dump_dns.c - library function to emit decoded dns message on a FILE.
9 /* Define to 1 if you have the `ns_initparse' function. */
10 #define HAVE_NS_INITPARSE 1
12 /* Define to 1 if you have the `ns_parserr' function. */
13 #define HAVE_NS_PARSERR 1
15 #if HAVE_NS_INITPARSE && HAVE_NS_PARSERR
18 * Copyright (c) 2007 by Internet Systems Consortium, Inc. ("ISC")
20 * Permission to use, copy, modify, and/or distribute this software for any
21 * purpose with or without fee is hereby granted, provided that the above
22 * copyright notice and this permission notice appear in all copies.
24 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
25 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
26 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR
27 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
28 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
29 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
30 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
35 #ifndef __USE_POSIX199309
36 #define __USE_POSIX199309
41 #define u_int32_t uint32_t
42 #define u_int16_t uint16_t
45 #include <sys/socket.h>
48 #include <netinet/in.h>
49 #include <arpa/inet.h>
50 #include <arpa/nameser.h>
63 extern const char *_res_opcodes
[];
64 extern const char *_res_sectioncodes
[];
66 #define p_rcode __p_rcode
68 extern const char *p_rcode(int rcode
);
70 static void dump_dns_sect(ns_msg
*, ns_sect
, FILE *, const char *);
71 static void dump_dns_rr(ns_msg
*, ns_rr
*, ns_sect
, FILE *);
72 void dump_payload(u_char
* xdata
, uint16_t dlen
);
73 char *fasthex(u_char
* xdata
, u_int16_t length
);
74 void printchars(char buf
[NS_MAXDNAME
], u_char
* cdata
, u_int16_t dlen
);
83 #define MY_GET16(s, cp) do { \
84 register const u_char *t_cp = (const u_char *)(cp); \
85 (s) = ((u_int16_t)t_cp[0] << 8) \
86 | ((u_int16_t)t_cp[1]) \
91 #define MY_GET32(l, cp) do { \
92 register const u_char *t_cp = (const u_char *)(cp); \
93 (l) = ((u_int32_t)t_cp[0] << 24) \
94 | ((u_int32_t)t_cp[1] << 16) \
95 | ((u_int32_t)t_cp[2] << 8) \
96 | ((u_int32_t)t_cp[3]) \
102 const char *_res_opcodes
[] = {
106 "CQUERYU", /* experimental */
107 "NOTIFY", /* experimental */
120 #endif /* __FreeBSD__ */
122 //#include "dump_dns.h"
125 dump_dns(const u_char
* payload
, size_t paylen
,
126 FILE * trace
, const char *endline
, const char *src_ip
, time_t ts
)
128 u_int opcode
, rcode
, id
;
131 const char *host
= "host";
133 /*fprintf(trace, "%sdns ", endline); */
134 fprintf(trace
, "%ld||%s||%s||", ts
, host
, src_ip
);
135 if(ns_initparse(payload
, paylen
, &msg
) < 0) {
136 fputs(strerror(errno
), trace
);
139 opcode
= ns_msg_getflag(msg
, ns_f_opcode
);
140 rcode
= ns_msg_getflag(msg
, ns_f_rcode
);
142 fprintf(trace
, "%s,%s,%u", _res_opcodes
[opcode
], p_rcode(rcode
), id
);
144 #define FLAG(t,f) if (ns_msg_getflag(msg, f)) { \
145 fprintf(trace, "%s%s", sep, t); \
158 //if(ns_o_query == opcode && ns_msg_getflag(msg,ns_f_qr)){
160 dump_dns_sect(&msg
, ns_s_qd
, trace
, endline
);
162 dump_dns_sect(&msg
, ns_s_an
, trace
, endline
);
164 dump_dns_sect(&msg
, ns_s_ns
, trace
, endline
);
165 // additional records?
166 dump_dns_sect(&msg
, ns_s_ar
, trace
, endline
);
167 fprintf(trace
, "\n");
171 dump_dns_sect(ns_msg
* msg
, ns_sect sect
, FILE * trace
,
177 fprintf(trace
, "||");
178 rrmax
= ns_msg_count(*msg
, sect
);
183 fprintf(trace
, "%d", rrmax
);
184 //fprintf(trace, "%s%d", endline, rrmax);
185 //fprintf(trace, "%s", endline);
186 for(rrnum
= 0; rrnum
< rrmax
; rrnum
++) {
187 if(ns_parserr(msg
, sect
, rrnum
, &rr
)) {
188 fputs(strerror(errno
), trace
);
191 fprintf(trace
, "||");
192 dump_dns_rr(msg
, &rr
, sect
, trace
);
197 dump_dns_rr(ns_msg
* msg
, ns_rr
* rr
, ns_sect sect
, FILE * trace
)
199 char buf
[NS_MAXDNAME
];
206 class = ns_rr_class(*rr
);
207 type
= ns_rr_type(*rr
);
208 fprintf(trace
, "%s,%s,%s",
209 ns_rr_name(*rr
), p_class(class), p_type(type
));
212 fprintf(trace
, ",%lu", (u_long
) ns_rr_ttl(*rr
));
213 rd
= ns_rr_rdata(*rr
);
216 n
= ns_name_uncompress(ns_msg_base(*msg
), ns_msg_end(*msg
),
217 rd
, buf
, sizeof buf
);
223 n
= ns_name_uncompress(ns_msg_base(*msg
), ns_msg_end(*msg
),
224 rd
, buf
, sizeof buf
);
230 if(ns_msg_end(*msg
) - rd
< 5 * NS_INT32SZ
)
232 for(n
= 0; n
< 5; n
++)
233 MY_GET32(soa
[n
], rd
);
234 sprintf(buf
, "%u,%u,%u,%u,%u", soa
[0], soa
[1], soa
[2], soa
[3],
238 inet_ntop(AF_INET
, rd
, buf
, sizeof buf
);
241 inet_ntop(AF_INET6
, rd
, buf
, sizeof buf
);
245 fprintf(trace
, ",%u", mx
);
251 n
= ns_name_uncompress(ns_msg_base(*msg
), ns_msg_end(*msg
),
252 rd
, buf
, sizeof buf
);
258 sprintf(buf
, "[%u]", ns_rr_rdlen(*rr
));
259 //fprintf(stderr, ",[%u],", ns_rr_rdlen(*rr));
260 /*fprintf(trace, ",");
261 for (i=1;i<ns_rr_rdlen(*rr);i++) {
262 if ( 31 < rd[i] && rd[i] < 127) {
263 fprintf(trace, "%c", rd[i]);
275 void printchars(char buf
[NS_MAXDNAME
], u_char
* cdata
, u_int16_t dlen
)
280 for(i
= 0; i
< dlen
; i
++) {
281 if(31 < cdata
[i
] && cdata
[i
] < 127) {
282 printf("%c", cdata
[i
]);
291 dump_dns(const u_char
* payload
, size_t paylen
,
292 FILE * trace
, const char *endline
)
296 fprintf(trace
, "NO BINDLIB\n");