Special StrField that handles DNS encoding/decoding. It will also handle DNS decompression. (may be StrLenField if a length_from is passed),
| 333 | |
| 334 | |
| 335 | class DNSStrField(StrLenField): |
| 336 | """ |
| 337 | Special StrField that handles DNS encoding/decoding. |
| 338 | It will also handle DNS decompression. |
| 339 | (may be StrLenField if a length_from is passed), |
| 340 | """ |
| 341 | def any2i(self, pkt, x): |
| 342 | if x and isinstance(x, list): |
| 343 | return [self.h2i(pkt, y) for y in x] |
| 344 | return super(DNSStrField, self).any2i(pkt, x) |
| 345 | |
| 346 | def h2i(self, pkt, x): |
| 347 | # Setting a DNSStrField manually (h2i) means any current compression will break |
| 348 | if ( |
| 349 | pkt and |
| 350 | isinstance(pkt.parent, DNSCompressedPacket) and |
| 351 | pkt.parent.raw_packet_cache |
| 352 | ): |
| 353 | pkt.parent.clear_cache() |
| 354 | if not x: |
| 355 | return b"." |
| 356 | x = bytes_encode(x) |
| 357 | if x[-1:] != b"." and not _is_ptr(x): |
| 358 | return x + b"." |
| 359 | return x |
| 360 | |
| 361 | def i2m(self, pkt, x): |
| 362 | return dns_encode(x, check_built=True) |
| 363 | |
| 364 | def i2len(self, pkt, x): |
| 365 | return len(self.i2m(pkt, x)) |
| 366 | |
| 367 | def get_full(self, pkt): |
| 368 | while pkt and not isinstance(pkt, DNSCompressedPacket): |
| 369 | pkt = pkt.parent or pkt.underlayer |
| 370 | if not pkt: |
| 371 | return None |
| 372 | return pkt.get_full() |
| 373 | |
| 374 | def getfield(self, pkt, s): |
| 375 | remain = b"" |
| 376 | if self.length_from: |
| 377 | remain, s = super(DNSStrField, self).getfield(pkt, s) |
| 378 | # Decode the compressed DNS message |
| 379 | decoded, left = dns_get_str(s, full=self.get_full(pkt)) |
| 380 | # returns (remaining, decoded) |
| 381 | return left + remain, decoded |
| 382 | |
| 383 | |
| 384 | class DNSTextField(StrLenField): |
no outgoing calls
no test coverage detected