Unbound DNS Server, Python module: inspect response message elements -


goal

i leverage unbound python module examine response before it's dispatched client. primarily, i'm interested in ;; answer section:, i.e. ip address query got resolved to.

problem

what had looked trivial modification of logdnsmsg function turned out dounting task of browsing reply_info, rrset_ref , ub_packed_rrset_key structures in pursuit of desired ;; answer section: bytes.

the reason logdnsmsg function not work expected a queries ;; answer section:, while suprisingly operates expected ;; authority section: on aaaa queries.

lemme demonstrate comparison between python implemented logdnsmsg function , native log_dns_msg function; former displaying gibberish , latter performing expected. both functions called within python module context follows:

+++ def operate(id, event, qstate, qdata):     log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))     if (qstate.return_msg):         logdnsmsg(qstate)         log_dns_msg("blackpie karmmmmmm xxxxxxx", qstate.return_msg.qinfo, qstate.return_msg.rep) +++ 

note altered original logdnsmsg uses logging framework in favour of print. output same print being scattered across logfile @ buffer's discretion.

dig output:

karm@localhost:~$ dig seznam.cz  @127.0.0.1 -p53535 ; <<>> dig 9.9.4-p2-redhat-9.9.4-18.p2.fc20 <<>> seznam.cz @127.0.0.1 -p53535 ;; global options: +cmd ;; got answer: ;; ->>header<<- opcode: query, status: noerror, id: 38630 ;; flags: qr rd ra; query: 1, answer: 1, authority: 0, additional: 1 ;; opt pseudosection: ; edns: version: 0, flags:; udp: 4096 ;; question section: ;seznam.cz.     in  ;; answer section: seznam.cz.    300 in  77.75.76.3 ;; query time: 656 msec ;; server: 127.0.0.1#53535(127.0.0.1) ;; when: sat apr 25 16:04:32 cest 2015 ;; msg size  rcvd: 54 

output aaaa query, ;; authority section: looks decent enough both logdnsmsg , log_dns_msg:

[1429970672] unbound[14053:0] info: pythonmod: operate called, id: 1, event:module_event_moddone [1429970672] unbound[14053:0] info: ------------------------------------------------------------------------------------------ [1429970672] unbound[14053:0] info: query: e.root-servers.net., type: aaaa (28), class: in (1)  [1429970672] unbound[14053:0] info: ------------------------------------------------------------------------------------------ [1429970672] unbound[14053:0] info: return    reply :: flags: 8080, qdcount: 1, security:0, ttl=86400 [1429970672] unbound[14053:0] info:           qinfo :: qname: ['e', 'root-servers', 'net', ''] e.root-servers.net., qtype: aaaa, qclass: in [1429970672] unbound[14053:0] info: reply: [1429970672] unbound[14053:0] info: 0:['root-servers', 'net', ''] root-servers.net. flags: 0004 [1429970672] unbound[14053:0] info: type:soa (6) class:in (1) [1429970672] unbound[14053:0] info:   0:ttl=3600000 [1429970672] unbound[14053:0] info:  [1429970672] unbound[14053:0] info:        0x00 | 00 40 01 61 0c 72 6f 6f 74 2d 73 65 72 76 65 72 73 | . @ . . r o o t - s e r v e r s         0x10 | 73 03 6e 65 74 00 05 6e 73 74 6c 64 0c 76 65 72 69 | s . n e t . . n s t l d . v e r         0x20 | 69 73 69 67 6e 2d 67 72 73 03 63 6f 6d 00 78 0c e3 | s g n - g r s . c o m . x . .         0x30 | e3 24 00 00 38 40 00 00 1c 20 00 12 75 00 00 36 ee | . $ . . 8 @ . . .   . . u . . 6 .         0x40 | ee 80                                              | . .  [1429970672] unbound[14053:0] info: ------------------------------------------------------------------------------------------ [1429970672] unbound[14053:0] info: blackpie karmmmmmm xxxxxxx ;; ->>header<<- opcode: query, rcode: noerror, id: 0 ;; flags: qr ra ; query: 1, answer: 0, authority: 1, additional: 0  ;; question section: e.root-servers.net. in  aaaa ;; answer section: ;; authority section: root-servers.net. 3600000 in  soa a.root-servers.net. nstld.verisign-grs.com. 2014110500 14400 7200 1209600 3600000 ;; additional section: ;; msg size  rcvd: 96 [1429970672] unbound[14053:0] debug: mesh_run: python module exit state module_finished 

on contrary, a query, ;; answer section: useless far logdnsmsg goes:

[1429970672] unbound[14053:0] info: pythonmod: operate called, id: 1, event:module_event_moddone [1429970672] unbound[14053:0] info: ------------------------------------------------------------------------------------------ [1429970672] unbound[14053:0] info: query: seznam.cz., type: (1), class: in (1)  [1429970672] unbound[14053:0] info: ------------------------------------------------------------------------------------------ [1429970672] unbound[14053:0] info: return    reply :: flags: 8080, qdcount: 1, security:0, ttl=300 [1429970672] unbound[14053:0] info:           qinfo :: qname: ['seznam', 'cz', ''] seznam.cz., qtype: a, qclass: in [1429970672] unbound[14053:0] info: reply: [1429970672] unbound[14053:0] info: 0:['seznam', 'cz', ''] seznam.cz. flags: 0000 [1429970672] unbound[14053:0] info: type:a (1) class:in (1) [1429970672] unbound[14053:0] info:   0:ttl=300 [1429970672] unbound[14053:0] info:  [1429970672] unbound[14053:0] info:        0x00 | 00 04 4d 4b 4c 03                                  | . . m k l .  [1429970672] unbound[14053:0] info: ------------------------------------------------------------------------------------------ [1429970672] unbound[14053:0] info: blackpie karmmmmmm xxxxxxx ;; ->>header<<- opcode: query, rcode: noerror, id: 0 ;; flags: qr ra ; query: 1, answer: 1, authority: 0, additional: 0  ;; question section: seznam.cz.  in  ;; answer section: seznam.cz.  300 in  77.75.76.3 ;; authority section: ;; additional section: ;; msg size  rcvd: 43 [1429970672] unbound[14053:0] debug: mesh_run: python module exit state module_finished 

note 00 04 4d 4b 4c 03 bytes erroneously interpreted ascii.

question

where in struct ub_packed_rrset_key** rrsets; 1 finds desired ;; answer section: data? (if indeed right place look.)

i've been fiddling quite time without luck. examined sldns_wire2str_pkt_scan function used internally unpacking wire binary data, none wiser.

logdnsmsg() logging hex dump of contents of each dns resource record. outputs bytes alongside ascii interpretation (with .s non-printable bytes). means if data contains ascii strings these visible in output, while other types of data (like ip addresses) not translate meaningful text.

the first 2 bytes of data rdlength field, indicating length of record data. remaining bytes rdata field proper. interpretation of these bytes depends on record type. a records consist of single 32-bit ip address, easy parse.

the following example code prints contents of a record:

def print_a_record(data):     rdlength, rdata = data[:2], data[2:]     assert rdlength == '\x00\x04'     assert len(rdata) == 4     addr_bytes = [ord(c) c in rdata]     print('{}.{}.{}.{}'.format(*addr_bytes)) 

further information:


Comments

Popular posts from this blog

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -

ubuntu - Selenium Node Not Connecting to Hub, Not Opening Port -