윈도 SNMP 서비스(SNMP Service)에는 트랩(SNMP Trap) 메시지를 외부로 전달할 수 있는 기능이 있다. 트랩 메시지를 포함한 SNMP 메시지는 UDP 기반의 메시지이므로 네트워크 레벨에서 전송이 보장되지 않는다는 단점이 있지만, 뭐 어쨌든 그런 기능은 있다.


 

물론 이 기능은 SNMP 서비스가 SNMP 메시지를 받을 때 자기 자신이 처리하고 난 후 정해진 규칙에 따라 메시지들을 가공한 뒤 다른 곳으로 전달도 해주는 방식이다. 여기서 메시지를 가공하는 규칙은 확장 에이전트를 통해 만들 수 있다.

 

 

그런데, 이런 시나리오는 현재 내가 지원하고 있는 K사의 어떤 프로젝트에서 진행하고 있는 시나리오와는 맞지 않았다.

 

1. 윈도 SNMP 서비스와 확장 에이전트를 분석하다 보니, 이것들은 외부로부터 SNMP 메시지를 받아 자체적으로 처리하는데 중점을 두어 설계가 되어 있는 것 같다. 즉, SNMP 매니저(서버) 기능에 최적화된 시스템이란 얘기다.

 

2. 즉, 윈도 SNMP 서비스는 주기적으로 상태를 보관했다가 요청 시 최종 보관된 상태 값만 전달하는, 말 그대로 시스템 상태 모니터링의 용도에 최적화되어 있는 것으로 보이며, 확장 에이전트를 통해 외부로 SNMP 트랩 메시지를 전달할 수 있게 구조(API)는 만들어져 있지만, 일단 받아놓은 메시지를 가지고 특정 이벤트 발생에 의해 외부로 전달하는 방식이기 때문에 메시지를 처리하는 과정도 복잡할 뿐만 아니라 짧은 시간에 대용량 처리에 활용하기에는 적합하지 않다.


3. K사의 해당 프로젝트에서 요구되고 있는 기능은, SNMP 매니저(서버)로서의 기능이 아니라, SNMP 에이전트(클라이언트) 역할, 즉, 단순한 소켓 클라이언트 정도의 수준으로서, 빠르게 특정 메시지를 외부 서버로 전달하는 역할이라 볼 수 있다. 즉, 대용량의 데이터를 빠른 시간 안에 처리할 수 있는 고성능이 요구되는 것이다.


4. 윈도에서 기본 제공하는 서비스 중 해당 요구사항을 충족할 수 있는 서비스로는, 내가 알기론, MSMQ 서비스가 유일하다. 그러나 이런 상황을 모르는 상태에서 어떤 이유에 의해 SNMP 트랩 메시지를 전달해주기로 "결정"된 사항이라면, 절대 고성능을 기대할 수 없는 위 SNMP 서비스 시나리오를 이용하는 대신, SNMP/TRAP에 대한 RFC 및 프로토콜을 분석하여 UDP 소켓 프로그래밍으로 직접 원하는 데이터를 만들어 전송하는 방법 밖에 없을 것 같다.

 

이상의 결론을 도출함에 따라  윈도용 SNMP 트랩 전송과 관련된 공개 라이브러리를 인터넷에서 찾아봤더니 거의 없었다. 그나마 있는 공개 소스 및 라이브러리들도 SNMP 트랩 메시지를 받아서 처리하는 부분에 관한 것들 뿐이고, 트랩 메시지를 외부로 전송하는 내용을 담고 있는 것들은 전혀 눈에 띄지 않았다.


그러다 문득, Code Project에 올라온 어떤 게시물에 달린 코멘트들을 읽다보니, 우연히 누군가가 스스로 이런 문제의식을 가지고 관련 라이브러리를 만들어 공개해놓았다는 내용이 보였다. 즉시 링크를 검색하여 찾아봤더니 이곳이었다!

 

http://www.codeplex.com/sharpsnmplib

 

여기서 제공하는 라이브러리에는 유일하게 SNMP 트랩 메시지를 전송하는 기능이 포함되어 있었는데, 문제는, 사용할 수 있는 예제도 없고, Mono용 C#(3.0 - VS2008)으로 만들어진 데다, 몇 가지 버그도 있어서 그대로 사용하기엔 어려운 점이 많았다. 소스를 받아 .NET 2.0(내가 사용하는 환경: VS 2005)에서 사용할 수 있도록 수정하고, 쉽게 전송하는 용도로 사용할 수 있게 캡슐화까지 했는데, 테스트를 진행하는 와중에 원본 코드에 몇 가지 버그가 있다는 것을 알게 된 것이다. (테스트에 사용된 MIB Browser가 2종류였는데, 그 중 하나에는 트랩 메시지가 아예 나타나지 않는 것이 아닌가!)

 

그래서 그 원인을 밝히기 위해 RFC 문서도 뒤져보고, 네트워크 모니터로 패킷을 캡쳐하여 윈도 SNMP 서비스에서 전송하는 트랩 메시지와 이 라이브러리로 전송한 메시지를 일일이 비교/분석해가면서 결국 버그(멀티바이트 처리 부분)를 수정한 뒤 SNMPTrapSender.dll 이라는 클래스 라이브러리로 만들었다.


그런데 아뿔싸! K사의 해당 프로젝트에서는 .NET 2.0을 사용하지 않는 관계로 다시 이를 .NET 1.1에서 사용할 수 있도록 수정하고, 트랩 메시지 전송 이외의 불필요한 부분을 모두 제거해서 SNMPTrapSender_v1.dll 이라는 클래스 라이브러리로 만들었다. (전체 기능을 다 살리기에는 시간도 모자랐고, 수정해야 할 부분이 어마어마하게 많아서 당장 사용하지 않는 불필요한 기능들은 삭제)

 

이렇게 해서, 윈도(.NET) 환경에서도 SNMP 트랩 메시지를 쉽고 빠르게 보낼 수 있게 되었다.

(그러나... 서버간 데이터 통신에 SNMP 트랩 메시지를 사용하는 것은 여전히 위험하고 미련한 짓일 뿐이라는 내 생각에는 변함이 없다!)

 

첨부한 라이브러리의 사용방법은 다음과 같다.

using Lextm.SharpSnmpLib; // 공개 라이브러리 네임스페이스 참조 (원작자를 존중해서 그냥 놔뒀다)

using SNMPTrapSender; // 내가 만든 라이브러리 네임스페이스 참조 (.NET 1.1용은 "SNMPTrapSenderv1"이다.)

 

...

 

private const string MANAGER_IP = "127.0.0.1"; // 보낼 대상 SNMP 매니저(서버)
private const string COMMUNITY = "public";

 

...

 

// 테스트: SNMPv2c 버전 메시지로 설정한다. (SNMPv1으로 보낼 때는 VersionCode.V1을 쓰면 된다.)
TrapSender sender = new TrapSender(VersionCode.V2);

 

// 트랩 메시지로 전송할 변수 목록
List<Variable> varBind = new List<Variable>(); // .NET 1.1에서는 ArrayList로 쓰면 된다. 

 

// Octet String 형식
string s = "TEST_DATA";

OctetString data = new OctetString(s);

 

// 변수 OID
uint[] snmpOID = { 1, 3, 6, 1, 4, 1, 14008, 99999, 100, 1 };
ObjectIdentifier oid = new ObjectIdentifier(snmpOID);

varBind.Add(new Variable(oid, data));

 

// 트랩 OID
uint[] trapOID = { 1, 3, 6, 1, 4, 1, 14008, 99999, 200, 1 };

 

// 트랩 메시지 전송
sender.Send(MANAGER_IP, COMMUNITY, trapOID, varBind);

 

첨부(압축)파일 구성:

- SNMPTrapSender.dll: .NET Framework v2.0용 라이브러리

- Program.cs: .NET Framework v2.0용 샘플

- SNMPTrapSender_v1.dll: .NET Framework v1.1용 라이브러리

- Program_v1.cs: .NET Framework v1.1용 샘플

 

이 글에 첨부로 올려두었습니다. 아래 "첨부파일" 링크를 클릭하시고 다운로드 받으세요.


SNMPTrapSender_v2.zip

 


'Tech: > .NET·C#' 카테고리의 다른 글

VS2005에서 .NET 1.1로 빌드하기  (0) 2009.04.14
주의: 값 형식과 참조 형식  (0) 2008.10.25
윈도 서비스 확장 클래스: ServiceInstallerEx  (0) 2008.08.14
SNMP에 사용자 정의 값 쓰기  (0) 2008.08.14
MessageBoxEx  (0) 2008.08.07


Posted by 떼르미
,


자바스크립트를 허용해주세요!
Please Enable JavaScript![ Enable JavaScript ]