init
This commit is contained in:
Executable
+67
@@ -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())
|
||||
Reference in New Issue
Block a user