# IP-адреса в карточках пакетов Пакеты теперь сохраняют `sourceIp` и `destinationIp` из IPv4/IPv6-заголовка при захвате TCP и UDP. Эти поля возвращаются в API пакетов и выводятся над содержимым в формате `источник → получатель`, в текстовом и HEX-режиме. Склеивание соседних пакетов сохраняет адреса; TLS/WebSocket обработчики наследуют их через `toBuilder()`. При запуске штатный `spring.jpa.hibernate.ddl-auto=update` добавит nullable колонки `source_ip` и `destination_ip` в таблицу `packet`. Старые записи останутся без адресов: раньше эти данные не сохранялись. Для их восстановления нужен повторный импорт исходного PCAP. Если автоматическое изменение схемы отключено, перед запуском нужно добавить две nullable колонки varchar(255). Изменены backend и git submodule `frontend`; при переносе правок нужно сохранять изменения обоих репозиториев. Для существующего Linux-развёртывания с настроенным `.env` пересоберите приложение: ```sh docker compose up -d --build packmate ``` Проверка backend: `./gradlew test bootJar` (JDK 17). Проверка frontend: `npm ci`, `npm run lint -- --no-fix src/components/Packet.vue`, `NODE_OPTIONS=--openssl-legacy-provider npm run build` (проверено с Node 18). Результат: 5 новых проверок IP прошли, frontend lint/build и backend bootJar успешны. В Windows существующий TLS-тест зависит от LF в PEM-файле: с CRLF падает исходный `RsaKeysHolder`. После преобразования переносов только в `build/resources/test/tls.key` и запуска `test -x processTestResources` прошли все 13 тестов. Live capture и миграция PostgreSQL в этой проверке не запускались. ## Фильтрация IP регулярным выражением В **Patterns → +** выберите **Search in**: - **Source IP** — адрес отправителя конкретного пакета; - **Destination IP** — адрес получателя; - **Either IP address** — совпадение хотя бы с одним из двух адресов; - **Packet content** — прежний поиск по содержимому. При выборе IP метод автоматически переключается на **Regular expression**. Например, `^10\.20\.30\.[0-9]+$` выбирает адреса с префиксом `10.20.30.`, а `^192\.0\.2\.17$` — ровно один адрес. Regex проверяется по строке адреса, показанной в карточке, без порта. IPv6 может быть записан в развёрнутой форме; например, `(?i)^2001:db8:` ищет этот префикс независимо от регистра. Поиск использует Java regex `find()`; якоря `^` и `$` задают совпадение всей строки. Для фильтра списка оставьте действие **Highlight found pattern**, сохраните паттерн и выберите его в **Patterns**. Совпавшие IP подсвечиваются в карточках; совпадения по адресам не меняют подсветку payload. Действие **Ignore matching streams** исключает совпадающие новые потоки из сохранения. Направление Request/Response задаётся отдельно; Source/Destination всегда относятся к направлению конкретного пакета, а не к фиксированной роли client/server. Для уже сохранённых потоков с IP можно запустить **Apply pattern to older streams**. Без сохранённых адресов IP-паттерн не совпадёт, даже с `.*`. Существующее ограничение lookback по service описано в архитектурном ревью (оно пока не исправлено); до его исправления historical поиск не обеспечивает изоляцию выбранного сервиса. Новые потоки учитывают service и direction. API создания паттерна получает новое поле `searchTarget`: `CONTENT`, `SOURCE_IP`, `DESTINATION_IP`, `EITHER_IP`. Для IP допустим только `searchType: REGEX`. Если поле отсутствует/null, действует прежний поиск CONTENT. API совпадений возвращает `searchTarget` фактически совпавшего поля. При обновлении также добавляются nullable строковые колонки `search_target` в таблицы `pattern` и `found_pattern` (штатный Hibernate ddl-auto=update). Null в старых строках означает CONTENT. При ручном управлении схемой добавьте эти две колонки varchar(255) перед запуском. Backend и frontend нужно обновить совместно; frontend находится в отдельном git submodule. Проверки этого этапа: 20 backend tests (12 новых сценариев IP-паттернов плюс существующие matching/IP tests), 5 frontend tests (`npm run test:ip-patterns`), lint четырёх компонентов, frontend production build и backend bootJar — успешны. Работа с живым захватом и PostgreSQL в этом этапе не проверялась.