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;

  

nodejs实现接收Snmp的Trap消息的更多相关文章

  1. 关于Snmp的Trap代码开发之坑

    最近是被这个snmp的trap给坑了,其实回想起来主要是对这个不了解.特别是对snmp协议研究不够深入, 真的不想看这些协议东西,只想大概知道.结果在开发snmp trap时候被坑了,下面列下自己踩到 ...

  2. Unity3D与iOS消息交互方法(1)--iOS接收Unity3D发出的消息

    跨平台这种事情不管多NB, 总要有些与原生系统交互的方法, 比如  Unity3D与iOS消息交互方法. 一: 建立一个空的Unity工程. File -->  New Project 二: 编 ...

  3. WIN7/8系统下程序接收不到WM_COPYDATA 消息的原因和解决

    在WIN7/win8,如果发送消息的程序用户权限低于和接收消息的程序,则消 息无法传递.发送程序必须等于或者等于接收程序的权限.如发送与接收 是同一个用户,或者发送是管理员帐户,接收是是普通用户,这样 ...

  4. C/C++控制台接收不到鼠标消息-【解决办法】

    控制台编程中,使用了鼠标操作,遇到了控制台无法接收到鼠标消息的问题,可尝试一下办法解决 [win10系统] 在控制台标题栏右键-默认值-选项,将一下对勾取消 然后调用如下函数: HANDLE hIn ...

  5. nodejs之socket.io 私发消息和选择群组发消息

    写在前面:其实有的时候忙碌是好的,比如忙碌起来的自己手机可以一天耗费掉只有20%的电,忙碌的自己很专心于一件事情,但是忙碌不等于过度疲劳,本周忙碌有点上脑,迷糊了一天,都在补觉,还是要去平衡下自己一天 ...

  6. 【招聘App】—— React/Nodejs/MongoDB全栈项目:消息列表

    前言:最近在学习Redux+react+Router+Nodejs全栈开发高级课程,这里对实践过程作个记录,方便自己和大家翻阅.最终成果github地址:https://github.com/66We ...

  7. nodejs数据接收body-parser中间件

    给大家翻译一下npm上body-parser的资料 nodejs 的body数据解析中间件 插件作用:对于req.body属性,在操作数据前分析进来的请求体的插件 首先学习解析一个http处理 这篇文 ...

  8. springboot使用activemq同时接收queue和topic消息

    原文链接:https://blog.csdn.net/jia_costa/article/details/79354478 新建springboot项目, pom文件如下 <?xml versi ...

  9. 解决在 win10 下 vs2017 中创建 MFC 程序拖放文件接收不到 WM_DROPFILES 消息问题

    解决方案 这个问题是由于 win10 的安全机制搞的鬼,即使以管理员权限运行也不行,因为它会把 WM_DROPFILES 消息过滤掉,那怎么办呢?只需在窗口初始化 OnInitDialog() 里添加 ...

随机推荐

  1. NET中级课--文件,流,序列化2

    1.流的类型体系: 基础流    装饰器流    包装器类    帮助类 2.               stream file~     memory~     network~ stream是个 ...

  2. MJExtension(JSON到数据模型的自动转换)

    整理自:http://www.jianshu.com/p/93c242452b9b. 1.MJExtension的功能 字典-->模型 模型-->字典 字典数组-->模型数组 模型数 ...

  3. OpenCV——CvMatchShapes函数

    功能:根据计算比较两张图像Hu不变距(函数返回值代表相似度大小,完全相同的图像返回值是0,返回值最大是1) double cvMatchShapes(const void* object1, cons ...

  4. (转) int argc, char* argv[] 的用法

    int main(int argc, char* argv[]) 這兩個參數的作用是什麼呢?argc 是指命令行輸入參數的個數,argv存儲了所有的命令行參數.假如你的程式是hello.exe,如果在 ...

  5. Delphi Length函数

    unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...

  6. Mac OS X和iOS上基本数据类型的字节数

    在Mac和IPhone上分别运行下面的程序: NSLog(@"char size = %lu", sizeof(char)); NSLog(@"short int siz ...

  7. PHP怎么实现网站中,同一个用户不能同时在线?

    先上图,看个大概: 一般的原则就是,后一个用户登录时会把前一个用户踢下线. 在用户首次登录时,我们会把用户的sessionid保存到数据库,这个是用户的唯一标识.方便后边操作. 用户只有在登录时才会和 ...

  8. ThinkPhp调用webservice

    模板页: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl ...

  9. haproxy之负载均衡算法

    backend     blance 算法 动态hash的特点     服务器运行时就可进行权重调整,即只需要重新载入配置文件即可,不需要重新启动haproxy     支持慢速启动,即重新恢复的后端 ...

  10. java通过jdbc连接mysql数据库

    下载mysql驱动包: http://dev.mysql.com/downloads/file.php?id=456317 解压之后里面有个mysql-connector-java-5.1.35-bi ...