master
Sergey Marinkevich 1 month ago
commit b27803241c

@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""
Извлекает уникальные QNAME из текстового вывода tcpdump (UDP/TCP DNS).
Ответы и соответствие IP не учитываются только запрошенные имена.
"""
from __future__ import annotations
import argparse
import re
import sys
from typing import Set, TextIO
# Запрос: <txid>+ <TYPE>? <qname>. (<остаток длины>)
# Примеры: "47028+ A? talk-pilsner.kakao.com. (40)"
# TCP: "... length 48 31523+ A? api.example.com. (46)"
_QUERY = re.compile(
r"""
(?<!\d) # не середина числа
(\d+)\+ # txid и флаг запроса
\s+
(\S+?) # тип (A, AAAA, PTR, …)
\?
\s+
([^\s()]+) # QNAME (с завершающей точкой в дампе)
\s+
\(\d+\) # длина хвоста пакета
""",
re.VERBOSE,
)
def main() -> int:
parser = argparse.ArgumentParser(
description="Список уникальных доменов из текстового вывода tcpdump (DNS-запросы)."
)
parser.add_argument(
"file",
nargs="?",
default="-",
help="Файл с дампом; по умолчанию или «-» — читать stdin",
)
args = parser.parse_args()
inp: TextIO
if args.file == "-":
inp = sys.stdin
else:
inp = open(args.file, encoding="utf-8", errors="replace")
seen: Set[str] = set()
try:
for line in inp:
for m in _QUERY.finditer(line):
name = m.group(3).rstrip(".")
if name and name not in seen:
seen.add(name)
print(name)
finally:
if inp is not sys.stdin:
inp.close()
return 0
if __name__ == "__main__":
raise SystemExit(main())
Loading…
Cancel
Save