Introdução
Este é o nosso último post teórico e vamos aprender nele como escrever a nossa MIB de exemplo na notação ASN.1. Antes de mais nada, já aviso que não sairão letrados nesta notação, apenas aprenderemos o necessário para o exemplo. Afinal, é uma série para iniciantes, não ? Aumente seu nível de concentração pois teremos um post bem mais extenso aqui. Mãos à obra ! (Links para os posts anteriores: I, II, III, e IV)
Descrevendo a hierarquia
A primeira coisa a saber é como derivar um nodo do outro na notação ASN.1, isto é, como estabelecer as relações de hierarquia entre os objetos (OIDs) na árvore. Para indicar isto, veja a seguinte notação:
nodoFilho ::= { nodoPai numeroDoNodoFilho }
Uma observação: o correto é se referir ao “nodo” como OID ou objeto, mas vou usar nodo enquanto considerar que ele represente com mais clareza o conceito e ir mudando para OID no decorrer do texto. Perdoem a falta de rigor técnico em favorecimento da aprendizagem.
Voltando ao nosso caso, para indicar a relação de hierarquia entre o nodo “acme”, cujo suposto número privado foi 54321, e a sua origem, “enterprises”, fazemos a seguinte declaração:
acme ::= { enterprises 54321 }
Se você esqueceu, a representação gráfica da MIB está a seguir:
Observando a hierarquia, é possível notar que temos o nodo “exemplo” logo a seguir, com número zero. Ou seja:
exemplo ::= { acme 0 }
Da mesma forma, os nodos “leds” e “sistema”, derivados de “exemplo”, são representados como abaixo, em plena conformidade com o nosso diagrama de MIB:
leds ::= { exemplo 0 }
sistema ::= { exemplo 1 }
Finalmente, temos derivações de “leds” e “sistema”, onde realmente se encontram os objetos que queremos ter acesso:
capsLock ::= { leds 0 }
numLock ::= { leds 1 }
scrollLock ::= { leds 2 }
runTime ::= { sistema 0 }
Colocando tudo junto, ficamos com a lista abaixo (compare este resultado com a figura que represente a MIB, caso tenha dúvida):
acme ::= { enterprises 54321 }
exemplo ::= { acme 0 }
leds ::= { exemplo 0 }
sistema ::= { exemplo 1 }
capsLock ::= { leds 0 }
numLock ::= { leds 1 }
scrollLock ::= { leds 2 }
runTime ::= { sistema 0 }
Fácil, nhein ? Mas não é só isso. Precisamos ainda detalhar cada entrada dessas. Algumas delas são apenas relações de hierarquia que precisam ser declaradas, outras são objetos que serão realmente lidos e precisam ter definidos os seus tipos de dados, direitos de acesso, descrição, etc. Também é preciso prover uma informação geral sobre a MIB, como data de criação, versão, entre outras coisas.
Detalhando a descrição do objeto
De uma forma geral, as declarações anteriores serão modificadas para apresentar este detalhamento, ou melhor, esta caracterização do objeto, segundo este novo modelo:
nodoFilho MACRO-DE-CARACTERIZACAO-DO-OBJETO
DETALHE-1 valor-1
DETALHE-2 valor-2
...
DETALHE-n valor-n
::= { nodoPai numeroDoNodoFilho }
Por exemplo, os objetos capsLock, numLock, scrollLock e runTime são os elementos que serão realmente acessados pelo gerente SNMP. Na realidade, eles devem ser declarados com a ajuda de uma macro chamada “OBJECT-TYPE” (ver RFC 1212), que irá permitir definir o tipo de dado, direitos de acesso, etc. Esta macro irá ser inserida entre o nome do objeto e sua declaração de herança. Vamos ver como ficaria a declaração completa do runTime para se ter uma ideia:
runTime OBJECT-TYPE
SYNTAX Counter32
ACCESS read-only
STATUS mandatory
DESCRIPTION "Current running time in seconds"
::= { sistema 3 }
Note que foi definido o tipo de dado (Counter32), os direitos de acesso (read-only), a sua obrigatoriedade de implementação e a descrição do objeto. Recomendo fortemente que você leia as RFCs citadas ao final deste post ou quando for precisar de criar a sua própria MIB.
Vamos ver outro exemplo, no caso para o led capsLock:
capsLock OBJECT-TYPE
SYNTAX INTEGER { aceso(1), apagado(2) }
ACCESS read-only
STATUS mandatory
DESCRIPTION
"
Caps Lock Led Status:
1: Aceso
2: Apagado
"
::= { leds 0 }
O tipo de dado usado agora foi INTEGER, sendo também fornecida a faixa válida de valores, 1 e 2, com seus respectivos rótulos, “aceso” e “apagado”. Isto lembra muito uma enumeração em linguagem C, com uma notação um pouco diferente, no caso “rótulo(id)”. Caso queira declarar apenas uma faixa de valores, sem rótulos, você pode usar algo como “INTEGER(0..65536)”, indicando uma faixa de 0 a 65536. Também é possível usar o tipo “Integer32″ e não ter que especificar faixas (RFC 2578). Notou como é simples colocar strings longas, de múltiplas linhas ?
numLock segue o mesmo padrão de capsLock, por ser somente leitura:
numLock OBJECT-TYPE
SYNTAX INTEGER { aceso(1), apagado(2) }
ACCESS read-only
STATUS mandatory
DESCRIPTION
"
Num Lock Led Status:
1: Aceso
2: Apagado
"
::= { leds 1 }
Apenas scrollLock se altera, já que permite a escrita no objeto. Não é preciso ter midi-chlorians no sangue para chutar como ficaria:
scrollLock OBJECT-TYPE
SYNTAX INTEGER { aceso(1), apagado(2) }
ACCESS read-write
STATUS mandatory
DESCRIPTION
"
Scroll Lock Led Status:
1: Aceso
2: Apagado
"
::= { leds 2 }
Isto completa a descrição dos objetos que serão acessados mas faltam ainda três coisas:
- A descrição da MIB exemplo que estamos criando (autor, data, revisão, etc)
- Detalhamento de nodos que são puramente para descrição da hierarquia (“leds” e “sistema”)
- Seções de importação de macros, algo parecido com o que temos nos “#includes” em um programa em C.
Detalhando o módulo
Para a descrição da MIB, a referência é a RFC 2578, que apresenta todos os detalhes. A grosso modo, a nossa definição poderia ser feita com a ajuda da macro “MODULE-IDENTITY”:
exemplo MODULE-IDENTITY
LAST-UPDATED "201203010000Z"
ORGANIZATION "ACME S/A"
CONTACT-INFO
"
Marcelo Barros de Almeida
Sertaozinho/SP
Brazil -http://jedizone.wordpress.com
"
DESCRIPTION
"exemplo MIB, initial revision"
::= { acme 0 }
Relativamente simples, não ? Caso a MIB mude, você pode ir adicionando a descrição das revisões com os campos “REVISION” e “DESCRIPTION”. Perceba também que a data segue o formato “YYYYMMDDHHMMZ”. O “Z” significa GMT e precisa estar no final. Os outros campos são auto-explicativos.
Detalhando a hierarquia
Objetos úteis apenas para montagem da hierarquia, como “leds” e “sistema”, são definidos com a ajuda de “OBJECT IDENTIFIER”, sem muitos rodeios:
acme OBJECT IDENTIFIER ::= { enterprises 54321 }
leds OBJECT IDENTIFIER ::= { exemplo 0 }
sistema OBJECT IDENTIFIER ::= { exemplo 1 }
Detalhando a definição da MIB
Quase pronto. O toque final é “envelopar” tudo que fizemos, indicando os includes necessários, como pode ser visto abaixo. São as inclusões que trazem a definição de cada macro utilizada e também passam a prover determinados tipos de dados. Aproveite para aprender que linhas começando com “–” significam comentários e são excelentes para melhorar ainda mais a documentação da MIB:
EXEMPLO-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY,
OBJECT-TYPE,
Counter32 FROM SNMPv2-SMI,
enterprises FROM SNMPv2-SMI;
--
-- Nossa declaração de MIB vai aqui dentro !
--
END
Fica um lembrete de que a convenção é usar nomes de OIDs que comecem em letras minúsculas e que o nome da MIB deve ser escrito em letras maiúsculas. Também não é válido usar “_” na definição do nome, daí a definição “EXEMPLO-MIB”.
Finalmente, basta colocar tudo junto e teremos o arquivo de MIB que pode ser visto ao final do post. Salve-o com o nome EXEMPLO-MIB. Neste ponto, uma vez que você já deve ter entendido a lógica da MIB, não é difícil começar a planejar a sua MIB. De novo, não deixe de ler as RFCs pertinentes para aprender a usar outros tipos de dados e aprofundar-se nos detalhes (a lista de leituras está logo ao final).
Por hoje é só. No próximo post vamos dar uma pausa na teoria e fazer a instalação do Net-SNMP. Vamos precisar também do código fonte para adicionar a nossa MIB no agente. Até lá !
Referências
- RFC4181: Guidelines for Authors and Reviewers of MIB Documents
- RFC2578: Structure of Management Information Version 2 (SMIv2)
- RFC1212: Concise MIB Definitions
- Dicas do que fazer e não fazer
Arquivo EXEMPLO-MIB
EXEMPLO-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY,
OBJECT-TYPE,
Counter32 FROM SNMPv2-SMI,
enterprises FROM SNMPv2-SMI;
--
-- Descrição da MIB exemplo
--
exemplo MODULE-IDENTITY
LAST-UPDATED "201203010000Z"
ORGANIZATION "ACME S/A"
CONTACT-INFO
"
Marcelo Barros de Almeida
Sertaozinho/SP
Brazil - http://jedizone.wordpress.com
"
DESCRIPTION
"exemplo MIB, initial revision."
::= { acme 0 }
--
-- Hierarquia auxiliar
--
acme OBJECT IDENTIFIER ::= { enterprises 54321 }
leds OBJECT IDENTIFIER ::= { exemplo 0 }
sistema OBJECT IDENTIFIER ::= { exemplo 1 }
--
-- Objetos exportados
--
capsLock OBJECT-TYPE
SYNTAX INTEGER { aceso(1), apagado(2) }
ACCESS read-only
STATUS mandatory
DESCRIPTION
"
Caps Lock Led Status:
1: Aceso
2: Apagado
"
::= { leds 0 }
numLock OBJECT-TYPE
SYNTAX INTEGER { aceso(1), apagado(2) }
ACCESS read-only
STATUS mandatory
DESCRIPTION
"
Num Lock Led Status:
1: Aceso
2: Apagado
"
::= { leds 1 }
scrollLock OBJECT-TYPE
SYNTAX INTEGER { aceso(1), apagado(2) }
ACCESS read-write
STATUS mandatory
DESCRIPTION
"
Scroll Lock Led Status:
1: Aceso
2: Apagado
"
::= { leds 2 }
runTime OBJECT-TYPE
SYNTAX Counter32
ACCESS read-only
STATUS mandatory
DESCRIPTION "Current running ime in seconds"
::= { sistema 3 }
END
