1'''
2 resip.py: This example shows how to generate authoritative response
3           and how to find out the IP address of a client
4
5 Copyright (c) 2009, Zdenek Vasicek (vasicek AT fit.vutbr.cz)
6                     Marek Vavrusa  (xvavru00 AT stud.fit.vutbr.cz)
7
8 This software is open source.
9
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
13
14    * Redistributions of source code must retain the above copyright notice,
15      this list of conditions and the following disclaimer.
16
17    * Redistributions in binary form must reproduce the above copyright notice,
18      this list of conditions and the following disclaimer in the documentation
19      and/or other materials provided with the distribution.
20
21    * Neither the name of the organization nor the names of its
22      contributors may be used to endorse or promote products derived from this
23      software without specific prior written permission.
24
25 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
29 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 POSSIBILITY OF SUCH DAMAGE.
36
37
38 Usage:
39
40   dig @127.0.0.1 -t TXT what.is.my.ip.
41'''
42
43def init(id, cfg): return True
44
45def deinit(id): return True
46
47def inform_super(id, qstate, superqstate, qdata): return True
48
49def operate(id, event, qstate, qdata):
50    print("Operate {} state: {}".format(event, qstate))
51
52    # Please note that if this module blocks, by moving to the validator
53    # to validate or iterator to lookup or spawn a subquery to look up,
54    # then, other incoming queries are queued up onto this module and
55    # all of them receive the same reply.
56    # You can inspect the cache.
57
58    if (event == MODULE_EVENT_NEW) or (event == MODULE_EVENT_PASS):
59        if (qstate.qinfo.qname_str.endswith("what.is.my.ip.")): #query name ends with localdomain
60            #create instance of DNS message (packet) with given parameters
61            msg = DNSMessage(qstate.qinfo.qname_str, RR_TYPE_TXT, RR_CLASS_IN, PKT_QR | PKT_RA | PKT_AA)
62            #append RR
63            if (qstate.qinfo.qtype == RR_TYPE_TXT) or (qstate.qinfo.qtype == RR_TYPE_ANY):
64                rl = qstate.mesh_info.reply_list
65                while (rl):
66                    if rl.query_reply:
67                        q = rl.query_reply
68                        # The TTL of 0 is mandatory, otherwise it ends up in
69                        # the cache, and is returned to other IP addresses.
70                        msg.answer.append("%s 0 IN TXT \"%s %d (%s)\"" % (qstate.qinfo.qname_str, q.addr,q.port,q.family))
71                    rl = rl.next
72
73            #set qstate.return_msg
74            if not msg.set_return_msg(qstate):
75                qstate.ext_state[id] = MODULE_ERROR
76                return True
77
78            #we don't need validation, result is valid
79            qstate.return_msg.rep.security = 2
80
81            qstate.return_rcode = RCODE_NOERROR
82            qstate.ext_state[id] = MODULE_FINISHED
83            return True
84        else:
85            #pass the query to validator
86            qstate.ext_state[id] = MODULE_WAIT_MODULE
87            return True
88
89    if event == MODULE_EVENT_MODDONE:
90        log_info("pythonmod: iterator module done")
91        qstate.ext_state[id] = MODULE_FINISHED
92        return True
93
94    log_err("pythonmod: bad event")
95    qstate.ext_state[id] = MODULE_ERROR
96    return True
97