ASN.1 обеспечивает стандартный способ представления данных и кодирования их для передачи по сети.

Основу модели SNMP составляет множество объектов, которые станции управления могут считывать и записывать при помощи агентов. Чтобы устройства различных производителей могли сообщать и понимать управляющую информацию, объекты должны быть определены стандартным, не зависящим от производителя образом. Кроме того, они должны единообразно кодироваться при передаче по сети. Иными словами, SNMP необходим стандартный язык описания объектов вместе с правилами кодирования. Этот язык — абстрактное описание синтаксиса (Abstract Syntax Notation One, ASN.1) — разработчики SNMP заимствовали из стандартов OSI. ASN.1 представляет собой высокоуровневый язык описания типов данных и определяет формат сообщений SNMP при передаче их между агентами и станциями управления. Как и большая часть OSI, он обширен, сложен и не очень эффективен.

Сам язык описания данных определен в стандарте Международной организации по стандартизации (International Standard Organization, ISO) за номером 8824 под названием "Спецификация абстрактного описания синтаксиса, один", а правила кодирования закреплены в стандарте 8825 под названием "Спецификация базовых правил кодирования для ASN.1". Абстрактный синтаксис ASN.1 позволяет определять базовые объекты и затем объединять их в более сложные. Декларации в ASN.1 с функциональной точки зрения схожи с декларациями из файлов-заголовков для программ на С.

АБСТРАКТНЫЙ СИНТАКСИС

SNMP вводит свои условные обозначения, несколько отличные от ASN.1. Базовые типы данных записывают строчными буквами (например, целочисленный тип данных — как INTEGER). Определяемые пользователем типы данных начинаются со строчной буквы, но при этом они должны содержать по крайней мере один символ, отличный от строчной буквы. Идентификаторы переменных начинаются с прописной буквы, при этом они могут содержать прописные и строчные буквы, цифры и дефисы. Пробелы (знаки табуляции, переноса строки и т. п.) не учитываются. Комментарии начинаются с "- -" (двойного дефиса) и заканчиваются либо вместе с концом строки, либо той же последовательностью символов "- -".

Допустимые в SNMP базовые типы данных ASN.1 приведены в Таблице 1. Переменная типа INTEGER может в теории принимать любое целочисленное значение, но область ее значений ограничивают другие правила SNMP. В качестве примера использования типов мы рассмотрим, как переменная counter типа INTEGER декларируется и (если необходимо) инициализируется значением, равным 0.

counter INTEGER ::= 0

Очень часто переменную требуется ограничить конкретными значениями или конкретным диапазоном. Это можно сделать посредством определения необходимого подтипа следующим образом:

Status ::= INTEGER { on(1), off(2), unknown(3) }

PacketSize ::= INTEGER (0..1023)

Переменные типа BIT STRING и OCTET STRING представляют собой строку из 0 и более бит или байт, соответственно. Для обоих типов пользователь может задать длину строки и начальное значение. Тип OBJECT IDENTIFIER позволяет идентифицировать объекты. Любой объект в любом официальном стандарте может быть идентифицирован уникальным образом. Данная цель достигается за счет введения дерева стандартов, при этом каждый объект соответствующего стандарта получает свое место в дереве. Верхний уровень дерева составляют наиболее важные в мире (с точки зрения ISO) организации, а именно ISO и CCITT (теперь ITU), а также их объединение. Нас интересует прежде всего четвертая ветвь ISO с идентификатором identified-organization(3) (признанные организации по стандартизации), далее dod(6) (Министерство обороны США), а затем internet(1). Ветвь internet содержит четыре ветви. Объекты базы управляющей информации находятся под ветвью mgmt (см. Рисунок 1). Помимо текстового идентификатора (label) каждая ветвь имеет свой числовой идентификатор (number). Объект может записываться с использованием текстовых или числовых идентификаторов в любой их комбинации. Как видно из описанной структуры, все объекты базы управляющей информации имеют общий префикс

iso.identified-organization.

dod.internet.mgmt.mib-2


или

{1 3 6 1 2 1}

или

{internet(1) 2 1}

и т. п. Таким образом, любой объект может быть представлен с помощью идентификатора объекта.

Рисунок 1.

Рисунок 1. Каждый объект может быть идентифицирован уникальным образом.

ASN.1 описывает несколько способов создания новых типов данных. Прежде всего, это использование простых составных типов данных (SNMP задействует только три из них). SEQUENCE — это упорядоченный список типов, подобный структуре в С, SEQUENCE OF — одномерный массив переменных одного типа, а CHOICE — объединение из заданного списка типов.

Другой способ состоит в назначении тэгов имеющимся типам данных. Тэги подразделяются на четыре класса или категории: универсальный (universal), общеприкладной (application-wide), контекстно-зависимый (context-specific) и частный (private). Каждый тэг состоит из метки и целочисленного идентификатора, например:

IpAddress ::= [APPLICATION 0] OCTET STRING (SIZE (4))

определяет общеприкладной тип данных в виде строки байт длиной в 4 октета.

ASN.1 описывает сложный механизм макросов, активно используемый в SNMP. Макрос может служить в качестве своего рода прототипа для создания множества новых типов и значений, каждого со своим собственным синтаксисом. Каждый макрос определяет несколько (возможно, необязательных) ключевых слов, используемых при вызове для идентификации параметров (иными словами, параметры макроса идентифицируются не по местоположению, а по ключевому слову).

БАЗОВЫЕ ПРАВИЛА КОДИРОВАНИЯ

Транспортный синтаксис ASN.1 определяет однозначный способ преобразования значений переменных допустимых типов в последовательность байт для передачи по сети. В ASN.1 он называется базовыми правилами кодирования (Basic Encoding Rules, BER). Правила являются рекурсивными, так что кодирование составных объектов представляет собой составление в цепочку закодированных последовательностей составляющих объектов.

Каждое передаваемое значение — как базового, так и производного типа — состоит из трех полей:

  • идентификатор;
  • длина поля данных (в байтах);
  • поле данных.

В отличие от ASN.1, протокол SNMP требует всегда указывать длину поля данных, поэтому флаг конца поля данных не используется.

Первое поле состоит в действительности из трех полей (см. Рисунок 2). Два старших бита идентифицируют тип тэга (или, в иной терминологии, класса). Значения поля 00, 01, 10 и 11 соответствуют тэгам Universal, Application, Context-specific и Private. Следующий бит определяет принадлежность переменной к базовому или производному типу данных — 0 для базового, 1 — для производного. Оставшиеся 5 бит могут использоваться для кодирования значения тэга (кода), не превышающего 30. Если значение тэга равно 31 или больше, то пять младших бит содержат одни единицы (11111), а реальное значение дается в следующем байте или байтах.

Рисунок 2.

Рисунок 2. Первый байт всякого передаваемого элемента данных в соответствии с синтаксисом ASN.1.

Используемые правила для кодирования значений, больших 30, позволяют справляться с произвольно большими числами. Каждый последующий байт содержит 7 бит данных, а старший бит задается равным 0 во всех байтах, за исключением последнего. Таким образом, значения тэга до 27-1 могут быть переданы с помощью двух байт.

Таблица 1 — Базовые типы переменных, допустимые в SNMP
Тип переменнойОписаниеКод
INTEGERЦелое число произвольной длины2
BIT STRINGСтрока из 0 или более бит3
OCTET STRINGСтрока из 0 или более байт4
NULLДержатель места5
OBJECT IDENTIFIERОфициально определенный тип данных6

Значение третьего поля зависит от значения первого поля. Например, базовые и простые составные типы данных принадлежат к классу Universal. Каждый базовый тип имеет свой код, как указано в третьей колонке в Таблице 1, SEQUENCE и SEQUENCE OF имеют один и тот же код 16, а CHOICE не имеет своего кода, так как реальное значение всегда принадлежит к определенному типу. Именно присвоенный код указывается в третьем поле.

Поле длины данных указывает, сколько байт занимают данные. Если данные короче 128 байт, то их длина может быть выражена при помощи одного байта, при этом значение крайнего левого бита будет равно 0. Если данные оказываются длиннее, то первый байт содержит 1 в старшем бите и длину поля длины данных (до 127 байт) в младших 7 битах. Например, если длина данных равна 1000 байт, то первый байт поля длины данных будет содержать 130, т. е. он сообщает принимающей стороне о том, что за ним следует еще два байта поля длины данных. Последующие два байта содержат действительное значение длины данных — 1000, при этом старший байт идет первым.

Кодирование поля данных зависит от конкретного типа данных. Целые числа кодируются при помощи дополнительного кода. Положительное целое число менее 128 кодируется при помощи одного байта и т. д. Старший значащий байт передается первым.

Строки бит передаются, как есть. Единственная проблема в том, что поле длины данных указывает длину в байтах, а не в битах. Принятое решение состоит во вставке одного байта перед строкой битов с указанием, сколько бит последнего байта не используются. Например, строка "010011111" длиной 9 бит будет иметь вид 07, 4F, 80 (в шестнадцатеричном представлении).

Строка байт передается справа налево — сначала старшие, а потом младшие байты. Нулевое значение указывается посредством задания поля длины данных равным 0. Никакое числовое значение реально не передается.

OBJECT IDENTIFIER кодируется в виде последовательности целых чисел, из которых он состоит. Например, ветвь mib-2 имеет префикс {1 3 6 1 2 1}. Однако, поскольку первое число всегда равно 0, 1 или 2, а второе — меньше 40 (как определено ISO), первые два числа, х и y, кодируются с помощью одного байта в виде 40x+y. Таким образом, для mib-2 первый байт равен 43. Числа более 127 кодируются с помощью нескольких байт, первый бит числа задается равным 1, а количество следующих байт — в оставшихся 7 битах.

Оба типа SEQUENCE передаются следующим образом: сначала тип или тэг, затем общая длина всех последующих полей и, наконец, сами поля по порядку. Кодирование значения переменной типа CHOICE производится в соответствии с реальным передаваемым типом данных.

СТРУКТУРА УПРАВЛЯЮЩЕЙ ИНФОРМАЦИИ

Выше мы кратко рассмотрели только те части ASN.1, что используются в SNMP. В действительности документы по SNMP организованы иным образом. Так, в RFC 1442 вначале говорится, что структуры данных в SNMP будут описываться с помощью ASN.1, а затем на более чем 50 страницах перечисляются неиспользуемые части ASN.1 и вводятся новые определения. В частности, RFC 1442 определяет четыре основных макроса и восемь новых типов данных, активно используемых в SNMP. Это своего рода надподмножество ASN.1 известно под именем структуры управляющей информации (Structure of Management Information, SMI). Оно и применяется на практике для определения структур данных SNMP.

На самом нижнем уровне переменные SNMP определяются как отдельные объекты. Взаимосвязанные объекты объединяются в группы, а группы собираются в модули. Например, объекты IP и объекты TCP имеют каждый свою группу. Маршрутизатор может поддерживать группу IP, так как он должен предоставлять информацию, например, о потерянных пакетах, но не группу TCP, так как он функционирует на более низком уровне. Если какое-то устройство поддерживает определенную группу, то оно должно поддерживать и все объекты из этой группы. Однако поддержка производителем определенного модуля не налагает на него ответственности по поддержке всех групп этого модуля, так как не все они могут иметь отношение к конкретному устройству.

Модули MIB запускаются посредством вызова макроса MODULE-IDENTITY. Его параметры сообщают имя и адрес разработчика, данные о версии и другую информацию. За ним обычно следует вызов макроса OBJECT-TYPE, сообщающего реальные используемые переменные и их свойства.

Таблица 2 — Используемые SNMP типы данных
НазваниеТипДлина в байтахОписание
INTEGERЧисловой4Целое число (32 бит в текущей реализации)
Counter32Числовой4Беззнаковый 32-разрядный счетчик с обнулением
Gauge32Числовой4Беззнаковый 32-разрядный счетчик без обнуления
Integer32Числовой432 бит даже на 64-разрядном ЦПУ
Uinteger32Числовой4То же, что Integer32, но беззнаковый
Counter64Числовой864-разрядный счетчик
TimeTicksЧисловой4Секундомер в сотых долях секунды
BIT STRINGСтроковый4Строка бит длиной от 1 до 32 бит
OCTET STRINGСтроковый>0Строка байт переменной длины
OpaqueСтроковый>0Устаревший, только для обратной совместимости
OBJECT IDENTIFIERСтроковый>0Последовательность целых чисел
IpAddressСтроковый4Internet-адрес
NsapAddressСтроковый<22Адрес OSI NSAP

Макрос OBJECT-TYPE имеет четыре обязательных и четыре необязательных параметра. Первый обязательный параметр — SYNTAX — определяет тип переменной в соответствии с приведенным в Таблице 2 списком. По большей части эти типы говорят сами за себя. Суффикс 32 используется, если переменная должна представлять собой 32-разрядное число, даже если компьютеры имеют 64-разрядные ЦПУ. Счетчики Gauge отличаются от Counter тем, что они не обнуляются при достижении максимального значения. MAX-ACCESS содержит информацию о доступе к переменной. Наиболее типичные значения — "чтение/запись" и "только чтение". Станция может менять значение переменной с признаком "чтение/запись" и читать переменную с признаком "только чтение". STATUS имеет три возможных значения. Переменная со статусом CURRENT соответствует текущей спецификации SNMP, переменная со статусом OBSOLETE не соответствует текущей спецификации, а переменная со статусом DEPRECATED находится в некоем промежуточном состоянии. На самом деле она не нужна в стандарте, но не запрещена, дабы избежать претензий со стороны тех поставщиков, кто продолжает использовать их в своих продуктах. Последний обязательный параметр — DESCRIPTIONDESCRIPTION — содержит описание переменной. Он предназначен для людей, а не для компьютеров.

СЕТЕВОЙ ЭСПЕРАНТО

Несмотря на некоторую громоздкость, абстрактное описание синтаксиса, а точнее, его конкретная форма, используемая в SNMP, позволяет сетевым устройствам различных производителей представлять и сообщать управляющую информацию в стандартном виде. Это открывает перед разработчиками возможность создавать всеобъемлющие платформы управления сетью, так как многие современные сетевые устройства поддерживают относящиеся к ним базы управляющей информации, объекты которых описываются и передаются в соответствии с ASN.1.

Дмитрий Ганьжа — ответственный редактор LAN. С ним можно связаться по адресу: diga@lanmag.ru.