]>
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('appliedPolicy') and response
.appliedPolicy
:
75 policystr
= ', Applied policy: ' + response
.appliedPolicy
79 tagsstr
= ', Tags: ' + ','.join(response
.tags
)
81 rrscount
= len(response
.rrs
)
83 print("- Response Code: %d, RRs: %d%s%s" % (response
.rcode
,
88 for rr
in response
.rrs
:
91 if rr
.HasField('class'):
92 rrclass
= getattr(rr
, 'class')
94 if (rrclass
== 1 or rrclass
== 255) and rr
.HasField('rdata'):
96 rdatastr
= socket
.inet_ntop(socket
.AF_INET
, rr
.rdata
)
100 rdatastr
= socket
.inet_ntop(socket
.AF_INET6
, rr
.rdata
)
102 print("\t - %d, %d, %s, %d, %s" % (rrclass
,
108 def printSummary(self
, msg
, typestr
):
109 datestr
= datetime
.datetime
.fromtimestamp(msg
.timeSec
).strftime('%Y-%m-%d %H:%M:%S')
110 if msg
.HasField('timeUsec'):
111 datestr
= datestr
+ '.' + str(msg
.timeUsec
)
114 fromvalue
= getattr(msg
, 'from')
115 if msg
.socketFamily
== dnsmessage_pb2
.PBDNSMessage
.INET
:
116 if msg
.HasField('from'):
117 ipfromstr
= socket
.inet_ntop(socket
.AF_INET
, fromvalue
)
118 if msg
.HasField('to'):
119 iptostr
= socket
.inet_ntop(socket
.AF_INET
, msg
.to
)
121 if msg
.HasField('from'):
122 ipfromstr
= socket
.inet_ntop(socket
.AF_INET6
, fromvalue
)
123 if msg
.HasField('to'):
124 iptostr
= socket
.inet_ntop(socket
.AF_INET6
, msg
.to
)
126 if msg
.socketProtocol
== dnsmessage_pb2
.PBDNSMessage
.UDP
:
131 messageidstr
= binascii
.hexlify(bytearray(msg
.messageId
))
132 initialrequestidstr
= ''
134 # if msg.HasField('initialRequestId'):
135 # initialrequestidstr = ', initial uuid: ' + binascii.hexlify(bytearray(msg.initialRequestId))
137 requestor
= self
.getRequestorSubnet(msg
)
139 requestorstr
= ' (' + requestor
+ ')'
141 print('[%s] %s of size %d: %s%s -> %s (%s), id: %d, uuid: %s%s' % (datestr
,
150 initialrequestidstr
))
152 def getRequestorSubnet(self
, msg
):
154 if msg
.HasField('originalRequestorSubnet'):
155 if len(msg
.originalRequestorSubnet
) == 4:
156 requestorstr
= socket
.inet_ntop(socket
.AF_INET
,
157 msg
.originalRequestorSubnet
)
158 elif len(msg
.originalRequestorSubnet
) == 16:
159 requestorstr
= socket
.inet_ntop(socket
.AF_INET6
,
160 msg
.originalRequestorSubnet
)
163 class PDNSPBListener(object):
165 def __init__(self
, addr
, port
):
166 res
= socket
.getaddrinfo(addr
, port
, socket
.AF_UNSPEC
,
167 socket
.SOCK_STREAM
, 0,
170 print("Error parsing the supplied address")
172 family
, socktype
, _
, _
, sockaddr
= res
[0]
173 self
._sock
= socket
.socket(family
, socktype
)
174 self
._sock
.setsockopt(socket
.SOL_SOCKET
, socket
.SO_REUSEPORT
, 1)
176 self
._sock
.bind(sockaddr
)
177 except socket
.error
as exp
:
178 print("Error while binding: %s" % str(exp
))
181 self
._sock
.listen(100)
185 (conn
, _
) = self
._sock
.accept()
187 handler
= PDNSPBConnHandler(conn
)
188 thread
= threading
.Thread(name
='Connection Handler',
189 target
=PDNSPBConnHandler
.run
,
191 thread
.setDaemon(True)
197 if __name__
== "__main__":
198 if len(sys
.argv
) != 3:
199 sys
.exit('Usage: %s <address> <port>' % (sys
.argv
[0]))
201 PDNSPBListener(sys
.argv
[1], sys
.argv
[2]).run()