| 1270 | |
| 1271 | |
| 1272 | class DNS(DNSCompressedPacket): |
| 1273 | name = "DNS" |
| 1274 | FORCE_TCP = False |
| 1275 | fields_desc = [ |
| 1276 | ConditionalField(ShortField("length", None), |
| 1277 | lambda p: p.FORCE_TCP or isinstance(p.underlayer, TCP)), |
| 1278 | ShortField("id", 0), |
| 1279 | BitField("qr", 0, 1), |
| 1280 | BitEnumField("opcode", 0, 4, {0: "QUERY", 1: "IQUERY", 2: "STATUS"}), |
| 1281 | BitField("aa", 0, 1), |
| 1282 | BitField("tc", 0, 1), |
| 1283 | BitField("rd", 1, 1), |
| 1284 | BitField("ra", 0, 1), |
| 1285 | BitField("z", 0, 1), |
| 1286 | # AD and CD bits are defined in RFC 2535 |
| 1287 | BitField("ad", 0, 1), # Authentic Data |
| 1288 | BitField("cd", 0, 1), # Checking Disabled |
| 1289 | BitEnumField("rcode", 0, 4, {0: "ok", 1: "format-error", |
| 1290 | 2: "server-failure", 3: "name-error", |
| 1291 | 4: "not-implemented", 5: "refused"}), |
| 1292 | FieldLenField("qdcount", None, count_of="qd"), |
| 1293 | FieldLenField("ancount", None, count_of="an"), |
| 1294 | FieldLenField("nscount", None, count_of="ns"), |
| 1295 | FieldLenField("arcount", None, count_of="ar"), |
| 1296 | _DNSPacketListField("qd", [DNSQR()], DNSQR, count_from=lambda pkt: pkt.qdcount), |
| 1297 | _DNSPacketListField("an", [], _DNSRR, count_from=lambda pkt: pkt.ancount), |
| 1298 | _DNSPacketListField("ns", [], _DNSRR, count_from=lambda pkt: pkt.nscount), |
| 1299 | _DNSPacketListField("ar", [], _DNSRR, count_from=lambda pkt: pkt.arcount), |
| 1300 | ] |
| 1301 | |
| 1302 | def get_full(self): |
| 1303 | # Required for DNSCompressedPacket |
| 1304 | if isinstance(self.underlayer, TCP) or self.FORCE_TCP: |
| 1305 | return self.original[2:] |
| 1306 | else: |
| 1307 | return self.original |
| 1308 | |
| 1309 | def answers(self, other): |
| 1310 | return (isinstance(other, DNS) and |
| 1311 | self.id == other.id and |
| 1312 | self.qr == 1 and |
| 1313 | other.qr == 0) |
| 1314 | |
| 1315 | def mysummary(self): |
| 1316 | name = "" |
| 1317 | if self.qr: |
| 1318 | type = "Ans" |
| 1319 | if self.an and isinstance(self.an[0], DNSRR): |
| 1320 | name = ' %s' % self.an[0].rdata |
| 1321 | elif self.rcode != 0: |
| 1322 | name = self.sprintf(' %rcode%') |
| 1323 | else: |
| 1324 | type = "Qry" |
| 1325 | if self.qd and isinstance(self.qd[0], DNSQR): |
| 1326 | name = ' %s' % self.qd[0].qname |
| 1327 | return "%sDNS %s%s" % ( |
| 1328 | "m" |
| 1329 | if isinstance(self.underlayer, UDP) and self.underlayer.dport == 5353 |
no test coverage detected