기본적인 Socket 프로그래밍(UDP)을 할 줄 안다면 데이터를 전송하고 수신만 하면 간단하다.
문제는 메시지를 만드는 것과 수신한 데이터를 해석해내는 것이 관건이다.
SNMP 통신
- SNMP Message를 구성한다
- SNMP Agent에 UDP 161 포트에 접속해서 1번에서 만든 Message를 전송한다(데이터 송신-Snmp Request)
- 전송한 데이터에 대한 응답을 받는다(데이터 수신-Snmp Response)
- 데이터를 해석해서 사용한다
SNMP Message 포맷은 아래의 사이트를 참고하세요
http://www.tcpipguide.com/free/t_SNMPVersion1SNMPv1MessageFormat.htm
SNMP 메시지 샘플
Windows Server 2003에 SNMP 서비스를 올리고(SNMP Agent로 이용) SNMP Get 메시지를 보내서 SNMP Response 메시지를 받아보았다.
(참고로, 패킷 캡쳐는 WireShark를 이용하였다)
위의 두 그림에서 처음 빨갛게 표시된 0x03이 바로 UDP SNMP 메시지라고 알리는 매직넘버이다. (사실은 SNMP 시퀀스를 나타내는 값이다.)
매직넘버 이후에는 전체 메시지 길이 버전 정보(타입/길이/값), 커뮤니티 정보(타입/길이/값), PDU 데이터(타입, PDU상태[ID, status, index], Variation binding list)
로 데이터가 이루어진다.
주의 - OID의 시작(1.3 = iso.3)
패킷에서 보이다시피 1.3.6.1.2.1.1.1.0이 2B 06 01 02 01 01 01 00 (16진수)으로 나옴을 알 수 있다.
01 03 06 01 02 01 01 01 00 이 아니다. 1.3대신에 0x2B가 쓰였음을 알 수 있다.
여분의 바이트를 줄이기 위해 거의 고정인 이 값을 하나의 바이트로 줄여놓았다.
계산법은 1x40 + 3 = 43 = 0x2b 이다.
문제가 되는 것이, 0.40 = 1.0 = 40으로 둘다 0x28이란 값을 가지게 된다. 따라서 범위 이내가 되야 할 것이다.
참고: http://www.rane.com/note161.html
아래와 같은 사전 정의된 prefix가 있다.
0.0 : ccitt
1.3 : iso.org
2. : joint-iso-ccitt
주의 - BER의 길이
SNMP 메시지는 가변데이터이기 때문에 데이터가 나오기 전에는 데이터의 길이가 나온다.
처음에 데이터의 길이가 1바이트로 고정이 되었는지 알고 있었다. 그래서 SNMP Message의 길이는 최대 255-2(0x30, 길이) 만큼만 가질 수 있는 줄 알았는데,
응답 패킷을 보면 알 수 있지만 0x81과 같은 무엇인가 추가적인 숫자가 와서 길이에 대한 가변값을 알려줄 수 있게 되어 있었다.
위의 Windows Server에서 받은 응답과는 달리 아래의 Lexmark 프린터에서 받은 값은 길이를 나타내는 값을 무조건 1byte로 보고 있다.
Windows Server : 0x30, 0x81, 0xa8 ... 0x30, 0x81, 0x8b, 0x30, 0x81, 0x88
Lexmark Printer : 0x30, 0x61 ... 0x30, 0x46, 0x30, 0x44
메시지 길이에 대한 내용은 BER(Basic Encoding Rules)과 관련한 ASN.1에 기술되어 있다.
위키백과 - Basic Encoding Rules
A Layman's Guide to a Subset of ASN.1, BER, and DER
vijaymukhi.com - Basic Encoding Rules
integer etc. the byte following the structure tag, or the 'keyword' integer is used to indicate the length of the corresponding data type. Does this mean that the maximum length that can be indicated in BER related 'languages' is 255 bytes long. Wrong!, BER is far too advanced to be held back by such a drawback. In a situation where the length of the datatype exceeds one byte, the byte succeeding the data-type declaration has'1' in the 8th field followed by the length of the succeeding bytes which are used to represent the datatype. For example to indicate a length of an structure which is '0xabcd' bytes (43981) large we will use the following representation
짧은 형태와 긴 형태가 있는 것이었다.
짧은 형태 : 1옥텟(1바이트), 최상위 비트(MSB, 제일 왼쪽 비트)는 0이고 그외의 값은 길이를 나타냄
00000000 ~ 01111111 (0~127까지 표현이 가능)
긴 형태 : 2~127 옥텟, 최상위 비트가 1이고 나머지 값은 길이를 나타내는 길이를 나타냄. Second and following octets give the length, base 256, most significant digit first.
10000000 ~ 11111111 (0~127개의 길이를 나타내는 옥텟의 길이를 나타냄
예) 짧은 형태 00000002는 긴 형태 100000001 00000002 로 쓸 수 있다.
BER 포맷은 TLV 인코딩이라고 불리는데 type( 또는 tag)-length-value의 줄임말이다. 아래와 같은 형태로 인코딩 된다
1 | 2..2+n | 2+n..2+n+length |
---|---|---|
참고
C#으로 구현한 simple snmp : http://www.java2s.com/Code/CSharp/Network/SimpleSNMP.htm
wiki백과 - Basic Encoding Rules : http://en.wikipedia.org/wiki/Basic_Encoding_Rules
=> A Layman's Guide to a Subset of ASN.1, BER, and DER : http://luca.ntop.org/Teaching/Appunti/asn1.html
Product Review: SNMP Libraries for .NET Evaluation Report : http://www.lextm.com/2007/12/product-review-snmp-libraries-for-net.html
- C : Net-SNMP(BSD like) : http://net-snmp.sourceforge.net/
- Java : SNMP4j (Apache 2.0)
- C++ : SNMP++ (BSD like)
.NET
- SNMP++.NET : http://maom_onet.republika.pl/snmp/snmp_ppnet/
- PowerSNMP for .NET : http://www.dart.com/snmp-net-api-library.aspx
'Programing' 카테고리의 다른 글
SNMP - 래퍼 Rogério Paulo (0) | 2012.09.21 |
---|---|
SNMP 래퍼 클래스 (0) | 2012.09.21 |
MAC주소와 서브넷마스크 구하기 (0) | 2012.09.21 |
활성화된 네트워크 열거하기 (0) | 2012.09.21 |
구글 크롬 소스코드 빌드하기 (0) | 2012.09.21 |