Я изучаю стандартную реализацию ping. Здесь создается структура icmp и данные заполняются. Уровень IP добавляется ядром. Однако, когда мы получаем сообщение с использованием функции http://linux.die.net/man/2/recvfrom, я вижу, что они сначала анализируют IP-пакет и затем анализируют пакет ICMp. Почему это происходит. Код, на который я ссылаюсь, - это стандартная реализация ping, доступная в Интернете.Почему слой IP не удаляется ядром в программе ping
ответ
Это потому, что заголовок всегда включен при получении пакета IPv4 в сыром сокете. Обратите внимание на следующее в raw(7)
(курсив):
Слой IPv4 генерирует заголовок IP при посылке пакета, если опция
IP_HDRINCL
сокета не включена на гнездо. Когда он включен, пакет должен содержать IP-заголовок. Для получения IP-заголовка всегда включается в пакет.
Поскольку заголовок всегда включен и has variable length (для IPv4), оно должно быть разобрано, чтобы выяснить, где начинается данные ICMP.
Что касается , почему заголовок не удаляется (извините, если это было единственное, что вам было интересно), я не знаю. Моя дикая догадка заключается в том, что достаточно программ, которые работают с необработанным IPv4, хотят посмотреть на заголовок, который, похоже, не стоит включать в себя удаление его в качестве опции. Из быстрого взгляда кажется, что заголовок - лишен IPv6.
Стандарт ping
и ping6
приходят из iputils по пути, где ping_common.c, ping.c и ping6.c являются наиболее релевантными исходными файлами.
Большое спасибо. Это то, что я искал. Я также замечаю, что они правильно сдвигают длину ip-пакета на 2. Почему это? –
@GatsbyGreat: На какую реализацию ping вы смотрите? Правое смещение на 2 разделило бы на 4, но я не уверен, почему они это сделают. – Ulfalizer
http://www.opensource.apple.com/source/network_cmds/network_cmds-307.0.1/ping.tproj/ping.c. Я имел в виду сдвиг влево, хотя –