xref: /netbsd-src/external/bsd/unbound/dist/pythonmod/ubmodule-msg.py (revision 91f7d55fb697b5e0475da4718fa34c3a3ebeac85)
13b6c3722Schristos# -*- coding: utf-8 -*-
23b6c3722Schristos'''
33b6c3722Schristos ubmodule-msg.py: simple response packet logger
43b6c3722Schristos
53b6c3722Schristos Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz)
63b6c3722Schristos          Marek Vavrusa  (xvavru00 AT stud.fit.vutbr.cz)
73b6c3722Schristos
83b6c3722Schristos Copyright (c) 2008. All rights reserved.
93b6c3722Schristos
103b6c3722Schristos This software is open source.
113b6c3722Schristos
123b6c3722Schristos Redistribution and use in source and binary forms, with or without
133b6c3722Schristos modification, are permitted provided that the following conditions
143b6c3722Schristos are met:
153b6c3722Schristos
163b6c3722Schristos Redistributions of source code must retain the above copyright notice,
173b6c3722Schristos this list of conditions and the following disclaimer.
183b6c3722Schristos
193b6c3722Schristos Redistributions in binary form must reproduce the above copyright notice,
203b6c3722Schristos this list of conditions and the following disclaimer in the documentation
213b6c3722Schristos and/or other materials provided with the distribution.
223b6c3722Schristos
233b6c3722Schristos THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
243b6c3722Schristos "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
253b6c3722Schristos TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
263b6c3722Schristos PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
273b6c3722Schristos LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
283b6c3722Schristos CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
293b6c3722Schristos SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
303b6c3722Schristos INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
313b6c3722Schristos CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
323b6c3722Schristos ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
333b6c3722Schristos POSSIBILITY OF SUCH DAMAGE.
343b6c3722Schristos'''
353b6c3722Schristosimport os
363b6c3722Schristos
373b6c3722Schristosdef init(id, cfg):
38*91f7d55fSchristos    log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script']))
393b6c3722Schristos    return True
403b6c3722Schristos
413b6c3722Schristosdef deinit(id):
423b6c3722Schristos    log_info("pythonmod: deinit called, module id is %d" % id)
433b6c3722Schristos    return True
443b6c3722Schristos
453b6c3722Schristosdef inform_super(id, qstate, superqstate, qdata):
463b6c3722Schristos    return True
473b6c3722Schristos
483b6c3722Schristosdef setTTL(qstate, ttl):
493b6c3722Schristos    """Sets return_msg TTL and all the RRs TTL"""
503b6c3722Schristos    if qstate.return_msg:
513b6c3722Schristos        qstate.return_msg.rep.ttl = ttl
523b6c3722Schristos        if (qstate.return_msg.rep):
533b6c3722Schristos            for i in range(0,qstate.return_msg.rep.rrset_count):
543b6c3722Schristos                d = qstate.return_msg.rep.rrsets[i].entry.data
553b6c3722Schristos                for j in range(0,d.count+d.rrsig_count):
563b6c3722Schristos                    d.rr_ttl[j] = ttl
573b6c3722Schristos
583b6c3722Schristosdef dataHex(data, prefix=""):
593b6c3722Schristos    res = ""
603b6c3722Schristos    for i in range(0, (len(data)+15)/16):
613b6c3722Schristos        res += "%s0x%02X | " % (prefix, i*16)
623b6c3722Schristos        d = map(lambda x:ord(x), data[i*16:i*16+17])
633b6c3722Schristos        for ch in d:
643b6c3722Schristos            res += "%02X " % ch
653b6c3722Schristos        for i in range(0,17-len(d)):
663b6c3722Schristos            res += "   "
673b6c3722Schristos        res += "| "
683b6c3722Schristos        for ch in d:
693b6c3722Schristos            if (ch < 32) or (ch > 127):
703b6c3722Schristos                res += ". "
713b6c3722Schristos            else:
723b6c3722Schristos                res += "%c " % ch
733b6c3722Schristos        res += "\n"
743b6c3722Schristos    return res
753b6c3722Schristos
763b6c3722Schristosdef printReturnMsg(qstate):
773b6c3722Schristos    print "Return MSG rep   :: flags: %04X, QDcount: %d, Security:%d, TTL=%d" % (qstate.return_msg.rep.flags, qstate.return_msg.rep.qdcount,qstate.return_msg.rep.security, qstate.return_msg.rep.ttl)
783b6c3722Schristos    print "           qinfo :: qname:",qstate.return_msg.qinfo.qname_list, qstate.return_msg.qinfo.qname_str, "type:",qstate.return_msg.qinfo.qtype_str, "class:",qstate.return_msg.qinfo.qclass_str
793b6c3722Schristos    if (qstate.return_msg.rep):
803b6c3722Schristos        print "RRSets:",qstate.return_msg.rep.rrset_count
813b6c3722Schristos        prevkey = None
823b6c3722Schristos        for i in range(0,qstate.return_msg.rep.rrset_count):
833b6c3722Schristos            r = qstate.return_msg.rep.rrsets[i]
843b6c3722Schristos            rk = r.rk
853b6c3722Schristos            print i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags,
863b6c3722Schristos            print "type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)
873b6c3722Schristos
883b6c3722Schristos            d = r.entry.data
893b6c3722Schristos            print "    RRDatas:",d.count+d.rrsig_count
903b6c3722Schristos            for j in range(0,d.count+d.rrsig_count):
913b6c3722Schristos                print "    ",j,":","TTL=",d.rr_ttl[j],"RR data:"
923b6c3722Schristos                print dataHex(d.rr_data[j],"         ")
933b6c3722Schristos
943b6c3722Schristos
953b6c3722Schristosdef operate(id, event, qstate, qdata):
963b6c3722Schristos    log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event)))
973b6c3722Schristos    #print "pythonmod: per query data", qdata
983b6c3722Schristos
993b6c3722Schristos    print "Query:", ''.join(map(lambda x:chr(max(32,ord(x))),qstate.qinfo.qname)), qstate.qinfo.qname_list, qstate.qinfo.qname_str,
1003b6c3722Schristos    print "Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype,
1013b6c3722Schristos    print "Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass
1023b6c3722Schristos    print
1033b6c3722Schristos
1043b6c3722Schristos    #if event == MODULE_EVENT_PASS: #pokud mame "validator python iterator"
1053b6c3722Schristos    if (event == MODULE_EVENT_NEW) and (qstate.qinfo.qname_str.endswith(".seznam.cz.")): #pokud mame "python validator iterator"
1063b6c3722Schristos        print qstate.qinfo.qname_str
1073b6c3722Schristos
1083b6c3722Schristos        qstate.ext_state[id] = MODULE_FINISHED
1093b6c3722Schristos
1103b6c3722Schristos        msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300)
1113b6c3722Schristos        #msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1")
1123b6c3722Schristos        #msg.additional.append("yyy.seznam.cz. 10 IN A 1.1.1.2.")
1133b6c3722Schristos
1143b6c3722Schristos        if qstate.qinfo.qtype == RR_TYPE_A:
1153b6c3722Schristos            msg.answer.append("%s 10 IN A 192.168.1.1" % qstate.qinfo.qname_str)
1163b6c3722Schristos        if (qstate.qinfo.qtype == RR_TYPE_SRV) or (qstate.qinfo.qtype == RR_TYPE_ANY):
1173b6c3722Schristos            msg.answer.append("%s 10 IN SRV 0 0 80 neinfo.example.com." % qstate.qinfo.qname_str)
1183b6c3722Schristos        if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
1193b6c3722Schristos            msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str)
1203b6c3722Schristos
1213b6c3722Schristos        if not msg.set_return_msg(qstate):
1223b6c3722Schristos            qstate.ext_state[id] = MODULE_ERROR
1233b6c3722Schristos            return True
1243b6c3722Schristos
1253b6c3722Schristos        #qstate.return_msg.rep.security = 2 #pokud nebude nasledovat validator, je zapotrebi nastavit security, aby nebyl paket zahozen v mesh_send_reply
1263b6c3722Schristos        printReturnMsg(qstate)
1273b6c3722Schristos
1283b6c3722Schristos        #Authoritative result can't be stored in cache
1293b6c3722Schristos        #if (not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0)):
1303b6c3722Schristos        #    print "Can't store in cache"
1313b6c3722Schristos        #    qstate.ext_state[id] = MODULE_ERROR
1323b6c3722Schristos        #    return False
1333b6c3722Schristos        #print "Store OK"
1343b6c3722Schristos
1353b6c3722Schristos        qstate.return_rcode = RCODE_NOERROR
1363b6c3722Schristos        return True
1373b6c3722Schristos
1383b6c3722Schristos    if event == MODULE_EVENT_NEW:
1393b6c3722Schristos        qstate.ext_state[id] = MODULE_WAIT_MODULE
1403b6c3722Schristos        return True
1413b6c3722Schristos
1423b6c3722Schristos    if event == MODULE_EVENT_MODDONE:
1433b6c3722Schristos        log_info("pythonmod: previous module done")
1443b6c3722Schristos        qstate.ext_state[id] = MODULE_FINISHED
1453b6c3722Schristos        return True
1463b6c3722Schristos
1473b6c3722Schristos    if event == MODULE_EVENT_PASS:
1483b6c3722Schristos        log_info("pythonmod: event_pass")
1493b6c3722Schristos        qstate.ext_state[id] = MODULE_WAIT_MODULE
1503b6c3722Schristos        return True
1513b6c3722Schristos
1523b6c3722Schristos    log_err("pythonmod: BAD event")
1533b6c3722Schristos    qstate.ext_state[id] = MODULE_ERROR
1543b6c3722Schristos    return True
1553b6c3722Schristos
1563b6c3722Schristoslog_info("pythonmod: script loaded.")
157