java 接收snmp trap,nodejs实现接收Snmp的Trap消息

var assert = require(‘assert‘);

var ASN1 = {

EOC: 0,

Boolean: 1,

Integer: 2,

BitString: 3,

OctetString: 4,

Null: 5,

OID: 6,

ObjectDescriptor: 7,

External: 8,

Real: 9, // float

Enumeration: 10,

PDV: 11,

Utf8String: 12,

RelativeOID: 13,

Sequence: 16,

Set: 17,

NumericString: 18,

PrintableString: 19,

T61String: 20,

VideotexString: 21,

IA5String: 22,

UTCTime: 23,

GeneralizedTime: 24,

GraphicString: 25,

VisibleString: 26,

GeneralString: 28,

UniversalString: 29,

CharacterString: 30,

BMPString: 31,

Constructor: 32,

Context: 128,

TypeError: function(msg) {

var e = new Error();

e.name = ‘InvalidAsn1Error‘;

e.message = msg || ‘‘;

return e;

}

};

function Reader(data) {

if (!data || !Buffer.isBuffer(data))

throw new TypeError(‘data must be a node Buffer‘);

this._buf = data;

this._size = data.length;

// These hold the "current" state

this._len = 0;

this._offset = 0;

var self = this;

this.__defineGetter__(‘length‘, function() { return self._len; });

this.__defineGetter__(‘offset‘, function() { return self._offset; });

this.__defineGetter__(‘remain‘, function() {

return self._size - self._offset;

});

this.__defineGetter__(‘buffer‘, function() {

return self._buf.slice(self._offset);

});

}

/**

* Reads a single byte and advances offset; you can pass in `true` to make this

* a "peek" operation (i.e., get the byte, but don‘t advance the offset).

*

* @param {Boolean} peek true means don‘t move offset.

* @return {Number} the next byte, null if not enough data.

*/

Reader.prototype.readByte = function(peek) {

if (this._size - this._offset < 1)

return null;

var b = this._buf[this._offset] & 0xff;

if (!peek)

this._offset += 1;

return b;

};

Reader.prototype.peek = function() {

return this.readByte(true);

};

/**

* Reads a (potentially) variable length off the BER buffer. This call is

* not really meant to be called directly, as callers have to manipulate

* the internal buffer afterwards.

*

* As a result of this call, you can call `Reader.length`, until the

* next thing called that does a readLength.

*

* @return {Number} the amount of offset to advance the buffer.

* @throws {InvalidAsn1Error} on bad ASN.1

*/

Reader.prototype.readLength = function(offset) {

if (offset === undefined)

offset = this._offset;

if (offset >= this._size)

return null;

var lenB = this._buf[offset++] & 0xff;

if (lenB === null)

return null;

if ((lenB & 0x80) == 0x80) {

lenB &= 0x7f;

if (lenB == 0)

throw ASN1.TypeError(‘Indefinite length not supported‘);

if (lenB > 4)

throw ASN1.TypeError(‘encoding too long‘);

if (this._size - offset < lenB)

return null;

this._len = 0;

for (var i = 0; i < lenB; i++)

this._len = (this._len << 8) + (this._buf[offset++] & 0xff);

} else {

// Wasn‘t a variable length

this._len = lenB;

}

return offset;

};

/**

* Parses the next sequence in this BER buffer.

*

* To get the length of the sequence, call `Reader.length`.

*

* @return {Number} the sequence‘s tag.

*/

Reader.prototype.readSequence = function(tag) {

var seq = this.peek();

if (seq === null)

return null;

if (tag !== undefined && tag !== seq)

throw ASN1.TypeError(‘Expected 0x‘ + tag.toString(16) + ‘: got 0x‘ + seq.toString(16));

var o = this.readLength(this._offset + 1); // stored in `length`

if (o === null)

return null;

this._offset = o;

return seq;

};

Reader.prototype.readInt = function() {

return this.readTag(ASN1.Integer);

};

Reader.prototype.readBoolean = function() {

return (this.readTag(ASN1.Boolean) === 0 ? false : true);

};

Reader.prototype.readEnumeration = function() {

return this.readTag(ASN1.Enumeration);

};

Reader.prototype.readString = function(tag, retbuf) {

if (!tag)

tag = ASN1.OctetString;

var b = this.peek();

if (b === null)

return null;

if (b !== tag)

throw ASN1.TypeError(‘Expected 0x‘ + tag.toString(16) + ‘: got 0x‘ + b.toString(16));

var o = this.readLength(this._offset + 1); // stored in `length`

if (o === null)

return null;

if (this.length > this._size - o)

return null;

this._offset = o;

if (this.length === 0)

return retbuf ? new Buffer(0) : ‘‘;

var str = this._buf.slice(this._offset, this._offset + this.length);

this._offset += this.length;

return retbuf ? str : str.toString(‘utf8‘);

};

Reader.prototype.readOID = function(tag) {

if (!tag)

tag = ASN1.OID;

var b = this.readString(tag, true);

if (b === null)

return null;

var values = [];

var value = 0;

for (var i = 0; i < b.length; i++) {

var byte = b[i] & 0xff;

value <<= 7;

value += byte & 0x7f;

if ((byte & 0x80) == 0) {

values.push(value);

value = 0;

}

}

value = values.shift();

values.unshift(value % 40);

values.unshift((value / 40) >> 0);

return values.join(‘.‘);

};

Reader.prototype.readTag = function(tag) {

assert.ok(tag !== undefined);

var b = this.peek();

if (b === null)

return null;

if (b !== tag)

throw ASN1.TypeError(‘Expected 0x‘ + tag.toString(16) + ‘: got 0x‘ + b.toString(16));

var o = this.readLength(this._offset + 1); // stored in `length`

if (o === null)

return null;

if (this.length > 4)

throw ASN1.TypeError(‘Integer too long: ‘ + this.length);

if (this.length > this._size - o)

return null;

this._offset = o;

var fb = this._buf[this._offset];

var value = 0;

for (var i = 0; i < this.length; i++) {

value <<= 8;

value |= (this._buf[this._offset++] & 0xff);

}

if ((fb & 0x80) == 0x80 && i !== 4)

value -= (1 << (i * 8));

return value >> 0;

};

var dgram = require("dgram");

function parseTrapPacket(buffer){

var pkt = {};

var reader = new Reader(buffer);

reader.readSequence();

pkt.version = reader.readInt();//02 01 00

pkt.community = reader.readString();//04 06 70 75 62 6c 69 63

pkt.type = reader.readSequence();//a4

pkt.enterprise = reader.readOID()//0x06, 0x0c, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x91, 0x28, 0x02, 0x02, 0x47, 0x64

var bytes = reader.readString(64, true);//0x40, 0x04, 0xc0, 0xa8, 0x17, 0x0a,

pkt.agentAddr = bytes[0] + "." + bytes[1] + "." + bytes[2] + "." + bytes[3];

pkt.specific = reader.readInt();// 0x02, 0x01, 0x06,

pkt.generic = reader.readInt();//0x02, 0x01, 0x0a

pkt.upTime = reader.readTag(67);//

pkt.varbinds = readVarbinds(reader);

return pkt;

};

function readVarbinds (reader) {

var vbs = [];

reader.readSequence ();

while (1) {

reader.readSequence();

var oid = reader.readOID (), type = reader.peek (), value = ‘‘;

if (type == null) break;

switch(type){

case 1:

value = reader.readBoolean();

break;

case 2:

case 65:

case 66:

case 67:

value = reader.readTag(2);

break;

case 4:

value = reader.readString (null);

break;

case 5:

case 128:

case 129:

case 130:

reader.readByte ();

reader.readByte ();

value = null;

break;

case 6:

value = reader.readOID();

break;

case 64:

var bytes = reader.readString(64, true);

value = bytes.length == 4 ? bytes[0] + ‘.‘ + bytes[1] + ‘.‘ + bytes[2] + ‘.‘ + bytes[3] : ‘‘;

break;

case 68:

case 70:

value = reader.readString(type, true);

break;

}

vbs.push ({

oid: oid,

type: type,

value: value

});

}

return vbs;

}

function Receiver(port, onTrap, onError, onStart){

this.port = port;

this.socket = null;

this.isRunning = false;

this.onTrap = onTrap;

this.onError = onError;

this.onStart = onStart;

};

Receiver.prototype.start = function(){

var self = this;

if(self.isRunning) return;

var socket = self.socket = dgram.createSocket(‘udp4‘);

socket.on(‘error‘, function(err){

socket.close();

self.isRunning = false;

if(self.onError){

self.onError(err);

}

});

socket.on(‘message‘, function(msg, remote){

if(self.onTrap){

var pkt = parseTrapPacket(msg);

self.onTrap(remote, pkt);

}

});

socket.on(‘listening‘, function(){

self.isRunning = true;

if(self.onStart){

self.onStart(self.port);

}

});

socket.bind(self.port);

};

Receiver.prototype.stop = function(){

var self = this;

if(self.isRunning){

if(self.socket){

self.socket.close();

self.isRunning = false;

}

}

};

var trap = new Receiver(162, function(remote, pkt){

console.log(JSON.stringify(remote), JSON.stringify(pkt));

}, ‘‘, function(port){

console.log(‘begin listen on ‘ + port);

});

trap.start();

module.exports.TrapReceiver = Receiver;

原文:http://www.cnblogs.com/zh33gl/p/4763197.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值