Files
eduplan-cpp-eltex/diag/tasks/04_ipv4/task.md
T

2.1 KiB

Задача 04 — разбор IPv4-пакета и контрольная сумма (C++)

Это то, что реально делают сетевые железки: взять буфер из сокета и корректно разобрать заголовок, не выйдя за границы и не поверив «на слово» полям пакета.

struct Ipv4Header {
    uint8_t  version;          // должно быть 4
    uint8_t  ihl;              // длина заголовка в 32-битных словах
    uint8_t  protocol;         // 6 = TCP, 17 = UDP, 1 = ICMP
    uint16_t total_length;     // из заголовка (хост-порядок)
    uint32_t src_ip;           // байты как на проводе: 10.0.0.1 -> 0x0A000001
    uint32_t dst_ip;
    uint16_t header_checksum;  // поле из заголовка (хост-порядок)
};

// false: буфер короче 20 байт, version != 4, ihl < 5, ihl*4 > len,
//        total_length < ihl*4 или total_length > len
bool parse_ipv4(const uint8_t* buf, size_t len, Ipv4Header* out);

// сумма в дополнительном коде по len байтам, затем инверсия — значение для записи в поле
// (вызывается на буфере, где поле контрольной суммы уже обнулено)
uint16_t compute_checksum(const uint8_t* buf, size_t len);

// true, если контрольная сумма заголовка верна: сумма в дополнительном коде по ihl*4 байтам
// заголовка (вместе с полем контрольной суммы) равна 0xFFFF; нагрузка не участвует
bool checksum_valid(const uint8_t* buf, size_t len);

Проверка: python3 grade.py 04. Критерий: все ok, ASAN/UBSAN чистые. Запрещено приводить буфер к структуре через reinterpret_cast и читать поля как есть — на невыровненных адресах и в другом порядке байт это UB.