# Запрет адреса сети и broadcast (изменение 015) Находка ревью № 5, серьёзность — средняя. ## Context `create_address` проверяет только `ip in network`: в `198.51.100.0/25` назначаются `.0` и `.127` (воспроизведено). При этом `capacity()` для IPv4 ≤ /30 вычитает эти два адреса, поэтому `free = cap - stored` занижается, загрузка может превысить 100 %. ## Решение 1. `app/services.py`: `usable(net, ip) -> bool` — для IPv4 с длиной ≤ 30 ложь для адреса сети и broadcast; /31, /32 и IPv6 — без ограничений (как `capacity()` и `next_free`). 2. `create_address` (`app/api/v1/prefixes.py`): при `not usable` — 422 «Адрес сети/broadcast нельзя назначить: 198.51.100.0 — адрес сети 198.51.100.0/25». 3. **Существующие данные:** миграция не нужна. Скрипт `scripts/find_unusable_addresses.py` (только чтение) выводит такие записи; решение по ним — за администратором (в SUMMARY — результат по стенду). До очистки `utilization` ограничивается 100 % (`min(…, 100)` в `utilization()`), чтобы не показывать >100 %. 4. `allocate_next` уже использует `net.hosts()` — без изменений. ## Файлы `app/services.py`, `app/api/v1/prefixes.py`, `scripts/find_unusable_addresses.py`, `tests/test_api.py`, `README.md` (Модель данных). ## Тест `/25`: `.0` → 422, `.127` → 422, `.1` → 201; `/31`: оба адреса → 201. ## Проверка `pytest -q`; UI «Назначить адрес» с `.0` — сообщение в форме у поля.