Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 69 additions & 1 deletion lib/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,8 +382,76 @@ Agent.prototype._do_getnext = function _do_getnext(req, rsp) {
});
};

Agent.prototype._do_bulkget_one = function (req, rsp, oid, cb, first) {
var self = this;
var node = this._getnext_lookup(oid, first);
var nvb = req.pdu.varbinds.length;
var prq = new ProviderRequest(req.pdu.op, oid, node);
var handler;

if (!node || !node.decor('_agent').instancePossible()) {
handler = [ function _getset_nsohandler(pr) {
var rsd = data.createData({ type: 'Null',
value: data.endOfMibView });
var rsvb = varbind.createVarbind({
oid: pr.oid, data: rsd });
pr.done(rsvb);
} ];
} else {
handler = node.decor('_agent')._handler;
}

prq._done = function _getnext_done(rsvb) {
if (rsvb !== undefined) {
cb(rsvb);
return;
}
self._do_bulkget_one(req, rsp, prq.node.oid, cb, false);
};

handler.forEach(function (h) {
h(prq);
});
};

function belongsTo(oid, baseAddr) {
var target = data.canonicalizeOID(oid);
return baseAddr.every(function (d, i) {
return target[i] === d;
});
}

Agent.prototype._do_getbulk = function _do_getbulk(req, rsp) {
/* XXX yuck */
var self = this;

function createCallback (baseAddr) {
return function callback (rsvb) {
if (typeof rsvb === 'object' && varbind.isSnmpVarbind(rsvb)) {
if (rsp.pdu.varbinds.length > 0 && rsp.pdu.varbinds.slice(-1)[0].oid === rsvb.oid) {
// We just got a response from the same valid node twice, there are no more providers to be found
// Force the OID to be something that does not match with our base requested OID
var bogusAddr = Array.apply([], baseAddr);
bogusAddr.push(bogusAddr.pop() + 1, 0);
rsvb.oid = bogusAddr.join('.');
}
if (belongsTo(rsvb.oid, baseAddr)) {
rsp.pdu.varbinds.push(rsvb);
} else {
rsvb.data = data.createData({ type: 'Null', value: data.endOfMibView });
rsp.pdu.varbinds.push(rsvb);

self._transmit_response(req._conn_recv, rsp);
return;
}
self._do_bulkget_one(req, rsp, rsvb.oid, callback, true);
}
};
}

// It makes no sense to pass multiple getBulk requests in one PDU. snmpbulkwalk won't even do it. If a manager
// happens to do it, we ignore all but the first varbind.
var vb = req.pdu.varbinds[0];
self._do_bulkget_one(req, rsp, vb.oid, createCallback(data.canonicalizeOID(vb.oid)), true);
};

Agent.prototype._process_req = function _process_req(req) {
Expand Down