Files
eduplan-cpp-eltex/diag/tasks/13_subnet/task.md
T

2.3 KiB

Задача 13 — арифметика подсетей IPv4 (C++)

Адреса передаются в host byte order (0x0A000001 = 10.0.0.1), маска — длиной префикса.

struct Subnet {
    uint32_t network;      // адрес сети
    uint32_t broadcast;    // широковещательный адрес
    uint32_t first_host;   // первый адрес для узла
    uint32_t last_host;    // последний адрес для узла
    long long host_count;  // сколько адресов узлов доступно (для /0 не влезает в int)
};

Subnet subnet_of(uint32_t ip, int prefix);          // 0 <= prefix <= 32
bool   same_subnet(uint32_t a, uint32_t b, int prefix);
int    prefix_for_hosts(int hosts);                 // самая узкая подсеть, куда влезает hosts

Определения, которые нужно соблюсти:

  • для prefix <= 30: host_count = 2^(32-prefix) - 2, first_host = network + 1, last_host = broadcast - 1;
  • /31 (RFC 3021): host_count = 2, first_host = network, last_host = broadcast;
  • /32: host_count = 1, first_host = last_host = network = broadcast = ip;
  • prefix_for_hosts(h): наибольший prefix из диапазона 0..30 (то есть самая узкая подсеть), при котором host_count >= h. h < 1 или h > 2^32-2 → -1. Исключения /31 и /32 в подборе не участвуют — они для линков и одиночных адресов.

Эталонные примеры, которые обязаны сойтись: /26 → 62 узла; /24 → 254; /30 → 2; 10.0.1.130/26 → сеть 10.0.1.128, broadcast 10.0.1.191, узлы 129..190; prefix_for_hosts(62) → 26, prefix_for_hosts(63) → 25, prefix_for_hosts(254) → 24, prefix_for_hosts(1) → 30.

Проверка: python3 grade.py 13. Критерий: все ok, сборка без предупреждений.

Разбор после сдачи: как считать префикс по числу узлов за O(1) (32 - ceil(log2(h+2))), почему /31 — исключение, что такое маска в бинарном виде.