]>
git.ipfire.org Git - thirdparty/pdns.git/blob - contrib/ProtobufLogger.py
10 # run: protoc -I=../pdns/ --python_out=. ../pdns/dnsmessage.proto
11 # to generate dnsmessage_pb2
14 class PDNSPBConnHandler(object):
16 def __init__(self
, conn
):
21 data
= self
._conn
.recv(2)
24 (datalen
,) = struct
.unpack("!H", data
)
25 data
= self
._conn
.recv(datalen
)
27 msg
= dnsmessage_pb2
.PBDNSMessage()
28 msg
.ParseFromString(data
)
29 if msg
.type == dnsmessage_pb2
.PBDNSMessage
.DNSQueryType
:
30 self
.printQueryMessage(msg
)
31 elif msg
.type == dnsmessage_pb2
.PBDNSMessage
.DNSResponseType
:
32 self
.printResponseMessage(msg
)
34 # elif msg.type == dnsmessage_pb2.PBDNSMessage.DNSOutgoingQueryType:
35 # self.printOutgoingQueryMessage(msg)
36 # elif msg.type == dnsmessage_pb2.PBDNSMessage.DNSIncomingResponseType:
37 # self.printIncomingResponseMessage(msg)
39 print('Discarding unsupported message type %d' % (msg
.type))
43 def printQueryMessage(self
, message
):
44 self
.printSummary(message
, 'Query')
45 self
.printQuery(message
)
47 def printOutgoingQueryMessage(self
, message
):
48 self
.printSummary(message
, 'Query (O)')
49 self
.printQuery(message
)
51 def printResponseMessage(self
, message
):
52 self
.printSummary(message
, 'Response')
53 self
.printQuery(message
)
54 self
.printResponse(message
)
56 def printIncomingResponseMessage(self
, message
):
57 self
.printSummary(message
, 'Response (I)')
58 self
.printQuery(message
)
59 self
.printResponse(message
)
61 def printQuery(self
, message
):
62 if message
.HasField('question'):
64 if message
.question
.HasField('qClass'):
65 qclass
= message
.question
.qClass
66 print("- Question: %d, %d, %s" % (qclass
,
67 message
.question
.qType
,
68 message
.question
.qName
))
70 def printResponse(self
, message
):
71 if message
.HasField('response'):
72 response
= message
.response
74 if response
.HasField('queryTimeSec'):
75 datestr
= datetime
.datetime
.fromtimestamp(response
.queryTimeSec
).strftime('%Y-%m-%d %H:%M:%S')
76 if response
.HasField('queryTimeUsec'):
77 datestr
= datestr
+ '.' + str(response
.queryTimeUsec
)
78 print("- Query time: %s" % (datestr
))
81 if response
.HasField('appliedPolicy') and response
.appliedPolicy
:
82 policystr
= ', Applied policy: ' + response
.appliedPolicy
86 tagsstr
= ', Tags: ' + ','.join(response
.tags
)
88 rrscount
= len(response
.rrs
)
90 print("- Response Code: %d, RRs: %d%s%s" % (response
.rcode
,
95 for rr
in response
.rrs
:
98 if rr
.HasField('class'):
99 rrclass
= getattr(rr
, 'class')
101 if (rrclass
== 1 or rrclass
== 255) and rr
.HasField('rdata'):
103 rdatastr
= socket
.inet_ntop(socket
.AF_INET
, rr
.rdata
)
107 rdatastr
= socket
.inet_ntop(socket
.AF_INET6
, rr
.rdata
)
109 print("\t - %d, %d, %s, %d, %s" % (rrclass
,
115 def printSummary(self
, msg
, typestr
):
116 datestr
= datetime
.datetime
.fromtimestamp(msg
.timeSec
).strftime('%Y-%m-%d %H:%M:%S')
117 if msg
.HasField('timeUsec'):
118 datestr
= datestr
+ '.' + str(msg
.timeUsec
)
121 fromvalue
= getattr(msg
, 'from')
122 if msg
.socketFamily
== dnsmessage_pb2
.PBDNSMessage
.INET
:
123 if msg
.HasField('from'):
124 ipfromstr
= socket
.inet_ntop(socket
.AF_INET
, fromvalue
)
125 if msg
.HasField('to'):
126 iptostr
= socket
.inet_ntop(socket
.AF_INET
, msg
.to
)
128 if msg
.HasField('from'):
129 ipfromstr
= socket
.inet_ntop(socket
.AF_INET6
, fromvalue
)
130 if msg
.HasField('to'):
131 iptostr
= socket
.inet_ntop(socket
.AF_INET6
, msg
.to
)
133 if msg
.socketProtocol
== dnsmessage_pb2
.PBDNSMessage
.UDP
:
138 messageidstr
= binascii
.hexlify(bytearray(msg
.messageId
))
139 initialrequestidstr
= ''
141 # if msg.HasField('initialRequestId'):
142 # initialrequestidstr = ', initial uuid: ' + binascii.hexlify(bytearray(msg.initialRequestId))
144 requestor
= self
.getRequestorSubnet(msg
)
146 requestorstr
= ' (' + requestor
+ ')'
148 print('[%s] %s of size %d: %s%s -> %s (%s), id: %d, uuid: %s%s' % (datestr
,
157 initialrequestidstr
))
159 def getRequestorSubnet(self
, msg
):
161 if msg
.HasField('originalRequestorSubnet'):
162 if len(msg
.originalRequestorSubnet
) == 4:
163 requestorstr
= socket
.inet_ntop(socket
.AF_INET
,
164 msg
.originalRequestorSubnet
)
165 elif len(msg
.originalRequestorSubnet
) == 16:
166 requestorstr
= socket
.inet_ntop(socket
.AF_INET6
,
167 msg
.originalRequestorSubnet
)
170 class PDNSPBListener(object):
172 def __init__(self
, addr
, port
):
173 res
= socket
.getaddrinfo(addr
, port
, socket
.AF_UNSPEC
,
174 socket
.SOCK_STREAM
, 0,
177 print("Error parsing the supplied address")
179 family
, socktype
, _
, _
, sockaddr
= res
[0]
180 self
._sock
= socket
.socket(family
, socktype
)
181 self
._sock
.setsockopt(socket
.SOL_SOCKET
, socket
.SO_REUSEPORT
, 1)
183 self
._sock
.bind(sockaddr
)
184 except socket
.error
as exp
:
185 print("Error while binding: %s" % str(exp
))
188 self
._sock
.listen(100)
192 (conn
, _
) = self
._sock
.accept()
194 handler
= PDNSPBConnHandler(conn
)
195 thread
= threading
.Thread(name
='Connection Handler',
196 target
=PDNSPBConnHandler
.run
,
198 thread
.setDaemon(True)
204 if __name__
== "__main__":
205 if len(sys
.argv
) != 3:
206 sys
.exit('Usage: %s <address> <port>' % (sys
.argv
[0]))
208 PDNSPBListener(sys
.argv
[1], sys
.argv
[2]).run()