2017-02-16 23 views
2

Я пытаюсь разобрать пакет IPv6, полученный через raw socket, и решить, является ли оно ICMPv6 или нет. Я могу обработать Ethernet и Заголовок IPv6, но тогда есть дополнительные заголовки расширений. Если поле Next HeaderIPv6 заголовок не ICMPv6, я должен проходить через любые расширения, которые могут предшествовать.Как различать заголовок верхнего уровня и верхнего уровня

Итерация сама по себе не является проблемой, так как каждый заголовок расширения несет свою длину. Однако я не могу найти хороший способ разграничения между заголовком расширения, который может следовать, и другими протоколами верхнего уровня, такими как TCP и UDP. Я могу либо проверить, является ли Next Header одним из известных расширительных заголовков (в этом случае я могу итератировать), или если Next Header является протоколом верхнего уровня (в этом случае мне нужно остановиться, не будет ICMP ..).

В обоих подходах я полагаюсь на некоторый самосозданный список констант, против которого я проверяю Next Header, и этот список может измениться в будущем. Разве нет лучшего способа сказать, когда я нахожусь в конце заголовков расширений, и заголовок верхнего уровня (или ничего) следует?

+1

К сожалению, нет способа определить, что означает неизвестное значение следующего заголовка.Вы должны будете полагаться на таблицы в своем коде. –

ответ

3

Каждый заголовок расширения имеет свое собственное поле Next Header в качестве своего первого октета с тем же значением, что и (иное относительное местоположение) соответствующего поля фиксированного заголовка IPv6. Вы можете использовать их вместе с полями длины заголовков расширений для перехода через заголовки расширений, пока не найдете заголовок транспортного уровня. Wikipedia covers this в деталях.


Update:

Что касается вашего пересмотренного вопроса, нет, нет стандартной функции или алгоритма для различения кодов заголовка обозначения заголовков расширения и, обозначающие заголовки протокола, за исключением того, чтобы просто знать, какое есть. Они назначаются из одного и того же кодового пространства без специальной внутренней структуры.

Однако существует только 256 возможных значений, поэтому знание того, что возможно, возможно. Однако будьте осторожны: почти половина доступных кодов в настоящее время не назначена, но в будущем может быть назначена либо типам заголовков расширений, либо типам протоколов. До тех пор, пока коды не будут исчерпаны, ваше программное обеспечение будет необходимо признать три категории:

  • расширение заголовка, заголовок протокола
  • и
  • неизвестно.

Кроме того, что касается реализации такого теста, я бы рекомендовал создать и использовать таблицу поиска вместо создания сложного условного выражения. Что-то в этих строках:

enum header_type { HDR_PROTOCOL, HDR_EXTENSION, HDR_UNKNOWN }; 

const enum header_type header_types[256] = { 
    [0x00] = HDR_EXTENSION, // IPv6 hop-by-hop option 
    [0x01] = HDR_PROTOCOL, // ICMP 
    // ... both extension and protocol headers in this range ... 
    [0x8e] = HDR_PROTOCOL, // robust header compression 
    [0x8f] = HDR_UNKNOWN, // unassigned 
    // ... more unassigned ... 
    [0xfd] = HDR_UNKNOWN, // for experimentation 
    [0xfe] = HDR_UNKNOWN, // for experimentation 
    [0xff] = HDR_UNKNOWN, // reserved 
}; 

Вы можете использовать это, чтобы ответить на несколько вопросов и очень эффективно.Явные указатели в инициализаторе не являются строго необходимыми, но я думаю, что это хорошая идея: они помогут вам проверить и поддерживать таблицу.

+1

Кроме того, IANA ведет список возможных значений IPv4 Protocol/IPv6 Next Header (всего 256 возможных значений) в [Assigned Internet Protocol Numbers] (https://www.iana.org/assignments/protocol-numbers/protocol- numbers.xhtml). –

+0

Теперь я вижу, что я не говорил, что я уже смотрю на поле заголовка заголовка расширителя. Проблема все еще в том, что я искал какой-то стандартный способ узнать, будет ли следующий заголовок также распространяться или нет. Как отметил @RonMaupin, таких значений не так много, поэтому я написал функцию, подобную этой http://pastebin.com/SXeshCmA, но я надеялся на лучший подход. – Raven

+0

@Raven, я обновил этот ответ с информацией и рекомендациями, относящимися к вашему пересмотренному вопросу. –

2

На самом деле нечего делать, кроме прогулки по цепочке, и похоже, что это то, что вы делаете. Как вы просите в своем комментарии, «стандартный способ узнать, будет ли следующий заголовок также расширять или нет», если это одно из значений, что означает, что это заголовок расширения IPv6. Первоначально, за исключением заголовка расширения Hop-by-hop (который игнорирует большинство сетевых администраторов, потому что это низкая практика, позволяющая конечным устройствам определять маршрутизацию), все промежуточные узлы (маршрутизаторы и т. Д.) Должны были ignore extension headers:

за одним исключением, расширенные заголовки не рассматриваются или обработаны любой узел вдоль пути доставки пакета, пока пакет не достигнет узла (или каждый из множества узлов, в случае многоадресной передачи) указанном в поле Адрес адресата заголовка IPv6. Там, нормальное демультиплексирование в поле Next Header заголовка IPv6 вызывает модуль для обработки первого заголовка расширения или заголовок верхнего уровня , если нет заголовка расширения. Содержимое и семантика каждого заголовка расширения определяют, следует ли перейти к следующему заголовку. Поэтому заголовки расширений должны быть обработаны строго в порядке их появления в пакете; приемник не должен, например, сканировать через пакет, который ищет конкретный вид заголовка расширения и обрабатывать этот заголовок до обработки всех предыдущих.

за исключением указанных в предыдущем абзаце, является Hop в каждом конкретном Hop Опции заголовка, который несет в себе информацию, которая должна быть рассмотрен и обрабатывается каждым узлом на пути доставки пакета, в том числе узлов источника и назначения. Заголовок Hop-by-Hop Options, когда присутствует , должен немедленно следовать заголовку IPv6. Его присутствие - , обозначенное нулевым значением в поле Next Header заголовка IPv6 .

Если в результате обработки заголовка, узел требуется, чтобы продолжить к следующему заголовку но значению Next Header в текущем заголовке является непризнанным узлом, он должен отбросить этот пакет и отправить ICMP Параметр Сообщение об ошибке для источника пакета с Значение ICMP-кода 1 («непризнанный следующий тип заголовка») и поле указателя ICMP, содержащее смещение нераспознанного значения в исходном пакете. То же самое действие следует предпринять, если узел встречает значение следующего заголовка нуля в любом заголовке, отличном от заголовка IPv6 .

К сожалению, реальность установлена, и это уже не так. Теперь даже возможно, что промежуточные узлы будут добавлять заголовки расширений, а цепочка заголовков может оказаться фрагментированной.

RFC 6564, A Uniform Format for IPv6 Extension Headers пытается принести некоторый заказ заголовкам расширения IPv6, но, к сожалению, он ничего не может сделать о ранее определенных заголовках расширения IPv6.

RFC 7045, Transmission and Processing of IPv6 Extension Headers обсуждает проблемы с заголовками расширения IPv6.

Смежные вопросы