10cd9f4ecSchristos# -*- coding: utf-8 -*- 20cd9f4ecSchristos''' 30cd9f4ecSchristos ubmodule-msg.py: simple response packet logger 40cd9f4ecSchristos 50cd9f4ecSchristos Authors: Zdenek Vasicek (vasicek AT fit.vutbr.cz) 60cd9f4ecSchristos Marek Vavrusa (xvavru00 AT stud.fit.vutbr.cz) 70cd9f4ecSchristos 80cd9f4ecSchristos Copyright (c) 2008. All rights reserved. 90cd9f4ecSchristos 100cd9f4ecSchristos This software is open source. 110cd9f4ecSchristos 120cd9f4ecSchristos Redistribution and use in source and binary forms, with or without 130cd9f4ecSchristos modification, are permitted provided that the following conditions 140cd9f4ecSchristos are met: 150cd9f4ecSchristos 160cd9f4ecSchristos Redistributions of source code must retain the above copyright notice, 170cd9f4ecSchristos this list of conditions and the following disclaimer. 180cd9f4ecSchristos 190cd9f4ecSchristos Redistributions in binary form must reproduce the above copyright notice, 200cd9f4ecSchristos this list of conditions and the following disclaimer in the documentation 210cd9f4ecSchristos and/or other materials provided with the distribution. 220cd9f4ecSchristos 230cd9f4ecSchristos THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 240cd9f4ecSchristos "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 250cd9f4ecSchristos TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 260cd9f4ecSchristos PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE 270cd9f4ecSchristos LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 280cd9f4ecSchristos CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 290cd9f4ecSchristos SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 300cd9f4ecSchristos INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 310cd9f4ecSchristos CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 320cd9f4ecSchristos ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 330cd9f4ecSchristos POSSIBILITY OF SUCH DAMAGE. 340cd9f4ecSchristos 350cd9f4ecSchristos Modified for unit test by Wouter Wijngaards, NLnet Labs, 2009. 360cd9f4ecSchristos''' 370cd9f4ecSchristosimport os 380cd9f4ecSchristos 390cd9f4ecSchristosdef init(id, cfg): 40*91f7d55fSchristos log_info("pythonmod: init called, module id is %d port: %d script: %s" % (id, cfg.port, mod_env['script'])) 410cd9f4ecSchristos return True 420cd9f4ecSchristos 430cd9f4ecSchristosdef deinit(id): 440cd9f4ecSchristos log_info("pythonmod: deinit called, module id is %d" % id) 450cd9f4ecSchristos return True 460cd9f4ecSchristos 470cd9f4ecSchristosdef inform_super(id, qstate, superqstate, qdata): 480cd9f4ecSchristos return True 490cd9f4ecSchristos 500cd9f4ecSchristosdef setTTL(qstate, ttl): 510cd9f4ecSchristos """Sets return_msg TTL and all the RRs TTL""" 520cd9f4ecSchristos if qstate.return_msg: 530cd9f4ecSchristos qstate.return_msg.rep.ttl = ttl 540cd9f4ecSchristos if (qstate.return_msg.rep): 550cd9f4ecSchristos for i in range(0,qstate.return_msg.rep.rrset_count): 560cd9f4ecSchristos d = qstate.return_msg.rep.rrsets[i].entry.data 570cd9f4ecSchristos for j in range(0,d.count+d.rrsig_count): 580cd9f4ecSchristos d.rr_ttl[j] = ttl 590cd9f4ecSchristos 600cd9f4ecSchristosdef dataHex(data, prefix=""): 610cd9f4ecSchristos res = "" 62f42d8de7Schristos for i in range(0, int((len(data)+15)/16)): 630cd9f4ecSchristos res += "%s0x%02X | " % (prefix, i*16) 64f42d8de7Schristos if type(data[0]) == type(1): 65f42d8de7Schristos d = map(lambda x:int(x), data[i*16:i*16+17]) 66f42d8de7Schristos else: 670cd9f4ecSchristos d = map(lambda x:ord(x), data[i*16:i*16+17]) 680cd9f4ecSchristos for ch in d: 69f42d8de7Schristos res += "%02X " % int(ch) 70f42d8de7Schristos for i in range(0,17-len(data[i*16:i*16+17])): 710cd9f4ecSchristos res += " " 720cd9f4ecSchristos res += "| " 730cd9f4ecSchristos for ch in d: 740cd9f4ecSchristos if (ch < 32) or (ch > 127): 750cd9f4ecSchristos res += ". " 760cd9f4ecSchristos else: 770cd9f4ecSchristos res += "%c " % ch 780cd9f4ecSchristos res += "\n" 790cd9f4ecSchristos return res 800cd9f4ecSchristos 810cd9f4ecSchristosdef printReturnMsg(qstate): 82f42d8de7Schristos 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)) 83f42d8de7Schristos 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) 840cd9f4ecSchristos if (qstate.return_msg.rep): 85f42d8de7Schristos print ("RRSets:",qstate.return_msg.rep.rrset_count) 860cd9f4ecSchristos prevkey = None 870cd9f4ecSchristos for i in range(0,qstate.return_msg.rep.rrset_count): 880cd9f4ecSchristos r = qstate.return_msg.rep.rrsets[i] 890cd9f4ecSchristos rk = r.rk 90f42d8de7Schristos print (i,":",rk.dname_list, rk.dname_str, "flags: %04X" % rk.flags) 91f42d8de7Schristos print ("type:",rk.type_str,"(%d)" % ntohs(rk.type), "class:",rk.rrset_class_str,"(%d)" % ntohs(rk.rrset_class)) 920cd9f4ecSchristos 930cd9f4ecSchristos d = r.entry.data 94f42d8de7Schristos print (" RRDatas:",d.count+d.rrsig_count) 950cd9f4ecSchristos for j in range(0,d.count+d.rrsig_count): 96f42d8de7Schristos print (" ",j,":","TTL=",d.rr_ttl[j],"RR data:") 97f42d8de7Schristos print (dataHex(d.rr_data[j]," ")) 980cd9f4ecSchristos 990cd9f4ecSchristos 1000cd9f4ecSchristosdef operate(id, event, qstate, qdata): 1010cd9f4ecSchristos log_info("pythonmod: operate called, id: %d, event:%s" % (id, strmodulevent(event))) 102f42d8de7Schristos #print ("pythonmod: per query data", qdata) 1030cd9f4ecSchristos 104f42d8de7Schristos print ("Query:", qstate.qinfo.qname, qstate.qinfo.qname_list, qstate.qinfo.qname_str) 105f42d8de7Schristos print ("Type:",qstate.qinfo.qtype_str,"(%d)" % qstate.qinfo.qtype) 106f42d8de7Schristos print ("Class:",qstate.qinfo.qclass_str,"(%d)" % qstate.qinfo.qclass) 107f42d8de7Schristos print () 1080cd9f4ecSchristos 1090cd9f4ecSchristos if (event == MODULE_EVENT_NEW or event == MODULE_EVENT_PASS) and (qstate.qinfo.qname_str.endswith("example.com.")): 110f42d8de7Schristos print (qstate.qinfo.qname_str) 1110cd9f4ecSchristos 1120cd9f4ecSchristos qstate.ext_state[id] = MODULE_FINISHED 1130cd9f4ecSchristos 1140cd9f4ecSchristos # eat time 1150cd9f4ecSchristos y = 20 1160cd9f4ecSchristos for z in range(2, 10000): 1170cd9f4ecSchristos y = y*2 - z/2 1180cd9f4ecSchristos y = y/2 + z 1190cd9f4ecSchristos 1200cd9f4ecSchristos msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_A, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA) #, 300) 1210cd9f4ecSchristos #msg.authority.append("xxx.seznam.cz. 10 IN A 192.168.1.1") 1220cd9f4ecSchristos #msg.additional.append("yyy.seznam.cz. 10 IN A 1.1.1.2.") 1230cd9f4ecSchristos 1240cd9f4ecSchristos # answer can be returned to the client without further checking. 1250cd9f4ecSchristos 1260cd9f4ecSchristos if qstate.qinfo.qtype == RR_TYPE_A: 1270cd9f4ecSchristos msg.answer.append("%s 10 IN A 192.168.1.1" % qstate.qinfo.qname_str) 1280cd9f4ecSchristos if (qstate.qinfo.qtype == RR_TYPE_SRV) or (qstate.qinfo.qtype == RR_TYPE_ANY): 1290cd9f4ecSchristos msg.answer.append("%s 10 IN SRV 0 0 80 neinfo.example.com." % qstate.qinfo.qname_str) 1300cd9f4ecSchristos if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY): 1310cd9f4ecSchristos msg.answer.append("%s 10 IN TXT path=/" % qstate.qinfo.qname_str) 1320cd9f4ecSchristos 1330cd9f4ecSchristos if not msg.set_return_msg(qstate): 1340cd9f4ecSchristos qstate.ext_state[id] = MODULE_ERROR 1350cd9f4ecSchristos return True 1360cd9f4ecSchristos 1370cd9f4ecSchristos #qstate.return_msg.rep.security = 2 #pokud nebude nasledovat validator, je zapotrebi nastavit security, aby nebyl paket zahozen v mesh_send_reply 1380cd9f4ecSchristos printReturnMsg(qstate) 1390cd9f4ecSchristos 1400cd9f4ecSchristos #Authoritative result can't be stored in cache 1410cd9f4ecSchristos #if (not storeQueryInCache(qstate, qstate.return_msg.qinfo, qstate.return_msg.rep, 0)): 1420cd9f4ecSchristos # print "Can't store in cache" 1430cd9f4ecSchristos # qstate.ext_state[id] = MODULE_ERROR 1440cd9f4ecSchristos # return False 1450cd9f4ecSchristos #print "Store OK" 1460cd9f4ecSchristos 1470cd9f4ecSchristos qstate.return_rcode = RCODE_NOERROR 1480cd9f4ecSchristos return True 1490cd9f4ecSchristos 1500cd9f4ecSchristos if event == MODULE_EVENT_NEW: 1510cd9f4ecSchristos qstate.ext_state[id] = MODULE_WAIT_MODULE 1520cd9f4ecSchristos return True 1530cd9f4ecSchristos 1540cd9f4ecSchristos if event == MODULE_EVENT_MODDONE: 1550cd9f4ecSchristos log_info("pythonmod: previous module done") 1560cd9f4ecSchristos qstate.ext_state[id] = MODULE_FINISHED 1570cd9f4ecSchristos return True 1580cd9f4ecSchristos 1590cd9f4ecSchristos if event == MODULE_EVENT_PASS: 1600cd9f4ecSchristos log_info("pythonmod: event_pass") 1610cd9f4ecSchristos qstate.ext_state[id] = MODULE_WAIT_MODULE 1620cd9f4ecSchristos return True 1630cd9f4ecSchristos 1640cd9f4ecSchristos log_err("pythonmod: BAD event") 1650cd9f4ecSchristos qstate.ext_state[id] = MODULE_ERROR 1660cd9f4ecSchristos return True 1670cd9f4ecSchristos 1680cd9f4ecSchristoslog_info("pythonmod: script loaded.") 169