[
  {
    "path": ".gitignore",
    "content": ".*.swp\ngmon.out\nnode_modules\nlib-cov\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n    \"curly\": true,\n    \"eqeqeq\": true,\n    \"forin\": true,\n    \"immed\": true,\n    \"latedef\": true,\n    \"newcap\": true,\n    \"noarg\": true,\n    \"noempty\": true,\n    \"undef\": true,\n    \"trailing\": true,\n    \"node\": true,\n    \"nomen\": false,\n    \"plusplus\": false\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - node\n  - lts/*\n  - '12'\n  - '10'\n  - '8'\ncache: yarn\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (C) 2012 Jakob Borg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\n- The above copyright notice and this permission notice shall be included in\n  all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "                                                                 __\n                                                                /\\ \\__  __\n      ____    ___     ___ ___   _____              ___      __  \\ \\ ,_\\/\\_\\   __  __     __\n     /',__\\ /' _ `\\ /' __` __`\\/\\ '__`\\  _______ /' _ `\\  /'__`\\ \\ \\ \\/\\/\\ \\ /\\ \\/\\ \\  /'__`\\\n    /\\__, `\\/\\ \\/\\ \\/\\ \\/\\ \\/\\ \\ \\ \\L\\ \\/\\______\\/\\ \\/\\ \\/\\ \\L\\.\\_\\ \\ \\_\\ \\ \\\\ \\ \\_/ |/\\  __/\n    \\/\\____/\\ \\_\\ \\_\\ \\_\\ \\_\\ \\_\\ \\ ,__/\\/______/\\ \\_\\ \\_\\ \\__/.\\_\\\\ \\__\\\\ \\_\\\\ \\___/ \\ \\____\\\n     \\/___/  \\/_/\\/_/\\/_/\\/_/\\/_/\\ \\ \\/           \\/_/\\/_/\\/__/\\/_/ \\/__/ \\/_/ \\/__/   \\/____/\n                                  \\ \\_\\\n                                   \\/_/\n\nsnmp-native  [![Build Status](https://secure.travis-ci.org/calmh/node-snmp-native.png)](http://travis-ci.org/calmh/node-snmp-native)\n===========\n\nThis is a native SNMP library for Node.js. The purpose is to provide enough\nfunctionality to perform large scale monitoring of network equipment. Current\nfeatures towards this end are:\n\n - Full implementation of SNMPv2c, including 64 bit data types.\n - Support for Get, GetNext and Set requests, with optimizations such as GetAll\n   and GetSubtree.\n - No unusual external dependencies, no non-JavaScript code.\n - Very high performance, unlimited parallellism. (There are always limits.\n   However, there are no arbitrary such imposed by this code and you at least\n   won't run out of file descriptors.)\n - De facto standards compliance. Generated packets are compared against\n   Net-SNMP and should be identical in all relevant aspects.\n - Well tested. Test coverage should be at or close to 100% for all important\n   code paths.\n\nIt specifically does *not* include:\n\n - Compatibility with SNMPv1, SNMPv2u or SNMPv3. These are (in order)\n   deprecated, weird, and too complicated. Yes, it's an opinionated library.\n - MIB parsing. Do this in your client app if it's necessary.\n\nIt's optimized for polling tens of thousands of counters on hundreds or\nthousands of hosts in a parallell manner. This is known to work (although\nperformance might be limited by less than optimal SNMP agent implementations in\nrandom network gear).\n\nDocumentation\n=============\n\nInstallation\n------------\n\n    $ npm install snmp-native\n\nUsage\n-----\n\n### Import\n\n```javascript\nvar snmp = require('snmp-native');\n```\n\n### new Session(options)\n\nCreate a `Session`. The `Session` constructor, like most of the other\nfunctions, take an `options` object. The options passed to the `Session` will\nbe the defaults for any subsequent function calls on that session, but can be\noverridden as needed. Useful parameters here are `host`, `port` and `family`.\n\n```javascript\n// Create a Session with default settings.\nvar session = new snmp.Session();\n\n// Create a Session with explicit default host, port, and community.\nvar session = new snmp.Session({ host: 'device.example.com', port: 161, community: 'special' });\n\n// Create an IPv6 Session.\nvar session = new snmp.Session({ host: '2001:db8::42', family: 'udp6', community: 'private' });\n```\n\nThe following options are recognized as properties in the options object. All\ncan be specified in the `Session` constructor and optionally overridden at a\nlater time by setting them in the option object to a method call.\n\nFor optimum performance when polling many hosts, create a session without\nspecifying the `host`. Reuse this session for all hosts and specify the `host`\non each `get`, `getAll`, etc.\n\n - `host`: The host to send the request to. An resolvable name is allowed in\n   addition to IP addresses. Default: `'localhost'`.\n - `port`: The UDP port number to send the request to. Default: `161`.\n - `community`: The SNMP community name. Default: `'public'`.\n - `family`: Address family to bind to. This is only used by the `Session`\n   constructor since that is when the bind is done. It cannot be changed or\n   overridden after construction. Default: `'udp4'`. Valid values: `'udp4'` or\n   `'udp6'`.\n - `timeouts`: An array of timeout values. Values are times in milliseconds,\n   the length of the array is the total number of transmissions that will\n   occur. Default: `[5000, 5000, 5000, 5000]` (four attempts, with five seconds\n   between each). A backoff can be implemented by timeouts along the lines of\n   `[ 1000, 2000, 4000, 8000 ]`. Retransmissions can be disabled by using only\n   a single timeout value: `[ 5000 ]`.\n - `bindPort`: UDP port used to bind the socket locally. Default: `0` (random port)\n - `msgReceived`: A `(message, rinfo) => {}` function responsible to handle incoming\n   messages and sending UDP responses back. If nothing is given here, the default implementation\n   is used. This is useful if you want to implement custom logic in your application\n\n### VarBind objects\n\nAll of the `get*` functions return arrays of `VarBind` as the result to the\ncallback. The `VarBind` objects have the following properties:\n\n - `oid`: The OID they represent (in array form).\n - `type`: The integer type code for the returned value.\n - `value`: The value, in decoded form. This will be an integer for integer,\n   gauge, counter and timetick types, a string for an octet string value, an\n   array for array or IP number types.\n - `valueRaw`: For octet string values, this is a raw `Buffer` representing the string.\n - `valueHex`: For octet string values, this is a hex string representation of the value.\n - `sendStamp`: The timestamp (in milliseconds) when the request was transmitted.\n - `receiveStamp`: The timestamp (in milliseconds) when the response was received.\n\n### get(options, callback)\n\nPerform a simple GetRequest. Options (in addition to the ones defined above for `Session`):\n\n - `oid`: The OID to get. Example: `[1, 3, 6, 1, 4, 1, 1, 2, 3, 4]` or\n   `'.1.3.6.1.4.1.1.2.3.4'`. Both forms are accepted, but the string form will\n   need to be parsed to an array, slightly increasing CPU usage.\n\nWill call the specified `callback` with an `error` object (`null` on success)\nand the varbind that was received.\n\n```javascript\nsession.get({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0] }, function (error, varbinds) {\n    if (error) {\n        console.log('Fail :(');\n    } else {\n        console.log(varbinds[0].oid + ' = ' + varbinds[0].value + ' (' + varbinds[0].type + ')');\n    }\n});\n```\n\nYou can also specify host, community, etc explicitly.\n\n```javascript\nsession.get({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0], host: 'localhost', community: 'test' }, ...);\n```\n\n### getNext(options, callback)\n\nPerform a simple GetNextRequest. Options:\n\n - `oid`: The OID to get. Example: `[1, 3, 6, 1, 4, 1, 1, 2, 3, 4]` or `'.1.3.6.1.4.1.1.2.3.4'`.\n\nWill call the specified `callback` with an `error` object (`null` on success)\nand the varbind that was received.\n\n```javascript\nsession.getNext({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0] }, function (error, varbinds) {\n    if (error) {\n        console.log('Fail :(');\n    } else {\n        console.log(varbinds[0].oid + ' = ' + varbinds[0].value + ' (' + varbinds[0].type + ')');\n    }\n});\n```\n\n### getAll(options, callback)\n\nPerform repeated GetRequests to fetch all the required values. Multiple OIDs\nwill get packed into as few GetRequest packets as possible to minimize\nroundtrip delays. Gets will be issued serially (not in parallell) to avoid\nflooding hosts. Options:\n\n - `oids`: An array of OIDs to get. Example: `[[1, 3, 6, 1, 4, 1, 1, 2, 3], [1,\n   3, 6, 1, 4, 1, 1, 2, 4]]` or `['.1.3.6.1.4.1.1.2.3.4',\n   '.1.3.6.1.4.1.2.3.4.5']`.\n - `abortOnError`: Whether to stop or continue when an error is encountered.\n   Default: `false`.\n - `combinedTimeout`: Timeout in milliseconds that the getAll() may take.\n   Default: no timeout.\n\nThe callback will be called with an error object or a list of varbinds. If the\noptions property `abortOnError` is false (default) any variables that couldn't\nbe fetched will simply be omitted from the results. If it is true, the callback\nwill be called with an error object on any failure. If the `combinedTimeout` is\ntriggered, the callback is called with an error and the partial results.\n\n```javascript\nvar oids = [ [1, 3, 6, 1, 4, 1, 42, 1, 0], [1, 3, 6, 1, 4, 1, 42, 2, 0], ... ];\nsession.getAll({ oids: oids }, function (error, varbinds) {\n    varbinds.forEach(function (vb) {\n        console.log(vb.oid + ' = ' + vb.value + ' (' + vb.type + ')');\n    });\n});\n```\n\n### getSubtree(options, callback)\n\nPerform repeated GetNextRequests to fetch all values in the specified tree. Options:\n\n - `oid`: The OID to get. Example: `[1, 3, 6, 1, 4, 1, 1, 2, 3, 4]` or `'.1.3.6.1.4.1.1.2.3.4'`.\n - `combinedTimeout`: Timeout in milliseconds that the getSubtree() may take.\n   Default: no timeout.\n\nWill call the specified `callback` with an `error` object (`null` on success)\nand the list of varbinds that was fetched. If the `combinedTimeout` is triggered,\nthe callback is called with an error and the partial results.\n\n```javascript\nsession.getSubtree({ oid: [1, 3, 6, 1, 4, 1, 42] }, function (error, varbinds) {\n    if (error) {\n        console.log('Fail :(');\n    } else {\n        varbinds.forEach(function (vb) {\n            console.log(vb.oid + ' = ' + vb.value + ' (' + vb.type + ')');\n        });\n    }\n});\n```\n\n### set(options, callback)\n\nPerform a simple SetRequest. Options:\n\n - `oid`: The OID to perform the set on. Example: `[1, 3, 6, 1, 4, 1, 1, 2, 3, 4]`\n   or `'.1.3.6.1.4.1.1.2.3.4'`.\n - `value`: The value to set. Example: `42`.\n - `type`: The type of the value. Currently supports `asn1ber.T.Integer` (2), `asn1ber.T.Gauge` (66),\n   `asn1ber.T.IpAddress` (64), `asn1ber.T.OctetString` (4) and `asn1ber.T.Null` (5).\n   Example: `2`.\n\nExample:\n\n```javascript\nsession.set({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0], value: 42, type: 2 }, function (error, varbind) {\n    if (error) {\n        console.log('Fail :(');\n    } else {\n        console.log('The set is done.');\n    }\n});\n```\n\nIf you're not really interested in the outcome of the set (and if you are, why\naren't you using scripted telnet or ssh instead to begin with?), you can call\nit without a callback:\n\n```javascript\nsession.set({ oid: [1, 3, 6, 1, 4, 1, 42, 1, 0], value: 42, type: 2 });\n```\n\n### close()\n\nCancels all outstanding requests and frees used OS resources. Outstanding\nrequests will call their callback with the \"Cancelled\" error set.\n\nExample:\n\n```javascript\nsession.close();\n```\n\nLicense\n=======\n\nMIT\n\n"
  },
  {
    "path": "docs/asn1ber.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n  <title>asn1ber.js</title>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n  <link rel=\"stylesheet\" media=\"all\" href=\"docco.css\" />\n</head>\n<body>\n  <div id=\"container\">\n    <div id=\"background\"></div>\n    \n      <ul id=\"jump_to\">\n        <li>\n          <a class=\"large\" href=\"javascript:void(0);\">Jump To &hellip;</a>\n          <a class=\"small\" href=\"javascript:void(0);\">+</a>\n          <div id=\"jump_wrapper\">\n          <div id=\"jump_page\">\n            \n              \n              <a class=\"source\" href=\"example.html\">\n                example.js\n              </a>\n            \n              \n              <a class=\"source\" href=\"asn1ber.html\">\n                asn1ber.js\n              </a>\n            \n              \n              <a class=\"source\" href=\"snmp.html\">\n                snmp.js\n              </a>\n            \n          </div>\n        </li>\n      </ul>\n    \n    <ul class=\"sections\">\n        \n          <li id=\"title\">\n              <div class=\"annotation\">\n                  <h1>asn1ber.js</h1>\n              </div>\n          </li>\n        \n        \n        \n        <li id=\"section-1\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-1\">&#182;</a>\n              </div>\n              <p>This file implements a minimal subset of Abstract Syntax Notation One (<strong>ASN.1</strong>)\nBasic Encoding Rules (<strong>BER</strong>), namely the parts that are necessary for sending\nand receiving SNMPv2c messages.</p>\n<p>(c) 2012 Jakob Borg, Nym Networks</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"string\">\"use strict\"</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-2\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-2\">&#182;</a>\n              </div>\n              <p>We define constants for the commonly used ASN.1 types in SNMP.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> T = {\n    Integer: <span class=\"number\">0x02</span>,\n    OctetString: <span class=\"number\">0x04</span>,\n    Null: <span class=\"number\">0x05</span>,\n    ObjectIdentifier: <span class=\"number\">0x06</span>,\n    Sequence: <span class=\"number\">0x30</span>,\n    IpAddress: <span class=\"number\">0x40</span>,\n    Counter: <span class=\"number\">0x41</span>,\n    Gauge: <span class=\"number\">0x42</span>,\n    TimeTicks: <span class=\"number\">0x43</span>,\n    Opaque: <span class=\"number\">0x44</span>,\n    NsapAddress: <span class=\"number\">0x45</span>,\n    Counter64: <span class=\"number\">0x46</span>,\n    NoSuchObject: <span class=\"number\">0x80</span>,\n    NoSuchInstance: <span class=\"number\">0x81</span>,\n    EndOfMibView: <span class=\"number\">0x82</span>,\n    PDUBase: <span class=\"number\">0xA0</span>\n};\n\n<span class=\"keyword\">var</span> P = {\n    GetRequestPDU: <span class=\"number\">0x00</span>,\n    GetNextRequestPDU: <span class=\"number\">0x01</span>,\n    GetResponsePDU: <span class=\"number\">0x02</span>,\n    SetRequestPDU: <span class=\"number\">0x03</span>\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-3\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-3\">&#182;</a>\n              </div>\n              <p>The types are also available for consumers of the library.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.types = T;\nexports.pduTypes = P;\nexports.unittest = {};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-4\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-4\">&#182;</a>\n              </div>\n              <h2>Private helper functions</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-5\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-5\">&#182;</a>\n              </div>\n              <p>Encode a length as it should be encoded.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">lengthArray</span><span class=\"params\">(len)</span> {</span>\n    <span class=\"keyword\">var</span> arr = [];\n\n    <span class=\"keyword\">if</span> (len &lt;= <span class=\"number\">127</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-6\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-6\">&#182;</a>\n              </div>\n              <p>Return a single byte if the value is 127 or less.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">return</span> [ len ];\n    } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-7\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-7\">&#182;</a>\n              </div>\n              <p>Otherwise encode it as a MSB base-256 integer.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">while</span> (len &gt; <span class=\"number\">0</span>) {\n            arr.push(len % <span class=\"number\">256</span>);\n            len = parseInt(len / <span class=\"number\">256</span>, <span class=\"number\">10</span>);\n        }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-8\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-8\">&#182;</a>\n              </div>\n              <p>Add a length byte in front and set the high bit to indicate\nthat this is a longer value than one byte.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        arr.push(<span class=\"number\">128</span> + arr.length);\n        arr.reverse();\n        <span class=\"keyword\">return</span> arr;\n    }\n}\n\nexports.unittest.lengthArray = lengthArray;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-9\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-9\">&#182;</a>\n              </div>\n              <p>Return a wrapped copy of the passed <code>contents</code>, with the specified wrapper type.\nThis is used for Sequence and other constructed types.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">wrapper</span><span class=\"params\">(type, contents)</span> {</span>\n    <span class=\"keyword\">var</span> buf, len, i;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-10\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-10\">&#182;</a>\n              </div>\n              <p>Get the encoded length of the contents</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    len = lengthArray(contents.length);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-11\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-11\">&#182;</a>\n              </div>\n              <p>Set up a buffer with the type and length bytes plus a straight copy of the content.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    buf = <span class=\"keyword\">new</span> Buffer(<span class=\"number\">1</span> + contents.length + len.length);\n    buf[<span class=\"number\">0</span>] = type;\n    <span class=\"keyword\">for</span> (i = <span class=\"number\">1</span>; i &lt; len.length + <span class=\"number\">1</span>; i++) {\n        buf[i] = len[i - <span class=\"number\">1</span>];\n    }\n    contents.copy(buf, len.length + <span class=\"number\">1</span>, <span class=\"number\">0</span>);\n    <span class=\"keyword\">return</span> buf;\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-12\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-12\">&#182;</a>\n              </div>\n              <p>Get the encoded representation of a number in an OID.\nIf the number is less than 128, pass it as it is.\nOtherwise return an array of base-128 digits, most significant first,\nwith the high bit set on all octets except the last one.\nThis encoding should be used for all number in an OID except the first\ntwo (.1.3) which are handled specially.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">oidInt</span><span class=\"params\">(val)</span> {</span>\n    <span class=\"keyword\">var</span> bytes = [];\n\n    bytes.push(val % <span class=\"number\">128</span>);\n    val = parseInt(val / <span class=\"number\">128</span>, <span class=\"number\">10</span>);\n    <span class=\"keyword\">while</span> (val &gt; <span class=\"number\">127</span>) {\n        bytes.push(<span class=\"number\">128</span> + val % <span class=\"number\">128</span>);\n        val = parseInt(val / <span class=\"number\">128</span>, <span class=\"number\">10</span>);\n    }\n    bytes.push(val + <span class=\"number\">128</span>);\n    <span class=\"keyword\">return</span> bytes.reverse();\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-13\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-13\">&#182;</a>\n              </div>\n              <p>Encode an OID. The first two number are encoded specially\nin the first octet, then the rest are encoded as one octet per number\nunless the number exceeds 127. If so, it&#39;s encoded as several base-127\noctets with the high bit set to indicate continuation.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">oidArray</span><span class=\"params\">(oid)</span> {</span>\n    <span class=\"keyword\">var</span> bytes, i, val;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-14\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-14\">&#182;</a>\n              </div>\n              <p>Enforce some minimum requirements on the OID.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">if</span> (oid.length &lt; <span class=\"number\">2</span>) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">\"Minimum OID length is two.\"</span>);\n    } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (oid[<span class=\"number\">0</span>] !== <span class=\"number\">1</span> || oid[<span class=\"number\">1</span>] !== <span class=\"number\">3</span>) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">\"SNMP OIDs always start with .1.3.\"</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-15\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-15\">&#182;</a>\n              </div>\n              <p>Calculate the first byte of the encoded OID according to the &#39;special&#39; rule.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    bytes = [ <span class=\"number\">40</span> * oid[<span class=\"number\">0</span>] + oid[<span class=\"number\">1</span>] ];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-16\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-16\">&#182;</a>\n              </div>\n              <p>For the rest of the OID, encode each number individually and add the\nresulting bytes to the buffer.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">for</span> (i = <span class=\"number\">2</span>; i &lt; oid.length; i++) {\n        val = oid[i];\n        <span class=\"keyword\">if</span> (val &gt; <span class=\"number\">127</span>) {\n            bytes = bytes.concat(oidInt(val));\n        } <span class=\"keyword\">else</span> {\n            bytes.push(val);\n        }\n    }\n\n    <span class=\"keyword\">return</span> bytes;\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-17\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-17\">&#182;</a>\n              </div>\n              <p>Divide an integer into base-256 bytes.\nMost significant byte first.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">intArray</span><span class=\"params\">(val)</span> {</span>\n    <span class=\"keyword\">var</span> array = [];\n\n    <span class=\"keyword\">if</span> (val === <span class=\"number\">0</span>) {\n        array.push(<span class=\"number\">0</span>);\n    } <span class=\"keyword\">else</span> {\n        <span class=\"keyword\">while</span> (val &gt; <span class=\"number\">0</span>) {\n            array.push(val % <span class=\"number\">256</span>);\n            val = parseInt(val / <span class=\"number\">256</span>, <span class=\"number\">10</span>);\n        }\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-18\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-18\">&#182;</a>\n              </div>\n              <p>Do not produce integers that look negative (high bit\nof first byte set).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">if</span> (array[array.length - <span class=\"number\">1</span>] &gt;= <span class=\"number\">0x80</span>) {\n        array.push(<span class=\"number\">0</span>);\n    }\n\n    <span class=\"keyword\">return</span> array.reverse();\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-19\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-19\">&#182;</a>\n              </div>\n              <h2>Functions to encode ASN.1 from native objects</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-20\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-20\">&#182;</a>\n              </div>\n              <p>Encode a simple integer.\nIntegers are encoded as a simple base-256 byte sequence, most significant byte first,\nprefixed with a length byte. In principle we support arbitrary integer sizes, in practice\nJavascript doesn&#39;t even <strong>have</strong> integers so some precision might get lost.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeInteger = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(val)</span> {</span>\n    <span class=\"keyword\">var</span> i, arr, buf;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-21\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-21\">&#182;</a>\n              </div>\n              <p>Get the bytes that we&#39;re going to encode.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    arr = intArray(val);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-22\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-22\">&#182;</a>\n              </div>\n              <p>Now that we know the length, we allocate a buffer of the required size.\nWe set the type and length bytes appropriately.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    buf = <span class=\"keyword\">new</span> Buffer(<span class=\"number\">2</span> + arr.length);\n    buf[<span class=\"number\">0</span>] = T.Integer;\n    buf[<span class=\"number\">1</span>] = arr.length;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-23\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-23\">&#182;</a>\n              </div>\n              <p>Copy the bytes into the array.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; arr.length; i++) {\n        buf[i + <span class=\"number\">2</span>] = arr[i];\n    }\n\n    <span class=\"keyword\">return</span> buf;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-24\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-24\">&#182;</a>\n              </div>\n              <p>Create the representation of a Null, <code>05 00</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeNull = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">()</span> {</span>\n    <span class=\"keyword\">var</span> buf = <span class=\"keyword\">new</span> Buffer(<span class=\"number\">2</span>);\n    buf[<span class=\"number\">0</span>] = T.Null;\n    buf[<span class=\"number\">1</span>] = <span class=\"number\">0</span>;\n    <span class=\"keyword\">return</span> buf;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-25\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-25\">&#182;</a>\n              </div>\n              <p>Encode a Sequence, which is a wrapper of type <code>30</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeSequence = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(contents)</span> {</span>\n    <span class=\"keyword\">return</span> wrapper(T.Sequence, contents);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-26\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-26\">&#182;</a>\n              </div>\n              <p>Encode an OctetString, which is a wrapper of type <code>04</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeOctetString = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(string)</span> {</span>\n    <span class=\"keyword\">var</span> buf, contents;\n\n    <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> string === <span class=\"string\">'string'</span>) {\n        contents = <span class=\"keyword\">new</span> Buffer(string);\n    } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (Buffer.isBuffer(string)) {\n        contents = string;\n    } <span class=\"keyword\">else</span> {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Only Buffer and string types are acceptable as OctetString.'</span>);\n    }\n\n    <span class=\"keyword\">return</span> wrapper(T.OctetString, contents);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-27\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-27\">&#182;</a>\n              </div>\n              <p>Encode an IpAddress, which is a wrapper of type <code>40</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeIpAddress = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(address)</span> {</span>\n    <span class=\"keyword\">var</span> contents, octets, value = [];\n\n    <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> address !== <span class=\"string\">'string'</span> &amp;&amp; !Buffer.isBuffer(address)) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Only Buffer and string types are acceptable as OctetString.'</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-28\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-28\">&#182;</a>\n              </div>\n              <p>assume that the string is in dotted decimal format ipv4\nalso, use toString in case a buffer was passed in.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    octets = address.toString().split(<span class=\"string\">'.'</span>);\n    <span class=\"keyword\">if</span> (octets.length !== <span class=\"number\">4</span>) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'IP Addresses must be specified in dotted decimal format.'</span>);\n    }\n    octets.forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(octet)</span> {</span>\n        <span class=\"keyword\">var</span> octetValue = parseInt(octet, <span class=\"number\">10</span>);\n        <span class=\"keyword\">if</span> (octet &lt; <span class=\"number\">0</span> || octet &gt; <span class=\"number\">255</span>) {\n            <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'IP Address octets must be between 0 and 255 inclusive.'</span> + JSON.stringify(octets));\n        }\n        value.push(octetValue);\n    });\n\n    contents = <span class=\"keyword\">new</span> Buffer(value);\n\n    <span class=\"keyword\">return</span> wrapper(T.IpAddress, contents);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-29\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-29\">&#182;</a>\n              </div>\n              <p>Encode an ObjectId.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeOid = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(oid)</span> {</span>\n    <span class=\"keyword\">var</span> buf, bytes, i, len;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-30\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-30\">&#182;</a>\n              </div>\n              <p>Get the encoded format of the OID.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    bytes = oidArray(oid);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-31\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-31\">&#182;</a>\n              </div>\n              <p>Get the encoded format of the length</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    len = lengthArray(bytes.length);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-32\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-32\">&#182;</a>\n              </div>\n              <p>Fill in the buffer with type, length and OID data.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    buf = <span class=\"keyword\">new</span> Buffer(<span class=\"number\">1</span> + bytes.length + len.length);\n    buf[<span class=\"number\">0</span>] = T.ObjectIdentifier;\n    <span class=\"keyword\">for</span> (i = <span class=\"number\">1</span>; i &lt; len.length + <span class=\"number\">1</span>; i++) {\n        buf[i] = len[i - <span class=\"number\">1</span>];\n    }\n    <span class=\"keyword\">for</span> (i = len.length + <span class=\"number\">1</span>; i &lt; bytes.length + len.length + <span class=\"number\">1</span>; i++) {\n        buf[i] = bytes[i - len.length - <span class=\"number\">1</span>];\n    }\n\n    <span class=\"keyword\">return</span> buf;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-33\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-33\">&#182;</a>\n              </div>\n              <p>Encode an SNMP request with specified <code>contents</code>.\nThe <code>type</code> code is 0 for <code>GetRequest</code>, 1 for <code>GetNextRequest</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.encodeRequest = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(type, contents)</span> {</span>\n    <span class=\"keyword\">return</span> wrapper(T.PDUBase + type, contents);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-34\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-34\">&#182;</a>\n              </div>\n              <h2>Functions to parse ASN.1 to native objects</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-35\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-35\">&#182;</a>\n              </div>\n              <p>Parse and return type, data length and header length.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">typeAndLength</span><span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">var</span> res, len, i;\n\n    res = { type: buf[<span class=\"number\">0</span>], len: <span class=\"number\">0</span>, header: <span class=\"number\">1</span> };\n    <span class=\"keyword\">if</span> (buf[<span class=\"number\">1</span>] &lt; <span class=\"number\">128</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-36\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-36\">&#182;</a>\n              </div>\n              <p>If bit 8 is zero, this byte indicates the content length (up to 127 bytes).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        res.len = buf[<span class=\"number\">1</span>];\n        res.header += <span class=\"number\">1</span>;\n    } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-37\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-37\">&#182;</a>\n              </div>\n              <p>If bit 8 is 1, bits 0 to 7 indicate the number of following legth bytes.\nThese bytes are a simple msb base-256 integer indicating the content length.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; buf[<span class=\"number\">1</span>] - <span class=\"number\">128</span>; i++) {\n            res.len += buf[i + <span class=\"number\">1</span>];\n            res.len *= <span class=\"number\">256</span>;\n        }\n        res.header += buf[<span class=\"number\">1</span>] - <span class=\"number\">128</span> + <span class=\"number\">1</span>;\n    }\n    <span class=\"keyword\">return</span> res;\n}\n\nexports.typeAndLength = typeAndLength;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-38\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-38\">&#182;</a>\n              </div>\n              <p>Parse a buffer containing a representation of an integer.\nVerifies the type, then multiplies in each byte as it comes.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.parseInteger = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">var</span> i, val;\n\n    <span class=\"keyword\">if</span> (buf[<span class=\"number\">0</span>] !== T.Integer &amp;&amp; buf[<span class=\"number\">0</span>] !== T.Counter &amp;&amp;\n        buf[<span class=\"number\">0</span>] !== T.Counter64 &amp;&amp; buf[<span class=\"number\">0</span>] !== T.Gauge &amp;&amp;\n        buf[<span class=\"number\">0</span>] !== T.TimeTicks) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Buffer '</span> + buf.toString(<span class=\"string\">'hex'</span>) + <span class=\"string\">' does not appear to be an Integer'</span>);\n    }\n\n    val = <span class=\"number\">0</span>;\n    <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; buf[<span class=\"number\">1</span>]; i++) {\n        val *= <span class=\"number\">256</span>;\n        val += buf[i + <span class=\"number\">2</span>];\n    }\n\n    <span class=\"keyword\">return</span> val;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-39\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-39\">&#182;</a>\n              </div>\n              <p>Parse a buffer containing a representation of an OctetString.\nVerify the type, then just grab the string out of the buffer.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.parseOctetString = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">if</span> (buf[<span class=\"number\">0</span>] !== T.OctetString) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Buffer does not appear to be an OctetString'</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-40\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-40\">&#182;</a>\n              </div>\n              <p>SNMP doesn&#39;t specify an encoding so I pick UTF-8 as the &#39;most standard&#39;\nencoding. We&#39;ll see if that assumption survives contact with actual reality.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">return</span> buf.toString(<span class=\"string\">'utf-8'</span>, <span class=\"number\">2</span>, <span class=\"number\">2</span> + buf[<span class=\"number\">1</span>]);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-41\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-41\">&#182;</a>\n              </div>\n              <p>Parse a buffer containing a representation of an ObjectIdentifier.\nVerify the type, then apply the relevent encoding rules.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.parseOid = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">var</span> oid, val, i;\n\n    <span class=\"keyword\">if</span> (buf[<span class=\"number\">0</span>] !== T.ObjectIdentifier) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Buffer does not appear to be an ObjectIdentifier'</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-42\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-42\">&#182;</a>\n              </div>\n              <p>The first byte contains the first two numbers in the OID</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    oid = [ parseInt(buf[<span class=\"number\">2</span>] / <span class=\"number\">40</span>, <span class=\"number\">10</span>), buf[<span class=\"number\">2</span>] % <span class=\"number\">40</span> ];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-43\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-43\">&#182;</a>\n              </div>\n              <p>The rest of the data is a base-128-encoded OID</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; buf[<span class=\"number\">1</span>] - <span class=\"number\">1</span>; i++) {\n        val = <span class=\"number\">0</span>;\n        <span class=\"keyword\">while</span> (buf[i + <span class=\"number\">3</span>] &gt;= <span class=\"number\">128</span>) {\n            val += buf[i + <span class=\"number\">3</span>] - <span class=\"number\">128</span>;\n            val *= <span class=\"number\">128</span>;\n            i++;\n        }\n        val += buf[i + <span class=\"number\">3</span>];\n        oid.push(val);\n    }\n\n    <span class=\"keyword\">return</span> oid;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-44\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-44\">&#182;</a>\n              </div>\n              <p>Parse a buffer containing a representation of an array type.\nThis is for example an IpAddress.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.parseArray = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">var</span> i, nelem, array;\n\n    <span class=\"keyword\">if</span> (buf[<span class=\"number\">0</span>] !== T.IpAddress) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Buffer does not appear to be an array type.'</span>);\n    }\n\n    nelem = buf[<span class=\"number\">1</span>];\n    array = [];\n\n    <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; buf[<span class=\"number\">1</span>]; i++) {\n        array.push(buf[i + <span class=\"number\">2</span>]);\n    }\n\n    <span class=\"keyword\">return</span> array;\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-45\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-45\">&#182;</a>\n              </div>\n              <p>Parse a buffer containing a representation of an opaque type.\nThis is for example an IpAddress.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.parseOpaque = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">var</span> hdr;\n\n    hdr = typeAndLength(buf);\n\n    <span class=\"keyword\">if</span> (hdr.type !== T.Opaque) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Buffer does not appear to be an opaque type.'</span>);\n    }\n\n    <span class=\"keyword\">return</span> <span class=\"string\">'0x'</span> + buf.slice(hdr.header).toString(<span class=\"string\">'hex'</span>);\n};\n\n<span class=\"comment\">/*globals exports: false*/</span></pre></div></div>\n            \n        </li>\n        \n    </ul>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "docs/coverage.html",
    "content": "<!DOCTYPE html><html><head><title>Coverage</title><script>\n\nheadings = [];\n\nonload = function(){\n  headings = document.querySelectorAll('h2');\n};\n\nonscroll = function(e){\n  var heading = find(window.scrollY);\n  if (!heading) return;\n  var links = document.querySelectorAll('#menu a')\n    , link;\n\n  for (var i = 0, len = links.length; i < len; ++i) {\n    link = links[i];\n    link.className = link.getAttribute('href') == '#' + heading.id\n      ? 'active'\n      : '';\n  }\n};\n\nfunction find(y) {\n  var i = headings.length\n    , heading;\n\n  while (i--) {\n    heading = headings[i];\n    if (y >= heading.offsetTop) {\n      return heading;\n    }\n  }\n}\n</script>\n<style>\n\nbody {\n  font: 14px/1.6 \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  margin: 0;\n  color: #2C2C2C;\n  border-top: 2px solid #ddd;\n}\n\n#coverage {\n  padding: 60px;\n}\n\nh1 a {\n  color: inherit;\n  font-weight: inherit;\n}\n\nh1 a:hover {\n  text-decoration: none;\n}\n\n.onload h1 {\n  opacity: 1;\n}\n\nh2 {\n  width: 80%;\n  margin-top: 80px;\n  margin-bottom: 0;\n  font-weight: 100;\n  letter-spacing: 1px;\n  border-bottom: 1px solid #eee;\n}\n\na {\n  color: #8A6343;\n  font-weight: bold;\n  text-decoration: none;\n}\n\na:hover {\n  text-decoration: underline;\n}\n\nul {\n  margin-top: 20px;\n  padding: 0 15px;\n  width: 100%;\n}\n\nul li {\n  float: left;\n  width: 40%;\n  margin-top: 5px;\n  margin-right: 60px;\n  list-style: none;\n  border-bottom: 1px solid #eee;\n  padding: 5px 0;\n  font-size: 12px;\n}\n\nul::after {\n  content: '.';\n  height: 0;\n  display: block;\n  visibility: hidden;\n  clear: both;\n}\n\ncode {\n  font: 12px monaco, monospace;\n}\n\npre {\n  margin: 30px;\n  padding: 30px;\n  border: 1px solid #eee;\n  border-bottom-color: #ddd;\n  -webkit-border-radius: 2px;\n  -moz-border-radius: 2px;\n  -webkit-box-shadow: inset 0 0 10px #eee;\n  -moz-box-shadow: inset 0 0 10px #eee;\n  overflow-x: auto;\n}\n\nimg {\n  margin: 30px;\n  padding: 1px;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n  -webkit-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;\n  -moz-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;\n  max-width: 100%;\n}\n\nfooter {\n  background: #eee;\n  width: 100%;\n  padding: 50px 0;\n  text-align: right;\n  border-top: 1px solid #ddd;\n}\n\nfooter span {\n  display: block;\n  margin-right: 30px;\n  color: #888;\n  font-size: 12px;\n}\n\n#menu {\n  position: fixed;\n  font-size: 12px;\n  overflow-y: auto;\n  top: 0;\n  right: 0;\n  margin: 0;\n  height: 100%;\n  padding: 15px 0;\n  text-align: right;\n  border-left: 1px solid #eee;\n  -moz-box-shadow: 0 0 2px #888\n     , inset 5px 0 20px rgba(0,0,0,.5)\n     , inset 5px 0 3px rgba(0,0,0,.3);\n  -webkit-box-shadow: 0 0 2px #888\n     , inset 5px 0 20px rgba(0,0,0,.5)\n     , inset 5px 0 3px rgba(0,0,0,.3);\n  -webkit-font-smoothing: antialiased;\n  background: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAMAAAAOARRQAAABelBMVEUjJSU6OzshIyM5OjoqKy02NjgsLS01NTYjJCUzNTUgISMlJSc0NTUvMDA6PDwlJyg1NjYoKis2NjYrLS02ODkpKyw0NDYrLC04ODovLzA4Ojo0NDUtLy86OjwjIyU4OTosLS82ODgtLS8hIyQvMTEnKCooKSsrKy0qLCwkJSUnKCkrLCwpKiwwMjIxMzMqLC0tLS0pKissLC00NTYwMDIwMTQpKysoKSovMDEtLzA2OTkxMzUrKywvLy8qKyszNTY5OzsqKiw6OjswMDExNDUoKiozNDUvMDIyNDY1Njg2Njk5OTozMzU0NjY4ODkiIyUiIyQ4OTkuMDEmKCowMjQwMTErLS4qKywwMTMhIiMpKiopKy0tLjAkJScxNDQvLzExNDYyNDQmKCk5OTslJig5OjskJSYxMzQrLS8gISIwMTIoKCk1NTUlJSUnJygwMDA4ODgiIiMhISI8PDw6Ojo5OTkpKSojIyQ7OzsyMjIpKSssLCw6Ozw1NjlrfLakAAAg2UlEQVR42jR6i3ea6rYvPgANIAhVXh8WvkQlioUiFlFcBtAmoiRNdzxqu9p0J7vrdK29zuPeex77nnvO/35n1r1ndHRktI0jTOacv/l7lCBK5UqVpOha/YxmWK7BC4TQFKVXrbYsnimqxuuMVlOQ0XltWjUdCwRJ1M+tC1KudOs9q6+da2adUewG0SC0SwELfHtgDds93VEuydEbl3QMWeNoYkR7b/0x1ZRobGI3mLwzAhePqTAwhg6aogjNsGy7/jwQ4rkdqe7CWLxF8k9LfMVFyRS7VJqtkrW8Vt/bkR8FZJao16ipknbC3Yw2lM7laO6HBEOadEZ2tpf65c4v8e3u7FyU6qbiNNyCuzXZ6pawgnwgmrpTT/Q7w2EZmiIJ0dzWDI7mhQ80IfRnMu2kzA5r5r1pIFoia+/d93HRYp1GV8TbrkWoU/+jdI0Ff6yGwTjT1Hn8J+8m1rKpGiYPuNiHnMtNMIv+zpsk84MYTNW1/+DpwXLvckdOCMYowVNPREe0QlM8xRHXXFhcNDzupwsSmb5pH+0t0RP2Qk+QtI7F1Qm6JRC6ZPBtPq/dq/kH+jxtCljn9TIpW6rQIgmSVyj6lPICIw4N/taka41PFUInth0je9+jO6Kt1G4/a7V2LEgG02B0pHVuCZrgltSKMuIl5SyufUv9mYuQi+mFgzbBEtFo2g+Dh4sSTrLNu8JPh00sQydpb00tqXBvqRN7Q7kqzcnIxCGnvZt/WmJacoOEO6Dcn8Qre03pOCSQxbMOXUuDNx9SxuLz4W1I18gvjViQ67zV0rxdWL8Te/TQkuo8STS41DR48W7L6YP2uWIqiUV8rd6Gbf/rnegKZeG8TpAM6afhGze9JAOxbLjsnUXEbrZ9vLYd7MT32cPF5mKKxmjy7huaoD9n62GOxni3iIJwv0IzZAZjdZkUtolCNLVfYZNaquFjGszVVf+J0vrz4CawoKdHnOzb0NMH7CDBOybfYNJ4rfeMyFNjkFYVTzMFs87rnPGXLUOeNKRVc0LnU7/UIgelzsy3CMuth0YfvnY0wsD3vODUL3eJcKqHQpm8yM3XZQWJxO6Un9iYloyyLpOwN2obHy6W6gbpcb44XmyC+mg+itAcaprGcrwZCqMj/GmtKn0zPvpTz/Cv1dw21XwP3cRupg3H3MF/S71eTKj1YrdwKdc2Mw0fRmb2sFf8lW3aU6JbIZSEPqvXvjM7G/aApyXlXeqKfMq0g/Su3rUGJPSPrtGElgknrZM3xUXqsAP6zMCNVn5u8aJnSNpJv2uru7t2jfRziW2+GuhqfldUNbPk71olwo+46ePUo1U3WKk/e5YK07F/wGRgcpODmQnIlVeHCWBE4puBi2jq28UKpqiN1/4UOrGz59TNYrrQHtd+11sG40BGD+pXdelNqGOg4NXe8W4eacJV/NS9/2Umtym6WQqveqR9xdCMElpxnbkalM4Vf9uaEcWZaKdyibEIjWKxJZPN95niCL3GiaXyssIrHxoLkqkzLCXULN46/f2h3tQJgyip+Tk9EAjJ9aJshq7t8X45aowSKspMSvPf7r9R8yxNptIaHS5ozuEm6luPDApugyNP8OaqiQ4BjaequXA54SLC83eHIY2r+CZp4409Xqw8Aa2oI7XkCrQi+in0w5AqF/kLNrcUz+qkl/lAobY1jSnx5OJNhyXIz3qfNFlXc0TKaglNwdWkWYt9QQ1Kr6W8zue21iNrdJk+N5oCr2O9nEtWKC7IS5J/zdDEYrmnAYfg6agCy+qcgz7ZofeDc4PbUWSvkshWuAc7OjiUyLkj+RAtdlwXJcjxdpkTTHDhK8lBCi8+JtvDVL1W6elmOM++YS0LuSlaP1oUvAeiW3cFnvTr8EbTz1tsSMYdGeZe40sRWu5uAfj7q+ZoKv2FNQ0p5XY1lmlcigHZqTPpabufEVrNuNPi165w3uCVQJHyJqmSJ7ZHnguqwtCmwViIJijj04ba2JNYtB+yORf5gg1/9t9iw4vUpeqiunSAbf+IBdj/b+iG2qrHvuNP0Vd/+ThVZT/lrvHYjjgDbbyxaqgHNM2uhxa1GW3UedZYhMMwM4mQhltouK+IV4NdbIQNM+8Yv311RZk9kT4tiYR4LkyFcuPpdcjuhUuFqBAWRZa11lcZ3gEBlXywsNhrt+plISZP5DlsV9l4EgY6J3yZPTUcMrgaWAT3oI79eSbGEbcJpr6BD8kyDiVt+G0/hXosQN4NFXKlfWIfsIs0BHODVok1/IGnKFHJYIquh8Xo+2+bkQNTGgWmN/fZ0Y33LSj6lr1GyV7mWIKg7ZTRZPGuhF/zjRNcQ1UPtSYgnWQxSs0yrVhwNDcdGMNSNe2JT3WuzbAM3HykyAajS3Uphf6STKEqxLas9EnmnhA/lyj9Uj+JoY7SVgVmGLl46Rm2u98sbkap2lzAdKBG4r6LgulQOSSjQv1GWdQ0jtDUK/mAaqM1Uqjpu4k3Rvfvxv7YTxLSK+wN3E5jVIzmF23uZ7hiH/sVP49D7tvoKp4S8b1LuvRlivVB/algbhcFITYVXvDpLzpDfplR2uD5V4XJFxpjmIpLc9Y5sB2TpBRix7Bme6GZIq+06v3XzNeTcA4obQIKxrnT4C2JpOqD92dbmSX8MGazly5EsZVMvSU1f4RZwyu8iQXbVdeLlZrjuTT1jrY1uk5c7iZ7RsvhhluqAkq4JpVQAg7RJFtSu+xgJ8Pv6O1j5DkLxT8mkbfyRW5DrQmG7hiDIjCgBsADbjuof6YHLGeV6a5Q1Smx9joUXPpdaaDx97A/Wq00oJkdR7ZYuQRfS533JtxO1erduqWOYIt3wh0wpbLuCNIYkwxbswbikCUu2CDCS+Q+7rgVtfRcm+SOcdKPRlZ/rE7wNVUEE39KTS5uvUKN1PUnkloPkyzhyGQ8qkouEjJ3H/VXdqG6asSRiw3ecMlBvDDt8dDhBHXMwZ2Cajzjr7/76T+IavqPYvz6r7//E/3X3+N//h/0QozbjPgPiir69P/8X3/9F/yv8b/827/++98WItPu5/Hvwd8YPf5bp/2/lX/T/+Of/0MJ/lYTa+L/Ef+d9vN/3/2T6P/+jyTzu/evf6U7vxN7B6pJkRtAF6jUr8I+P8RsP/ptGhfqFk+pQ/DgAy6NJtRYJdXmp4gK7WLqLKJ+MaKhGjOojvL+SnIWrkpy0SLHDe4QuyNzaEA15mLMCcmE8Em+4HdOihW4/ZWuppJEmzeAwcDtv7MuLc9y2V5atvxXNe3S4DUMt5/Qy2LM9kSYKiVWBuKlfp4nxTntpuW03JbIlkiRvBXmT23g1I2OYe6IizUHPIq6zm6mbfsbteKmi/sg9J+ocQBMctGFO7iljo8TPN+z3jxw4do+ZwfqoR9dkNTKHyM305GpTkfhcHexVkPVGEbUOjuo9f0UMPHBFlGEx0SLvJvVRKTwW7PSew5oPme+E42+frJa9cGt2njS3dK5kIif2eYbhuSEQXEqMVfUjhGIuin0G0/W5ezJyJQy3SpMLai4M0JUWb5u1k9tny5bd1pPwYBpQuDCXZl62xg4CdVEAtflXHs6JKmP/pH6mOl796Lgopj0o8d5kKh00hxG3OSdEE/QBo9Hgr8JJqAeLDwJohG5j/DGh61Rc/+tf22/8kEnxHNCEjo0ElvvGfESZkqmz2BDcKV1H1buSkhkdg7p1IMGs2s17nYjpblrWuE2K9WEO/hcRp5e9oOF/QBmOaDtgil+oaU6szPrdwW65fOB0KUTsVUn7LFU7J8e6cxJIl9+FHw5MQMzuQJ+4oxMH3iW/5GK+hWuG0T+gTLs+fAjdtUd58TmIUq04EeyRCYCjkldow234aIgR5bqwrtZosZ+6YEqAmDqatJ9lWasz4IquKALPtd92hGI3Z2BdzzZue+REl1Om4DIWD+RrtUTOJLI+S0jHowXXdAxsGLSd40zYNuEUlOGhrwL6c7tcOtUOvpJCP7QBQS19H+GvZn05ewjlVLz+IGKoC9TyfQjLMBNmXCuqqtTdOSukZW48B0HqgSTCBrBnlFvF4CG2Su7yFzqmJFURK3UmTT3ru050r0ptUpMilYnBJWfl2Bv6kPlUuE1kxxpdzui9AubsR2N2boVSu81OulAwBqoSr1LZ0LLYOomyZHmjqnXlP72s8LnDouEJjtodBvdHaG1jMySYO7crWd90MpCRyCG14vb5IE7Arupw/y/RcCm/Tm3zK6zYj8PYNaGldiUfkB/LHWcmf2lVM+mwyU27a0qq2tscrQ/vzBjN26DnntIrOyGizzXK35yKQdYnUABkyN4saz3WD/viF+eCcsXnIajdWYJWaYHRstIis9CS+tqnFGmz2j5uzfr3Z4prqgK4XOT/PyftvjZqIm8lhkfxJ7Ol3CJF1piYBGAG8wtAk56Drw1YwmOpcz+NdfkSpSLplRXLXHL0Rquj6YW/gabqgK7Dgr6NwtH0B/AN7XrN+MVJ6AmXmUuqmQulrNNYPmH0RoDogydOKLo/QbfYNARSQQKISRCzRXU+q9WWJFL3LZW6u34CkeG97xC0NNGaJ0bvK6SnZS3zPskr5EtuCgjMWR5o2x5BqhKmDWJPRe7JMEOyRb5uUKlHaGVtq5ivSOaSliSXp9SQm2qk8MRJh10MAp9QQ2H5t59J8rjiwSZtoIfMGjlLPVNdYl/LBR0AO6WLGDmkLkIPRE45Y9MftdAK/yNu1Hn6tzOQTesgQ+8fSzB19wO91vCnO23vOWQdwJ63SJrYjdfKFW6W281PKs2k8iT9ai1cgJ4sa3xqdvmtxR8/+D1B8AKc2u+6JftryRhMWSQtoSBgIyyQGyxcnELuAasXN12oSriU4RMz1DD6RL0TSV+om7i1Yt+jEE/jnawM8cX/UhN4nkiv/w9eALrzNhXuQfOzFL0Fi6SjF7/4Qn8rLYBoa85cvgAnkCEBP+HPbEnquVXCZsMS/yzYw2Vru60P/+nJPYKkzZFjmbykzUoEqV836T5q3fP/L383dF82tx18/AZgZczMAgyeWYKmSZIqtHL+e+O4ZRcq9VI3g/qPeCoiK4pcgEqdbS0S/Be54sbVQOuJVPNBblIghzeasNu7h/g+Sz1IdhI5lCwq1nUb3Ji4OCIcqQZqtqJ5w7rXrg/DA9IgVmEGhDgGecEwnCTHffXcXs0V3OCEVzYDKS1vp/oX+ng+6XVU86UjA6FMO2RXOOOrqY1GgPvrAk9HV/BXtCu5RuwF8qgdGDLsBcui4E33ymdBip1X8uKyhIWT8qNRDsXz+gvO9UiEC0d8RG4Tf2x8H4slljgHtCBcxHLTWOYJm5H/fCPCzOgf9qgOUxTRZ0Pc6ha5yLuLVT9ntvIa6gacE99mCovdUumTQdRP4RPsS9129eEe2uSvvGh0bV4Y3QPPhPZMqhZWSMa5R0Hc1SGO4IVOQc0FrirlibTVfKRrYkD8kz3b+X65/QkUNaZdrdl3mCap0Hf3YcCw/LiouJYNbqz88UqeDYv93yO7vvXtgl4XCyAO4ODkY6W+83+LZU//p3/zXNGGrUKClCiOnL27iJZbNWDF02XXAOeFlB7IaADoMH1Yqr+UP9biyZDEa/iJt4MDeIz6GKTdLVBfWGVtRN4fdT2rgReX8UXwF2zOrradm4J0nyTgdPnai3RvzpZvCKDUqjOwD/QA6EDaMCLewX6QWYVnHY1sx1bd8ovYnPm1ZvPH+rE20lWjOCnZ66/xDt0QAl15FjfBcZp+i9OU0RNPQ0t3x2pSNWo8eiYudwsnuP1Hq6iH1LJCJynkYsfgJ0p3pF6SoQk2l+jqE8CPk+ziGJRSKjs+W5AO185umPdkYzlK4wl7TC9NxyyDP7ZoyYVoXiuS6SjnInlLWrwz1i8bGTKXX0AVQWkSfIlglW3zRJRJ8bg5VgE6ZEnqNu9B++0GNQvDQJvFize4ESNKBJP+8vA3LM4AX5SIBq08Mob+7QMTCZx4nwP/64+4BnlZC+8WtlP/CXw6t1PwMwkJ3jhP1FiXLhDF/3I6FGUzO2DSi9ABxKyyL9paZxSEz40ZCPQToDAJu1959k7QdbVxgB4icsu2s4zsTPJhcEDo+N1GX4zSk/wriRh8AqwL62972i9HJHd1ydaLXVzvKvOfGGw5RVcUVMiKXFH4APdkQU/dc5BX0YfKTNZYXCW9mb8bc8mufoQP6BbdQmT99ZjoYfr/go4TgQX9IDgztim7wyFeGMfbNaeqj8Dzs38pgcqwSv2hbqB3oSGKWKy+sesY7p57wAHldqE6NDudk/W7s/zjrK4rZFlFvaGxnSZdHbc1y47qDN6xkoK8O3bfr2j41dlJZ71rB4dlDqapPFa8N6xBrprUdtenUCHwxKNhw1uuTBh+9uU45k4REpQABN2bAO9DSLqoIL26gNroWgup5pUMxHUNSq4Gyz47vBPvilpo5f9OYI2ddAqTqmnxXERxQJ3UK8fHbVE9HagHi3+tqNRoNsArdmAxHA5LwtQo9ZAaNKUTljnokljo2x8scqVpEEIPc01fPCdHOCg0DeWBz8D5TVAAfx8aRH5X2ZYNI3ebKDZdeJ+oBDAxmRqJ30Eh2/DaeAy5diVNMpEDmXiPDsGTzBLXy8eVDdJoIafgx/gxMyQi454QrW56nCyeELgSuNNEmYkflF+t3CZQOVRWjKhIuCclmQSlAXT3+4JGG75B4t/5hQ+ldMP4LsAW6z3XmU6IJJwpnGVnsgUZhoY1fZlwTR8wSU7xRejf2uCx9Z5trVTRRJP9KnEb134dEieil6eCOGWgboI7xsqsqM99jfJLTePjygKlH2CVxxsse9QRzTBFjD/Kjqitr/CCTBt/SJ6nLxz7cKP9pFqBpp0lN5y+adKNsZjrPuroemZauH9aTTFD3EKHW8S55XBLFQAt1jgxTQCTwxmx/JyfsZDN1RroN3VaxpSenpIX7K+ZbL8VdlQDcI4Cbzg3QJLa9yVqNxUelu+EtxLVqeekaAvSJkO6sSVqbUajxqhKshNpvZqoeApF0k/0P0ikkwUcbdwc4A1ejN7Oo0O15kG7hTMoK3hZRBCX7YYeLW0wvcXx/18n/u37yLgzBYVBUvORGli+sfRcX/74uD6P4hq+7xu54TlWJLFzT63uwUDwuEDdOjJQqx7JV+ZjaEAPi7t0MMrR4Q8Rkf18uxD6RK0RKh0hL8YU+DeL97i4pa5ZSyAfXKwZRS/8gXcxdZXm62RBDj8U3sN8x95b5PpPs/mCBKYvpaA50pN5Ct/499AFTtwQ5vgeSh+NHrKIi4NVpwM/XzRaNfJD856lPE6M21zWPguFsH7jbLVyEDfRmt4VwrhCJ5VTYmcSPfGgO5clfN+vbaDZ7sakU5+2vZ2WCDY031NxJarVytfDDVtiafcTGO2rJ/taoL3zChN2qmjxofczTOYQPPVQPh0JVtYgdUQINcSiNEEy58UdYXX1MpWUCEBx7LbcGtAm8XWRQTVOaoV3ySri4RShhs/B/0m4jX6OAwXOvcA09bNSG4czEGv/Wey6V/jbTCNTW6awXdNTcA1GsPe1E9fZdGl7R0vyoVpIdJtfC6d32NNErrvq/R+d65VG+YOwRXppXxOCYyGNSf1K3x6VxAW/vtz4EC1SgCOSPdN62sLsoIzuDfg8GwZAbquVO8HIuFP/ToVoeUB7nnwMF35a1wK1tI6fkrqFKhQdeJpwyls0pIy8AZde3/6LUUbFaYJthyUJSU/kqDXTLQElnn0Jr4B2RVghNrmNmoEn7pXIeshPguXVsvwoTdmClq49JJU3LWhHyWTrJL9bRP6VKv3tZoA/th77p5Jw++OEENvyvWy/pNeExiDUVQaXIRGh8xySZTI36yueFaSXo1uJY0RnXYgEOoWWOJHeaVuX/bGNhHsh2yinznl/++NJcE9j6fBPRcBdq9hb8awNw8U7Bl6GM7x69EDOIIbX/npZ++amlHR9L/35mE/2Ss4gb0xCcY4VyTFLRE796vHysLAamqcyO+aFQyJIDBNslbH2/MrAvZiSEIedc/cqjmv4fbda2pXbv+F5a2szSsdkm9noiNURXt8edUhGUF6fSZWd1IJaXKFwD+49R6eCXD4Bkef7j9tRtNMVgW8BhRz/Qpy1TmeYk0doyjZoJSbePOReVHgkFsCFuQJ+Lgc4BxeAsK/cOiNDRmdNw0ctYhn/nQ498dYI5znzGLoJi1rav7Cn88rL3wLePVtDK5gl77Tki3gHEsIAQ2+IKgarj7Y8W1IQzV5V9N+0TjLqbg68WfKcOmBCOj3JkwJhVIkwDhc+JorXuZEPMEh0vvH3x7iqf+VAwXgd4diZiaJD1zHL9Snx6Wfg4IugreyhabQkcir+y5XgDtdx3Avs7lkeeCBwDvZoTUCXx5QrZkcEqWfYEiEYRs/EphmRALSNGR1Iclgdr5VFoELpzF4++f35w3/j0t5ucW3n2ch4PQCLuUXupsPRR7UA5FjSKrMtPcKAZJfagO4lGE7FH3YKMjorpK0ZxAv+i2JkJhtAMWWWFej4RhPR/cJ3DxwocCvXDi4SGZU4cu+K32XndiFWgopAl+0GApcwf1XvymJcFs39jExIBO4yUjU9MExBLQYc9H+W7+IgdESPRpciT+rKZPebVtaVq+1GYO/5xTAL3HASjNTGIgMvdjWbgc7JvdE1zIFpuC0U9ESiZyzBixzxWxj4Kwh8My34q+FK3KNLtmsA1qyrmKSNQOXCPUZd+ONelBTvFoUI/CYsqa/RhtKiyMf2CgSFqEPk59Y3uqnlZ8gFpswfSYyko23yVZYxzKGxGm49Zqxg1l8oz5Ra9XaRwHkuxepmgyhm0SoNy2KlbcEqK+9QqS9PNx9Ihm9U7gsR55SSJ1FBDNnkuWKxIZ0SDpXuOGwZdoUbOMDPHP4vBAgz2VlSEJAHZGJVbYIg7l/FO5KfIVvxC8pPPxMGcNMoevFDeStt2iqztE10n2TA4dgJH76YS9HDhKHD3iCx6ieFX84BAI3QQnngh76f5ruPQVbr5qZmck/5UjDc26lfrOvUBWy0Ogl8bCoOkMOns81TnC3cuUS9KW8+9A+fe3XYZOFUPG1u5epSSmDLw0s5s2F0W30ANeo+zJkJQz9SPZgzwYpEoktofhGVfmLOAB20boCbW1QWq/NpET/hnMecw/uSyAH4NJc3ECOU4nnkK1fj3S/i5dwb3R7k00AqQQUwt7Ie1qV0aY/VQX0J8hLPy7eBNXMHYZYDNxHZ2Qh6AuXJxq+AeRec/Q+JLhZV6hpXwQEzw7bf5v9uUf2vpq3qlhmy0IIGTkwYdCfSAFmqbdo+3XvDTDjFJde0mbeQLcn2n31xaAqJ0ixO/CLsT4I4G4DoncVTgRGNBtsCcjISWT+oeXZ4Iedw/8OsJI1aPnNKLX/60VvcZb94uasRxCkqlPQ11u1Sa2hHvB80WQENxVyzjns0/PiEByyil21Te6oisk3mNCEMrhouCFO3yEZTHHOCMy9eb/4Tmi8cVf3Lf7P53SY2hX3PSN033As3ETIMLHWumWEO9JXHA2y2SIBlIPpLGG2qvNsCIlIr+B1SWAqRKm2w6Blf7U+zCSBwJrfHG5i8J5Gax/cVonMlon7aHJX/gSvucIncRP93XCqkv7D8IFKFsLiBgHqUpXhE3pYjEcV1dk/JD9zFVCfEaQIVX8Jmfz7IIofcBKQ4OaG+C3xC2veX9CD+iAFXDNaGg9eTVxvkbJRJlW4Nk9Wk13kn696jWppRDe/8pDrYMO9ZyxZ98ReKSz9kWKLLyk2zCZgAniCkLJVX3n1M9DYbomyahWiv/KixRIV9hj/oFz87I+HLznbPTjpa+D+bZQnMuRsljTpv90vQUt/pK7jCFnA30B/jtroSF2/m/gpWn1aQs5WeA6ghzF8SdqWI20fghdSeDOCSCmLgTkfaGgGDmw7nHFkRzGtag57IHS2na06I+gzEphXo1w/Zx2BM/jKL2nZoFjHggtFQjYi8nSVRSXIE58RPbBObXk7uuIL9+rs/5Zo7suJInEUxgsiZZAWS25iBtpEiZeBgDtghEoAE0sjcayNq85M4tbu/LF5h51335PsGzQ09O875+vUS89lkWMyNOFoip2PuyWyMP/iU2XIZdfCCJNDjebDoBLQdpy7QQZC7s9c0wjHJervQNDu2jWzBW5MSAJMr7bP+Iv92BkS/GGgzjEn7MF1IRKFwwzbjbS4/slGOmhx9cZrFu7HSEefojNv3r0UaKfKOWzXsq1zEugbzlMDFsacRJJI/iJlK3vtkZ+PLZIVMFlKA32wbq2Kd5T0uCLZ1CPkAfCdzkz2EYscjDcZq2AWfziN2covN4kXE1lQXPPLTNM1xx3tbiepcO/t3SWm4w87qfh99SL0ZnY+LKFPLPeXVM2mIIoVWt+9Nk0I7nY4O79iGYqxZ8RVz289an6NVdJWnSKZvJQCAuHNiVaDxPAFoH392t9wot5t0/qmU95eEWNbU2udUW5sN9JVqcYlvAIfLeYC33oUzzxZgSktsv21mA7Uly1FA5VnoJFh6N244Wmv3YJGFv/TCPryaw+ZORlpZjQdq/2DYXr3EZskfed0G61P09ipTKmlTQ1067Rg5+PAk5FlQ9e0SWbGf2B/08kqymOTMVOznsALHHNFH4LFRKl2F/NOiYFl9khNHnSu9Ak5sq26Ynl/i2fdTle29Y1ugqmR5Yj4YT9pvslFyYCbw0mNFr5rVQm1LvkG27QMq9ph3t8fmn6r6SQ4oSbr5tz+J1kIawGzDxb6VYOvvWhobDTXfBeNv3b4aNm5XUinsCGqG2q/45m3+LoCOsddFceYhRx1Tsss9PLdPfJdErFMjYd3gddjiP0+XQjcRadZP6bwNLySvunFf20Czy6JqdEW2a96KxdYdOryBv1BjbuUq2yCHeh+6sk7fGmmPi50pe/1l5TyPe5oHW9oPnhPswLyf2TFDdCyYlhwBCstv5C1HwlW7xWoGT9XZt4qVj5WryLPLLD6h/5cMLEjWzgCeAIKNsLak92aBqBsHl4AJwl2N4jfvbSkBExGimv0nFvv09uDScQbjx+w4kPQjgjlW+g9ws9VEJvI2k8N6XxVu0uIwovgTFdunG24gBtaDi+y1YLQwZ8mwbip5fVlO3k0n0AEr/ETbtu8Vjkm+nNSiEb7X/3fMjBL5A8PdgG+/FnbexbFFExmEfetXAnisEKy5z44WVPpQZjSy/jzeGn4yDRsFGqhh87QPaDBWhlo37IFbe/C0xynS91d2tP/AJoJS0sVF6iwAAAAAElFTkSuQmCC\");\n}\n\n#menu::after {\n  display: block;\n  content: '';\n  padding-top: 80px;\n}\n\n#logo {\n  position: fixed;\n  bottom: 10px;\n  right: 10px;\n  background: rgba(255,255,255,.1);\n  font-size: 11px;\n  display: block;\n  width: 20px;\n  height: 20px;\n  line-height: 20px;\n  text-align: center;\n  -webkit-border-radius: 20px;\n  -moz-border-radius: 20px;\n  -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);\n  -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);\n  color: inherit;\n}\n\n#menu li a {\n  display: block;\n  color: white;\n  padding: 0 35px 0 25px;\n  -webkit-transition: background 300ms;\n  -moz-transition: background 300ms;\n}\n\n#menu li {\n  position: relative;\n  list-style: none;\n}\n\n#menu a:hover,\n#menu a.active {\n  text-decoration: none;\n  background: rgba(255,255,255,.1);\n}\n\n#menu li:hover .cov {\n  opacity: 1;\n}\n\n#menu li .dirname {\n  opacity: .60;\n  padding-right: 2px;\n}\n\n#menu li .basename {\n  opacity: 1;\n}\n\n#menu .cov {\n  background: rgba(0,0,0,.4);\n  position: absolute;\n  top: 0;\n  right: 8px;\n  font-size: 9px;\n  opacity: .6;\n  text-align: left;\n  width: 17px;\n  -webkit-border-radius: 10px;\n  -moz-border-radius: 10px;\n  padding: 2px 3px;\n  text-align: center;\n}\n\n#stats:nth-child(2n) {\n  display: inline-block;\n  margin-top: 15px;\n  border: 1px solid #eee;\n  padding: 10px;\n  -webkit-box-shadow: inset 0 0 2px #eee;\n  -moz-box-shadow: inset 0 0 2px #eee;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n}\n\n#stats div {\n  float: left;\n  padding: 0 5px;\n}\n\n#stats::after {\n  display: block;\n  content: '';\n  clear: both;\n}\n\n#stats .sloc::after {\n  content: ' SLOC';\n  color: #b6b6b6;\n}\n\n#stats .percentage::after {\n  content: ' coverage';\n  color: #b6b6b6;\n}\n\n#stats .hits,\n#stats .misses {\n  display: none;\n}\n\n.high {\n  color: #00d4b4;\n}\n.medium {\n  color: #e87d0d;\n}\n.low {\n  color: #d4081a;\n}\n.terrible {\n  color: #d4081a;\n  font-weight: bold;\n}\n\ntable {\n  width: 80%;\n  margin-top: 10px;\n  border-collapse: collapse;\n  border: 1px solid #cbcbcb;\n  color: #363636;\n  -webkit-border-radius: 3px;\n  -moz-border-radius: 3px;\n}\n\ntable thead {\n  display: none;\n}\n\ntable td.line,\ntable td.hits {\n  width: 20px;\n  background: #eaeaea;\n  text-align: center;\n  font-size: 11px;\n  padding: 0 10px;\n  color: #949494;\n}\n\ntable td.hits {\n  width: 10px;\n  padding: 2px 5px;\n  color: rgba(0,0,0,.2);\n  background: #f0f0f0;\n}\n\ntr.miss td.line,\ntr.miss td.hits {\n  background: #e6c3c7;\n}\n\ntr.miss td {\n  background: #f8d5d8;\n}\n\ntd.source {\n  padding-left: 15px;\n  line-height: 15px;\n  white-space: pre;\n  font: 12px monaco, monospace;\n}\n\ncode .comment { color: #ddd }\ncode .init { color: #2F6FAD }\ncode .string { color: #5890AD }\ncode .keyword { color: #8A6343 }\ncode .number { color: #2F6FAD }\n</style></head><body><div id=\"coverage\"><h1 id=\"overview\">Coverage</h1><div id=\"menu\"><li><a href=\"#overview\">overview</a></li><li><span class=\"cov high\">98</span><a href=\"#lib/asn1ber.js\"><span class=\"dirname\">lib/</span><span class=\"basename\">asn1ber.js</span></a></li><li><span class=\"cov high\">95</span><a href=\"#lib/snmp.js\"><span class=\"dirname\">lib/</span><span class=\"basename\">snmp.js</span></a></li><a id=\"logo\" href=\"http://visionmedia.github.com/mocha/\">m</a></div><div id=\"stats\" class=\"high\"><div class=\"percentage\">96%</div><div class=\"sloc\">473</div><div class=\"hits\">457</div><div class=\"misses\">16</div></div><div id=\"files\"><div class=\"file\"><h2 id=\"lib/asn1ber.js\">lib/asn1ber.js</h2><div id=\"stats\" class=\"high\"><div class=\"percentage\">98%</div><div class=\"sloc\">156</div><div class=\"hits\">153</div><div class=\"misses\">3</div></div><table id=\"source\"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class=\"line\">1</td><td class=\"hits\"></td><td class=\"source\">// This file implements a minimal subset of Abstract Syntax Notation One (**ASN.1**)</td></tr><tr><td class=\"line\">2</td><td class=\"hits\"></td><td class=\"source\">// Basic Encoding Rules (**BER**), namely the parts that are necessary for sending</td></tr><tr><td class=\"line\">3</td><td class=\"hits\"></td><td class=\"source\">// and receiving SNMPv2c messages.</td></tr><tr><td class=\"line\">4</td><td class=\"hits\"></td><td class=\"source\">//</td></tr><tr><td class=\"line\">5</td><td class=\"hits\"></td><td class=\"source\">// (c) 2012 Jakob Borg, Nym Networks</td></tr><tr><td class=\"line\">6</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">7</td><td class=\"hits\"></td><td class=\"source\">&quot;use strict&quot;;</td></tr><tr><td class=\"line\">8</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">9</td><td class=\"hits\"></td><td class=\"source\">// We define constants for the commonly used ASN.1 types in SNMP.</td></tr><tr><td class=\"line\">10</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">11</td><td class=\"hits\">1</td><td class=\"source\">var T = {</td></tr><tr><td class=\"line\">12</td><td class=\"hits\"></td><td class=\"source\">    Integer: 0x02,</td></tr><tr><td class=\"line\">13</td><td class=\"hits\"></td><td class=\"source\">    OctetString: 0x04,</td></tr><tr><td class=\"line\">14</td><td class=\"hits\"></td><td class=\"source\">    Null: 0x05,</td></tr><tr><td class=\"line\">15</td><td class=\"hits\"></td><td class=\"source\">    ObjectIdentifier: 0x06,</td></tr><tr><td class=\"line\">16</td><td class=\"hits\"></td><td class=\"source\">    Sequence: 0x30,</td></tr><tr><td class=\"line\">17</td><td class=\"hits\"></td><td class=\"source\">    IpAddress: 0x40,</td></tr><tr><td class=\"line\">18</td><td class=\"hits\"></td><td class=\"source\">    Counter: 0x41,</td></tr><tr><td class=\"line\">19</td><td class=\"hits\"></td><td class=\"source\">    Gauge: 0x42,</td></tr><tr><td class=\"line\">20</td><td class=\"hits\"></td><td class=\"source\">    TimeTicks: 0x43,</td></tr><tr><td class=\"line\">21</td><td class=\"hits\"></td><td class=\"source\">    Opaque: 0x44,</td></tr><tr><td class=\"line\">22</td><td class=\"hits\"></td><td class=\"source\">    NsapAddress: 0x45,</td></tr><tr><td class=\"line\">23</td><td class=\"hits\"></td><td class=\"source\">    Counter64: 0x46,</td></tr><tr><td class=\"line\">24</td><td class=\"hits\"></td><td class=\"source\">    NoSuchObject: 0x80,</td></tr><tr><td class=\"line\">25</td><td class=\"hits\"></td><td class=\"source\">    NoSuchInstance: 0x81,</td></tr><tr><td class=\"line\">26</td><td class=\"hits\"></td><td class=\"source\">    EndOfMibView: 0x82,</td></tr><tr><td class=\"line\">27</td><td class=\"hits\"></td><td class=\"source\">    PDUBase: 0xA0</td></tr><tr><td class=\"line\">28</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">29</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">30</td><td class=\"hits\">1</td><td class=\"source\">var P = {</td></tr><tr><td class=\"line\">31</td><td class=\"hits\"></td><td class=\"source\">    GetRequestPDU: 0x00,</td></tr><tr><td class=\"line\">32</td><td class=\"hits\"></td><td class=\"source\">    GetNextRequestPDU: 0x01,</td></tr><tr><td class=\"line\">33</td><td class=\"hits\"></td><td class=\"source\">    GetResponsePDU: 0x02,</td></tr><tr><td class=\"line\">34</td><td class=\"hits\"></td><td class=\"source\">    SetRequestPDU: 0x03</td></tr><tr><td class=\"line\">35</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">36</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">37</td><td class=\"hits\"></td><td class=\"source\">// The types are also available for consumers of the library.</td></tr><tr><td class=\"line\">38</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">39</td><td class=\"hits\">1</td><td class=\"source\">exports.types = T;</td></tr><tr class=\"hit\"><td class=\"line\">40</td><td class=\"hits\">1</td><td class=\"source\">exports.pduTypes = P;</td></tr><tr class=\"hit\"><td class=\"line\">41</td><td class=\"hits\">1</td><td class=\"source\">exports.unittest = {};</td></tr><tr><td class=\"line\">42</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">43</td><td class=\"hits\"></td><td class=\"source\">// Private helper functions</td></tr><tr><td class=\"line\">44</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">45</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">46</td><td class=\"hits\"></td><td class=\"source\">// Encode a length as it should be encoded.</td></tr><tr><td class=\"line\">47</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">48</td><td class=\"hits\"></td><td class=\"source\">function lengthArray(len) {</td></tr><tr class=\"hit\"><td class=\"line\">49</td><td class=\"hits\">345</td><td class=\"source\">    var arr = [];</td></tr><tr><td class=\"line\">50</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">51</td><td class=\"hits\">345</td><td class=\"source\">    if (len &lt;= 127) {</td></tr><tr><td class=\"line\">52</td><td class=\"hits\"></td><td class=\"source\">        // Return a single byte if the value is 127 or less.</td></tr><tr class=\"hit\"><td class=\"line\">53</td><td class=\"hits\">339</td><td class=\"source\">        return [ len ];</td></tr><tr><td class=\"line\">54</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr><td class=\"line\">55</td><td class=\"hits\"></td><td class=\"source\">        // Otherwise encode it as a MSB base-256 integer.</td></tr><tr class=\"hit\"><td class=\"line\">56</td><td class=\"hits\">6</td><td class=\"source\">        while (len &gt; 0) {</td></tr><tr class=\"hit\"><td class=\"line\">57</td><td class=\"hits\">8</td><td class=\"source\">            arr.push(len % 256);</td></tr><tr class=\"hit\"><td class=\"line\">58</td><td class=\"hits\">8</td><td class=\"source\">            len = parseInt(len / 256, 10);</td></tr><tr><td class=\"line\">59</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">60</td><td class=\"hits\"></td><td class=\"source\">        // Add a length byte in front and set the high bit to indicate</td></tr><tr><td class=\"line\">61</td><td class=\"hits\"></td><td class=\"source\">        // that this is a longer value than one byte.</td></tr><tr class=\"hit\"><td class=\"line\">62</td><td class=\"hits\">6</td><td class=\"source\">        arr.push(128 + arr.length);</td></tr><tr class=\"hit\"><td class=\"line\">63</td><td class=\"hits\">6</td><td class=\"source\">        arr.reverse();</td></tr><tr class=\"hit\"><td class=\"line\">64</td><td class=\"hits\">6</td><td class=\"source\">        return arr;</td></tr><tr><td class=\"line\">65</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">66</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">67</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">68</td><td class=\"hits\">1</td><td class=\"source\">exports.unittest.lengthArray = lengthArray;</td></tr><tr><td class=\"line\">69</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">70</td><td class=\"hits\"></td><td class=\"source\">// Return a wrapped copy of the passed `contents`, with the specified wrapper type.</td></tr><tr><td class=\"line\">71</td><td class=\"hits\"></td><td class=\"source\">// This is used for Sequence and other constructed types.</td></tr><tr><td class=\"line\">72</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">73</td><td class=\"hits\"></td><td class=\"source\">function wrapper(type, contents) {</td></tr><tr class=\"hit\"><td class=\"line\">74</td><td class=\"hits\">266</td><td class=\"source\">    var buf, len, i;</td></tr><tr><td class=\"line\">75</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">76</td><td class=\"hits\"></td><td class=\"source\">    // Get the encoded length of the contents</td></tr><tr class=\"hit\"><td class=\"line\">77</td><td class=\"hits\">266</td><td class=\"source\">    len = lengthArray(contents.length);</td></tr><tr><td class=\"line\">78</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">79</td><td class=\"hits\"></td><td class=\"source\">    // Set up a buffer with the type and length bytes plus a straight copy of the content.</td></tr><tr class=\"hit\"><td class=\"line\">80</td><td class=\"hits\">266</td><td class=\"source\">    buf = new Buffer(1 + contents.length + len.length);</td></tr><tr class=\"hit\"><td class=\"line\">81</td><td class=\"hits\">266</td><td class=\"source\">    buf[0] = type;</td></tr><tr class=\"hit\"><td class=\"line\">82</td><td class=\"hits\">266</td><td class=\"source\">    for (i = 1; i &lt; len.length + 1; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">83</td><td class=\"hits\">271</td><td class=\"source\">        buf[i] = len[i - 1];</td></tr><tr><td class=\"line\">84</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr class=\"hit\"><td class=\"line\">85</td><td class=\"hits\">266</td><td class=\"source\">    contents.copy(buf, len.length + 1, 0);</td></tr><tr class=\"hit\"><td class=\"line\">86</td><td class=\"hits\">266</td><td class=\"source\">    return buf;</td></tr><tr><td class=\"line\">87</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">88</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">89</td><td class=\"hits\"></td><td class=\"source\">// Get the encoded representation of a number in an OID.</td></tr><tr><td class=\"line\">90</td><td class=\"hits\"></td><td class=\"source\">// If the number is less than 128, pass it as it is.</td></tr><tr><td class=\"line\">91</td><td class=\"hits\"></td><td class=\"source\">// Otherwise return an array of base-128 digits, most significant first,</td></tr><tr><td class=\"line\">92</td><td class=\"hits\"></td><td class=\"source\">// with the high bit set on all octets except the last one.</td></tr><tr><td class=\"line\">93</td><td class=\"hits\"></td><td class=\"source\">// This encoding should be used for all number in an OID except the first</td></tr><tr><td class=\"line\">94</td><td class=\"hits\"></td><td class=\"source\">// two (.1.3) which are handled specially.</td></tr><tr><td class=\"line\">95</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">96</td><td class=\"hits\"></td><td class=\"source\">function oidInt(val) {</td></tr><tr class=\"hit\"><td class=\"line\">97</td><td class=\"hits\">3</td><td class=\"source\">    var bytes = [];</td></tr><tr><td class=\"line\">98</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">99</td><td class=\"hits\">3</td><td class=\"source\">    bytes.push(val % 128);</td></tr><tr class=\"hit\"><td class=\"line\">100</td><td class=\"hits\">3</td><td class=\"source\">    val = parseInt(val / 128, 10);</td></tr><tr class=\"hit\"><td class=\"line\">101</td><td class=\"hits\">3</td><td class=\"source\">    while (val &gt; 127) {</td></tr><tr class=\"hit\"><td class=\"line\">102</td><td class=\"hits\">1</td><td class=\"source\">        bytes.push(128 + val % 128);</td></tr><tr class=\"hit\"><td class=\"line\">103</td><td class=\"hits\">1</td><td class=\"source\">        val = parseInt(val / 128, 10);</td></tr><tr><td class=\"line\">104</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr class=\"hit\"><td class=\"line\">105</td><td class=\"hits\">3</td><td class=\"source\">    bytes.push(val + 128);</td></tr><tr class=\"hit\"><td class=\"line\">106</td><td class=\"hits\">3</td><td class=\"source\">    return bytes.reverse();</td></tr><tr><td class=\"line\">107</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">108</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">109</td><td class=\"hits\"></td><td class=\"source\">// Encode an OID. The first two number are encoded specially</td></tr><tr><td class=\"line\">110</td><td class=\"hits\"></td><td class=\"source\">// in the first octet, then the rest are encoded as one octet per number</td></tr><tr><td class=\"line\">111</td><td class=\"hits\"></td><td class=\"source\">// unless the number exceeds 127. If so, it's encoded as several base-127</td></tr><tr><td class=\"line\">112</td><td class=\"hits\"></td><td class=\"source\">// octets with the high bit set to indicate continuation.</td></tr><tr><td class=\"line\">113</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">114</td><td class=\"hits\"></td><td class=\"source\">function oidArray(oid) {</td></tr><tr class=\"hit\"><td class=\"line\">115</td><td class=\"hits\">76</td><td class=\"source\">    var bytes, i, val;</td></tr><tr><td class=\"line\">116</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">117</td><td class=\"hits\"></td><td class=\"source\">    // Enforce some minimum requirements on the OID.</td></tr><tr class=\"hit\"><td class=\"line\">118</td><td class=\"hits\">76</td><td class=\"source\">    if (oid.length &lt; 2) {</td></tr><tr class=\"hit\"><td class=\"line\">119</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error(&quot;Minimum OID length is two.&quot;);</td></tr><tr class=\"hit\"><td class=\"line\">120</td><td class=\"hits\">75</td><td class=\"source\">    } else if (oid[0] !== 1 || oid[1] !== 3) {</td></tr><tr class=\"hit\"><td class=\"line\">121</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error(&quot;SNMP OIDs always start with .1.3.&quot;);</td></tr><tr><td class=\"line\">122</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">123</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">124</td><td class=\"hits\"></td><td class=\"source\">    // Calculate the first byte of the encoded OID according to the 'special' rule.</td></tr><tr class=\"hit\"><td class=\"line\">125</td><td class=\"hits\">74</td><td class=\"source\">    bytes = [ 40 * oid[0] + oid[1] ];</td></tr><tr><td class=\"line\">126</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">127</td><td class=\"hits\"></td><td class=\"source\">    // For the rest of the OID, encode each number individually and add the</td></tr><tr><td class=\"line\">128</td><td class=\"hits\"></td><td class=\"source\">    // resulting bytes to the buffer.</td></tr><tr class=\"hit\"><td class=\"line\">129</td><td class=\"hits\">74</td><td class=\"source\">    for (i = 2; i &lt; oid.length; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">130</td><td class=\"hits\">511</td><td class=\"source\">        val = oid[i];</td></tr><tr class=\"hit\"><td class=\"line\">131</td><td class=\"hits\">511</td><td class=\"source\">        if (val &gt; 127) {</td></tr><tr class=\"hit\"><td class=\"line\">132</td><td class=\"hits\">3</td><td class=\"source\">            bytes = bytes.concat(oidInt(val));</td></tr><tr><td class=\"line\">133</td><td class=\"hits\"></td><td class=\"source\">        } else {</td></tr><tr class=\"hit\"><td class=\"line\">134</td><td class=\"hits\">508</td><td class=\"source\">            bytes.push(val);</td></tr><tr><td class=\"line\">135</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">136</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">137</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">138</td><td class=\"hits\">74</td><td class=\"source\">    return bytes;</td></tr><tr><td class=\"line\">139</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">140</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">141</td><td class=\"hits\"></td><td class=\"source\">// Divide an integer into base-256 bytes.</td></tr><tr><td class=\"line\">142</td><td class=\"hits\"></td><td class=\"source\">// Most significant byte first.</td></tr><tr><td class=\"line\">143</td><td class=\"hits\"></td><td class=\"source\">function intArray(val) {</td></tr><tr class=\"hit\"><td class=\"line\">144</td><td class=\"hits\">198</td><td class=\"source\">    var array = [];</td></tr><tr><td class=\"line\">145</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">146</td><td class=\"hits\">198</td><td class=\"source\">    if (val === 0) {</td></tr><tr class=\"hit\"><td class=\"line\">147</td><td class=\"hits\">94</td><td class=\"source\">        array.push(0);</td></tr><tr><td class=\"line\">148</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr class=\"hit\"><td class=\"line\">149</td><td class=\"hits\">104</td><td class=\"source\">        while (val &gt; 0) {</td></tr><tr class=\"hit\"><td class=\"line\">150</td><td class=\"hits\">246</td><td class=\"source\">            array.push(val % 256);</td></tr><tr class=\"hit\"><td class=\"line\">151</td><td class=\"hits\">246</td><td class=\"source\">            val = parseInt(val / 256, 10);</td></tr><tr><td class=\"line\">152</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">153</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">154</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">155</td><td class=\"hits\"></td><td class=\"source\">    // Do not produce integers that look negative (high bit</td></tr><tr><td class=\"line\">156</td><td class=\"hits\"></td><td class=\"source\">    // of first byte set).</td></tr><tr class=\"hit\"><td class=\"line\">157</td><td class=\"hits\">198</td><td class=\"source\">    if (array[array.length - 1] &gt;= 0x80) {</td></tr><tr class=\"hit\"><td class=\"line\">158</td><td class=\"hits\">2</td><td class=\"source\">        array.push(0);</td></tr><tr><td class=\"line\">159</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">160</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">161</td><td class=\"hits\">198</td><td class=\"source\">    return array.reverse();</td></tr><tr><td class=\"line\">162</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">163</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">164</td><td class=\"hits\"></td><td class=\"source\">// Functions to encode ASN.1 from native objects</td></tr><tr><td class=\"line\">165</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">166</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">167</td><td class=\"hits\"></td><td class=\"source\">// Encode a simple integer.</td></tr><tr><td class=\"line\">168</td><td class=\"hits\"></td><td class=\"source\">// Integers are encoded as a simple base-256 byte sequence, most significant byte first,</td></tr><tr><td class=\"line\">169</td><td class=\"hits\"></td><td class=\"source\">// prefixed with a length byte. In principle we support arbitrary integer sizes, in practice</td></tr><tr><td class=\"line\">170</td><td class=\"hits\"></td><td class=\"source\">// Javascript doesn't even **have** integers so some precision might get lost.</td></tr><tr><td class=\"line\">171</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">172</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeInteger = function (val) {</td></tr><tr class=\"hit\"><td class=\"line\">173</td><td class=\"hits\">198</td><td class=\"source\">    var i, arr, buf;</td></tr><tr><td class=\"line\">174</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">175</td><td class=\"hits\"></td><td class=\"source\">    // Get the bytes that we're going to encode.</td></tr><tr class=\"hit\"><td class=\"line\">176</td><td class=\"hits\">198</td><td class=\"source\">    arr = intArray(val);</td></tr><tr><td class=\"line\">177</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">178</td><td class=\"hits\"></td><td class=\"source\">    // Now that we know the length, we allocate a buffer of the required size.</td></tr><tr><td class=\"line\">179</td><td class=\"hits\"></td><td class=\"source\">    // We set the type and length bytes appropriately.</td></tr><tr class=\"hit\"><td class=\"line\">180</td><td class=\"hits\">198</td><td class=\"source\">    buf = new Buffer(2 + arr.length);</td></tr><tr class=\"hit\"><td class=\"line\">181</td><td class=\"hits\">198</td><td class=\"source\">    buf[0] = T.Integer;</td></tr><tr class=\"hit\"><td class=\"line\">182</td><td class=\"hits\">198</td><td class=\"source\">    buf[1] = arr.length;</td></tr><tr><td class=\"line\">183</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">184</td><td class=\"hits\"></td><td class=\"source\">    // Copy the bytes into the array.</td></tr><tr class=\"hit\"><td class=\"line\">185</td><td class=\"hits\">198</td><td class=\"source\">    for (i = 0; i &lt; arr.length; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">186</td><td class=\"hits\">342</td><td class=\"source\">        buf[i + 2] = arr[i];</td></tr><tr><td class=\"line\">187</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">188</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">189</td><td class=\"hits\">198</td><td class=\"source\">    return buf;</td></tr><tr><td class=\"line\">190</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">191</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">192</td><td class=\"hits\"></td><td class=\"source\">// Create the representation of a Null, `05 00`.</td></tr><tr><td class=\"line\">193</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">194</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeNull = function () {</td></tr><tr class=\"hit\"><td class=\"line\">195</td><td class=\"hits\">67</td><td class=\"source\">    var buf = new Buffer(2);</td></tr><tr class=\"hit\"><td class=\"line\">196</td><td class=\"hits\">67</td><td class=\"source\">    buf[0] = T.Null;</td></tr><tr class=\"hit\"><td class=\"line\">197</td><td class=\"hits\">67</td><td class=\"source\">    buf[1] = 0;</td></tr><tr class=\"hit\"><td class=\"line\">198</td><td class=\"hits\">67</td><td class=\"source\">    return buf;</td></tr><tr><td class=\"line\">199</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">200</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">201</td><td class=\"hits\"></td><td class=\"source\">// Encode a Sequence, which is a wrapper of type `30`.</td></tr><tr><td class=\"line\">202</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">203</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeSequence = function (contents) {</td></tr><tr class=\"hit\"><td class=\"line\">204</td><td class=\"hits\">168</td><td class=\"source\">    return wrapper(T.Sequence, contents);</td></tr><tr><td class=\"line\">205</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">206</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">207</td><td class=\"hits\"></td><td class=\"source\">// Encode an OctetString, which is a wrapper of type `04`.</td></tr><tr><td class=\"line\">208</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">209</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeOctetString = function (string) {</td></tr><tr class=\"hit\"><td class=\"line\">210</td><td class=\"hits\">52</td><td class=\"source\">    var buf, contents;</td></tr><tr><td class=\"line\">211</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">212</td><td class=\"hits\">52</td><td class=\"source\">    if (typeof string === 'string') {</td></tr><tr class=\"hit\"><td class=\"line\">213</td><td class=\"hits\">49</td><td class=\"source\">        contents = new Buffer(string);</td></tr><tr class=\"hit\"><td class=\"line\">214</td><td class=\"hits\">3</td><td class=\"source\">    } else if (Buffer.isBuffer(string)) {</td></tr><tr class=\"hit\"><td class=\"line\">215</td><td class=\"hits\">1</td><td class=\"source\">        contents = string;</td></tr><tr><td class=\"line\">216</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr class=\"hit\"><td class=\"line\">217</td><td class=\"hits\">2</td><td class=\"source\">        throw new Error('Only Buffer and string types are acceptable as OctetString.');</td></tr><tr><td class=\"line\">218</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">219</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">220</td><td class=\"hits\">50</td><td class=\"source\">    return wrapper(T.OctetString, contents);</td></tr><tr><td class=\"line\">221</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">222</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">223</td><td class=\"hits\"></td><td class=\"source\">// Encode an IpAddress, which is a wrapper of type `40`.</td></tr><tr><td class=\"line\">224</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">225</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeIpAddress = function (address) {</td></tr><tr class=\"hit\"><td class=\"line\">226</td><td class=\"hits\">1</td><td class=\"source\">    var contents, octets, value = [];</td></tr><tr><td class=\"line\">227</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">228</td><td class=\"hits\">1</td><td class=\"source\">    if (typeof address !== 'string' &amp;&amp; !Buffer.isBuffer(address)) {</td></tr><tr class=\"miss\"><td class=\"line\">229</td><td class=\"hits\">0</td><td class=\"source\">        throw new Error('Only Buffer and string types are acceptable as OctetString.');</td></tr><tr><td class=\"line\">230</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">231</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">232</td><td class=\"hits\"></td><td class=\"source\">    // assume that the string is in dotted decimal format ipv4</td></tr><tr><td class=\"line\">233</td><td class=\"hits\"></td><td class=\"source\">    // also, use toString in case a buffer was passed in.</td></tr><tr><td class=\"line\">234</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">235</td><td class=\"hits\">1</td><td class=\"source\">    octets = address.toString().split('.');</td></tr><tr class=\"hit\"><td class=\"line\">236</td><td class=\"hits\">1</td><td class=\"source\">    if (octets.length !== 4) {</td></tr><tr class=\"miss\"><td class=\"line\">237</td><td class=\"hits\">0</td><td class=\"source\">        throw new Error('IP Addresses must be specified in dotted decimal format.');</td></tr><tr><td class=\"line\">238</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr class=\"hit\"><td class=\"line\">239</td><td class=\"hits\">1</td><td class=\"source\">    octets.forEach(function (octet) {</td></tr><tr class=\"hit\"><td class=\"line\">240</td><td class=\"hits\">4</td><td class=\"source\">        var octetValue = parseInt(octet, 10);</td></tr><tr class=\"hit\"><td class=\"line\">241</td><td class=\"hits\">4</td><td class=\"source\">        if (octet &lt; 0 || octet &gt; 255) {</td></tr><tr class=\"miss\"><td class=\"line\">242</td><td class=\"hits\">0</td><td class=\"source\">            throw new Error('IP Address octets must be between 0 and 255 inclusive.' + JSON.stringify(octets));</td></tr><tr><td class=\"line\">243</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">244</td><td class=\"hits\">4</td><td class=\"source\">        value.push(octetValue);</td></tr><tr><td class=\"line\">245</td><td class=\"hits\"></td><td class=\"source\">    });</td></tr><tr><td class=\"line\">246</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">247</td><td class=\"hits\">1</td><td class=\"source\">    contents = new Buffer(value);</td></tr><tr><td class=\"line\">248</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">249</td><td class=\"hits\">1</td><td class=\"source\">    return wrapper(T.IpAddress, contents);</td></tr><tr><td class=\"line\">250</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">251</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">252</td><td class=\"hits\"></td><td class=\"source\">// Encode an ObjectId.</td></tr><tr><td class=\"line\">253</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">254</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeOid = function (oid) {</td></tr><tr class=\"hit\"><td class=\"line\">255</td><td class=\"hits\">76</td><td class=\"source\">    var buf, bytes, i, len;</td></tr><tr><td class=\"line\">256</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">257</td><td class=\"hits\"></td><td class=\"source\">    // Get the encoded format of the OID.</td></tr><tr class=\"hit\"><td class=\"line\">258</td><td class=\"hits\">76</td><td class=\"source\">    bytes = oidArray(oid);</td></tr><tr><td class=\"line\">259</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">260</td><td class=\"hits\"></td><td class=\"source\">    // Get the encoded format of the length</td></tr><tr class=\"hit\"><td class=\"line\">261</td><td class=\"hits\">74</td><td class=\"source\">    len = lengthArray(bytes.length);</td></tr><tr><td class=\"line\">262</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">263</td><td class=\"hits\"></td><td class=\"source\">    // Fill in the buffer with type, length and OID data.</td></tr><tr class=\"hit\"><td class=\"line\">264</td><td class=\"hits\">74</td><td class=\"source\">    buf = new Buffer(1 + bytes.length + len.length);</td></tr><tr class=\"hit\"><td class=\"line\">265</td><td class=\"hits\">74</td><td class=\"source\">    buf[0] = T.ObjectIdentifier;</td></tr><tr class=\"hit\"><td class=\"line\">266</td><td class=\"hits\">74</td><td class=\"source\">    for (i = 1; i &lt; len.length + 1; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">267</td><td class=\"hits\">74</td><td class=\"source\">        buf[i] = len[i - 1];</td></tr><tr><td class=\"line\">268</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr class=\"hit\"><td class=\"line\">269</td><td class=\"hits\">74</td><td class=\"source\">    for (i = len.length + 1; i &lt; bytes.length + len.length + 1; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">270</td><td class=\"hits\">589</td><td class=\"source\">        buf[i] = bytes[i - len.length - 1];</td></tr><tr><td class=\"line\">271</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">272</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">273</td><td class=\"hits\">74</td><td class=\"source\">    return buf;</td></tr><tr><td class=\"line\">274</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">275</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">276</td><td class=\"hits\"></td><td class=\"source\">// Encode an SNMP request with specified `contents`.</td></tr><tr><td class=\"line\">277</td><td class=\"hits\"></td><td class=\"source\">// The `type` code is 0 for `GetRequest`, 1 for `GetNextRequest`.</td></tr><tr><td class=\"line\">278</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">279</td><td class=\"hits\">1</td><td class=\"source\">exports.encodeRequest = function (type, contents) {</td></tr><tr class=\"hit\"><td class=\"line\">280</td><td class=\"hits\">47</td><td class=\"source\">    return wrapper(T.PDUBase + type, contents);</td></tr><tr><td class=\"line\">281</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">282</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">283</td><td class=\"hits\"></td><td class=\"source\">// Functions to parse ASN.1 to native objects</td></tr><tr><td class=\"line\">284</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">285</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">286</td><td class=\"hits\"></td><td class=\"source\">// Parse and return type, data length and header length.</td></tr><tr><td class=\"line\">287</td><td class=\"hits\"></td><td class=\"source\">function typeAndLength(buf) {</td></tr><tr class=\"hit\"><td class=\"line\">288</td><td class=\"hits\">268</td><td class=\"source\">    var res, len, i;</td></tr><tr><td class=\"line\">289</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">290</td><td class=\"hits\">268</td><td class=\"source\">    res = { type: buf[0], len: 0, header: 1 };</td></tr><tr class=\"hit\"><td class=\"line\">291</td><td class=\"hits\">268</td><td class=\"source\">    if (buf[1] &lt; 128) {</td></tr><tr><td class=\"line\">292</td><td class=\"hits\"></td><td class=\"source\">        // If bit 8 is zero, this byte indicates the content length (up to 127 bytes).</td></tr><tr class=\"hit\"><td class=\"line\">293</td><td class=\"hits\">261</td><td class=\"source\">        res.len = buf[1];</td></tr><tr class=\"hit\"><td class=\"line\">294</td><td class=\"hits\">261</td><td class=\"source\">        res.header += 1;</td></tr><tr><td class=\"line\">295</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr><td class=\"line\">296</td><td class=\"hits\"></td><td class=\"source\">        // If bit 8 is 1, bits 0 to 7 indicate the number of following legth bytes.</td></tr><tr><td class=\"line\">297</td><td class=\"hits\"></td><td class=\"source\">        // These bytes are a simple msb base-256 integer indicating the content length.</td></tr><tr class=\"hit\"><td class=\"line\">298</td><td class=\"hits\">7</td><td class=\"source\">        for (i = 0; i &lt; buf[1] - 128; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">299</td><td class=\"hits\">10</td><td class=\"source\">            res.len += buf[i + 1];</td></tr><tr class=\"hit\"><td class=\"line\">300</td><td class=\"hits\">10</td><td class=\"source\">            res.len *= 256;</td></tr><tr><td class=\"line\">301</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">302</td><td class=\"hits\">7</td><td class=\"source\">        res.header += buf[1] - 128 + 1;</td></tr><tr><td class=\"line\">303</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr class=\"hit\"><td class=\"line\">304</td><td class=\"hits\">268</td><td class=\"source\">    return res;</td></tr><tr><td class=\"line\">305</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">306</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">307</td><td class=\"hits\">1</td><td class=\"source\">exports.typeAndLength = typeAndLength;</td></tr><tr><td class=\"line\">308</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">309</td><td class=\"hits\"></td><td class=\"source\">// Parse a buffer containing a representation of an integer.</td></tr><tr><td class=\"line\">310</td><td class=\"hits\"></td><td class=\"source\">// Verifies the type, then multiplies in each byte as it comes.</td></tr><tr><td class=\"line\">311</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">312</td><td class=\"hits\">1</td><td class=\"source\">exports.parseInteger = function (buf) {</td></tr><tr class=\"hit\"><td class=\"line\">313</td><td class=\"hits\">281</td><td class=\"source\">    var i, val;</td></tr><tr><td class=\"line\">314</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">315</td><td class=\"hits\">281</td><td class=\"source\">    if (buf[0] !== T.Integer &amp;&amp; buf[0] !== T.Counter &amp;&amp;</td></tr><tr><td class=\"line\">316</td><td class=\"hits\"></td><td class=\"source\">        buf[0] !== T.Counter64 &amp;&amp; buf[0] !== T.Gauge &amp;&amp;</td></tr><tr><td class=\"line\">317</td><td class=\"hits\"></td><td class=\"source\">        buf[0] !== T.TimeTicks) {</td></tr><tr class=\"hit\"><td class=\"line\">318</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Buffer ' + buf.toString('hex') + ' does not appear to be an Integer');</td></tr><tr><td class=\"line\">319</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">320</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">321</td><td class=\"hits\">280</td><td class=\"source\">    val = 0;</td></tr><tr class=\"hit\"><td class=\"line\">322</td><td class=\"hits\">280</td><td class=\"source\">    for (i = 0; i &lt; buf[1]; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">323</td><td class=\"hits\">547</td><td class=\"source\">        val *= 256;</td></tr><tr class=\"hit\"><td class=\"line\">324</td><td class=\"hits\">547</td><td class=\"source\">        val += buf[i + 2];</td></tr><tr><td class=\"line\">325</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">326</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">327</td><td class=\"hits\">280</td><td class=\"source\">    return val;</td></tr><tr><td class=\"line\">328</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">329</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">330</td><td class=\"hits\"></td><td class=\"source\">// Parse a buffer containing a representation of an OctetString.</td></tr><tr><td class=\"line\">331</td><td class=\"hits\"></td><td class=\"source\">// Verify the type, then just grab the string out of the buffer.</td></tr><tr><td class=\"line\">332</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">333</td><td class=\"hits\">1</td><td class=\"source\">exports.parseOctetString = function (buf) {</td></tr><tr class=\"hit\"><td class=\"line\">334</td><td class=\"hits\">78</td><td class=\"source\">    if (buf[0] !== T.OctetString) {</td></tr><tr class=\"hit\"><td class=\"line\">335</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Buffer does not appear to be an OctetString');</td></tr><tr><td class=\"line\">336</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">337</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">338</td><td class=\"hits\"></td><td class=\"source\">    // SNMP doesn't specify an encoding so I pick UTF-8 as the 'most standard'</td></tr><tr><td class=\"line\">339</td><td class=\"hits\"></td><td class=\"source\">    // encoding. We'll see if that assumption survives contact with actual reality.</td></tr><tr class=\"hit\"><td class=\"line\">340</td><td class=\"hits\">77</td><td class=\"source\">    return buf.toString('utf-8', 2, 2 + buf[1]);</td></tr><tr><td class=\"line\">341</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">342</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">343</td><td class=\"hits\"></td><td class=\"source\">// Parse a buffer containing a representation of an ObjectIdentifier.</td></tr><tr><td class=\"line\">344</td><td class=\"hits\"></td><td class=\"source\">// Verify the type, then apply the relevent encoding rules.</td></tr><tr><td class=\"line\">345</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">346</td><td class=\"hits\">1</td><td class=\"source\">exports.parseOid = function (buf) {</td></tr><tr class=\"hit\"><td class=\"line\">347</td><td class=\"hits\">90</td><td class=\"source\">    var oid, val, i;</td></tr><tr><td class=\"line\">348</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">349</td><td class=\"hits\">90</td><td class=\"source\">    if (buf[0] !== T.ObjectIdentifier) {</td></tr><tr class=\"hit\"><td class=\"line\">350</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Buffer does not appear to be an ObjectIdentifier');</td></tr><tr><td class=\"line\">351</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">352</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">353</td><td class=\"hits\"></td><td class=\"source\">    // The first byte contains the first two numbers in the OID</td></tr><tr class=\"hit\"><td class=\"line\">354</td><td class=\"hits\">89</td><td class=\"source\">    oid = [ parseInt(buf[2] / 40, 10), buf[2] % 40 ];</td></tr><tr><td class=\"line\">355</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">356</td><td class=\"hits\"></td><td class=\"source\">    // The rest of the data is a base-128-encoded OID</td></tr><tr class=\"hit\"><td class=\"line\">357</td><td class=\"hits\">89</td><td class=\"source\">    for (i = 0; i &lt; buf[1] - 1; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">358</td><td class=\"hits\">681</td><td class=\"source\">        val = 0;</td></tr><tr class=\"hit\"><td class=\"line\">359</td><td class=\"hits\">681</td><td class=\"source\">        while (buf[i + 3] &gt;= 128) {</td></tr><tr class=\"hit\"><td class=\"line\">360</td><td class=\"hits\">17</td><td class=\"source\">            val += buf[i + 3] - 128;</td></tr><tr class=\"hit\"><td class=\"line\">361</td><td class=\"hits\">17</td><td class=\"source\">            val *= 128;</td></tr><tr class=\"hit\"><td class=\"line\">362</td><td class=\"hits\">17</td><td class=\"source\">            i++;</td></tr><tr><td class=\"line\">363</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">364</td><td class=\"hits\">681</td><td class=\"source\">        val += buf[i + 3];</td></tr><tr class=\"hit\"><td class=\"line\">365</td><td class=\"hits\">681</td><td class=\"source\">        oid.push(val);</td></tr><tr><td class=\"line\">366</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">367</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">368</td><td class=\"hits\">89</td><td class=\"source\">    return oid;</td></tr><tr><td class=\"line\">369</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">370</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">371</td><td class=\"hits\"></td><td class=\"source\">// Parse a buffer containing a representation of an array type.</td></tr><tr><td class=\"line\">372</td><td class=\"hits\"></td><td class=\"source\">// This is for example an IpAddress.</td></tr><tr><td class=\"line\">373</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">374</td><td class=\"hits\">1</td><td class=\"source\">exports.parseArray = function (buf) {</td></tr><tr class=\"hit\"><td class=\"line\">375</td><td class=\"hits\">3</td><td class=\"source\">    var i, nelem, array;</td></tr><tr><td class=\"line\">376</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">377</td><td class=\"hits\">3</td><td class=\"source\">    if (buf[0] !== T.IpAddress) {</td></tr><tr class=\"hit\"><td class=\"line\">378</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Buffer does not appear to be an array type.');</td></tr><tr><td class=\"line\">379</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">380</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">381</td><td class=\"hits\">2</td><td class=\"source\">    nelem = buf[1];</td></tr><tr class=\"hit\"><td class=\"line\">382</td><td class=\"hits\">2</td><td class=\"source\">    array = [];</td></tr><tr><td class=\"line\">383</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">384</td><td class=\"hits\">2</td><td class=\"source\">    for (i = 0; i &lt; buf[1]; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">385</td><td class=\"hits\">8</td><td class=\"source\">        array.push(buf[i + 2]);</td></tr><tr><td class=\"line\">386</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">387</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">388</td><td class=\"hits\">2</td><td class=\"source\">    return array;</td></tr><tr><td class=\"line\">389</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">390</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">391</td><td class=\"hits\"></td><td class=\"source\">// Parse a buffer containing a representation of an opaque type.</td></tr><tr><td class=\"line\">392</td><td class=\"hits\"></td><td class=\"source\">// This is for example an IpAddress.</td></tr><tr><td class=\"line\">393</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">394</td><td class=\"hits\">1</td><td class=\"source\">exports.parseOpaque = function (buf) {</td></tr><tr class=\"hit\"><td class=\"line\">395</td><td class=\"hits\">4</td><td class=\"source\">    var hdr;</td></tr><tr><td class=\"line\">396</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">397</td><td class=\"hits\">4</td><td class=\"source\">    hdr = typeAndLength(buf);</td></tr><tr><td class=\"line\">398</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">399</td><td class=\"hits\">4</td><td class=\"source\">    if (hdr.type !== T.Opaque) {</td></tr><tr class=\"hit\"><td class=\"line\">400</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Buffer does not appear to be an opaque type.');</td></tr><tr><td class=\"line\">401</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">402</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">403</td><td class=\"hits\">3</td><td class=\"source\">    return '0x' + buf.slice(hdr.header).toString('hex');</td></tr><tr><td class=\"line\">404</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">405</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">406</td><td class=\"hits\"></td><td class=\"source\">/*globals exports: false*/</td></tr><tr><td class=\"line\">407</td><td class=\"hits\"></td><td class=\"source\"> </td></tr></tbody></table></div><div class=\"file\"><h2 id=\"lib/snmp.js\">lib/snmp.js</h2><div id=\"stats\" class=\"high\"><div class=\"percentage\">95%</div><div class=\"sloc\">317</div><div class=\"hits\">304</div><div class=\"misses\">13</div></div><table id=\"source\"><thead><tr><th>Line</th><th>Hits</th><th>Source</th></tr></thead><tbody><tr><td class=\"line\">1</td><td class=\"hits\"></td><td class=\"source\">// Introduction</td></tr><tr><td class=\"line\">2</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">3</td><td class=\"hits\"></td><td class=\"source\">// This is `node-snmp-native`, a native (Javascript) implementation of an SNMP</td></tr><tr><td class=\"line\">4</td><td class=\"hits\"></td><td class=\"source\">// client library targeted at Node.js. It's MIT licensed and available at</td></tr><tr><td class=\"line\">5</td><td class=\"hits\"></td><td class=\"source\">// https://github.com/calmh/node-snmp-native</td></tr><tr><td class=\"line\">6</td><td class=\"hits\"></td><td class=\"source\">//</td></tr><tr><td class=\"line\">7</td><td class=\"hits\"></td><td class=\"source\">// (c) 2012 Jakob Borg, Nym Networks</td></tr><tr><td class=\"line\">8</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">9</td><td class=\"hits\"></td><td class=\"source\">&quot;use strict&quot;;</td></tr><tr><td class=\"line\">10</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">11</td><td class=\"hits\"></td><td class=\"source\">// Code</td></tr><tr><td class=\"line\">12</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">13</td><td class=\"hits\"></td><td class=\"source\">// This file implements a structure representing an SNMP message</td></tr><tr><td class=\"line\">14</td><td class=\"hits\"></td><td class=\"source\">// and routines for converting to and from the network representation.</td></tr><tr><td class=\"line\">15</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">16</td><td class=\"hits\"></td><td class=\"source\">// Define our external dependencies.</td></tr><tr class=\"hit\"><td class=\"line\">17</td><td class=\"hits\">1</td><td class=\"source\">var assert = require('assert');</td></tr><tr class=\"hit\"><td class=\"line\">18</td><td class=\"hits\">1</td><td class=\"source\">var dgram = require('dgram');</td></tr><tr class=\"hit\"><td class=\"line\">19</td><td class=\"hits\">1</td><td class=\"source\">var events = require('events');</td></tr><tr><td class=\"line\">20</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">21</td><td class=\"hits\"></td><td class=\"source\">// We also need our ASN.1 BER en-/decoding routines.</td></tr><tr class=\"hit\"><td class=\"line\">22</td><td class=\"hits\">1</td><td class=\"source\">var asn1ber = require('./asn1ber');</td></tr><tr><td class=\"line\">23</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">24</td><td class=\"hits\"></td><td class=\"source\">// Basic structures</td></tr><tr><td class=\"line\">25</td><td class=\"hits\"></td><td class=\"source\">// ----</td></tr><tr><td class=\"line\">26</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">27</td><td class=\"hits\"></td><td class=\"source\">// A `VarBind` is the innermost structure, containing an OID-Value pair.</td></tr><tr><td class=\"line\">28</td><td class=\"hits\"></td><td class=\"source\">function VarBind() {</td></tr><tr class=\"hit\"><td class=\"line\">29</td><td class=\"hits\">223</td><td class=\"source\">    this.type = 5;</td></tr><tr class=\"hit\"><td class=\"line\">30</td><td class=\"hits\">223</td><td class=\"source\">    this.value = null;</td></tr><tr><td class=\"line\">31</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">32</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">33</td><td class=\"hits\"></td><td class=\"source\">// The `PDU` contains the SNMP request or response fields and a list of `VarBinds`.</td></tr><tr><td class=\"line\">34</td><td class=\"hits\"></td><td class=\"source\">function PDU() {</td></tr><tr class=\"hit\"><td class=\"line\">35</td><td class=\"hits\">108</td><td class=\"source\">    this.type = asn1ber.pduTypes.GetRequestPDU;</td></tr><tr class=\"hit\"><td class=\"line\">36</td><td class=\"hits\">108</td><td class=\"source\">    this.reqid = 1;</td></tr><tr class=\"hit\"><td class=\"line\">37</td><td class=\"hits\">108</td><td class=\"source\">    this.error = 0;</td></tr><tr class=\"hit\"><td class=\"line\">38</td><td class=\"hits\">108</td><td class=\"source\">    this.errorIndex = 0;</td></tr><tr class=\"hit\"><td class=\"line\">39</td><td class=\"hits\">108</td><td class=\"source\">    this.varbinds = [ new VarBind() ];</td></tr><tr><td class=\"line\">40</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">41</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">42</td><td class=\"hits\"></td><td class=\"source\">// The `Packet` contains the SNMP version and community and the `PDU`.</td></tr><tr><td class=\"line\">43</td><td class=\"hits\"></td><td class=\"source\">function Packet() {</td></tr><tr class=\"hit\"><td class=\"line\">44</td><td class=\"hits\">108</td><td class=\"source\">    this.version = 1;</td></tr><tr class=\"hit\"><td class=\"line\">45</td><td class=\"hits\">108</td><td class=\"source\">    this.community = 'public';</td></tr><tr class=\"hit\"><td class=\"line\">46</td><td class=\"hits\">108</td><td class=\"source\">    this.pdu = new PDU();</td></tr><tr><td class=\"line\">47</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">48</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">49</td><td class=\"hits\"></td><td class=\"source\">// Allow consumers to create packet structures from scratch.</td></tr><tr class=\"hit\"><td class=\"line\">50</td><td class=\"hits\">1</td><td class=\"source\">exports.Packet = Packet;</td></tr><tr><td class=\"line\">51</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">52</td><td class=\"hits\"></td><td class=\"source\">// Private helper functions</td></tr><tr><td class=\"line\">53</td><td class=\"hits\"></td><td class=\"source\">// ----</td></tr><tr><td class=\"line\">54</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">55</td><td class=\"hits\"></td><td class=\"source\">// Concatenate several buffers to one.</td></tr><tr><td class=\"line\">56</td><td class=\"hits\"></td><td class=\"source\">function concatBuffers(buffers) {</td></tr><tr class=\"hit\"><td class=\"line\">57</td><td class=\"hits\">210</td><td class=\"source\">    var total, cur = 0, buf;</td></tr><tr><td class=\"line\">58</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">59</td><td class=\"hits\"></td><td class=\"source\">    // First we calculate the total length,</td></tr><tr class=\"hit\"><td class=\"line\">60</td><td class=\"hits\">210</td><td class=\"source\">    total = buffers.reduce(function (tot, b) {</td></tr><tr class=\"hit\"><td class=\"line\">61</td><td class=\"hits\">538</td><td class=\"source\">        return tot + b.length;</td></tr><tr><td class=\"line\">62</td><td class=\"hits\"></td><td class=\"source\">    }, 0);</td></tr><tr><td class=\"line\">63</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">64</td><td class=\"hits\"></td><td class=\"source\">    // then we allocate a new Buffer large enough to contain all data,</td></tr><tr class=\"hit\"><td class=\"line\">65</td><td class=\"hits\">210</td><td class=\"source\">    buf = new Buffer(total);</td></tr><tr class=\"hit\"><td class=\"line\">66</td><td class=\"hits\">210</td><td class=\"source\">    buffers.forEach(function (buffer) {</td></tr><tr><td class=\"line\">67</td><td class=\"hits\"></td><td class=\"source\">        // finally we copy the data into the new larger buffer.</td></tr><tr class=\"hit\"><td class=\"line\">68</td><td class=\"hits\">538</td><td class=\"source\">        buffer.copy(buf, cur, 0);</td></tr><tr class=\"hit\"><td class=\"line\">69</td><td class=\"hits\">538</td><td class=\"source\">        cur += buffer.length;</td></tr><tr><td class=\"line\">70</td><td class=\"hits\"></td><td class=\"source\">    });</td></tr><tr><td class=\"line\">71</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">72</td><td class=\"hits\">210</td><td class=\"source\">    return buf;</td></tr><tr><td class=\"line\">73</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">74</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">75</td><td class=\"hits\"></td><td class=\"source\">// Clear a pending packet when it times out or is successfully received.</td></tr><tr><td class=\"line\">76</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">77</td><td class=\"hits\"></td><td class=\"source\">function clearRequest(reqs, reqid) {</td></tr><tr class=\"hit\"><td class=\"line\">78</td><td class=\"hits\">43</td><td class=\"source\">    var self = this;</td></tr><tr><td class=\"line\">79</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">80</td><td class=\"hits\">43</td><td class=\"source\">    var entry = reqs[reqid];</td></tr><tr class=\"hit\"><td class=\"line\">81</td><td class=\"hits\">43</td><td class=\"source\">    if (entry) {</td></tr><tr class=\"hit\"><td class=\"line\">82</td><td class=\"hits\">43</td><td class=\"source\">        if (entry.timeout) {</td></tr><tr class=\"hit\"><td class=\"line\">83</td><td class=\"hits\">42</td><td class=\"source\">            clearTimeout(entry.timeout);</td></tr><tr><td class=\"line\">84</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">85</td><td class=\"hits\">43</td><td class=\"source\">        delete reqs[reqid];</td></tr><tr><td class=\"line\">86</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">87</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">88</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">89</td><td class=\"hits\"></td><td class=\"source\">// Convert a string formatted OID to an array, leaving anything non-string alone.</td></tr><tr><td class=\"line\">90</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">91</td><td class=\"hits\"></td><td class=\"source\">function parseSingleOid(oid) {</td></tr><tr class=\"hit\"><td class=\"line\">92</td><td class=\"hits\">79</td><td class=\"source\">    if (typeof oid !== 'string') {</td></tr><tr class=\"hit\"><td class=\"line\">93</td><td class=\"hits\">59</td><td class=\"source\">        return oid;</td></tr><tr><td class=\"line\">94</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">95</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">96</td><td class=\"hits\">20</td><td class=\"source\">    if (oid[0] !== '.') {</td></tr><tr class=\"hit\"><td class=\"line\">97</td><td class=\"hits\">4</td><td class=\"source\">        throw new Error('Invalid OID format');</td></tr><tr><td class=\"line\">98</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">99</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">100</td><td class=\"hits\">16</td><td class=\"source\">    oid = oid.split('.')</td></tr><tr><td class=\"line\">101</td><td class=\"hits\"></td><td class=\"source\">        .filter(function (s) {</td></tr><tr class=\"hit\"><td class=\"line\">102</td><td class=\"hits\">154</td><td class=\"source\">            return s.length &gt; 0;</td></tr><tr><td class=\"line\">103</td><td class=\"hits\"></td><td class=\"source\">        })</td></tr><tr><td class=\"line\">104</td><td class=\"hits\"></td><td class=\"source\">        .map(function (s) {</td></tr><tr class=\"hit\"><td class=\"line\">105</td><td class=\"hits\">138</td><td class=\"source\">            return parseInt(s, 10);</td></tr><tr><td class=\"line\">106</td><td class=\"hits\"></td><td class=\"source\">        });</td></tr><tr><td class=\"line\">107</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">108</td><td class=\"hits\">16</td><td class=\"source\">    return oid;</td></tr><tr><td class=\"line\">109</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">110</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">111</td><td class=\"hits\"></td><td class=\"source\">// Fix any OIDs in the 'oid' or 'oids' objects that are passed as strings.</td></tr><tr><td class=\"line\">112</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">113</td><td class=\"hits\"></td><td class=\"source\">function parseOids(options) {</td></tr><tr class=\"hit\"><td class=\"line\">114</td><td class=\"hits\">58</td><td class=\"source\">    if (options.oid) {</td></tr><tr class=\"hit\"><td class=\"line\">115</td><td class=\"hits\">48</td><td class=\"source\">        options.oid = parseSingleOid(options.oid);</td></tr><tr><td class=\"line\">116</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr class=\"hit\"><td class=\"line\">117</td><td class=\"hits\">55</td><td class=\"source\">    if (options.oids) {</td></tr><tr class=\"hit\"><td class=\"line\">118</td><td class=\"hits\">5</td><td class=\"source\">        options.oids = options.oids.map(parseSingleOid);</td></tr><tr><td class=\"line\">119</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">120</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">121</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">122</td><td class=\"hits\"></td><td class=\"source\">// Update targ with attributes from _defs.</td></tr><tr><td class=\"line\">123</td><td class=\"hits\"></td><td class=\"source\">// Any existing attributes on targ are untouched.</td></tr><tr><td class=\"line\">124</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">125</td><td class=\"hits\"></td><td class=\"source\">function defaults(targ, _defs) {</td></tr><tr class=\"hit\"><td class=\"line\">126</td><td class=\"hits\">159</td><td class=\"source\">    [].slice.call(arguments, 1).forEach(function (def) {</td></tr><tr class=\"hit\"><td class=\"line\">127</td><td class=\"hits\">164</td><td class=\"source\">        Object.keys(def).forEach(function (key) {</td></tr><tr class=\"hit\"><td class=\"line\">128</td><td class=\"hits\">818</td><td class=\"source\">            if (!targ.hasOwnProperty(key)) {</td></tr><tr class=\"hit\"><td class=\"line\">129</td><td class=\"hits\">468</td><td class=\"source\">                targ[key] = def[key];</td></tr><tr><td class=\"line\">130</td><td class=\"hits\"></td><td class=\"source\">            }</td></tr><tr><td class=\"line\">131</td><td class=\"hits\"></td><td class=\"source\">        });</td></tr><tr><td class=\"line\">132</td><td class=\"hits\"></td><td class=\"source\">    });</td></tr><tr><td class=\"line\">133</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">134</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">135</td><td class=\"hits\"></td><td class=\"source\">// Encode structure to ASN.1 BER</td></tr><tr><td class=\"line\">136</td><td class=\"hits\"></td><td class=\"source\">// ----</td></tr><tr><td class=\"line\">137</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">138</td><td class=\"hits\"></td><td class=\"source\">// Return an ASN.1 BER encoding of a Packet structure.</td></tr><tr><td class=\"line\">139</td><td class=\"hits\"></td><td class=\"source\">// This is suitable for transmission on a UDP socket.</td></tr><tr><td class=\"line\">140</td><td class=\"hits\"></td><td class=\"source\">function encode(pkt) {</td></tr><tr class=\"hit\"><td class=\"line\">141</td><td class=\"hits\">47</td><td class=\"source\">    var version, community, reqid, err, erridx, vbs, pdu, message;</td></tr><tr><td class=\"line\">142</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">143</td><td class=\"hits\"></td><td class=\"source\">    // We only support SNMPv2c, so enforce that version stamp.</td></tr><tr class=\"hit\"><td class=\"line\">144</td><td class=\"hits\">47</td><td class=\"source\">    if (pkt.version !== 1) {</td></tr><tr class=\"miss\"><td class=\"line\">145</td><td class=\"hits\">0</td><td class=\"source\">        throw new Error('Only SNMPv2c is supported.');</td></tr><tr><td class=\"line\">146</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">147</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">148</td><td class=\"hits\"></td><td class=\"source\">    // Encode the message header fields.</td></tr><tr class=\"hit\"><td class=\"line\">149</td><td class=\"hits\">47</td><td class=\"source\">    version = asn1ber.encodeInteger(pkt.version);</td></tr><tr class=\"hit\"><td class=\"line\">150</td><td class=\"hits\">47</td><td class=\"source\">    community = asn1ber.encodeOctetString(pkt.community);</td></tr><tr><td class=\"line\">151</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">152</td><td class=\"hits\"></td><td class=\"source\">    // Encode the PDU header fields.</td></tr><tr class=\"hit\"><td class=\"line\">153</td><td class=\"hits\">47</td><td class=\"source\">    reqid = asn1ber.encodeInteger(pkt.pdu.reqid);</td></tr><tr class=\"hit\"><td class=\"line\">154</td><td class=\"hits\">47</td><td class=\"source\">    err = asn1ber.encodeInteger(pkt.pdu.error);</td></tr><tr class=\"hit\"><td class=\"line\">155</td><td class=\"hits\">47</td><td class=\"source\">    erridx = asn1ber.encodeInteger(pkt.pdu.errorIndex);</td></tr><tr><td class=\"line\">156</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">157</td><td class=\"hits\"></td><td class=\"source\">    // Encode the PDU varbinds.</td></tr><tr class=\"hit\"><td class=\"line\">158</td><td class=\"hits\">47</td><td class=\"source\">    vbs = [];</td></tr><tr class=\"hit\"><td class=\"line\">159</td><td class=\"hits\">47</td><td class=\"source\">    pkt.pdu.varbinds.forEach(function (vb) {</td></tr><tr class=\"hit\"><td class=\"line\">160</td><td class=\"hits\">73</td><td class=\"source\">        var oid = asn1ber.encodeOid(vb.oid), val;</td></tr><tr><td class=\"line\">161</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">162</td><td class=\"hits\">73</td><td class=\"source\">        if (vb.type === asn1ber.types.Null) {</td></tr><tr class=\"hit\"><td class=\"line\">163</td><td class=\"hits\">66</td><td class=\"source\">            val = asn1ber.encodeNull();</td></tr><tr class=\"hit\"><td class=\"line\">164</td><td class=\"hits\">7</td><td class=\"source\">        } else if (vb.type === asn1ber.types.Integer) {</td></tr><tr class=\"hit\"><td class=\"line\">165</td><td class=\"hits\">5</td><td class=\"source\">            val = asn1ber.encodeInteger(vb.value);</td></tr><tr class=\"hit\"><td class=\"line\">166</td><td class=\"hits\">2</td><td class=\"source\">        } else if (vb.type === asn1ber.types.IpAddress) {</td></tr><tr class=\"hit\"><td class=\"line\">167</td><td class=\"hits\">1</td><td class=\"source\">            val = asn1ber.encodeIpAddress(vb.value);</td></tr><tr class=\"hit\"><td class=\"line\">168</td><td class=\"hits\">1</td><td class=\"source\">        } else if (vb.type === asn1ber.types.OctetString) {</td></tr><tr class=\"hit\"><td class=\"line\">169</td><td class=\"hits\">1</td><td class=\"source\">            val = asn1ber.encodeOctetString(vb.value);</td></tr><tr><td class=\"line\">170</td><td class=\"hits\"></td><td class=\"source\">        } else {</td></tr><tr class=\"miss\"><td class=\"line\">171</td><td class=\"hits\">0</td><td class=\"source\">            throw new Error('Unknown varbind type &quot;' + vb.type + '&quot; in encoding.');</td></tr><tr><td class=\"line\">172</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">173</td><td class=\"hits\">72</td><td class=\"source\">        vbs.push(asn1ber.encodeSequence(concatBuffers([oid, val])));</td></tr><tr><td class=\"line\">174</td><td class=\"hits\"></td><td class=\"source\">    });</td></tr><tr><td class=\"line\">175</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">176</td><td class=\"hits\"></td><td class=\"source\">    // Concatenate all the varbinds together.</td></tr><tr class=\"hit\"><td class=\"line\">177</td><td class=\"hits\">46</td><td class=\"source\">    vbs = asn1ber.encodeSequence(concatBuffers(vbs));</td></tr><tr><td class=\"line\">178</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">179</td><td class=\"hits\"></td><td class=\"source\">    // Create the PDU by concatenating the inner fields and adding a request structure around it.</td></tr><tr class=\"hit\"><td class=\"line\">180</td><td class=\"hits\">46</td><td class=\"source\">    pdu = asn1ber.encodeRequest(pkt.pdu.type, concatBuffers([reqid, err, erridx, vbs]));</td></tr><tr><td class=\"line\">181</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">182</td><td class=\"hits\"></td><td class=\"source\">    // Create the message by concatenating the header fields and the PDU.</td></tr><tr class=\"hit\"><td class=\"line\">183</td><td class=\"hits\">46</td><td class=\"source\">    message = asn1ber.encodeSequence(concatBuffers([version, community, pdu]));</td></tr><tr><td class=\"line\">184</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">185</td><td class=\"hits\">46</td><td class=\"source\">    return message;</td></tr><tr><td class=\"line\">186</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">187</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">188</td><td class=\"hits\">1</td><td class=\"source\">exports.encode = encode;</td></tr><tr><td class=\"line\">189</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">190</td><td class=\"hits\"></td><td class=\"source\">// Parse ASN.1 BER into a structure</td></tr><tr><td class=\"line\">191</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">192</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">193</td><td class=\"hits\"></td><td class=\"source\">// Parse an SNMP packet into its component fields.</td></tr><tr><td class=\"line\">194</td><td class=\"hits\"></td><td class=\"source\">// We don't do a lot of validation so a malformed packet will probably just</td></tr><tr><td class=\"line\">195</td><td class=\"hits\"></td><td class=\"source\">// make us blow up.</td></tr><tr><td class=\"line\">196</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">197</td><td class=\"hits\"></td><td class=\"source\">function parse(buf) {</td></tr><tr class=\"hit\"><td class=\"line\">198</td><td class=\"hits\">61</td><td class=\"source\">    var pkt, oid, bvb, vb, hdr;</td></tr><tr><td class=\"line\">199</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">200</td><td class=\"hits\">61</td><td class=\"source\">    pkt = new Packet();</td></tr><tr><td class=\"line\">201</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">202</td><td class=\"hits\"></td><td class=\"source\">    // First we have a sequence marker (two bytes).</td></tr><tr><td class=\"line\">203</td><td class=\"hits\"></td><td class=\"source\">    // We don't care about those, so cut them off.</td></tr><tr class=\"hit\"><td class=\"line\">204</td><td class=\"hits\">61</td><td class=\"source\">    hdr = asn1ber.typeAndLength(buf);</td></tr><tr class=\"hit\"><td class=\"line\">205</td><td class=\"hits\">61</td><td class=\"source\">    assert.equal(asn1ber.types.Sequence, hdr.type);</td></tr><tr class=\"hit\"><td class=\"line\">206</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(hdr.header);</td></tr><tr><td class=\"line\">207</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">208</td><td class=\"hits\"></td><td class=\"source\">    // Then comes the version field (integer). Parse it and slice it.</td></tr><tr class=\"hit\"><td class=\"line\">209</td><td class=\"hits\">59</td><td class=\"source\">    pkt.version = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));</td></tr><tr class=\"hit\"><td class=\"line\">210</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(2 + buf[1]);</td></tr><tr><td class=\"line\">211</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">212</td><td class=\"hits\"></td><td class=\"source\">    // We then get the community. Parse and slice.</td></tr><tr class=\"hit\"><td class=\"line\">213</td><td class=\"hits\">59</td><td class=\"source\">    pkt.community = asn1ber.parseOctetString(buf.slice(0, buf[1] + 2));</td></tr><tr class=\"hit\"><td class=\"line\">214</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(2 + buf[1]);</td></tr><tr><td class=\"line\">215</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">216</td><td class=\"hits\"></td><td class=\"source\">    // Here's the PDU structure. We're interested in the type. Slice the rest.</td></tr><tr class=\"hit\"><td class=\"line\">217</td><td class=\"hits\">59</td><td class=\"source\">    hdr = asn1ber.typeAndLength(buf);</td></tr><tr class=\"hit\"><td class=\"line\">218</td><td class=\"hits\">59</td><td class=\"source\">    assert.ok(hdr.type &gt;= 0xA0);</td></tr><tr class=\"hit\"><td class=\"line\">219</td><td class=\"hits\">59</td><td class=\"source\">    pkt.pdu.type = hdr.type - 0xA0;</td></tr><tr class=\"hit\"><td class=\"line\">220</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(hdr.header);</td></tr><tr><td class=\"line\">221</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">222</td><td class=\"hits\"></td><td class=\"source\">    // The request id field.</td></tr><tr class=\"hit\"><td class=\"line\">223</td><td class=\"hits\">59</td><td class=\"source\">    pkt.pdu.reqid = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));</td></tr><tr class=\"hit\"><td class=\"line\">224</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(2 + buf[1]);</td></tr><tr><td class=\"line\">225</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">226</td><td class=\"hits\"></td><td class=\"source\">    // The error field.</td></tr><tr class=\"hit\"><td class=\"line\">227</td><td class=\"hits\">59</td><td class=\"source\">    pkt.pdu.error = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));</td></tr><tr class=\"hit\"><td class=\"line\">228</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(2 + buf[1]);</td></tr><tr><td class=\"line\">229</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">230</td><td class=\"hits\"></td><td class=\"source\">    // The error index field.</td></tr><tr class=\"hit\"><td class=\"line\">231</td><td class=\"hits\">59</td><td class=\"source\">    pkt.pdu.errorIndex = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));</td></tr><tr class=\"hit\"><td class=\"line\">232</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(2 + buf[1]);</td></tr><tr><td class=\"line\">233</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">234</td><td class=\"hits\"></td><td class=\"source\">    // Here's the varbind list. Not interested.</td></tr><tr class=\"hit\"><td class=\"line\">235</td><td class=\"hits\">59</td><td class=\"source\">    hdr = asn1ber.typeAndLength(buf);</td></tr><tr class=\"hit\"><td class=\"line\">236</td><td class=\"hits\">59</td><td class=\"source\">    assert.equal(asn1ber.types.Sequence, hdr.type);</td></tr><tr class=\"hit\"><td class=\"line\">237</td><td class=\"hits\">59</td><td class=\"source\">    buf = buf.slice(hdr.header);</td></tr><tr><td class=\"line\">238</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">239</td><td class=\"hits\"></td><td class=\"source\">    // Now comes the varbinds. There might be many, so we loop for as long as we have data.</td></tr><tr class=\"hit\"><td class=\"line\">240</td><td class=\"hits\">59</td><td class=\"source\">    pkt.pdu.varbinds = [];</td></tr><tr class=\"hit\"><td class=\"line\">241</td><td class=\"hits\">59</td><td class=\"source\">    while (buf[0] === asn1ber.types.Sequence) {</td></tr><tr class=\"hit\"><td class=\"line\">242</td><td class=\"hits\">85</td><td class=\"source\">        vb = new VarBind();</td></tr><tr><td class=\"line\">243</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">244</td><td class=\"hits\"></td><td class=\"source\">        // Slice off the sequence header.</td></tr><tr class=\"hit\"><td class=\"line\">245</td><td class=\"hits\">85</td><td class=\"source\">        hdr = asn1ber.typeAndLength(buf);</td></tr><tr class=\"hit\"><td class=\"line\">246</td><td class=\"hits\">85</td><td class=\"source\">        assert.equal(asn1ber.types.Sequence, hdr.type);</td></tr><tr class=\"hit\"><td class=\"line\">247</td><td class=\"hits\">85</td><td class=\"source\">        bvb = buf.slice(hdr.header);</td></tr><tr><td class=\"line\">248</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">249</td><td class=\"hits\"></td><td class=\"source\">        // Parse and save the ObjectIdentifier.</td></tr><tr class=\"hit\"><td class=\"line\">250</td><td class=\"hits\">85</td><td class=\"source\">        vb.oid = asn1ber.parseOid(bvb);</td></tr><tr><td class=\"line\">251</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">252</td><td class=\"hits\"></td><td class=\"source\">        // Parse the value. We use the type marker to figure out</td></tr><tr><td class=\"line\">253</td><td class=\"hits\"></td><td class=\"source\">        // what kind of value it is and call the appropriate parser</td></tr><tr><td class=\"line\">254</td><td class=\"hits\"></td><td class=\"source\">        // routine. For the SNMPv2c error types, we simply set the</td></tr><tr><td class=\"line\">255</td><td class=\"hits\"></td><td class=\"source\">        // value to a text representation of the error and leave handling</td></tr><tr><td class=\"line\">256</td><td class=\"hits\"></td><td class=\"source\">        // up to the user.</td></tr><tr class=\"hit\"><td class=\"line\">257</td><td class=\"hits\">85</td><td class=\"source\">        bvb = bvb.slice(2 + bvb[1]);</td></tr><tr class=\"hit\"><td class=\"line\">258</td><td class=\"hits\">85</td><td class=\"source\">        vb.type = bvb[0];</td></tr><tr class=\"hit\"><td class=\"line\">259</td><td class=\"hits\">85</td><td class=\"source\">        if (vb.type === asn1ber.types.Null) {</td></tr><tr><td class=\"line\">260</td><td class=\"hits\"></td><td class=\"source\">            // Null type.</td></tr><tr class=\"hit\"><td class=\"line\">261</td><td class=\"hits\">16</td><td class=\"source\">            vb.value = null;</td></tr><tr class=\"hit\"><td class=\"line\">262</td><td class=\"hits\">69</td><td class=\"source\">        } else if (vb.type === asn1ber.types.OctetString) {</td></tr><tr><td class=\"line\">263</td><td class=\"hits\"></td><td class=\"source\">            // Octet string type.</td></tr><tr class=\"hit\"><td class=\"line\">264</td><td class=\"hits\">16</td><td class=\"source\">            vb.value = asn1ber.parseOctetString(bvb);</td></tr><tr class=\"hit\"><td class=\"line\">265</td><td class=\"hits\">53</td><td class=\"source\">        } else if (vb.type === asn1ber.types.Integer ||</td></tr><tr><td class=\"line\">266</td><td class=\"hits\"></td><td class=\"source\">            vb.type === asn1ber.types.Counter ||</td></tr><tr><td class=\"line\">267</td><td class=\"hits\"></td><td class=\"source\">            vb.type === asn1ber.types.Counter64 ||</td></tr><tr><td class=\"line\">268</td><td class=\"hits\"></td><td class=\"source\">            vb.type === asn1ber.types.TimeTicks ||</td></tr><tr><td class=\"line\">269</td><td class=\"hits\"></td><td class=\"source\">            vb.type === asn1ber.types.Gauge) {</td></tr><tr><td class=\"line\">270</td><td class=\"hits\"></td><td class=\"source\">            // Integer type and it's derivatives that behave in the same manner.</td></tr><tr class=\"hit\"><td class=\"line\">271</td><td class=\"hits\">41</td><td class=\"source\">            vb.value = asn1ber.parseInteger(bvb);</td></tr><tr class=\"hit\"><td class=\"line\">272</td><td class=\"hits\">12</td><td class=\"source\">        } else if (vb.type === asn1ber.types.ObjectIdentifier) {</td></tr><tr><td class=\"line\">273</td><td class=\"hits\"></td><td class=\"source\">            // Object identifier type.</td></tr><tr class=\"hit\"><td class=\"line\">274</td><td class=\"hits\">1</td><td class=\"source\">            vb.value = asn1ber.parseOid(bvb);</td></tr><tr class=\"hit\"><td class=\"line\">275</td><td class=\"hits\">11</td><td class=\"source\">        } else if (vb.type === asn1ber.types.IpAddress) {</td></tr><tr><td class=\"line\">276</td><td class=\"hits\"></td><td class=\"source\">            // IP Address type.</td></tr><tr class=\"hit\"><td class=\"line\">277</td><td class=\"hits\">1</td><td class=\"source\">            vb.value = asn1ber.parseArray(bvb);</td></tr><tr class=\"hit\"><td class=\"line\">278</td><td class=\"hits\">10</td><td class=\"source\">        } else if (vb.type === asn1ber.types.Opaque) {</td></tr><tr><td class=\"line\">279</td><td class=\"hits\"></td><td class=\"source\">            // Opaque type. The 'parsing' here is very light; basically we return a</td></tr><tr><td class=\"line\">280</td><td class=\"hits\"></td><td class=\"source\">            // string representation of the raw bytes in hex.</td></tr><tr class=\"hit\"><td class=\"line\">281</td><td class=\"hits\">2</td><td class=\"source\">            vb.value = asn1ber.parseOpaque(bvb);</td></tr><tr class=\"hit\"><td class=\"line\">282</td><td class=\"hits\">8</td><td class=\"source\">        } else if (vb.type === asn1ber.types.EndOfMibView) {</td></tr><tr><td class=\"line\">283</td><td class=\"hits\"></td><td class=\"source\">            // End of MIB view error, returned when attempting to GetNext beyond the end</td></tr><tr><td class=\"line\">284</td><td class=\"hits\"></td><td class=\"source\">            // of the current view.</td></tr><tr class=\"hit\"><td class=\"line\">285</td><td class=\"hits\">1</td><td class=\"source\">            vb.value = 'endOfMibView';</td></tr><tr class=\"hit\"><td class=\"line\">286</td><td class=\"hits\">7</td><td class=\"source\">        } else if (vb.type === asn1ber.types.NoSuchObject) {</td></tr><tr><td class=\"line\">287</td><td class=\"hits\"></td><td class=\"source\">            // No such object error, returned when attempting to Get/GetNext an OID that doesn't exist.</td></tr><tr class=\"hit\"><td class=\"line\">288</td><td class=\"hits\">1</td><td class=\"source\">            vb.value = 'noSuchObject';</td></tr><tr class=\"hit\"><td class=\"line\">289</td><td class=\"hits\">6</td><td class=\"source\">        } else if (vb.type === asn1ber.types.NoSuchInstance) {</td></tr><tr><td class=\"line\">290</td><td class=\"hits\"></td><td class=\"source\">            // No such instance error, returned when attempting to Get/GetNext an instance</td></tr><tr><td class=\"line\">291</td><td class=\"hits\"></td><td class=\"source\">            // that doesn't exist in a given table.</td></tr><tr class=\"hit\"><td class=\"line\">292</td><td class=\"hits\">6</td><td class=\"source\">            vb.value = 'noSuchInstance';</td></tr><tr><td class=\"line\">293</td><td class=\"hits\"></td><td class=\"source\">        } else {</td></tr><tr><td class=\"line\">294</td><td class=\"hits\"></td><td class=\"source\">            // Something else that we can't handle, so throw an error.</td></tr><tr><td class=\"line\">295</td><td class=\"hits\"></td><td class=\"source\">            // The error will be caught and presented in a useful manner on stderr,</td></tr><tr><td class=\"line\">296</td><td class=\"hits\"></td><td class=\"source\">            // with a dump of the message causing it.</td></tr><tr class=\"miss\"><td class=\"line\">297</td><td class=\"hits\">0</td><td class=\"source\">            throw new Error('Unrecognized value type ' + vb.type);</td></tr><tr><td class=\"line\">298</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">299</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">300</td><td class=\"hits\"></td><td class=\"source\">        // Take the raw octet string value and preseve it as a buffer and hex string.</td></tr><tr class=\"hit\"><td class=\"line\">301</td><td class=\"hits\">85</td><td class=\"source\">        vb.valueRaw = bvb.slice(2);</td></tr><tr class=\"hit\"><td class=\"line\">302</td><td class=\"hits\">85</td><td class=\"source\">        vb.valueHex = vb.valueRaw.toString('hex');</td></tr><tr><td class=\"line\">303</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">304</td><td class=\"hits\"></td><td class=\"source\">        // Add the request id to the varbind (even though it doesn't really belong)</td></tr><tr><td class=\"line\">305</td><td class=\"hits\"></td><td class=\"source\">        // so that it will be availble to the end user.</td></tr><tr class=\"hit\"><td class=\"line\">306</td><td class=\"hits\">85</td><td class=\"source\">        vb.requestId = pkt.pdu.reqid;</td></tr><tr><td class=\"line\">307</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">308</td><td class=\"hits\"></td><td class=\"source\">        // Push whatever we parsed to the varbind list.</td></tr><tr class=\"hit\"><td class=\"line\">309</td><td class=\"hits\">85</td><td class=\"source\">        pkt.pdu.varbinds.push(vb);</td></tr><tr><td class=\"line\">310</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">311</td><td class=\"hits\"></td><td class=\"source\">        // Go fetch the next varbind, if there seems to be any.</td></tr><tr class=\"hit\"><td class=\"line\">312</td><td class=\"hits\">85</td><td class=\"source\">        if (buf.length &gt; hdr.header + hdr.len) {</td></tr><tr class=\"hit\"><td class=\"line\">313</td><td class=\"hits\">26</td><td class=\"source\">            buf = buf.slice(hdr.header + hdr.len);</td></tr><tr><td class=\"line\">314</td><td class=\"hits\"></td><td class=\"source\">        } else {</td></tr><tr class=\"hit\"><td class=\"line\">315</td><td class=\"hits\">59</td><td class=\"source\">            break;</td></tr><tr><td class=\"line\">316</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">317</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">318</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">319</td><td class=\"hits\">59</td><td class=\"source\">    return pkt;</td></tr><tr><td class=\"line\">320</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">321</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">322</td><td class=\"hits\">1</td><td class=\"source\">exports.parse = parse;</td></tr><tr><td class=\"line\">323</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">324</td><td class=\"hits\"></td><td class=\"source\">// Utility functions</td></tr><tr><td class=\"line\">325</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">326</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">327</td><td class=\"hits\"></td><td class=\"source\">// Compare two OIDs, returning -1, 0 or +1 depending on the relation between</td></tr><tr><td class=\"line\">328</td><td class=\"hits\"></td><td class=\"source\">// oidA and oidB.</td></tr><tr><td class=\"line\">329</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">330</td><td class=\"hits\">1</td><td class=\"source\">exports.compareOids = function (oidA, oidB) {</td></tr><tr class=\"hit\"><td class=\"line\">331</td><td class=\"hits\">9</td><td class=\"source\">    var mlen, i;</td></tr><tr><td class=\"line\">332</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">333</td><td class=\"hits\"></td><td class=\"source\">    // The undefined OID, if there is any, is deemed lesser.</td></tr><tr class=\"hit\"><td class=\"line\">334</td><td class=\"hits\">9</td><td class=\"source\">    if (typeof oidA === 'undefined' &amp;&amp; typeof oidB !== 'undefined') {</td></tr><tr class=\"hit\"><td class=\"line\">335</td><td class=\"hits\">1</td><td class=\"source\">        return 1;</td></tr><tr class=\"hit\"><td class=\"line\">336</td><td class=\"hits\">8</td><td class=\"source\">    } else if (typeof oidA !== 'undefined' &amp;&amp; typeof oidB === 'undefined') {</td></tr><tr class=\"hit\"><td class=\"line\">337</td><td class=\"hits\">1</td><td class=\"source\">        return -1;</td></tr><tr><td class=\"line\">338</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">339</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">340</td><td class=\"hits\"></td><td class=\"source\">    // Check each number part of the OIDs individually, and if there is any</td></tr><tr><td class=\"line\">341</td><td class=\"hits\"></td><td class=\"source\">    // position where one OID is larger than the other, return accordingly.</td></tr><tr><td class=\"line\">342</td><td class=\"hits\"></td><td class=\"source\">    // This will only check up to the minimum length of both OIDs.</td></tr><tr class=\"hit\"><td class=\"line\">343</td><td class=\"hits\">7</td><td class=\"source\">    mlen = Math.min(oidA.length, oidB.length);</td></tr><tr class=\"hit\"><td class=\"line\">344</td><td class=\"hits\">7</td><td class=\"source\">    for (i = 0; i &lt; mlen; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">345</td><td class=\"hits\">26</td><td class=\"source\">        if (oidA[i] &gt; oidB[i]) {</td></tr><tr class=\"hit\"><td class=\"line\">346</td><td class=\"hits\">1</td><td class=\"source\">            return -1;</td></tr><tr class=\"hit\"><td class=\"line\">347</td><td class=\"hits\">25</td><td class=\"source\">        } else if (oidB[i] &gt; oidA[i]) {</td></tr><tr class=\"hit\"><td class=\"line\">348</td><td class=\"hits\">1</td><td class=\"source\">            return 1;</td></tr><tr><td class=\"line\">349</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">350</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">351</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">352</td><td class=\"hits\"></td><td class=\"source\">    // If there is one OID that is longer than the other after the above comparison,</td></tr><tr><td class=\"line\">353</td><td class=\"hits\"></td><td class=\"source\">    // consider the shorter OID to be lesser.</td></tr><tr class=\"hit\"><td class=\"line\">354</td><td class=\"hits\">5</td><td class=\"source\">    if (oidA.length &gt; oidB.length) {</td></tr><tr class=\"hit\"><td class=\"line\">355</td><td class=\"hits\">2</td><td class=\"source\">        return -1;</td></tr><tr class=\"hit\"><td class=\"line\">356</td><td class=\"hits\">3</td><td class=\"source\">    } else if (oidB.length &gt; oidA.length) {</td></tr><tr class=\"hit\"><td class=\"line\">357</td><td class=\"hits\">2</td><td class=\"source\">        return 1;</td></tr><tr><td class=\"line\">358</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr><td class=\"line\">359</td><td class=\"hits\"></td><td class=\"source\">        // The OIDs are obviously equal.</td></tr><tr class=\"hit\"><td class=\"line\">360</td><td class=\"hits\">1</td><td class=\"source\">        return 0;</td></tr><tr><td class=\"line\">361</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">362</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">363</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">364</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">365</td><td class=\"hits\"></td><td class=\"source\">// Communication functions</td></tr><tr><td class=\"line\">366</td><td class=\"hits\"></td><td class=\"source\">// -----</td></tr><tr><td class=\"line\">367</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">368</td><td class=\"hits\"></td><td class=\"source\">// This is called for when we receive a message.</td></tr><tr><td class=\"line\">369</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">370</td><td class=\"hits\"></td><td class=\"source\">function msgReceived(msg, rinfo) {</td></tr><tr class=\"hit\"><td class=\"line\">371</td><td class=\"hits\">44</td><td class=\"source\">    var self = this, now = Date.now(), pkt, entry;</td></tr><tr><td class=\"line\">372</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">373</td><td class=\"hits\">44</td><td class=\"source\">    if (msg.length === 0) {</td></tr><tr><td class=\"line\">374</td><td class=\"hits\"></td><td class=\"source\">        // Not sure why we sometimes receive an empty message.</td></tr><tr><td class=\"line\">375</td><td class=\"hits\"></td><td class=\"source\">        // As far as I'm concerned it shouldn't happen, but we'll ignore it</td></tr><tr><td class=\"line\">376</td><td class=\"hits\"></td><td class=\"source\">        // and if it's necessary a retransmission of the request will be</td></tr><tr><td class=\"line\">377</td><td class=\"hits\"></td><td class=\"source\">        // made later.</td></tr><tr class=\"miss\"><td class=\"line\">378</td><td class=\"hits\">0</td><td class=\"source\">        return;</td></tr><tr><td class=\"line\">379</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">380</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">381</td><td class=\"hits\"></td><td class=\"source\">    // Parse the packet, or call the informative</td></tr><tr><td class=\"line\">382</td><td class=\"hits\"></td><td class=\"source\">    // parse error display if we fail.</td></tr><tr class=\"hit\"><td class=\"line\">383</td><td class=\"hits\">44</td><td class=\"source\">    try {</td></tr><tr class=\"hit\"><td class=\"line\">384</td><td class=\"hits\">44</td><td class=\"source\">        pkt = parse(msg);</td></tr><tr><td class=\"line\">385</td><td class=\"hits\"></td><td class=\"source\">    } catch (error) {</td></tr><tr class=\"hit\"><td class=\"line\">386</td><td class=\"hits\">1</td><td class=\"source\">        return self.parseError(error, msg);</td></tr><tr><td class=\"line\">387</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">388</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">389</td><td class=\"hits\"></td><td class=\"source\">    // If this message's request id matches one we've sent,</td></tr><tr><td class=\"line\">390</td><td class=\"hits\"></td><td class=\"source\">    // cancel any outstanding timeout and call the registered</td></tr><tr><td class=\"line\">391</td><td class=\"hits\"></td><td class=\"source\">    // callback.</td></tr><tr class=\"hit\"><td class=\"line\">392</td><td class=\"hits\">43</td><td class=\"source\">    entry = self.reqs[pkt.pdu.reqid];</td></tr><tr class=\"hit\"><td class=\"line\">393</td><td class=\"hits\">43</td><td class=\"source\">    if (entry) {</td></tr><tr class=\"hit\"><td class=\"line\">394</td><td class=\"hits\">40</td><td class=\"source\">        clearRequest(self.reqs, pkt.pdu.reqid);</td></tr><tr><td class=\"line\">395</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">396</td><td class=\"hits\">40</td><td class=\"source\">        if (typeof entry.callback === 'function') {</td></tr><tr class=\"hit\"><td class=\"line\">397</td><td class=\"hits\">39</td><td class=\"source\">            pkt.pdu.varbinds.forEach(function (vb) {</td></tr><tr class=\"hit\"><td class=\"line\">398</td><td class=\"hits\">65</td><td class=\"source\">                vb.receiveStamp = now;</td></tr><tr class=\"hit\"><td class=\"line\">399</td><td class=\"hits\">65</td><td class=\"source\">                vb.sendStamp = entry.sendStamp;</td></tr><tr><td class=\"line\">400</td><td class=\"hits\"></td><td class=\"source\">            });</td></tr><tr><td class=\"line\">401</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">402</td><td class=\"hits\">39</td><td class=\"source\">            entry.callback(null, pkt.pdu.varbinds);</td></tr><tr><td class=\"line\">403</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">404</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr><td class=\"line\">405</td><td class=\"hits\"></td><td class=\"source\">        // This happens if we receive the response to a message we've already timed out</td></tr><tr><td class=\"line\">406</td><td class=\"hits\"></td><td class=\"source\">        // and removed the request entry for. Maybe we shouldn't even log the warning.</td></tr><tr><td class=\"line\">407</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">408</td><td class=\"hits\"></td><td class=\"source\">        // Calculate the approximate send time and how old the packet is.</td></tr><tr class=\"hit\"><td class=\"line\">409</td><td class=\"hits\">3</td><td class=\"source\">        var age = (Date.now() &amp; 0x1fffff) - (pkt.pdu.reqid &gt;&gt;&gt; 10);</td></tr><tr class=\"hit\"><td class=\"line\">410</td><td class=\"hits\">3</td><td class=\"source\">        if (age &lt; 0) {</td></tr><tr class=\"miss\"><td class=\"line\">411</td><td class=\"hits\">0</td><td class=\"source\">            age += 0x200000;</td></tr><tr><td class=\"line\">412</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">413</td><td class=\"hits\">3</td><td class=\"source\">        console.warn('Response with unknown request ID from ' + rinfo.address + '. Consider increasing timeouts (' + age + ' ms old?).');</td></tr><tr><td class=\"line\">414</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">415</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">416</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">417</td><td class=\"hits\"></td><td class=\"source\">// Default options for new sessions and operations.</td></tr><tr class=\"hit\"><td class=\"line\">418</td><td class=\"hits\">1</td><td class=\"source\">exports.defaultOptions = {</td></tr><tr><td class=\"line\">419</td><td class=\"hits\"></td><td class=\"source\">    host: 'localhost',</td></tr><tr><td class=\"line\">420</td><td class=\"hits\"></td><td class=\"source\">    port: 161,</td></tr><tr><td class=\"line\">421</td><td class=\"hits\"></td><td class=\"source\">    community: 'public',</td></tr><tr><td class=\"line\">422</td><td class=\"hits\"></td><td class=\"source\">    family: 'udp4',</td></tr><tr><td class=\"line\">423</td><td class=\"hits\"></td><td class=\"source\">    timeouts: [ 5000, 5000, 5000, 5000 ]</td></tr><tr><td class=\"line\">424</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">425</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">426</td><td class=\"hits\"></td><td class=\"source\">// This creates a new SNMP session.</td></tr><tr><td class=\"line\">427</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">428</td><td class=\"hits\"></td><td class=\"source\">function Session(options) {</td></tr><tr class=\"hit\"><td class=\"line\">429</td><td class=\"hits\">47</td><td class=\"source\">    var self = this;</td></tr><tr><td class=\"line\">430</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">431</td><td class=\"hits\">47</td><td class=\"source\">    self.options = options || {};</td></tr><tr class=\"hit\"><td class=\"line\">432</td><td class=\"hits\">47</td><td class=\"source\">    defaults(self.options, exports.defaultOptions);</td></tr><tr><td class=\"line\">433</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">434</td><td class=\"hits\">47</td><td class=\"source\">    self.reqs = {};</td></tr><tr class=\"hit\"><td class=\"line\">435</td><td class=\"hits\">47</td><td class=\"source\">    self.socket = dgram.createSocket(self.options.family);</td></tr><tr class=\"hit\"><td class=\"line\">436</td><td class=\"hits\">47</td><td class=\"source\">    self.socket.on('message', msgReceived.bind(self));</td></tr><tr class=\"hit\"><td class=\"line\">437</td><td class=\"hits\">47</td><td class=\"source\">    self.socket.on('close', function () {</td></tr><tr><td class=\"line\">438</td><td class=\"hits\"></td><td class=\"source\">        // Remove the socket so we don't try to send a message on</td></tr><tr><td class=\"line\">439</td><td class=\"hits\"></td><td class=\"source\">        // it when it's closed.</td></tr><tr class=\"miss\"><td class=\"line\">440</td><td class=\"hits\">0</td><td class=\"source\">        self.socket = undefined;</td></tr><tr><td class=\"line\">441</td><td class=\"hits\"></td><td class=\"source\">    });</td></tr><tr class=\"hit\"><td class=\"line\">442</td><td class=\"hits\">47</td><td class=\"source\">    self.socket.on('error', function () {</td></tr><tr><td class=\"line\">443</td><td class=\"hits\"></td><td class=\"source\">        // Errors will be emitted here as well as on the callback to the send function.</td></tr><tr><td class=\"line\">444</td><td class=\"hits\"></td><td class=\"source\">        // We handle them there, so doing anything here is unnecessary.</td></tr><tr><td class=\"line\">445</td><td class=\"hits\"></td><td class=\"source\">        // But having no error handler trips up the test suite.</td></tr><tr><td class=\"line\">446</td><td class=\"hits\"></td><td class=\"source\">    });</td></tr><tr><td class=\"line\">447</td><td class=\"hits\"></td><td class=\"source\">}</td></tr><tr><td class=\"line\">448</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">449</td><td class=\"hits\"></td><td class=\"source\">// We inherit from EventEmitter so that we can emit error events</td></tr><tr><td class=\"line\">450</td><td class=\"hits\"></td><td class=\"source\">// on fatal errors.</td></tr><tr class=\"hit\"><td class=\"line\">451</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype = Object.create(events.EventEmitter.prototype);</td></tr><tr class=\"hit\"><td class=\"line\">452</td><td class=\"hits\">1</td><td class=\"source\">exports.Session = Session;</td></tr><tr><td class=\"line\">453</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">454</td><td class=\"hits\"></td><td class=\"source\">// Generate a request ID. It's best kept within a signed 32 bit integer.</td></tr><tr><td class=\"line\">455</td><td class=\"hits\"></td><td class=\"source\">// Uses the current time in ms, shifted left ten bits, plus a counter.</td></tr><tr><td class=\"line\">456</td><td class=\"hits\"></td><td class=\"source\">// This gives us space for 1 transmit every microsecond and wraps every</td></tr><tr><td class=\"line\">457</td><td class=\"hits\"></td><td class=\"source\">// ~1000 seconds. This is OK since we only need to keep unique ID:s for in</td></tr><tr><td class=\"line\">458</td><td class=\"hits\"></td><td class=\"source\">// flight packets and they should be safely timed out by then.</td></tr><tr><td class=\"line\">459</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">460</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.requestId = function () {</td></tr><tr class=\"hit\"><td class=\"line\">461</td><td class=\"hits\">45</td><td class=\"source\">    var self = this, now = Date.now();</td></tr><tr><td class=\"line\">462</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">463</td><td class=\"hits\">45</td><td class=\"source\">    if (!self.prevTs) {</td></tr><tr class=\"hit\"><td class=\"line\">464</td><td class=\"hits\">35</td><td class=\"source\">        self.prevTs = now;</td></tr><tr class=\"hit\"><td class=\"line\">465</td><td class=\"hits\">35</td><td class=\"source\">        self.counter = 0;</td></tr><tr><td class=\"line\">466</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">467</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">468</td><td class=\"hits\">45</td><td class=\"source\">    if (now === self.prevTs) {</td></tr><tr class=\"hit\"><td class=\"line\">469</td><td class=\"hits\">35</td><td class=\"source\">        self.counter += 1;</td></tr><tr class=\"hit\"><td class=\"line\">470</td><td class=\"hits\">35</td><td class=\"source\">        if (self.counter &gt; 1023) {</td></tr><tr class=\"miss\"><td class=\"line\">471</td><td class=\"hits\">0</td><td class=\"source\">            throw new Error('Request ID counter overflow. Adjust algorithm.');</td></tr><tr><td class=\"line\">472</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">473</td><td class=\"hits\"></td><td class=\"source\">    } else {</td></tr><tr class=\"hit\"><td class=\"line\">474</td><td class=\"hits\">10</td><td class=\"source\">        self.prevTs = now;</td></tr><tr class=\"hit\"><td class=\"line\">475</td><td class=\"hits\">10</td><td class=\"source\">        self.counter = 0;</td></tr><tr><td class=\"line\">476</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">477</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">478</td><td class=\"hits\">45</td><td class=\"source\">    return ((now &amp; 0x1fffff) &lt;&lt; 10) + self.counter;</td></tr><tr><td class=\"line\">479</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">480</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">481</td><td class=\"hits\"></td><td class=\"source\">// Display useful debugging information when a parse error occurs.</td></tr><tr><td class=\"line\">482</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">483</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.parseError = function (error, buffer) {</td></tr><tr class=\"hit\"><td class=\"line\">484</td><td class=\"hits\">1</td><td class=\"source\">    var self = this, hex;</td></tr><tr><td class=\"line\">485</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">486</td><td class=\"hits\"></td><td class=\"source\">    // Display a friendly introductory text.</td></tr><tr class=\"hit\"><td class=\"line\">487</td><td class=\"hits\">1</td><td class=\"source\">    console.error('Woops! An error occurred while parsing an SNMP message. :(');</td></tr><tr class=\"hit\"><td class=\"line\">488</td><td class=\"hits\">1</td><td class=\"source\">    console.error('To have this problem corrected, please report the information below verbatim');</td></tr><tr class=\"hit\"><td class=\"line\">489</td><td class=\"hits\">1</td><td class=\"source\">    console.error('via email to snmp@nym.se or by creating a GitHub issue at');</td></tr><tr class=\"hit\"><td class=\"line\">490</td><td class=\"hits\">1</td><td class=\"source\">    console.error('https://github.com/calmh/node-snmp-native/issues');</td></tr><tr class=\"hit\"><td class=\"line\">491</td><td class=\"hits\">1</td><td class=\"source\">    console.error('');</td></tr><tr class=\"hit\"><td class=\"line\">492</td><td class=\"hits\">1</td><td class=\"source\">    console.error('Thanks!');</td></tr><tr><td class=\"line\">493</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">494</td><td class=\"hits\"></td><td class=\"source\">    // Display the stack backtrace so we know where the exception happened.</td></tr><tr class=\"hit\"><td class=\"line\">495</td><td class=\"hits\">1</td><td class=\"source\">    console.error('');</td></tr><tr class=\"hit\"><td class=\"line\">496</td><td class=\"hits\">1</td><td class=\"source\">    console.error(error.stack);</td></tr><tr><td class=\"line\">497</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">498</td><td class=\"hits\"></td><td class=\"source\">    // Display the buffer data, nicely formatted so we can replicate the problem.</td></tr><tr class=\"hit\"><td class=\"line\">499</td><td class=\"hits\">1</td><td class=\"source\">    console.error('\\nMessage data:');</td></tr><tr class=\"hit\"><td class=\"line\">500</td><td class=\"hits\">1</td><td class=\"source\">    hex = buffer.toString('hex');</td></tr><tr class=\"hit\"><td class=\"line\">501</td><td class=\"hits\">1</td><td class=\"source\">    while (hex.length &gt; 0) {</td></tr><tr class=\"hit\"><td class=\"line\">502</td><td class=\"hits\">7</td><td class=\"source\">        console.error('    ' + hex.slice(0, 32).replace(/([0-9a-f]{2})/g, '$1 '));</td></tr><tr class=\"hit\"><td class=\"line\">503</td><td class=\"hits\">7</td><td class=\"source\">        hex = hex.slice(32);</td></tr><tr><td class=\"line\">504</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">505</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">506</td><td class=\"hits\"></td><td class=\"source\">    // Let the exception bubble upwards.</td></tr><tr class=\"hit\"><td class=\"line\">507</td><td class=\"hits\">1</td><td class=\"source\">    self.emit('error', error);</td></tr><tr><td class=\"line\">508</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">509</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">510</td><td class=\"hits\"></td><td class=\"source\">// Send a message. Can be used after manually constructing a correct Packet structure.</td></tr><tr><td class=\"line\">511</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">512</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.sendMsg = function (pkt, options, callback) {</td></tr><tr class=\"hit\"><td class=\"line\">513</td><td class=\"hits\">45</td><td class=\"source\">    var self = this, buf, reqid, retrans = 0;</td></tr><tr><td class=\"line\">514</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">515</td><td class=\"hits\">45</td><td class=\"source\">    defaults(options, self.options);</td></tr><tr><td class=\"line\">516</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">517</td><td class=\"hits\">45</td><td class=\"source\">    reqid = self.requestId();</td></tr><tr class=\"hit\"><td class=\"line\">518</td><td class=\"hits\">45</td><td class=\"source\">    pkt.pdu.reqid = reqid;</td></tr><tr><td class=\"line\">519</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">520</td><td class=\"hits\">45</td><td class=\"source\">    buf = encode(pkt);</td></tr><tr><td class=\"line\">521</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">522</td><td class=\"hits\"></td><td class=\"source\">    function transmit() {</td></tr><tr class=\"hit\"><td class=\"line\">523</td><td class=\"hits\">47</td><td class=\"source\">        if (!self.socket || !self.reqs[reqid]) {</td></tr><tr><td class=\"line\">524</td><td class=\"hits\"></td><td class=\"source\">            // The socket has already been closed, perhaps due to an error that ocurred while a timeout</td></tr><tr><td class=\"line\">525</td><td class=\"hits\"></td><td class=\"source\">            // was scheduled. We can't do anything about it now.</td></tr><tr class=\"miss\"><td class=\"line\">526</td><td class=\"hits\">0</td><td class=\"source\">            clearRequest(self.reqs, reqid);</td></tr><tr class=\"miss\"><td class=\"line\">527</td><td class=\"hits\">0</td><td class=\"source\">            return;</td></tr><tr><td class=\"line\">528</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">529</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">530</td><td class=\"hits\"></td><td class=\"source\">        // Send the message.</td></tr><tr class=\"hit\"><td class=\"line\">531</td><td class=\"hits\">47</td><td class=\"source\">        self.socket.send(buf, 0, buf.length, options.port, options.host, function (err, bytes) {</td></tr><tr class=\"hit\"><td class=\"line\">532</td><td class=\"hits\">47</td><td class=\"source\">            var entry = self.reqs[reqid];</td></tr><tr><td class=\"line\">533</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">534</td><td class=\"hits\">47</td><td class=\"source\">            if (err) {</td></tr><tr class=\"hit\"><td class=\"line\">535</td><td class=\"hits\">1</td><td class=\"source\">                clearRequest(self.reqs, reqid);</td></tr><tr class=\"hit\"><td class=\"line\">536</td><td class=\"hits\">1</td><td class=\"source\">                return callback(err);</td></tr><tr class=\"hit\"><td class=\"line\">537</td><td class=\"hits\">46</td><td class=\"source\">            } else if (entry) {</td></tr><tr class=\"hit\"><td class=\"line\">538</td><td class=\"hits\">46</td><td class=\"source\">                entry.sendStamp = Date.now();</td></tr><tr><td class=\"line\">539</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">540</td><td class=\"hits\">46</td><td class=\"source\">                if (options.timeouts[retrans]) {</td></tr><tr><td class=\"line\">541</td><td class=\"hits\"></td><td class=\"source\">                    // Set timeout and record the timer so that we can (attempt to) cancel it when we receive the reply.</td></tr><tr class=\"hit\"><td class=\"line\">542</td><td class=\"hits\">44</td><td class=\"source\">                    entry.timeout = setTimeout(transmit, options.timeouts[retrans]);</td></tr><tr class=\"hit\"><td class=\"line\">543</td><td class=\"hits\">44</td><td class=\"source\">                    retrans += 1;</td></tr><tr><td class=\"line\">544</td><td class=\"hits\"></td><td class=\"source\">                } else {</td></tr><tr class=\"hit\"><td class=\"line\">545</td><td class=\"hits\">2</td><td class=\"source\">                    clearRequest(self.reqs, reqid);</td></tr><tr class=\"hit\"><td class=\"line\">546</td><td class=\"hits\">2</td><td class=\"source\">                    return callback(new Error('Timeout'));</td></tr><tr><td class=\"line\">547</td><td class=\"hits\"></td><td class=\"source\">                }</td></tr><tr><td class=\"line\">548</td><td class=\"hits\"></td><td class=\"source\">            }</td></tr><tr><td class=\"line\">549</td><td class=\"hits\"></td><td class=\"source\">        });</td></tr><tr><td class=\"line\">550</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">551</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">552</td><td class=\"hits\"></td><td class=\"source\">    // Register the callback to call when we receive a reply.</td></tr><tr class=\"hit\"><td class=\"line\">553</td><td class=\"hits\">44</td><td class=\"source\">    self.reqs[reqid] = { callback: callback };</td></tr><tr><td class=\"line\">554</td><td class=\"hits\"></td><td class=\"source\">    // Transmit the message.</td></tr><tr class=\"hit\"><td class=\"line\">555</td><td class=\"hits\">44</td><td class=\"source\">    transmit();</td></tr><tr><td class=\"line\">556</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">557</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">558</td><td class=\"hits\"></td><td class=\"source\">// Shortcut to create a GetRequest and send it, while registering a callback.</td></tr><tr><td class=\"line\">559</td><td class=\"hits\"></td><td class=\"source\">// Needs `options.oid` to be an OID in array form.</td></tr><tr><td class=\"line\">560</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">561</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.get = function (options, callback) {</td></tr><tr class=\"hit\"><td class=\"line\">562</td><td class=\"hits\">24</td><td class=\"source\">    var self = this, pkt;</td></tr><tr><td class=\"line\">563</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">564</td><td class=\"hits\">24</td><td class=\"source\">    defaults(options, self.options);</td></tr><tr class=\"hit\"><td class=\"line\">565</td><td class=\"hits\">24</td><td class=\"source\">    parseOids(options);</td></tr><tr><td class=\"line\">566</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">567</td><td class=\"hits\">23</td><td class=\"source\">    if (!options.oid) {</td></tr><tr class=\"hit\"><td class=\"line\">568</td><td class=\"hits\">1</td><td class=\"source\">        return callback(null, []);</td></tr><tr><td class=\"line\">569</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">570</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">571</td><td class=\"hits\">22</td><td class=\"source\">    pkt = new Packet();</td></tr><tr class=\"hit\"><td class=\"line\">572</td><td class=\"hits\">22</td><td class=\"source\">    pkt.community = options.community;</td></tr><tr class=\"hit\"><td class=\"line\">573</td><td class=\"hits\">22</td><td class=\"source\">    pkt.pdu.varbinds[0].oid = options.oid;</td></tr><tr class=\"hit\"><td class=\"line\">574</td><td class=\"hits\">22</td><td class=\"source\">    self.sendMsg(pkt, options, callback);</td></tr><tr><td class=\"line\">575</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">576</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">577</td><td class=\"hits\"></td><td class=\"source\">// Shortcut to create a SetRequest and send it, while registering a callback.</td></tr><tr><td class=\"line\">578</td><td class=\"hits\"></td><td class=\"source\">// Needs `options.oid` to be an OID in array form, `options.value` to be an</td></tr><tr><td class=\"line\">579</td><td class=\"hits\"></td><td class=\"source\">// integer and `options.type` to be asn1ber.T.Integer (2).</td></tr><tr><td class=\"line\">580</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">581</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.set = function (options, callback) {</td></tr><tr class=\"hit\"><td class=\"line\">582</td><td class=\"hits\">10</td><td class=\"source\">    var self = this, pkt;</td></tr><tr><td class=\"line\">583</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">584</td><td class=\"hits\">10</td><td class=\"source\">    defaults(options, self.options);</td></tr><tr class=\"hit\"><td class=\"line\">585</td><td class=\"hits\">10</td><td class=\"source\">    parseOids(options);</td></tr><tr><td class=\"line\">586</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">587</td><td class=\"hits\">9</td><td class=\"source\">    if (!options.oid) {</td></tr><tr class=\"hit\"><td class=\"line\">588</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Missing required option `oid`.');</td></tr><tr class=\"hit\"><td class=\"line\">589</td><td class=\"hits\">8</td><td class=\"source\">    } else if (options.value === undefined) {</td></tr><tr class=\"hit\"><td class=\"line\">590</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Missing required option `value`.');</td></tr><tr class=\"hit\"><td class=\"line\">591</td><td class=\"hits\">7</td><td class=\"source\">    } else if (!options.type) {</td></tr><tr class=\"hit\"><td class=\"line\">592</td><td class=\"hits\">1</td><td class=\"source\">        throw new Error('Missing required option `type`.');</td></tr><tr><td class=\"line\">593</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">594</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">595</td><td class=\"hits\">6</td><td class=\"source\">    pkt = new Packet();</td></tr><tr class=\"hit\"><td class=\"line\">596</td><td class=\"hits\">6</td><td class=\"source\">    pkt.community = options.community;</td></tr><tr class=\"hit\"><td class=\"line\">597</td><td class=\"hits\">6</td><td class=\"source\">    pkt.pdu.type = asn1ber.pduTypes.SetRequestPDU;</td></tr><tr class=\"hit\"><td class=\"line\">598</td><td class=\"hits\">6</td><td class=\"source\">    pkt.pdu.varbinds[0].oid = options.oid;</td></tr><tr class=\"hit\"><td class=\"line\">599</td><td class=\"hits\">6</td><td class=\"source\">    pkt.pdu.varbinds[0].type = options.type;</td></tr><tr class=\"hit\"><td class=\"line\">600</td><td class=\"hits\">6</td><td class=\"source\">    pkt.pdu.varbinds[0].value = options.value;</td></tr><tr class=\"hit\"><td class=\"line\">601</td><td class=\"hits\">6</td><td class=\"source\">    self.sendMsg(pkt, options, callback);</td></tr><tr><td class=\"line\">602</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">603</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">604</td><td class=\"hits\"></td><td class=\"source\">// Shortcut to get all OIDs in the `options.oids` array sequentially. The</td></tr><tr><td class=\"line\">605</td><td class=\"hits\"></td><td class=\"source\">// callback is called when the entire operation is completed.  If</td></tr><tr><td class=\"line\">606</td><td class=\"hits\"></td><td class=\"source\">// options.abortOnError is truish, an error while getting any of the values</td></tr><tr><td class=\"line\">607</td><td class=\"hits\"></td><td class=\"source\">// will cause the callback to be called with error status. When</td></tr><tr><td class=\"line\">608</td><td class=\"hits\"></td><td class=\"source\">// `options.abortOnError` is falsish (the default), any errors will be ignored</td></tr><tr><td class=\"line\">609</td><td class=\"hits\"></td><td class=\"source\">// and any successfully retrieved values sent to the callback.</td></tr><tr><td class=\"line\">610</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">611</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.getAll = function (options, callback) {</td></tr><tr class=\"hit\"><td class=\"line\">612</td><td class=\"hits\">5</td><td class=\"source\">    var self = this, results = [];</td></tr><tr><td class=\"line\">613</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">614</td><td class=\"hits\">5</td><td class=\"source\">    defaults(options, self.options, { abortOnError: false });</td></tr><tr class=\"hit\"><td class=\"line\">615</td><td class=\"hits\">5</td><td class=\"source\">    parseOids(options);</td></tr><tr><td class=\"line\">616</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">617</td><td class=\"hits\">5</td><td class=\"source\">    if (!options.oids || options.oids.length === 0) {</td></tr><tr class=\"hit\"><td class=\"line\">618</td><td class=\"hits\">2</td><td class=\"source\">        return callback(null, []);</td></tr><tr><td class=\"line\">619</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">620</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">621</td><td class=\"hits\"></td><td class=\"source\">    function getOne(c) {</td></tr><tr class=\"hit\"><td class=\"line\">622</td><td class=\"hits\">4</td><td class=\"source\">        var oid, pkt, m, vb;</td></tr><tr><td class=\"line\">623</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">624</td><td class=\"hits\">4</td><td class=\"source\">        pkt = new Packet();</td></tr><tr class=\"hit\"><td class=\"line\">625</td><td class=\"hits\">4</td><td class=\"source\">        pkt.community = options.community;</td></tr><tr class=\"hit\"><td class=\"line\">626</td><td class=\"hits\">4</td><td class=\"source\">        pkt.pdu.varbinds = [];</td></tr><tr><td class=\"line\">627</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">628</td><td class=\"hits\"></td><td class=\"source\">        // Push up to 16 varbinds in the same message.</td></tr><tr><td class=\"line\">629</td><td class=\"hits\"></td><td class=\"source\">        // The number 16 isn't really that magical, it's just a nice round</td></tr><tr><td class=\"line\">630</td><td class=\"hits\"></td><td class=\"source\">        // number that usually seems to fit withing a single packet and gets</td></tr><tr><td class=\"line\">631</td><td class=\"hits\"></td><td class=\"source\">        // accepted by the switches I've tested it on.</td></tr><tr class=\"hit\"><td class=\"line\">632</td><td class=\"hits\">4</td><td class=\"source\">        for (m = 0; m &lt; 16 &amp;&amp; c &lt; options.oids.length; m++) {</td></tr><tr class=\"hit\"><td class=\"line\">633</td><td class=\"hits\">30</td><td class=\"source\">            vb = new VarBind();</td></tr><tr class=\"hit\"><td class=\"line\">634</td><td class=\"hits\">30</td><td class=\"source\">            vb.oid = options.oids[c];</td></tr><tr class=\"hit\"><td class=\"line\">635</td><td class=\"hits\">30</td><td class=\"source\">            pkt.pdu.varbinds.push(vb);</td></tr><tr class=\"hit\"><td class=\"line\">636</td><td class=\"hits\">30</td><td class=\"source\">            c++;</td></tr><tr><td class=\"line\">637</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">638</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">639</td><td class=\"hits\">4</td><td class=\"source\">        self.sendMsg(pkt, options, function (err, varbinds) {</td></tr><tr class=\"hit\"><td class=\"line\">640</td><td class=\"hits\">4</td><td class=\"source\">            if (options.abortOnError &amp;&amp; err) {</td></tr><tr class=\"miss\"><td class=\"line\">641</td><td class=\"hits\">0</td><td class=\"source\">                callback(err);</td></tr><tr><td class=\"line\">642</td><td class=\"hits\"></td><td class=\"source\">            } else {</td></tr><tr class=\"hit\"><td class=\"line\">643</td><td class=\"hits\">4</td><td class=\"source\">                if (varbinds) {</td></tr><tr class=\"hit\"><td class=\"line\">644</td><td class=\"hits\">4</td><td class=\"source\">                    results = results.concat(varbinds);</td></tr><tr><td class=\"line\">645</td><td class=\"hits\"></td><td class=\"source\">                }</td></tr><tr class=\"hit\"><td class=\"line\">646</td><td class=\"hits\">4</td><td class=\"source\">                if (c &lt; options.oids.length) {</td></tr><tr class=\"hit\"><td class=\"line\">647</td><td class=\"hits\">1</td><td class=\"source\">                    getOne(c);</td></tr><tr><td class=\"line\">648</td><td class=\"hits\"></td><td class=\"source\">                } else {</td></tr><tr class=\"hit\"><td class=\"line\">649</td><td class=\"hits\">3</td><td class=\"source\">                    callback(null, results);</td></tr><tr><td class=\"line\">650</td><td class=\"hits\"></td><td class=\"source\">                }</td></tr><tr><td class=\"line\">651</td><td class=\"hits\"></td><td class=\"source\">            }</td></tr><tr><td class=\"line\">652</td><td class=\"hits\"></td><td class=\"source\">        });</td></tr><tr><td class=\"line\">653</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">654</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">655</td><td class=\"hits\">3</td><td class=\"source\">    getOne(0);</td></tr><tr><td class=\"line\">656</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">657</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">658</td><td class=\"hits\"></td><td class=\"source\">// Shortcut to create a GetNextRequest and send it, while registering a callback.</td></tr><tr><td class=\"line\">659</td><td class=\"hits\"></td><td class=\"source\">// Needs `options.oid` to be an OID in array form.</td></tr><tr><td class=\"line\">660</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">661</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.getNext = function (options, callback) {</td></tr><tr class=\"hit\"><td class=\"line\">662</td><td class=\"hits\">16</td><td class=\"source\">    var self = this, pkt;</td></tr><tr><td class=\"line\">663</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">664</td><td class=\"hits\">16</td><td class=\"source\">    defaults(options, self.options);</td></tr><tr class=\"hit\"><td class=\"line\">665</td><td class=\"hits\">16</td><td class=\"source\">    parseOids(options);</td></tr><tr><td class=\"line\">666</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">667</td><td class=\"hits\">14</td><td class=\"source\">    if (!options.oid) {</td></tr><tr class=\"hit\"><td class=\"line\">668</td><td class=\"hits\">1</td><td class=\"source\">        return callback(null, []);</td></tr><tr><td class=\"line\">669</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">670</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">671</td><td class=\"hits\">13</td><td class=\"source\">    pkt = new Packet();</td></tr><tr class=\"hit\"><td class=\"line\">672</td><td class=\"hits\">13</td><td class=\"source\">    pkt.community = options.community;</td></tr><tr class=\"hit\"><td class=\"line\">673</td><td class=\"hits\">13</td><td class=\"source\">    pkt.pdu.type = 1;</td></tr><tr class=\"hit\"><td class=\"line\">674</td><td class=\"hits\">13</td><td class=\"source\">    pkt.pdu.varbinds[0].oid = options.oid;</td></tr><tr class=\"hit\"><td class=\"line\">675</td><td class=\"hits\">13</td><td class=\"source\">    self.sendMsg(pkt, options, callback);</td></tr><tr><td class=\"line\">676</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">677</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">678</td><td class=\"hits\"></td><td class=\"source\">// Shortcut to get all entries below the specified OID.</td></tr><tr><td class=\"line\">679</td><td class=\"hits\"></td><td class=\"source\">// The callback will be called once with the list of</td></tr><tr><td class=\"line\">680</td><td class=\"hits\"></td><td class=\"source\">// varbinds that was collected, or with an error object.</td></tr><tr><td class=\"line\">681</td><td class=\"hits\"></td><td class=\"source\">// Needs `options.oid` to be an OID in array form.</td></tr><tr><td class=\"line\">682</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">683</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.getSubtree = function (options, callback) {</td></tr><tr class=\"hit\"><td class=\"line\">684</td><td class=\"hits\">3</td><td class=\"source\">    var self = this, vbs = [];</td></tr><tr><td class=\"line\">685</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">686</td><td class=\"hits\">3</td><td class=\"source\">    defaults(options, self.options);</td></tr><tr class=\"hit\"><td class=\"line\">687</td><td class=\"hits\">3</td><td class=\"source\">    parseOids(options);</td></tr><tr><td class=\"line\">688</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">689</td><td class=\"hits\">3</td><td class=\"source\">    if (!options.oid) {</td></tr><tr class=\"hit\"><td class=\"line\">690</td><td class=\"hits\">1</td><td class=\"source\">        return callback(null, []);</td></tr><tr><td class=\"line\">691</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">692</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">693</td><td class=\"hits\">2</td><td class=\"source\">    options.startOid = options.oid;</td></tr><tr><td class=\"line\">694</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">695</td><td class=\"hits\"></td><td class=\"source\">    // Helper to check whether `oid` in inside the tree rooted at</td></tr><tr><td class=\"line\">696</td><td class=\"hits\"></td><td class=\"source\">    // `root` or not.</td></tr><tr><td class=\"line\">697</td><td class=\"hits\"></td><td class=\"source\">    function inTree(root, oid) {</td></tr><tr class=\"hit\"><td class=\"line\">698</td><td class=\"hits\">11</td><td class=\"source\">        var i;</td></tr><tr class=\"hit\"><td class=\"line\">699</td><td class=\"hits\">11</td><td class=\"source\">        if (oid.length &lt;= root.length) {</td></tr><tr class=\"hit\"><td class=\"line\">700</td><td class=\"hits\">1</td><td class=\"source\">            return false;</td></tr><tr><td class=\"line\">701</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">702</td><td class=\"hits\">10</td><td class=\"source\">        for (i = 0; i &lt; root.length; i++) {</td></tr><tr class=\"hit\"><td class=\"line\">703</td><td class=\"hits\">79</td><td class=\"source\">            if (oid[i] !== root[i]) {</td></tr><tr class=\"hit\"><td class=\"line\">704</td><td class=\"hits\">1</td><td class=\"source\">                return false;</td></tr><tr><td class=\"line\">705</td><td class=\"hits\"></td><td class=\"source\">            }</td></tr><tr><td class=\"line\">706</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr class=\"hit\"><td class=\"line\">707</td><td class=\"hits\">9</td><td class=\"source\">        return true;</td></tr><tr><td class=\"line\">708</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">709</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">710</td><td class=\"hits\"></td><td class=\"source\">    // Helper to handle the result of getNext and call the user's callback</td></tr><tr><td class=\"line\">711</td><td class=\"hits\"></td><td class=\"source\">    // as appropriate. The callback will see one of the following patterns:</td></tr><tr><td class=\"line\">712</td><td class=\"hits\"></td><td class=\"source\">    //  - callback([an Error object], undefined) -- an error ocurred.</td></tr><tr><td class=\"line\">713</td><td class=\"hits\"></td><td class=\"source\">    //  - callback(null, [a Packet object]) -- data from under the tree.</td></tr><tr><td class=\"line\">714</td><td class=\"hits\"></td><td class=\"source\">    //  - callback(null, null) -- end of tree.</td></tr><tr><td class=\"line\">715</td><td class=\"hits\"></td><td class=\"source\">    function result(error, varbinds) {</td></tr><tr class=\"hit\"><td class=\"line\">716</td><td class=\"hits\">11</td><td class=\"source\">        if (error) {</td></tr><tr class=\"miss\"><td class=\"line\">717</td><td class=\"hits\">0</td><td class=\"source\">            callback(error);</td></tr><tr><td class=\"line\">718</td><td class=\"hits\"></td><td class=\"source\">        } else {</td></tr><tr class=\"hit\"><td class=\"line\">719</td><td class=\"hits\">11</td><td class=\"source\">            if (inTree(options.startOid, varbinds[0].oid)) {</td></tr><tr class=\"hit\"><td class=\"line\">720</td><td class=\"hits\">9</td><td class=\"source\">                if (varbinds[0].value === 'endOfMibView' || varbinds[0].value === 'noSuchObject' || varbinds[0].value === 'noSuchInstance') {</td></tr><tr class=\"miss\"><td class=\"line\">721</td><td class=\"hits\">0</td><td class=\"source\">                    callback(null, vbs);</td></tr><tr><td class=\"line\">722</td><td class=\"hits\"></td><td class=\"source\">                } else {</td></tr><tr class=\"hit\"><td class=\"line\">723</td><td class=\"hits\">9</td><td class=\"source\">                    vbs.push(varbinds[0]);</td></tr><tr class=\"hit\"><td class=\"line\">724</td><td class=\"hits\">9</td><td class=\"source\">                    var next = { oid: varbinds[0].oid };</td></tr><tr class=\"hit\"><td class=\"line\">725</td><td class=\"hits\">9</td><td class=\"source\">                    defaults(next, options);</td></tr><tr class=\"hit\"><td class=\"line\">726</td><td class=\"hits\">9</td><td class=\"source\">                    self.getNext(next, result);</td></tr><tr><td class=\"line\">727</td><td class=\"hits\"></td><td class=\"source\">                }</td></tr><tr><td class=\"line\">728</td><td class=\"hits\"></td><td class=\"source\">            } else {</td></tr><tr class=\"hit\"><td class=\"line\">729</td><td class=\"hits\">2</td><td class=\"source\">                callback(null, vbs);</td></tr><tr><td class=\"line\">730</td><td class=\"hits\"></td><td class=\"source\">            }</td></tr><tr><td class=\"line\">731</td><td class=\"hits\"></td><td class=\"source\">        }</td></tr><tr><td class=\"line\">732</td><td class=\"hits\"></td><td class=\"source\">    }</td></tr><tr><td class=\"line\">733</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">734</td><td class=\"hits\">2</td><td class=\"source\">    self.getNext(options, result);</td></tr><tr><td class=\"line\">735</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">736</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr><td class=\"line\">737</td><td class=\"hits\"></td><td class=\"source\">// Close the socket. Necessary to finish the event loop and exit the program.</td></tr><tr><td class=\"line\">738</td><td class=\"hits\"></td><td class=\"source\"> </td></tr><tr class=\"hit\"><td class=\"line\">739</td><td class=\"hits\">1</td><td class=\"source\">Session.prototype.close = function () {</td></tr><tr class=\"miss\"><td class=\"line\">740</td><td class=\"hits\">0</td><td class=\"source\">    this.socket.close();</td></tr><tr><td class=\"line\">741</td><td class=\"hits\"></td><td class=\"source\">};</td></tr><tr><td class=\"line\">742</td><td class=\"hits\"></td><td class=\"source\"> </td></tr></tbody></table></div></div></div></body></html>"
  },
  {
    "path": "docs/docco.css",
    "content": "/*--------------------- Typography ----------------------------*/\n\n@font-face {\n    font-family: 'aller-light';\n    src: url('public/fonts/aller-light.eot');\n    src: url('public/fonts/aller-light.eot?#iefix') format('embedded-opentype'),\n         url('public/fonts/aller-light.woff') format('woff'),\n         url('public/fonts/aller-light.ttf') format('truetype');\n    font-weight: normal;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'aller-bold';\n    src: url('public/fonts/aller-bold.eot');\n    src: url('public/fonts/aller-bold.eot?#iefix') format('embedded-opentype'),\n         url('public/fonts/aller-bold.woff') format('woff'),\n         url('public/fonts/aller-bold.ttf') format('truetype');\n    font-weight: normal;\n    font-style: normal;\n}\n\n@font-face {\n    font-family: 'novecento-bold';\n    src: url('public/fonts/novecento-bold.eot');\n    src: url('public/fonts/novecento-bold.eot?#iefix') format('embedded-opentype'),\n         url('public/fonts/novecento-bold.woff') format('woff'),\n         url('public/fonts/novecento-bold.ttf') format('truetype');\n    font-weight: normal;\n    font-style: normal;\n}\n\n/*--------------------- Layout ----------------------------*/\nhtml { height: 100%; }\nbody {\n  font-family: \"aller-light\";\n  font-size: 14px;\n  line-height: 18px;\n  color: #30404f;\n  margin: 0; padding: 0;\n  height:100%;\n}\n#container { min-height: 100%; }\n\na {\n  color: #000;\n}\n\nb, strong {\n  font-weight: normal;\n  font-family: \"aller-bold\";\n}\n\np, ul, ol {\n  margin: 15px 0 0px;\n}\n\nh1, h2, h3, h4, h5, h6 {\n  color: #112233;\n  line-height: 1em;\n  font-weight: normal;\n  font-family: \"novecento-bold\";\n  text-transform: uppercase;\n  margin: 30px 0 15px 0;\n}\n\nh1 {\n  margin-top: 40px;\n}\n\nhr {\n  border: 0;\n  background: 1px solid #ddd;\n  height: 1px;\n  margin: 20px 0;\n}\n\npre, tt, code {\n  font-size: 12px; line-height: 16px;\n  font-family: Menlo, Monaco, Consolas, \"Lucida Console\", monospace;\n  margin: 0; padding: 0;\n}\n  .annotation pre {\n    display: block;\n    margin: 0;\n    padding: 7px 10px;\n    background: #fcfcfc;\n    -moz-box-shadow:    inset 0 0 10px rgba(0,0,0,0.1);\n    -webkit-box-shadow: inset 0 0 10px rgba(0,0,0,0.1);\n    box-shadow:         inset 0 0 10px rgba(0,0,0,0.1);\n    overflow-x: auto;\n  }\n    .annotation pre code {\n      border: 0;\n      padding: 0;\n      background: transparent;\n    }\n\n\nblockquote {\n  border-left: 5px solid #ccc;\n  margin: 0;\n  padding: 1px 0 1px 1em;\n}\n  .sections blockquote p {\n    font-family: Menlo, Consolas, Monaco, monospace;\n    font-size: 12px; line-height: 16px;\n    color: #999;\n    margin: 10px 0 0;\n    white-space: pre-wrap;\n  }\n\nul.sections {\n  list-style: none;\n  padding:0 0 5px 0;;\n  margin:0;\n}\n\n/*\n  Force border-box so that % widths fit the parent\n  container without overlap because of margin/padding.\n\n  More Info : http://www.quirksmode.org/css/box.html\n*/\nul.sections > li > div {\n  -moz-box-sizing: border-box;    /* firefox */\n  -ms-box-sizing: border-box;     /* ie */\n  -webkit-box-sizing: border-box; /* webkit */\n  -khtml-box-sizing: border-box;  /* konqueror */\n  box-sizing: border-box;         /* css3 */\n}\n\n\n/*---------------------- Jump Page -----------------------------*/\n#jump_to, #jump_page {\n  margin: 0;\n  background: white;\n  -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777;\n  -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px;\n  font: 16px Arial;\n  cursor: pointer;\n  text-align: right;\n  list-style: none;\n}\n\n#jump_to a {\n  text-decoration: none;\n}\n\n#jump_to a.large {\n  display: none;\n}\n#jump_to a.small {\n  font-size: 22px;\n  font-weight: bold;\n  color: #676767;\n}\n\n#jump_to, #jump_wrapper {\n  position: fixed;\n  right: 0; top: 0;\n  padding: 10px 15px;\n  margin:0;\n}\n\n#jump_wrapper {\n  display: none;\n  padding:0;\n}\n\n#jump_to:hover #jump_wrapper {\n  display: block;\n}\n\n#jump_page {\n  padding: 5px 0 3px;\n  margin: 0 0 25px 25px;\n}\n\n#jump_page .source {\n  display: block;\n  padding: 15px;\n  text-decoration: none;\n  border-top: 1px solid #eee;\n}\n\n#jump_page .source:hover {\n  background: #f5f5ff;\n}\n\n#jump_page .source:first-child {\n}\n\n/*---------------------- Low resolutions (> 320px) ---------------------*/\n@media only screen and (min-width: 320px) {\n  .pilwrap { display: none; }\n\n  ul.sections > li > div {\n    display: block;\n    padding:5px 10px 0 10px;\n  }\n\n  ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {\n    padding-left: 30px;\n  }\n\n  ul.sections > li > div.content {\n    background: #f5f5ff;\n    overflow-x:auto;\n    -webkit-box-shadow: inset 0 0 5px #e5e5ee;\n    box-shadow: inset 0 0 5px #e5e5ee;\n    border: 1px solid #dedede;\n    margin:5px 10px 5px 10px;\n    padding-bottom: 5px;\n  }\n\n  ul.sections > li > div.annotation pre {\n    margin: 7px 0 7px;\n    padding-left: 15px;\n  }\n\n  ul.sections > li > div.annotation p tt, .annotation code {\n    background: #f8f8ff;\n    border: 1px solid #dedede;\n    font-size: 12px;\n    padding: 0 0.2em;\n  }\n}\n\n/*----------------------  (> 481px) ---------------------*/\n@media only screen and (min-width: 481px) {\n  #container {\n    position: relative;\n  }\n  body {\n    background-color: #F5F5FF;\n    font-size: 15px;\n    line-height: 21px;\n  }\n  pre, tt, code {\n    line-height: 18px;\n  }\n  p, ul, ol {\n    margin: 0 0 15px;\n  }\n\n\n  #jump_to {\n    padding: 5px 10px;\n  }\n  #jump_wrapper {\n    padding: 0;\n  }\n  #jump_to, #jump_page {\n    font: 10px Arial;\n    text-transform: uppercase;\n  }\n  #jump_page .source {\n    padding: 5px 10px;\n  }\n  #jump_to a.large {\n    display: inline-block;\n  }\n  #jump_to a.small {\n    display: none;\n  }\n\n\n\n  #background {\n    position: absolute;\n    top: 0; bottom: 0;\n    width: 350px;\n    background: #fff;\n    border-right: 1px solid #e5e5ee;\n    z-index: -1;\n  }\n\n  ul.sections > li > div.annotation ul, ul.sections > li > div.annotation ol {\n    padding-left: 40px;\n  }\n\n  ul.sections > li {\n    white-space: nowrap;\n  }\n\n  ul.sections > li > div {\n    display: inline-block;\n  }\n\n  ul.sections > li > div.annotation {\n    max-width: 350px;\n    min-width: 350px;\n    min-height: 5px;\n    padding: 13px;\n    overflow-x: hidden;\n    white-space: normal;\n    vertical-align: top;\n    text-align: left;\n  }\n  ul.sections > li > div.annotation pre {\n    margin: 15px 0 15px;\n    padding-left: 15px;\n  }\n\n  ul.sections > li > div.content {\n    padding: 13px;\n    vertical-align: top;\n    background: #f5f5ff;\n    border: none;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n  }\n\n  .pilwrap {\n    position: relative;\n    display: inline;\n  }\n\n  .pilcrow {\n    font: 12px Arial;\n    text-decoration: none;\n    color: #454545;\n    position: absolute;\n    top: 3px; left: -20px;\n    padding: 1px 2px;\n    opacity: 0;\n    -webkit-transition: opacity 0.2s linear;\n  }\n    .for-h1 .pilcrow {\n      top: 47px;\n    }\n    .for-h2 .pilcrow, .for-h3 .pilcrow, .for-h4 .pilcrow {\n      top: 35px;\n    }\n\n  ul.sections > li > div.annotation:hover .pilcrow {\n    opacity: 1;\n  }\n}\n\n/*---------------------- (> 1025px) ---------------------*/\n@media only screen and (min-width: 1025px) {\n\n  body {\n    font-size: 16px;\n    line-height: 24px;\n  }\n\n  #background {\n    width: 525px;\n  }\n  ul.sections > li > div.annotation {\n    max-width: 525px;\n    min-width: 525px;\n    padding: 10px 25px 1px 50px;\n  }\n  ul.sections > li > div.content {\n    padding: 9px 15px 16px 25px;\n  }\n}\n\n/*---------------------- Syntax Highlighting -----------------------------*/\n\ntd.linenos { background-color: #f0f0f0; padding-right: 10px; }\nspan.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n/*\n\ngithub.com style (c) Vasily Polovnyov <vast@whiteants.net>\n\n*/\n\npre code {\n  display: block; padding: 0.5em;\n  color: #000;\n  background: #f8f8ff\n}\n\npre .comment,\npre .template_comment,\npre .diff .header,\npre .javadoc {\n  color: #408080;\n  font-style: italic\n}\n\npre .keyword,\npre .assignment,\npre .literal,\npre .css .rule .keyword,\npre .winutils,\npre .javascript .title,\npre .lisp .title,\npre .subst {\n  color: #954121;\n  /*font-weight: bold*/\n}\n\npre .number,\npre .hexcolor {\n  color: #40a070\n}\n\npre .string,\npre .tag .value,\npre .phpdoc,\npre .tex .formula {\n  color: #219161;\n}\n\npre .title,\npre .id {\n  color: #19469D;\n}\npre .params {\n  color: #00F;\n}\n\npre .javascript .title,\npre .lisp .title,\npre .subst {\n  font-weight: normal\n}\n\npre .class .title,\npre .haskell .label,\npre .tex .command {\n  color: #458;\n  font-weight: bold\n}\n\npre .tag,\npre .tag .title,\npre .rules .property,\npre .django .tag .keyword {\n  color: #000080;\n  font-weight: normal\n}\n\npre .attribute,\npre .variable,\npre .instancevar,\npre .lisp .body {\n  color: #008080\n}\n\npre .regexp {\n  color: #B68\n}\n\npre .class {\n  color: #458;\n  font-weight: bold\n}\n\npre .symbol,\npre .ruby .symbol .string,\npre .ruby .symbol .keyword,\npre .ruby .symbol .keymethods,\npre .lisp .keyword,\npre .tex .special,\npre .input_number {\n  color: #990073\n}\n\npre .builtin,\npre .constructor,\npre .built_in,\npre .lisp .title {\n  color: #0086b3\n}\n\npre .preprocessor,\npre .pi,\npre .doctype,\npre .shebang,\npre .cdata {\n  color: #999;\n  font-weight: bold\n}\n\npre .deletion {\n  background: #fdd\n}\n\npre .addition {\n  background: #dfd\n}\n\npre .diff .change {\n  background: #0086b3\n}\n\npre .chunk {\n  color: #aaa\n}\n\npre .tex .formula {\n  opacity: 0.5;\n}\n"
  },
  {
    "path": "docs/example.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n  <title>example.js</title>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n  <link rel=\"stylesheet\" media=\"all\" href=\"docco.css\" />\n</head>\n<body>\n  <div id=\"container\">\n    <div id=\"background\"></div>\n    \n      <ul id=\"jump_to\">\n        <li>\n          <a class=\"large\" href=\"javascript:void(0);\">Jump To &hellip;</a>\n          <a class=\"small\" href=\"javascript:void(0);\">+</a>\n          <div id=\"jump_wrapper\">\n          <div id=\"jump_page\">\n            \n              \n              <a class=\"source\" href=\"example.html\">\n                example.js\n              </a>\n            \n              \n              <a class=\"source\" href=\"asn1ber.html\">\n                asn1ber.js\n              </a>\n            \n              \n              <a class=\"source\" href=\"snmp.html\">\n                snmp.js\n              </a>\n            \n          </div>\n        </li>\n      </ul>\n    \n    <ul class=\"sections\">\n        \n          <li id=\"title\">\n              <div class=\"annotation\">\n                  <h1>example.js</h1>\n              </div>\n          </li>\n        \n        \n        \n        <li id=\"section-1\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-1\">&#182;</a>\n              </div>\n              <h2>Example code for node-snmp-native.</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-2\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-2\">&#182;</a>\n              </div>\n              <p>This file contains examples of how to use the library.</p>\n<h2>Basic setup</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-3\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-3\">&#182;</a>\n              </div>\n              <p>The snmp object is the main entry point to the library.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> snmp = require(<span class=\"string\">'snmp-native'</span>);\n\n<span class=\"keyword\">var</span> util = require(<span class=\"string\">'util'</span>);\n\n<span class=\"keyword\">var</span> host = <span class=\"string\">'localhost'</span>;\n<span class=\"keyword\">var</span> community = <span class=\"string\">'public'</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-4\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-4\">&#182;</a>\n              </div>\n              <p>A session is required to communicate with an agent.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> session = <span class=\"keyword\">new</span> snmp.Session({ host: host, community: community });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-5\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-5\">&#182;</a>\n              </div>\n              <p>All OIDs are represented as integer arrays.\nThere is no interpretation of string or MIB names.\nThis here is the OID for sysDescr.0.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> oid = [<span class=\"number\">1</span>, <span class=\"number\">3</span>, <span class=\"number\">6</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">0</span>];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-6\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-6\">&#182;</a>\n              </div>\n              <h2>Getting a single value</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-7\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-7\">&#182;</a>\n              </div>\n              <p>This is how you issue a simple get request.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>session.get({ oid: oid }, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(err, varbinds)</span> {</span>\n    <span class=\"keyword\">var</span> vb;\n\n    <span class=\"keyword\">if</span> (err) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-8\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-8\">&#182;</a>\n              </div>\n              <p>If there is an error, such as an SNMP timeout, we&#39;ll end up here.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        console.log(err);\n    } <span class=\"keyword\">else</span> {\n        vb = varbinds[<span class=\"number\">0</span>];\n        console.log(<span class=\"string\">'The system description is \"'</span> + vb.value + <span class=\"string\">'\"'</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-9\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-9\">&#182;</a>\n              </div>\n              <p>The session must be closed when you&#39;re done with it.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    session.close();\n});</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-10\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-10\">&#182;</a>\n              </div>\n              <h2>Parsing an OID string and getting an entire tree</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-11\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-11\">&#182;</a>\n              </div>\n              <p>Here we convert an OID from string representation to array.\nThis is the base OID for the ifName tree.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> oidStr = <span class=\"string\">'.1.3.6.1.2.1.31.1.1.1.1'</span>;\noid = oidStr\n    .split(<span class=\"string\">'.'</span>)\n    .filter(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(s)</span> {</span> <span class=\"keyword\">return</span> s.length &gt; <span class=\"number\">0</span>; })\n    .map(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(s)</span> {</span> <span class=\"keyword\">return</span> parseInt(s, <span class=\"number\">10</span>); });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-12\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-12\">&#182;</a>\n              </div>\n              <p>You can also get an entire subtree (an SNMP walk).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> session2 = <span class=\"keyword\">new</span> snmp.Session({ host: host, community: community });\nsession2.getSubtree({ oid: oid }, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(err, varbinds)</span> {</span>\n    <span class=\"keyword\">if</span> (err) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-13\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-13\">&#182;</a>\n              </div>\n              <p>If there is an error, such as an SNMP timeout, we&#39;ll end up here.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        console.log(err);\n    } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-14\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-14\">&#182;</a>\n              </div>\n              <p>This is the list of varbinds.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        varbinds.forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(vb)</span> {</span>\n            console.log(<span class=\"string\">'Name of interface '</span> + vb.oid[vb.oid.length - <span class=\"number\">1</span>]  + <span class=\"string\">' is \"'</span> + vb.value + <span class=\"string\">'\"'</span>);\n        });\n    }\n\n    session2.close();\n});</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-15\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-15\">&#182;</a>\n              </div>\n              <p>You can get all of a collection of OIDs in one go.\nThe semantics is similar to getSubtree.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> session3 = <span class=\"keyword\">new</span> snmp.Session({ host: host, community: community });\n<span class=\"keyword\">var</span> oids = [[<span class=\"number\">1</span>, <span class=\"number\">3</span>, <span class=\"number\">6</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">0</span>], [<span class=\"number\">1</span>, <span class=\"number\">3</span>, <span class=\"number\">6</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">0</span>]];\nsession3.getAll({ oids: oids }, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(err, varbinds)</span> {</span>\n    varbinds.forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(vb)</span> {</span>\n        console.log(vb.oid + <span class=\"string\">' = '</span> + vb.value);\n    });\n    session3.close();\n});</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-16\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-16\">&#182;</a>\n              </div>\n              <p>You can also create a destination-less &quot;session&quot; to use on multiple\nhosts. This is useful for conserving file descriptors when talking\nto a large number of hosts. This example scans the 192.168.1.0/24\nnetwork for SNMP responders.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> session4 = <span class=\"keyword\">new</span> snmp.Session({ community: community }); <span class=\"comment\">// New session without host parameter. We set community to avoid repeating it later.</span>\n<span class=\"keyword\">var</span> oid = [<span class=\"number\">1</span>, <span class=\"number\">3</span>, <span class=\"number\">6</span>, <span class=\"number\">1</span>, <span class=\"number\">2</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">1</span>, <span class=\"number\">0</span>]; <span class=\"comment\">// sysDescr.0</span>\n<span class=\"keyword\">var</span> cnt = <span class=\"number\">254</span>; <span class=\"comment\">// Expected number of callbacks.</span>\n<span class=\"keyword\">for</span> (<span class=\"keyword\">var</span> i = <span class=\"number\">1</span>; i &lt; <span class=\"number\">255</span>; i++) {\n    <span class=\"comment\">/*jshint loopfunc:true */</span></pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-17\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-17\">&#182;</a>\n              </div>\n              <p>We need a function to get a closure over i.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    (<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(host)</span> {</span>\n        session4.get({ oid: oid, host: host }, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(err, vbs)</span> {</span>\n            <span class=\"keyword\">if</span> (err) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-18\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-18\">&#182;</a>\n              </div>\n              <p>Probably a Timeout.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>                console.log(<span class=\"string\">'Error for '</span> + host + <span class=\"string\">': '</span> + err);\n            } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-19\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-19\">&#182;</a>\n              </div>\n              <p>Print the returned value (sysDescr).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>                <span class=\"keyword\">var</span> vb = vbs[<span class=\"number\">0</span>];\n                console.log(host + <span class=\"string\">': '</span> + vb.oid + <span class=\"string\">' = '</span> + vb.value);\n            }\n\n            <span class=\"keyword\">if</span> (--cnt === <span class=\"number\">0</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-20\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-20\">&#182;</a>\n              </div>\n              <p>All requests have returned, time to close the session and exit.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>                session4.close();\n            }\n        });\n    }(<span class=\"string\">'192.168.1.'</span> + i));\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-21\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-21\">&#182;</a>\n              </div>\n              <h2>Example output</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-22\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-22\">&#182;</a>\n              </div>\n              <p>The expected output is something along these lines.\nNote that the asynchronicity results in the responses\nbeing printed in a different order that what you might\nguess from the above code.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"comment\">/*\n1,3,6,1,2,1,1,1,0 = Solaris anto.nym.se 11.0 physical\n1,3,6,1,2,1,1,2,0 = 1,3,6,1,4,1,8072,3,2,3\nThe system description is \"Solaris anto.nym.se 11.0 physical\"\nName of interface 1 is \"lo0\"\nName of interface 2 is \"e1000g0\"\nName of interface 3 is \"vboxnet0\"\nName of interface 4 is \"e1000g1\"\nName of interface 5 is \"he0\"\nName of interface 6 is \"nym0\"\n&lt;... lots of timeouts for the scan stuff ...&gt;\n*/</span></pre></div></div>\n            \n        </li>\n        \n    </ul>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "docs/public/stylesheets/normalize.css",
    "content": "/*! normalize.css v2.0.1 | MIT License | git.io/normalize */\n\n/* ==========================================================================\n   HTML5 display definitions\n   ========================================================================== */\n\n/*\n * Corrects `block` display not defined in IE 8/9.\n */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nnav,\nsection,\nsummary {\n    display: block;\n}\n\n/*\n * Corrects `inline-block` display not defined in IE 8/9.\n */\n\naudio,\ncanvas,\nvideo {\n    display: inline-block;\n}\n\n/*\n * Prevents modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\n\naudio:not([controls]) {\n    display: none;\n    height: 0;\n}\n\n/*\n * Addresses styling for `hidden` attribute not present in IE 8/9.\n */\n\n[hidden] {\n    display: none;\n}\n\n/* ==========================================================================\n   Base\n   ========================================================================== */\n\n/*\n * 1. Sets default font family to sans-serif.\n * 2. Prevents iOS text size adjust after orientation change, without disabling\n *    user zoom.\n */\n\nhtml {\n    font-family: sans-serif; /* 1 */\n    -webkit-text-size-adjust: 100%; /* 2 */\n    -ms-text-size-adjust: 100%; /* 2 */\n}\n\n/*\n * Removes default margin.\n */\n\nbody {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Links\n   ========================================================================== */\n\n/*\n * Addresses `outline` inconsistency between Chrome and other browsers.\n */\n\na:focus {\n    outline: thin dotted;\n}\n\n/*\n * Improves readability when focused and also mouse hovered in all browsers.\n */\n\na:active,\na:hover {\n    outline: 0;\n}\n\n/* ==========================================================================\n   Typography\n   ========================================================================== */\n\n/*\n * Addresses `h1` font sizes within `section` and `article` in Firefox 4+,\n * Safari 5, and Chrome.\n */\n\nh1 {\n    font-size: 2em;\n}\n\n/*\n * Addresses styling not present in IE 8/9, Safari 5, and Chrome.\n */\n\nabbr[title] {\n    border-bottom: 1px dotted;\n}\n\n/*\n * Addresses style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\n\nb,\nstrong {\n    font-weight: bold;\n}\n\n/*\n * Addresses styling not present in Safari 5 and Chrome.\n */\n\ndfn {\n    font-style: italic;\n}\n\n/*\n * Addresses styling not present in IE 8/9.\n */\n\nmark {\n    background: #ff0;\n    color: #000;\n}\n\n\n/*\n * Corrects font family set oddly in Safari 5 and Chrome.\n */\n\ncode,\nkbd,\npre,\nsamp {\n    font-family: monospace, serif;\n    font-size: 1em;\n}\n\n/*\n * Improves readability of pre-formatted text in all browsers.\n */\n\npre {\n    white-space: pre;\n    white-space: pre-wrap;\n    word-wrap: break-word;\n}\n\n/*\n * Sets consistent quote types.\n */\n\nq {\n    quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\n/*\n * Addresses inconsistent and variable font size in all browsers.\n */\n\nsmall {\n    font-size: 80%;\n}\n\n/*\n * Prevents `sub` and `sup` affecting `line-height` in all browsers.\n */\n\nsub,\nsup {\n    font-size: 75%;\n    line-height: 0;\n    position: relative;\n    vertical-align: baseline;\n}\n\nsup {\n    top: -0.5em;\n}\n\nsub {\n    bottom: -0.25em;\n}\n\n/* ==========================================================================\n   Embedded content\n   ========================================================================== */\n\n/*\n * Removes border when inside `a` element in IE 8/9.\n */\n\nimg {\n    border: 0;\n}\n\n/*\n * Corrects overflow displayed oddly in IE 9.\n */\n\nsvg:not(:root) {\n    overflow: hidden;\n}\n\n/* ==========================================================================\n   Figures\n   ========================================================================== */\n\n/*\n * Addresses margin not present in IE 8/9 and Safari 5.\n */\n\nfigure {\n    margin: 0;\n}\n\n/* ==========================================================================\n   Forms\n   ========================================================================== */\n\n/*\n * Define consistent border, margin, and padding.\n */\n\nfieldset {\n    border: 1px solid #c0c0c0;\n    margin: 0 2px;\n    padding: 0.35em 0.625em 0.75em;\n}\n\n/*\n * 1. Corrects color not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\n\nlegend {\n    border: 0; /* 1 */\n    padding: 0; /* 2 */\n}\n\n/*\n * 1. Corrects font family not being inherited in all browsers.\n * 2. Corrects font size not being inherited in all browsers.\n * 3. Addresses margins set differently in Firefox 4+, Safari 5, and Chrome\n */\n\nbutton,\ninput,\nselect,\ntextarea {\n    font-family: inherit; /* 1 */\n    font-size: 100%; /* 2 */\n    margin: 0; /* 3 */\n}\n\n/*\n * Addresses Firefox 4+ setting `line-height` on `input` using `!important` in\n * the UA stylesheet.\n */\n\nbutton,\ninput {\n    line-height: normal;\n}\n\n/*\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *    and `video` controls.\n * 2. Corrects inability to style clickable `input` types in iOS.\n * 3. Improves usability and consistency of cursor style between image-type\n *    `input` and others.\n */\n\nbutton,\nhtml input[type=\"button\"], /* 1 */\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n    -webkit-appearance: button; /* 2 */\n    cursor: pointer; /* 3 */\n}\n\n/*\n * Re-set default cursor for disabled elements.\n */\n\nbutton[disabled],\ninput[disabled] {\n    cursor: default;\n}\n\n/*\n * 1. Addresses box sizing set to `content-box` in IE 8/9.\n * 2. Removes excess padding in IE 8/9.\n */\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n    box-sizing: border-box; /* 1 */\n    padding: 0; /* 2 */\n}\n\n/*\n * 1. Addresses `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Addresses `box-sizing` set to `border-box` in Safari 5 and Chrome\n *    (include `-moz` to future-proof).\n */\n\ninput[type=\"search\"] {\n    -webkit-appearance: textfield; /* 1 */\n    -moz-box-sizing: content-box;\n    -webkit-box-sizing: content-box; /* 2 */\n    box-sizing: content-box;\n}\n\n/*\n * Removes inner padding and search cancel button in Safari 5 and Chrome\n * on OS X.\n */\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n    -webkit-appearance: none;\n}\n\n/*\n * Removes inner padding and border in Firefox 4+.\n */\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n    border: 0;\n    padding: 0;\n}\n\n/*\n * 1. Removes default vertical scrollbar in IE 8/9.\n * 2. Improves readability and alignment in all browsers.\n */\n\ntextarea {\n    overflow: auto; /* 1 */\n    vertical-align: top; /* 2 */\n}\n\n/* ==========================================================================\n   Tables\n   ========================================================================== */\n\n/*\n * Remove most spacing between table cells.\n */\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0;\n}"
  },
  {
    "path": "docs/snmp.html",
    "content": "<!DOCTYPE html>\n\n<html>\n<head>\n  <title>snmp.js</title>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <meta name=\"viewport\" content=\"width=device-width, target-densitydpi=160dpi, initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n  <link rel=\"stylesheet\" media=\"all\" href=\"docco.css\" />\n</head>\n<body>\n  <div id=\"container\">\n    <div id=\"background\"></div>\n    \n      <ul id=\"jump_to\">\n        <li>\n          <a class=\"large\" href=\"javascript:void(0);\">Jump To &hellip;</a>\n          <a class=\"small\" href=\"javascript:void(0);\">+</a>\n          <div id=\"jump_wrapper\">\n          <div id=\"jump_page\">\n            \n              \n              <a class=\"source\" href=\"example.html\">\n                example.js\n              </a>\n            \n              \n              <a class=\"source\" href=\"asn1ber.html\">\n                asn1ber.js\n              </a>\n            \n              \n              <a class=\"source\" href=\"snmp.html\">\n                snmp.js\n              </a>\n            \n          </div>\n        </li>\n      </ul>\n    \n    <ul class=\"sections\">\n        \n          <li id=\"title\">\n              <div class=\"annotation\">\n                  <h1>snmp.js</h1>\n              </div>\n          </li>\n        \n        \n        \n        <li id=\"section-1\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-1\">&#182;</a>\n              </div>\n              <h2>Introduction</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-2\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-2\">&#182;</a>\n              </div>\n              <p>This is <code>node-snmp-native</code>, a native (Javascript) implementation of an SNMP\nclient library targeted at Node.js. It&#39;s MIT licensed and available at\n<a href=\"https://github.com/calmh/node-snmp-native\">https://github.com/calmh/node-snmp-native</a></p>\n<p>(c) 2012 Jakob Borg, Nym Networks</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"string\">\"use strict\"</span>;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-3\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-3\">&#182;</a>\n              </div>\n              <h2>Code</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-4\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-4\">&#182;</a>\n              </div>\n              <p>This file implements a structure representing an SNMP message\nand routines for converting to and from the network representation.</p>\n<p>Define our external dependencies.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> assert = require(<span class=\"string\">'assert'</span>);\n<span class=\"keyword\">var</span> dgram = require(<span class=\"string\">'dgram'</span>);\n<span class=\"keyword\">var</span> events = require(<span class=\"string\">'events'</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-5\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-5\">&#182;</a>\n              </div>\n              <p>We also need our ASN.1 BER en-/decoding routines.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"keyword\">var</span> asn1ber = require(<span class=\"string\">'./asn1ber'</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-6\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-6\">&#182;</a>\n              </div>\n              <h2>Basic structures</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-7\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-7\">&#182;</a>\n              </div>\n              <p>A <code>VarBind</code> is the innermost structure, containing an OID-Value pair.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">VarBind</span><span class=\"params\">()</span> {</span>\n    <span class=\"keyword\">this</span>.type = <span class=\"number\">5</span>;\n    <span class=\"keyword\">this</span>.value = <span class=\"literal\">null</span>;\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-8\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-8\">&#182;</a>\n              </div>\n              <p>The <code>PDU</code> contains the SNMP request or response fields and a list of <code>VarBinds</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">PDU</span><span class=\"params\">()</span> {</span>\n    <span class=\"keyword\">this</span>.type = asn1ber.pduTypes.GetRequestPDU;\n    <span class=\"keyword\">this</span>.reqid = <span class=\"number\">1</span>;\n    <span class=\"keyword\">this</span>.error = <span class=\"number\">0</span>;\n    <span class=\"keyword\">this</span>.errorIndex = <span class=\"number\">0</span>;\n    <span class=\"keyword\">this</span>.varbinds = [ <span class=\"keyword\">new</span> VarBind() ];\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-9\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-9\">&#182;</a>\n              </div>\n              <p>The <code>Packet</code> contains the SNMP version and community and the <code>PDU</code>.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Packet</span><span class=\"params\">()</span> {</span>\n    <span class=\"keyword\">this</span>.version = <span class=\"number\">1</span>;\n    <span class=\"keyword\">this</span>.community = <span class=\"string\">'public'</span>;\n    <span class=\"keyword\">this</span>.pdu = <span class=\"keyword\">new</span> PDU();\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-10\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-10\">&#182;</a>\n              </div>\n              <p>Allow consumers to create packet structures from scratch.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.Packet = Packet;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-11\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-11\">&#182;</a>\n              </div>\n              <h2>Private helper functions</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-12\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-12\">&#182;</a>\n              </div>\n              <p>Concatenate several buffers to one.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">concatBuffers</span><span class=\"params\">(buffers)</span> {</span>\n    <span class=\"keyword\">var</span> total, cur = <span class=\"number\">0</span>, buf;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-13\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-13\">&#182;</a>\n              </div>\n              <p>First we calculate the total length,</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    total = buffers.reduce(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(tot, b)</span> {</span>\n        <span class=\"keyword\">return</span> tot + b.length;\n    }, <span class=\"number\">0</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-14\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-14\">&#182;</a>\n              </div>\n              <p>then we allocate a new Buffer large enough to contain all data,</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    buf = <span class=\"keyword\">new</span> Buffer(total);\n    buffers.forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(buffer)</span> {</span></pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-15\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-15\">&#182;</a>\n              </div>\n              <p>finally we copy the data into the new larger buffer.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        buffer.copy(buf, cur, <span class=\"number\">0</span>);\n        cur += buffer.length;\n    });\n\n    <span class=\"keyword\">return</span> buf;\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-16\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-16\">&#182;</a>\n              </div>\n              <p>Clear a pending packet when it times out or is successfully received.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">clearRequest</span><span class=\"params\">(reqs, reqid)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>;\n\n    <span class=\"keyword\">var</span> entry = reqs[reqid];\n    <span class=\"keyword\">if</span> (entry) {\n        <span class=\"keyword\">if</span> (entry.timeout) {\n            clearTimeout(entry.timeout);\n        }\n        <span class=\"keyword\">delete</span> reqs[reqid];\n    }\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-17\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-17\">&#182;</a>\n              </div>\n              <p>Convert a string formatted OID to an array, leaving anything non-string alone.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">parseSingleOid</span><span class=\"params\">(oid)</span> {</span>\n    <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> oid !== <span class=\"string\">'string'</span>) {\n        <span class=\"keyword\">return</span> oid;\n    }\n\n    <span class=\"keyword\">if</span> (oid[<span class=\"number\">0</span>] !== <span class=\"string\">'.'</span>) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Invalid OID format'</span>);\n    }\n\n    oid = oid.split(<span class=\"string\">'.'</span>)\n        .filter(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(s)</span> {</span>\n            <span class=\"keyword\">return</span> s.length &gt; <span class=\"number\">0</span>;\n        })\n        .map(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(s)</span> {</span>\n            <span class=\"keyword\">return</span> parseInt(s, <span class=\"number\">10</span>);\n        });\n\n    <span class=\"keyword\">return</span> oid;\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-18\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-18\">&#182;</a>\n              </div>\n              <p>Fix any OIDs in the &#39;oid&#39; or &#39;oids&#39; objects that are passed as strings.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">parseOids</span><span class=\"params\">(options)</span> {</span>\n    <span class=\"keyword\">if</span> (options.oid) {\n        options.oid = parseSingleOid(options.oid);\n    }\n    <span class=\"keyword\">if</span> (options.oids) {\n        options.oids = options.oids.map(parseSingleOid);\n    }\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-19\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-19\">&#182;</a>\n              </div>\n              <p>Update targ with attributes from _defs.\nAny existing attributes on targ are untouched.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">defaults</span><span class=\"params\">(targ, _defs)</span> {</span>\n    [].slice.call(arguments, <span class=\"number\">1</span>).forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(def)</span> {</span>\n        Object.keys(def).forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(key)</span> {</span>\n            <span class=\"keyword\">if</span> (!targ.hasOwnProperty(key)) {\n                targ[key] = def[key];\n            }\n        });\n    });\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-20\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-20\">&#182;</a>\n              </div>\n              <h2>Encode structure to ASN.1 BER</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-21\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-21\">&#182;</a>\n              </div>\n              <p>Return an ASN.1 BER encoding of a Packet structure.\nThis is suitable for transmission on a UDP socket.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">encode</span><span class=\"params\">(pkt)</span> {</span>\n    <span class=\"keyword\">var</span> version, community, reqid, err, erridx, vbs, pdu, message;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-22\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-22\">&#182;</a>\n              </div>\n              <p>We only support SNMPv2c, so enforce that version stamp.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">if</span> (pkt.version !== <span class=\"number\">1</span>) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Only SNMPv2c is supported.'</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-23\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-23\">&#182;</a>\n              </div>\n              <p>Encode the message header fields.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    version = asn1ber.encodeInteger(pkt.version);\n    community = asn1ber.encodeOctetString(pkt.community);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-24\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-24\">&#182;</a>\n              </div>\n              <p>Encode the PDU header fields.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    reqid = asn1ber.encodeInteger(pkt.pdu.reqid);\n    err = asn1ber.encodeInteger(pkt.pdu.error);\n    erridx = asn1ber.encodeInteger(pkt.pdu.errorIndex);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-25\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-25\">&#182;</a>\n              </div>\n              <p>Encode the PDU varbinds.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    vbs = [];\n    pkt.pdu.varbinds.forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(vb)</span> {</span>\n        <span class=\"keyword\">var</span> oid = asn1ber.encodeOid(vb.oid), val;\n\n        <span class=\"keyword\">if</span> (vb.type === asn1ber.types.Null) {\n            val = asn1ber.encodeNull();\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.Integer) {\n            val = asn1ber.encodeInteger(vb.value);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.IpAddress) {\n            val = asn1ber.encodeIpAddress(vb.value);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.OctetString) {\n            val = asn1ber.encodeOctetString(vb.value);\n        } <span class=\"keyword\">else</span> {\n            <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Unknown varbind type \"'</span> + vb.type + <span class=\"string\">'\" in encoding.'</span>);\n        }\n        vbs.push(asn1ber.encodeSequence(concatBuffers([oid, val])));\n    });</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-26\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-26\">&#182;</a>\n              </div>\n              <p>Concatenate all the varbinds together.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    vbs = asn1ber.encodeSequence(concatBuffers(vbs));</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-27\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-27\">&#182;</a>\n              </div>\n              <p>Create the PDU by concatenating the inner fields and adding a request structure around it.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pdu = asn1ber.encodeRequest(pkt.pdu.type, concatBuffers([reqid, err, erridx, vbs]));</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-28\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-28\">&#182;</a>\n              </div>\n              <p>Create the message by concatenating the header fields and the PDU.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    message = asn1ber.encodeSequence(concatBuffers([version, community, pdu]));\n\n    <span class=\"keyword\">return</span> message;\n}\n\nexports.encode = encode;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-29\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-29\">&#182;</a>\n              </div>\n              <h2>Parse ASN.1 BER into a structure</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-30\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-30\">&#182;</a>\n              </div>\n              <p>Parse an SNMP packet into its component fields.\nWe don&#39;t do a lot of validation so a malformed packet will probably just\nmake us blow up.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">parse</span><span class=\"params\">(buf)</span> {</span>\n    <span class=\"keyword\">var</span> pkt, oid, bvb, vb, hdr;\n\n    pkt = <span class=\"keyword\">new</span> Packet();</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-31\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-31\">&#182;</a>\n              </div>\n              <p>First we have a sequence marker (two bytes).\nWe don&#39;t care about those, so cut them off.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    hdr = asn1ber.typeAndLength(buf);\n    assert.equal(asn1ber.types.Sequence, hdr.type);\n    buf = buf.slice(hdr.header);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-32\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-32\">&#182;</a>\n              </div>\n              <p>Then comes the version field (integer). Parse it and slice it.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pkt.version = asn1ber.parseInteger(buf.slice(<span class=\"number\">0</span>, buf[<span class=\"number\">1</span>] + <span class=\"number\">2</span>));\n    buf = buf.slice(<span class=\"number\">2</span> + buf[<span class=\"number\">1</span>]);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-33\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-33\">&#182;</a>\n              </div>\n              <p>We then get the community. Parse and slice.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pkt.community = asn1ber.parseOctetString(buf.slice(<span class=\"number\">0</span>, buf[<span class=\"number\">1</span>] + <span class=\"number\">2</span>));\n    buf = buf.slice(<span class=\"number\">2</span> + buf[<span class=\"number\">1</span>]);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-34\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-34\">&#182;</a>\n              </div>\n              <p>Here&#39;s the PDU structure. We&#39;re interested in the type. Slice the rest.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    hdr = asn1ber.typeAndLength(buf);\n    assert.ok(hdr.type &gt;= <span class=\"number\">0xA0</span>);\n    pkt.pdu.type = hdr.type - <span class=\"number\">0xA0</span>;\n    buf = buf.slice(hdr.header);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-35\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-35\">&#182;</a>\n              </div>\n              <p>The request id field.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pkt.pdu.reqid = asn1ber.parseInteger(buf.slice(<span class=\"number\">0</span>, buf[<span class=\"number\">1</span>] + <span class=\"number\">2</span>));\n    buf = buf.slice(<span class=\"number\">2</span> + buf[<span class=\"number\">1</span>]);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-36\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-36\">&#182;</a>\n              </div>\n              <p>The error field.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pkt.pdu.error = asn1ber.parseInteger(buf.slice(<span class=\"number\">0</span>, buf[<span class=\"number\">1</span>] + <span class=\"number\">2</span>));\n    buf = buf.slice(<span class=\"number\">2</span> + buf[<span class=\"number\">1</span>]);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-37\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-37\">&#182;</a>\n              </div>\n              <p>The error index field.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pkt.pdu.errorIndex = asn1ber.parseInteger(buf.slice(<span class=\"number\">0</span>, buf[<span class=\"number\">1</span>] + <span class=\"number\">2</span>));\n    buf = buf.slice(<span class=\"number\">2</span> + buf[<span class=\"number\">1</span>]);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-38\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-38\">&#182;</a>\n              </div>\n              <p>Here&#39;s the varbind list. Not interested.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    hdr = asn1ber.typeAndLength(buf);\n    assert.equal(asn1ber.types.Sequence, hdr.type);\n    buf = buf.slice(hdr.header);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-39\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-39\">&#182;</a>\n              </div>\n              <p>Now comes the varbinds. There might be many, so we loop for as long as we have data.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    pkt.pdu.varbinds = [];\n    <span class=\"keyword\">while</span> (buf[<span class=\"number\">0</span>] === asn1ber.types.Sequence) {\n        vb = <span class=\"keyword\">new</span> VarBind();</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-40\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-40\">&#182;</a>\n              </div>\n              <p>Slice off the sequence header.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        hdr = asn1ber.typeAndLength(buf);\n        assert.equal(asn1ber.types.Sequence, hdr.type);\n        bvb = buf.slice(hdr.header);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-41\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-41\">&#182;</a>\n              </div>\n              <p>Parse and save the ObjectIdentifier.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        vb.oid = asn1ber.parseOid(bvb);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-42\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-42\">&#182;</a>\n              </div>\n              <p>Parse the value. We use the type marker to figure out\nwhat kind of value it is and call the appropriate parser\nroutine. For the SNMPv2c error types, we simply set the\nvalue to a text representation of the error and leave handling\nup to the user.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        bvb = bvb.slice(<span class=\"number\">2</span> + bvb[<span class=\"number\">1</span>]);\n        vb.type = bvb[<span class=\"number\">0</span>];\n        <span class=\"keyword\">if</span> (vb.type === asn1ber.types.Null) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-43\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-43\">&#182;</a>\n              </div>\n              <p>Null type.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = <span class=\"literal\">null</span>;\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.OctetString) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-44\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-44\">&#182;</a>\n              </div>\n              <p>Octet string type.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = asn1ber.parseOctetString(bvb);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.Integer ||\n            vb.type === asn1ber.types.Counter ||\n            vb.type === asn1ber.types.Counter64 ||\n            vb.type === asn1ber.types.TimeTicks ||\n            vb.type === asn1ber.types.Gauge) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-45\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-45\">&#182;</a>\n              </div>\n              <p>Integer type and it&#39;s derivatives that behave in the same manner.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = asn1ber.parseInteger(bvb);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.ObjectIdentifier) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-46\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-46\">&#182;</a>\n              </div>\n              <p>Object identifier type.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = asn1ber.parseOid(bvb);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.IpAddress) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-47\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-47\">&#182;</a>\n              </div>\n              <p>IP Address type.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = asn1ber.parseArray(bvb);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.Opaque) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-48\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-48\">&#182;</a>\n              </div>\n              <p>Opaque type. The &#39;parsing&#39; here is very light; basically we return a\nstring representation of the raw bytes in hex.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = asn1ber.parseOpaque(bvb);\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.EndOfMibView) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-49\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-49\">&#182;</a>\n              </div>\n              <p>End of MIB view error, returned when attempting to GetNext beyond the end\nof the current view.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = <span class=\"string\">'endOfMibView'</span>;\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.NoSuchObject) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-50\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-50\">&#182;</a>\n              </div>\n              <p>No such object error, returned when attempting to Get/GetNext an OID that doesn&#39;t exist.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = <span class=\"string\">'noSuchObject'</span>;\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (vb.type === asn1ber.types.NoSuchInstance) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-51\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-51\">&#182;</a>\n              </div>\n              <p>No such instance error, returned when attempting to Get/GetNext an instance\nthat doesn&#39;t exist in a given table.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            vb.value = <span class=\"string\">'noSuchInstance'</span>;\n        } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-52\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-52\">&#182;</a>\n              </div>\n              <p>Something else that we can&#39;t handle, so throw an error.\nThe error will be caught and presented in a useful manner on stderr,\nwith a dump of the message causing it.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Unrecognized value type '</span> + vb.type);\n        }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-53\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-53\">&#182;</a>\n              </div>\n              <p>Take the raw octet string value and preseve it as a buffer and hex string.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        vb.valueRaw = bvb.slice(<span class=\"number\">2</span>);\n        vb.valueHex = vb.valueRaw.toString(<span class=\"string\">'hex'</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-54\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-54\">&#182;</a>\n              </div>\n              <p>Add the request id to the varbind (even though it doesn&#39;t really belong)\nso that it will be availble to the end user.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        vb.requestId = pkt.pdu.reqid;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-55\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-55\">&#182;</a>\n              </div>\n              <p>Push whatever we parsed to the varbind list.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        pkt.pdu.varbinds.push(vb);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-56\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-56\">&#182;</a>\n              </div>\n              <p>Go fetch the next varbind, if there seems to be any.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">if</span> (buf.length &gt; hdr.header + hdr.len) {\n            buf = buf.slice(hdr.header + hdr.len);\n        } <span class=\"keyword\">else</span> {\n            <span class=\"keyword\">break</span>;\n        }\n    }\n\n    <span class=\"keyword\">return</span> pkt;\n}\n\nexports.parse = parse;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-57\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-57\">&#182;</a>\n              </div>\n              <h2>Utility functions</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-58\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-58\">&#182;</a>\n              </div>\n              <p>Compare two OIDs, returning -1, 0 or +1 depending on the relation between\noidA and oidB.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.compareOids = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(oidA, oidB)</span> {</span>\n    <span class=\"keyword\">var</span> mlen, i;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-59\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-59\">&#182;</a>\n              </div>\n              <p>The undefined OID, if there is any, is deemed lesser.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> oidA === <span class=\"string\">'undefined'</span> &amp;&amp; <span class=\"keyword\">typeof</span> oidB !== <span class=\"string\">'undefined'</span>) {\n        <span class=\"keyword\">return</span> <span class=\"number\">1</span>;\n    } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> oidA !== <span class=\"string\">'undefined'</span> &amp;&amp; <span class=\"keyword\">typeof</span> oidB === <span class=\"string\">'undefined'</span>) {\n        <span class=\"keyword\">return</span> -<span class=\"number\">1</span>;\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-60\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-60\">&#182;</a>\n              </div>\n              <p>Check each number part of the OIDs individually, and if there is any\nposition where one OID is larger than the other, return accordingly.\nThis will only check up to the minimum length of both OIDs.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    mlen = Math.min(oidA.length, oidB.length);\n    <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; mlen; i++) {\n        <span class=\"keyword\">if</span> (oidA[i] &gt; oidB[i]) {\n            <span class=\"keyword\">return</span> -<span class=\"number\">1</span>;\n        } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (oidB[i] &gt; oidA[i]) {\n            <span class=\"keyword\">return</span> <span class=\"number\">1</span>;\n        }\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-61\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-61\">&#182;</a>\n              </div>\n              <p>If there is one OID that is longer than the other after the above comparison,\nconsider the shorter OID to be lesser.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">if</span> (oidA.length &gt; oidB.length) {\n        <span class=\"keyword\">return</span> -<span class=\"number\">1</span>;\n    } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (oidB.length &gt; oidA.length) {\n        <span class=\"keyword\">return</span> <span class=\"number\">1</span>;\n    } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-62\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-62\">&#182;</a>\n              </div>\n              <p>The OIDs are obviously equal.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">return</span> <span class=\"number\">0</span>;\n    }\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-63\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap for-h2\">\n                <a class=\"pilcrow\" href=\"#section-63\">&#182;</a>\n              </div>\n              <h2>Communication functions</h2>\n\n            </div>\n            \n        </li>\n        \n        \n        <li id=\"section-64\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-64\">&#182;</a>\n              </div>\n              <p>This is called for when we receive a message.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">msgReceived</span><span class=\"params\">(msg, rinfo)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, now = Date.now(), pkt, entry;\n\n    <span class=\"keyword\">if</span> (msg.length === <span class=\"number\">0</span>) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-65\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-65\">&#182;</a>\n              </div>\n              <p>Not sure why we sometimes receive an empty message.\nAs far as I&#39;m concerned it shouldn&#39;t happen, but we&#39;ll ignore it\nand if it&#39;s necessary a retransmission of the request will be\nmade later.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">return</span>;\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-66\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-66\">&#182;</a>\n              </div>\n              <p>Parse the packet, or call the informative\nparse error display if we fail.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"keyword\">try</span> {\n        pkt = parse(msg);\n    } <span class=\"keyword\">catch</span> (error) {\n        <span class=\"keyword\">return</span> self.parseError(error, msg);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-67\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-67\">&#182;</a>\n              </div>\n              <p>If this message&#39;s request id matches one we&#39;ve sent,\ncancel any outstanding timeout and call the registered\ncallback.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    entry = self.reqs[pkt.pdu.reqid];\n    <span class=\"keyword\">if</span> (entry) {\n        clearRequest(self.reqs, pkt.pdu.reqid);\n\n        <span class=\"keyword\">if</span> (<span class=\"keyword\">typeof</span> entry.callback === <span class=\"string\">'function'</span>) {\n            pkt.pdu.varbinds.forEach(<span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(vb)</span> {</span>\n                vb.receiveStamp = now;\n                vb.sendStamp = entry.sendStamp;\n            });\n\n            entry.callback(<span class=\"literal\">null</span>, pkt.pdu.varbinds);\n        }\n    } <span class=\"keyword\">else</span> {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-68\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-68\">&#182;</a>\n              </div>\n              <p>This happens if we receive the response to a message we&#39;ve already timed out\nand removed the request entry for. Maybe we shouldn&#39;t even log the warning.</p>\n<p>Calculate the approximate send time and how old the packet is.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">var</span> age = (Date.now() &amp; <span class=\"number\">0x1fffff</span>) - (pkt.pdu.reqid &gt;&gt;&gt; <span class=\"number\">10</span>);\n        <span class=\"keyword\">if</span> (age &lt; <span class=\"number\">0</span>) {\n            age += <span class=\"number\">0x200000</span>;\n        }\n        console.warn(<span class=\"string\">'Response with unknown request ID from '</span> + rinfo.address + <span class=\"string\">'. Consider increasing timeouts ('</span> + age + <span class=\"string\">' ms old?).'</span>);\n    }\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-69\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-69\">&#182;</a>\n              </div>\n              <p>Default options for new sessions and operations.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>exports.defaultOptions = {\n    host: <span class=\"string\">'localhost'</span>,\n    port: <span class=\"number\">161</span>,\n    community: <span class=\"string\">'public'</span>,\n    family: <span class=\"string\">'udp4'</span>,\n    timeouts: [ <span class=\"number\">5000</span>, <span class=\"number\">5000</span>, <span class=\"number\">5000</span>, <span class=\"number\">5000</span> ]\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-70\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-70\">&#182;</a>\n              </div>\n              <p>This creates a new SNMP session.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre><span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">Session</span><span class=\"params\">(options)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>;\n\n    self.options = options || {};\n    defaults(self.options, exports.defaultOptions);\n\n    self.reqs = {};\n    self.socket = dgram.createSocket(self.options.family);\n    self.socket.on(<span class=\"string\">'message'</span>, msgReceived.bind(self));\n    self.socket.on(<span class=\"string\">'close'</span>, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">()</span> {</span></pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-71\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-71\">&#182;</a>\n              </div>\n              <p>Remove the socket so we don&#39;t try to send a message on\nit when it&#39;s closed.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        self.socket = <span class=\"literal\">undefined</span>;\n    });\n    self.socket.on(<span class=\"string\">'error'</span>, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">()</span> {</span></pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-72\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-72\">&#182;</a>\n              </div>\n              <p>Errors will be emitted here as well as on the callback to the send function.\nWe handle them there, so doing anything here is unnecessary.\nBut having no error handler trips up the test suite.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    });\n}</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-73\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-73\">&#182;</a>\n              </div>\n              <p>We inherit from EventEmitter so that we can emit error events\non fatal errors.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype = Object.create(events.EventEmitter.prototype);\nexports.Session = Session;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-74\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-74\">&#182;</a>\n              </div>\n              <p>Generate a request ID. It&#39;s best kept within a signed 32 bit integer.\nUses the current time in ms, shifted left ten bits, plus a counter.\nThis gives us space for 1 transmit every microsecond and wraps every\n~1000 seconds. This is OK since we only need to keep unique ID:s for in\nflight packets and they should be safely timed out by then.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.requestId = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">()</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, now = Date.now();\n\n    <span class=\"keyword\">if</span> (!self.prevTs) {\n        self.prevTs = now;\n        self.counter = <span class=\"number\">0</span>;\n    }\n\n    <span class=\"keyword\">if</span> (now === self.prevTs) {\n        self.counter += <span class=\"number\">1</span>;\n        <span class=\"keyword\">if</span> (self.counter &gt; <span class=\"number\">1023</span>) {\n            <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Request ID counter overflow. Adjust algorithm.'</span>);\n        }\n    } <span class=\"keyword\">else</span> {\n        self.prevTs = now;\n        self.counter = <span class=\"number\">0</span>;\n    }\n\n    <span class=\"keyword\">return</span> ((now &amp; <span class=\"number\">0x1fffff</span>) &lt;<span class=\"xml\"><span class=\"tag\">&lt; <span class=\"attribute\">10</span>) + <span class=\"attribute\">self.counter</span>;\n};\n\n</span></pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-75\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-75\">&#182;</a>\n              </div>\n              <p>Display useful debugging information when a parse error occurs.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.parseError = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(error, buffer)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, hex;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-76\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-76\">&#182;</a>\n              </div>\n              <p>Display a friendly introductory text.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    console.error(<span class=\"string\">'Woops! An error occurred while parsing an SNMP message. :('</span>);\n    console.error(<span class=\"string\">'To have this problem corrected, please report the information below verbatim'</span>);\n    console.error(<span class=\"string\">'via email to snmp@nym.se or by creating a GitHub issue at'</span>);\n    console.error(<span class=\"string\">'https://github.com/calmh/node-snmp-native/issues'</span>);\n    console.error(<span class=\"string\">''</span>);\n    console.error(<span class=\"string\">'Thanks!'</span>);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-77\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-77\">&#182;</a>\n              </div>\n              <p>Display the stack backtrace so we know where the exception happened.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    console.error(<span class=\"string\">''</span>);\n    console.error(error.stack);</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-78\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-78\">&#182;</a>\n              </div>\n              <p>Display the buffer data, nicely formatted so we can replicate the problem.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    console.error(<span class=\"string\">'\\nMessage data:'</span>);\n    hex = buffer.toString(<span class=\"string\">'hex'</span>);\n    <span class=\"keyword\">while</span> (hex.length &gt; <span class=\"number\">0</span>) {\n        console.error(<span class=\"string\">'    '</span> + hex.slice(<span class=\"number\">0</span>, <span class=\"number\">32</span>).replace(<span class=\"regexp\">/([0-9a-f]{2})/g</span>, <span class=\"string\">'$1 '</span>));\n        hex = hex.slice(<span class=\"number\">32</span>);\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-79\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-79\">&#182;</a>\n              </div>\n              <p>Let the exception bubble upwards.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    self.emit(<span class=\"string\">'error'</span>, error);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-80\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-80\">&#182;</a>\n              </div>\n              <p>Send a message. Can be used after manually constructing a correct Packet structure.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.sendMsg = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(pkt, options, callback)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, buf, reqid, retrans = <span class=\"number\">0</span>;\n\n    defaults(options, self.options);\n\n    reqid = self.requestId();\n    pkt.pdu.reqid = reqid;\n\n    buf = encode(pkt);\n\n    <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">transmit</span><span class=\"params\">()</span> {</span>\n        <span class=\"keyword\">if</span> (!self.socket || !self.reqs[reqid]) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-81\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-81\">&#182;</a>\n              </div>\n              <p>The socket has already been closed, perhaps due to an error that ocurred while a timeout\nwas scheduled. We can&#39;t do anything about it now.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>            clearRequest(self.reqs, reqid);\n            <span class=\"keyword\">return</span>;\n        }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-82\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-82\">&#182;</a>\n              </div>\n              <p>Send the message.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        self.socket.send(buf, <span class=\"number\">0</span>, buf.length, options.port, options.host, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(err, bytes)</span> {</span>\n            <span class=\"keyword\">var</span> entry = self.reqs[reqid];\n\n            <span class=\"keyword\">if</span> (err) {\n                clearRequest(self.reqs, reqid);\n                <span class=\"keyword\">return</span> callback(err);\n            } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (entry) {\n                entry.sendStamp = Date.now();\n\n                <span class=\"keyword\">if</span> (options.timeouts[retrans]) {</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-83\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-83\">&#182;</a>\n              </div>\n              <p>Set timeout and record the timer so that we can (attempt to) cancel it when we receive the reply.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>                    entry.timeout = setTimeout(transmit, options.timeouts[retrans]);\n                    retrans += <span class=\"number\">1</span>;\n                } <span class=\"keyword\">else</span> {\n                    clearRequest(self.reqs, reqid);\n                    <span class=\"keyword\">return</span> callback(<span class=\"keyword\">new</span> Error(<span class=\"string\">'Timeout'</span>));\n                }\n            }\n        });\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-84\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-84\">&#182;</a>\n              </div>\n              <p>Register the callback to call when we receive a reply.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    self.reqs[reqid] = { callback: callback };</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-85\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-85\">&#182;</a>\n              </div>\n              <p>Transmit the message.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    transmit();\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-86\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-86\">&#182;</a>\n              </div>\n              <p>Shortcut to create a GetRequest and send it, while registering a callback.\nNeeds <code>options.oid</code> to be an OID in array form.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.get = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(options, callback)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, pkt;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    <span class=\"keyword\">if</span> (!options.oid) {\n        <span class=\"keyword\">return</span> callback(<span class=\"literal\">null</span>, []);\n    }\n\n    pkt = <span class=\"keyword\">new</span> Packet();\n    pkt.community = options.community;\n    pkt.pdu.varbinds[<span class=\"number\">0</span>].oid = options.oid;\n    self.sendMsg(pkt, options, callback);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-87\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-87\">&#182;</a>\n              </div>\n              <p>Shortcut to create a SetRequest and send it, while registering a callback.\nNeeds <code>options.oid</code> to be an OID in array form, <code>options.value</code> to be an\ninteger and <code>options.type</code> to be asn1ber.T.Integer (2).</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.set = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(options, callback)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, pkt;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    <span class=\"keyword\">if</span> (!options.oid) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Missing required option `oid`.'</span>);\n    } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (options.value === <span class=\"literal\">undefined</span>) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Missing required option `value`.'</span>);\n    } <span class=\"keyword\">else</span> <span class=\"keyword\">if</span> (!options.type) {\n        <span class=\"keyword\">throw</span> <span class=\"keyword\">new</span> Error(<span class=\"string\">'Missing required option `type`.'</span>);\n    }\n\n    pkt = <span class=\"keyword\">new</span> Packet();\n    pkt.community = options.community;\n    pkt.pdu.type = asn1ber.pduTypes.SetRequestPDU;\n    pkt.pdu.varbinds[<span class=\"number\">0</span>].oid = options.oid;\n    pkt.pdu.varbinds[<span class=\"number\">0</span>].type = options.type;\n    pkt.pdu.varbinds[<span class=\"number\">0</span>].value = options.value;\n    self.sendMsg(pkt, options, callback);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-88\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-88\">&#182;</a>\n              </div>\n              <p>Shortcut to get all OIDs in the <code>options.oids</code> array sequentially. The\ncallback is called when the entire operation is completed.  If\noptions.abortOnError is truish, an error while getting any of the values\nwill cause the callback to be called with error status. When\n<code>options.abortOnError</code> is falsish (the default), any errors will be ignored\nand any successfully retrieved values sent to the callback.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.getAll = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(options, callback)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, results = [];\n\n    defaults(options, self.options, { abortOnError: <span class=\"literal\">false</span> });\n    parseOids(options);\n\n    <span class=\"keyword\">if</span> (!options.oids || options.oids.length === <span class=\"number\">0</span>) {\n        <span class=\"keyword\">return</span> callback(<span class=\"literal\">null</span>, []);\n    }\n\n    <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">getOne</span><span class=\"params\">(c)</span> {</span>\n        <span class=\"keyword\">var</span> oid, pkt, m, vb;\n\n        pkt = <span class=\"keyword\">new</span> Packet();\n        pkt.community = options.community;\n        pkt.pdu.varbinds = [];</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-89\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-89\">&#182;</a>\n              </div>\n              <p>Push up to 16 varbinds in the same message.\nThe number 16 isn&#39;t really that magical, it&#39;s just a nice round\nnumber that usually seems to fit withing a single packet and gets\naccepted by the switches I&#39;ve tested it on.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>        <span class=\"keyword\">for</span> (m = <span class=\"number\">0</span>; m &lt; <span class=\"number\">16</span> &amp;&amp; c &lt; options.oids.length; m++) {\n            vb = <span class=\"keyword\">new</span> VarBind();\n            vb.oid = options.oids[c];\n            pkt.pdu.varbinds.push(vb);\n            c++;\n        }\n\n        self.sendMsg(pkt, options, <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(err, varbinds)</span> {</span>\n            <span class=\"keyword\">if</span> (options.abortOnError &amp;&amp; err) {\n                callback(err);\n            } <span class=\"keyword\">else</span> {\n                <span class=\"keyword\">if</span> (varbinds) {\n                    results = results.concat(varbinds);\n                }\n                <span class=\"keyword\">if</span> (c &lt; options.oids.length) {\n                    getOne(c);\n                } <span class=\"keyword\">else</span> {\n                    callback(<span class=\"literal\">null</span>, results);\n                }\n            }\n        });\n    }\n\n    getOne(<span class=\"number\">0</span>);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-90\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-90\">&#182;</a>\n              </div>\n              <p>Shortcut to create a GetNextRequest and send it, while registering a callback.\nNeeds <code>options.oid</code> to be an OID in array form.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.getNext = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(options, callback)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, pkt;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    <span class=\"keyword\">if</span> (!options.oid) {\n        <span class=\"keyword\">return</span> callback(<span class=\"literal\">null</span>, []);\n    }\n\n    pkt = <span class=\"keyword\">new</span> Packet();\n    pkt.community = options.community;\n    pkt.pdu.type = <span class=\"number\">1</span>;\n    pkt.pdu.varbinds[<span class=\"number\">0</span>].oid = options.oid;\n    self.sendMsg(pkt, options, callback);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-91\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-91\">&#182;</a>\n              </div>\n              <p>Shortcut to get all entries below the specified OID.\nThe callback will be called once with the list of\nvarbinds that was collected, or with an error object.\nNeeds <code>options.oid</code> to be an OID in array form.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.getSubtree = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">(options, callback)</span> {</span>\n    <span class=\"keyword\">var</span> self = <span class=\"keyword\">this</span>, vbs = [];\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    <span class=\"keyword\">if</span> (!options.oid) {\n        <span class=\"keyword\">return</span> callback(<span class=\"literal\">null</span>, []);\n    }\n\n    options.startOid = options.oid;</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-92\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-92\">&#182;</a>\n              </div>\n              <p>Helper to check whether <code>oid</code> in inside the tree rooted at\n<code>root</code> or not.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">inTree</span><span class=\"params\">(root, oid)</span> {</span>\n        <span class=\"keyword\">var</span> i;\n        <span class=\"keyword\">if</span> (oid.length &lt;= root.length) {\n            <span class=\"keyword\">return</span> <span class=\"literal\">false</span>;\n        }\n        <span class=\"keyword\">for</span> (i = <span class=\"number\">0</span>; i &lt; root.length; i++) {\n            <span class=\"keyword\">if</span> (oid[i] !== root[i]) {\n                <span class=\"keyword\">return</span> <span class=\"literal\">false</span>;\n            }\n        }\n        <span class=\"keyword\">return</span> <span class=\"literal\">true</span>;\n    }</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-93\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-93\">&#182;</a>\n              </div>\n              <p>Helper to handle the result of getNext and call the user&#39;s callback\nas appropriate. The callback will see one of the following patterns:\n - callback([an Error object], undefined) -- an error ocurred.\n - callback(null, [a Packet object]) -- data from under the tree.\n - callback(null, null) -- end of tree.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>    <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"title\">result</span><span class=\"params\">(error, varbinds)</span> {</span>\n        <span class=\"keyword\">if</span> (error) {\n            callback(error);\n        } <span class=\"keyword\">else</span> {\n            <span class=\"keyword\">if</span> (inTree(options.startOid, varbinds[<span class=\"number\">0</span>].oid)) {\n                <span class=\"keyword\">if</span> (varbinds[<span class=\"number\">0</span>].value === <span class=\"string\">'endOfMibView'</span> || varbinds[<span class=\"number\">0</span>].value === <span class=\"string\">'noSuchObject'</span> || varbinds[<span class=\"number\">0</span>].value === <span class=\"string\">'noSuchInstance'</span>) {\n                    callback(<span class=\"literal\">null</span>, vbs);\n                } <span class=\"keyword\">else</span> {\n                    vbs.push(varbinds[<span class=\"number\">0</span>]);\n                    <span class=\"keyword\">var</span> next = { oid: varbinds[<span class=\"number\">0</span>].oid };\n                    defaults(next, options);\n                    self.getNext(next, result);\n                }\n            } <span class=\"keyword\">else</span> {\n                callback(<span class=\"literal\">null</span>, vbs);\n            }\n        }\n    }\n\n    self.getNext(options, result);\n};</pre></div></div>\n            \n        </li>\n        \n        \n        <li id=\"section-94\">\n            <div class=\"annotation\">\n              \n              <div class=\"pilwrap \">\n                <a class=\"pilcrow\" href=\"#section-94\">&#182;</a>\n              </div>\n              <p>Close the socket. Necessary to finish the event loop and exit the program.</p>\n\n            </div>\n            \n            <div class=\"content\"><div class='highlight'><pre>Session.prototype.close = <span class=\"function\"><span class=\"keyword\">function</span> <span class=\"params\">()</span> {</span>\n    <span class=\"keyword\">this</span>.socket.close();\n};</pre></div></div>\n            \n        </li>\n        \n    </ul>\n  </div>\n</body>\n</html>\n"
  },
  {
    "path": "example.js",
    "content": "// Example code for node-snmp-native.\n// ----\n\n// This file contains examples of how to use the library.\n\n// Basic setup\n// -----\n\n// The snmp object is the main entry point to the library.\nvar snmp = require('snmp-native');\n\nvar util = require('util');\n\nvar host = 'localhost';\nvar community = 'public';\n\n// A session is required to communicate with an agent.\nvar session = new snmp.Session({ host: host, community: community });\n\n// All OIDs are represented as integer arrays.\n// There is no interpretation of string or MIB names.\n// This here is the OID for sysDescr.0.\nvar oid = [1, 3, 6, 1, 2, 1, 1, 1, 0];\n\n// Getting a single value\n// -----\n\n// This is how you issue a simple get request.\nsession.get({ oid: oid }, function (err, varbinds) {\n    var vb;\n\n    if (err) {\n        // If there is an error, such as an SNMP timeout, we'll end up here.\n        console.log(err);\n    } else {\n        vb = varbinds[0];\n        console.log('The system description is \"' + vb.value + '\"');\n    }\n\n    // The session must be closed when you're done with it.\n    session.close();\n});\n\n// Parsing an OID string and getting an entire tree\n// -----\n\n// Here we convert an OID from string representation to array.\n// This is the base OID for the ifName tree.\n\nvar oidStr = '.1.3.6.1.2.1.31.1.1.1.1';\noid = oidStr\n    .split('.')\n    .filter(function (s) { return s.length > 0; })\n    .map(function (s) { return parseInt(s, 10); });\n\n// You can also get an entire subtree (an SNMP walk).\n\nvar session2 = new snmp.Session({ host: host, community: community });\nsession2.getSubtree({ oid: oid }, function (err, varbinds) {\n    if (err) {\n        // If there is an error, such as an SNMP timeout, we'll end up here.\n        console.log(err);\n    } else {\n        // This is the list of varbinds.\n        varbinds.forEach(function (vb) {\n            console.log('Name of interface ' + vb.oid[vb.oid.length - 1]  + ' is \"' + vb.value + '\"');\n        });\n    }\n\n    session2.close();\n});\n\n// You can get all of a collection of OIDs in one go.\n// The semantics is similar to getSubtree.\n\nvar session3 = new snmp.Session({ host: host, community: community });\nvar oids = [[1, 3, 6, 1, 2, 1, 1, 1, 0], [1, 3, 6, 1, 2, 1, 1, 2, 0]];\nsession3.getAll({ oids: oids }, function (err, varbinds) {\n    varbinds.forEach(function (vb) {\n        console.log(vb.oid + ' = ' + vb.value);\n    });\n    session3.close();\n});\n\n// You can also create a destination-less \"session\" to use on multiple\n// hosts. This is useful for conserving file descriptors when talking\n// to a large number of hosts. This example scans the 192.168.1.0/24\n// network for SNMP responders.\n\nvar session4 = new snmp.Session({ community: community }); // New session without host parameter. We set community to avoid repeating it later.\nvar oid = [1, 3, 6, 1, 2, 1, 1, 1, 0]; // sysDescr.0\nvar cnt = 254; // Expected number of callbacks.\nfor (var i = 1; i < 255; i++) {\n    /*jshint loopfunc:true */\n    // We need a function to get a closure over i.\n    (function (host) {\n        session4.get({ oid: oid, host: host }, function (err, vbs) {\n            if (err) {\n                // Probably a Timeout.\n                console.log('Error for ' + host + ': ' + err);\n            } else {\n                // Print the returned value (sysDescr).\n                var vb = vbs[0];\n                console.log(host + ': ' + vb.oid + ' = ' + vb.value);\n            }\n\n            if (--cnt === 0) {\n                // All requests have returned, time to close the session and exit.\n                session4.close();\n            }\n        });\n    }('192.168.1.' + i));\n}\n\n// Example output\n// -----\n\n// The expected output is something along these lines.\n// Note that the asynchronicity results in the responses\n// being printed in a different order that what you might\n// guess from the above code.\n\n/*\n1,3,6,1,2,1,1,1,0 = Solaris anto.nym.se 11.0 physical\n1,3,6,1,2,1,1,2,0 = 1,3,6,1,4,1,8072,3,2,3\nThe system description is \"Solaris anto.nym.se 11.0 physical\"\nName of interface 1 is \"lo0\"\nName of interface 2 is \"e1000g0\"\nName of interface 3 is \"vboxnet0\"\nName of interface 4 is \"e1000g1\"\nName of interface 5 is \"he0\"\nName of interface 6 is \"nym0\"\n<... lots of timeouts for the scan stuff ...>\n*/\n\n"
  },
  {
    "path": "lib/asn1ber.js",
    "content": "// This file implements a minimal subset of Abstract Syntax Notation One (**ASN.1**)\n// Basic Encoding Rules (**BER**), namely the parts that are necessary for sending\n// and receiving SNMPv2c messages.\n//\n// (c) 2012 Jakob Borg, Nym Networks\n\n\"use strict\";\n\n// We define constants for the commonly used ASN.1 types in SNMP.\n\nvar T = {\n    Integer: 0x02,\n    OctetString: 0x04,\n    Null: 0x05,\n    ObjectIdentifier: 0x06,\n    Sequence: 0x30,\n    IpAddress: 0x40,\n    Counter: 0x41,\n    Gauge: 0x42,\n    TimeTicks: 0x43,\n    Opaque: 0x44,\n    NsapAddress: 0x45,\n    Counter64: 0x46,\n    NoSuchObject: 0x80,\n    NoSuchInstance: 0x81,\n    EndOfMibView: 0x82,\n    PDUBase: 0xA0\n};\n\nvar P = {\n    GetRequestPDU: 0x00,\n    GetNextRequestPDU: 0x01,\n    GetResponsePDU: 0x02,\n    SetRequestPDU: 0x03\n};\n\nvar E = {\n    NoError: 0,\n    TooBig: 1,\n    NoSuchName: 2,\n    BadValue: 3,\n    ReadOnly: 4,\n    GenErr: 5,\n    NoAccess: 6,\n    WrongType: 7,\n    WrongLength: 8,\n    WrongEncoding: 9,\n    WrongValue: 10,\n    NoCreation: 11,\n    InconsistentValue: 12,\n    ResourceUnavailable: 13,\n    CommitFailed: 14,\n    UndoFailed: 15,\n    AuthorizationError: 16,\n    NotWritable: 17,\n    InconsistentName: 18\n};\n\nvar LOG256 = Math.log(256);\n\n// The types are also available for consumers of the library.\n\nexports.types = T;\nexports.pduTypes = P;\nexports.errors = E;\nexports.unittest = {};\n\n// Private helper functions\n// -----\n\n// Encode a length as it should be encoded.\n\nfunction lengthArray(len) {\n    var arr = [];\n\n    if (len <= 127) {\n        // Return a single byte if the value is 127 or less.\n        return [ len ];\n    } else {\n        // Otherwise encode it as a MSB base-256 integer.\n        while (len > 0) {\n            arr.push(len % 256);\n            len = parseInt(len / 256, 10);\n        }\n        // Add a length byte in front and set the high bit to indicate\n        // that this is a longer value than one byte.\n        arr.push(128 + arr.length);\n        arr.reverse();\n        return arr;\n    }\n}\n\nexports.unittest.lengthArray = lengthArray;\n\n// Return a wrapped copy of the passed `contents`, with the specified wrapper type.\n// This is used for Sequence and other constructed types.\n\nfunction wrapper(type, contents) {\n    var buf, len, i;\n\n    // Get the encoded length of the contents\n    len = lengthArray(contents.length);\n\n    // Set up a buffer with the type and length bytes plus a straight copy of the content.\n    buf = new Buffer(1 + contents.length + len.length);\n    buf[0] = type;\n    for (i = 1; i < len.length + 1; i++) {\n        buf[i] = len[i - 1];\n    }\n    contents.copy(buf, len.length + 1, 0);\n    return buf;\n}\n\n// Get the encoded representation of a number in an OID.\n// If the number is less than 128, pass it as it is.\n// Otherwise return an array of base-128 digits, most significant first,\n// with the high bit set on all octets except the last one.\n// This encoding should be used for all number in an OID except the first\n// two (.1.3) which are handled specially.\n\nfunction oidInt(val) {\n    var bytes = [];\n\n    bytes.push(val % 128);\n    val = parseInt(val / 128, 10);\n    while (val > 127) {\n        bytes.push(128 + val % 128);\n        val = parseInt(val / 128, 10);\n    }\n    bytes.push(val + 128);\n    return bytes.reverse();\n}\n\n// Encode an OID. The first two number are encoded specially\n// in the first octet, then the rest are encoded as one octet per number\n// unless the number exceeds 127. If so, it's encoded as several base-127\n// octets with the high bit set to indicate continuation.\nfunction oidArray(oid) {\n    var bytes, i, val;\n\n    // Enforce some minimum requirements on the OID.\n    if (oid.length < 2) {\n        throw new Error(\"Minimum OID length is two.\");\n    } else if (oid[0] > 2) {\n        throw new Error(\"Invalid OID\");\n    } else if (oid[0] == 0 && oid[1] > 39) {\n        throw new Error(\"Invalid OID\");\n    } else if (oid[0] == 1 && oid[1] > 39) {\n        throw new Error(\"Invalid OID\");\n    } else if (oid[0] == 2 && oid[1] > 79) {\n        throw new Error(\"Invalid OID\");\n    }\n\n    // Calculate the first byte of the encoded OID according to the 'special' rule.\n    bytes = [ 40 * oid[0] + oid[1] ];\n\n    // For the rest of the OID, encode each number individually and add the\n    // resulting bytes to the buffer.\n    for (i = 2; i < oid.length; i++) {\n        val = oid[i];\n        if (val > 127) {\n            bytes = bytes.concat(oidInt(val));\n        } else {\n            bytes.push(val);\n        }\n    }\n\n    return bytes;\n}\n\n// Divide an integer into base-256 bytes.\n// Most significant byte first.\nfunction intArray(val) {\n    var array = [], encVal = val, bytes;\n\n    if (val === 0) {\n        array.push(0);\n    } else {\n        if (val < 0) {\n            bytes = Math.floor(1 + Math.log(-val) / LOG256);\n            // Encode negatives as 32-bit two's complement. Let's hope that fits.\n            encVal += Math.pow(2, 8 * bytes);\n        }\n        while (encVal > 0) {\n            array.push(encVal % 256);\n            encVal = parseInt(encVal / 256, 10);\n        }\n    }\n\n    // Do not produce integers that look negative (high bit\n    // of first byte set).\n    if (val > 0 && array[array.length - 1] >= 0x80) {\n        array.push(0);\n    }\n\n    return array.reverse();\n}\n\n// Functions to encode ASN.1 from native objects\n// -----\n\n// Encode a simple integer.\n// Integers are encoded as a simple base-256 byte sequence, most significant byte first,\n// prefixed with a length byte. In principle we support arbitrary integer sizes, in practice\n// Javascript doesn't even **have** integers so some precision might get lost.\n\nfunction encodeIntegerish(val, type) {\n    var i, arr, buf;\n\n    // Get the bytes that we're going to encode.\n    arr = intArray(val);\n\n    // Now that we know the length, we allocate a buffer of the required size.\n    // We set the type and length bytes appropriately.\n    buf = new Buffer(2 + arr.length);\n    buf[0] = type;\n    buf[1] = arr.length;\n\n    // Copy the bytes into the array.\n    for (i = 0; i < arr.length; i++) {\n        buf[i + 2] = arr[i];\n    }\n\n    return buf;\n}\n\n// Integer type, 0x02\nexports.encodeInteger = function (val) {\n    return(encodeIntegerish(val, T.Integer));\n};\n\n// Gauge type, 0x42\nexports.encodeGauge = function (val) {\n    return(encodeIntegerish(val, T.Gauge));\n};\n\n// Counter type, 0x41\nexports.encodeCounter = function (val) {\n    return(encodeIntegerish(val, T.Counter));\n};\n\n// TimeTicks type, 0x43\nexports.encodeTimeTicks = function (val) {\n    return(encodeIntegerish(val, T.TimeTicks));\n};\n\n// Create the representation of a Null, `05 00`.\n\nexports.encodeNull = function () {\n    var buf = new Buffer(2);\n    buf[0] = T.Null;\n    buf[1] = 0;\n    return buf;\n};\n\n// NoSuchObject type, 0x80\nexports.encodeNoSuchObject = function() {\n    var buf = new Buffer(2);\n    buf[0] = T.NoSuchObject;\n    buf[1] = 0;\n    return buf;\n};\n\n// NoSuchInstance type, 0x81\nexports.encodeNoSuchInstance = function() {\n    var buf = new Buffer(2);\n    buf[0] = T.NoSuchInstance;\n    buf[1] = 0;\n    return buf;\n};\n\n// EndOfMibView type, 0x82\nexports.encodeEndOfMibView = function() {\n    var buf = new Buffer(2);\n    buf[0] = T.EndOfMibView;\n    buf[1] = 0;\n    return buf;\n};\n\n// Encode a Sequence, which is a wrapper of type `30`.\n\nexports.encodeSequence = function (contents) {\n    return wrapper(T.Sequence, contents);\n};\n\n// Encode an OctetString, which is a wrapper of type `04`.\n\nexports.encodeOctetString = function (string) {\n    var buf, contents;\n\n    if (typeof string === 'string') {\n        contents = new Buffer(string);\n    } else if (Buffer.isBuffer(string)) {\n        contents = string;\n    } else {\n        throw new Error('Only Buffer and string types are acceptable as OctetString.');\n    }\n\n    return wrapper(T.OctetString, contents);\n};\n\n// Encode an IpAddress, which is a wrapper of type `40`.\n\nexports.encodeIpAddress = function (address) {\n    var contents, octets, value = [];\n\n    if (typeof address !== 'string' && !Buffer.isBuffer(address)) {\n        throw new Error('Only Buffer and string types are acceptable as OctetString.');\n    }\n\n    // assume that the string is in dotted decimal format ipv4\n    // also, use toString in case a buffer was passed in.\n\n    octets = address.toString().split('.');\n    if (octets.length !== 4) {\n        throw new Error('IP Addresses must be specified in dotted decimal format.');\n    }\n    octets.forEach(function (octet) {\n        var octetValue = parseInt(octet, 10);\n        if (octet < 0 || octet > 255) {\n            throw new Error('IP Address octets must be between 0 and 255 inclusive.' + JSON.stringify(octets));\n        }\n        value.push(octetValue);\n    });\n\n    contents = new Buffer(value);\n\n    return wrapper(T.IpAddress, contents);\n};\n\n// Encode an ObjectId.\n\nexports.encodeOid = function (oid) {\n    var buf, bytes, i, len;\n\n    // Get the encoded format of the OID.\n    bytes = oidArray(oid);\n\n    // Get the encoded format of the length\n    len = lengthArray(bytes.length);\n\n    // Fill in the buffer with type, length and OID data.\n    buf = new Buffer(1 + bytes.length + len.length);\n    buf[0] = T.ObjectIdentifier;\n    for (i = 1; i < len.length + 1; i++) {\n        buf[i] = len[i - 1];\n    }\n    for (i = len.length + 1; i < bytes.length + len.length + 1; i++) {\n        buf[i] = bytes[i - len.length - 1];\n    }\n\n    return buf;\n};\n\n// Encode an SNMP request with specified `contents`.\n// The `type` code is 0 for `GetRequest`, 1 for `GetNextRequest`.\n\nexports.encodeRequest = function (type, contents) {\n    return wrapper(T.PDUBase + type, contents);\n};\n\n// Functions to parse ASN.1 to native objects\n// -----\n\n// Parse and return type, data length and header length.\nfunction typeAndLength(buf) {\n    var res, len, i;\n\n    res = { type: buf[0], len: 0, header: 1 };\n    if (buf[1] < 128) {\n        // If bit 8 is zero, this byte indicates the content length (up to 127 bytes).\n        res.len = buf[1];\n        res.header += 1;\n    } else {\n        // If bit 8 is 1, bits 0 to 7 indicate the number of following legth bytes.\n        // These bytes are a simple msb base-256 integer indicating the content length.\n        for (i = 0; i < buf[1] - 128; i++) {\n            res.len *= 256;\n            res.len += buf[i + 2];\n        }\n        res.header += buf[1] - 128 + 1;\n    }\n    return res;\n}\n\nexports.typeAndLength = typeAndLength;\n\n// Parse a buffer containing a representation of an integer.\n// Verifies the type, then multiplies in each byte as it comes.\n\nexports.parseInteger = function (buf) {\n    var i, val, type, len;\n\n    type = buf[0];\n    len = buf[1];\n\n    if (type !== T.Integer && type !== T.Counter &&\n        type !== T.Counter64 && type !== T.Gauge &&\n        type !== T.TimeTicks) {\n        throw new Error('Buffer ' + buf.toString('hex') + ' does not appear to be an Integer');\n    }\n\n    val = 0;\n    for (i = 0; i < len; i++) {\n        val *= 256;\n        val += buf[i + 2];\n    }\n\n    if (buf[2] > 127 && type === T.Integer) {\n        return val - Math.pow(2, 8 * buf[1]);\n    } else {\n        return val;\n    }\n};\n\n// Parse a buffer containing a representation of an OctetString.\n// Verify the type, then just grab the string out of the buffer.\n\nexports.parseOctetString = function (buf) {\n    var i, len, lenBytes = 0;\n\n    if (buf[0] !== T.OctetString) {\n        throw new Error('Buffer does not appear to be an OctetString');\n    }\n\n    // SNMP doesn't specify an encoding so I pick UTF-8 as the 'most standard'\n    // encoding. We'll see if that assumption survives contact with actual reality.\n\n    len = buf[1];\n    if (len > 128) {\n        // Multi byte length encoding\n        lenBytes = len - 128;\n        len = 0;\n        for (i = 0; i < lenBytes; i++) {\n            len *= 256;\n            len += buf[2+i];\n        }\n    }\n    return buf.toString('utf-8', 2 + lenBytes, 2 + lenBytes + len);\n};\n\n// Parse a buffer containing a representation of an ObjectIdentifier.\n// Verify the type, then apply the relevent encoding rules.\n\nexports.parseOid = function (buf) {\n    var oid, val, i, o1, o2;\n\n    if (buf[0] !== T.ObjectIdentifier) {\n        throw new Error('Buffer does not appear to be an ObjectIdentifier');\n    }\n\n    // The first byte contains the first two numbers in the OID. They're\n    // magical! They're compactly encoded in a special way! KILL ME NOW!\n    o1 = parseInt(buf[2] / 40, 10);\n    if (o1 > 2) {\n        o1 = 2;\n    }\n    o2 = buf[2] - 40 * o1;\n    oid = [o1, o2];\n\n    // The rest of the data is a base-128-encoded OID\n    for (i = 0; i < buf[1] - 1; i++) {\n        val = 0;\n        while (buf[i + 3] >= 128) {\n            val += buf[i + 3] - 128;\n            val *= 128;\n            i++;\n        }\n        val += buf[i + 3];\n        oid.push(val);\n    }\n\n    return oid;\n};\n\n// Parse a buffer containing a representation of an array type.\n// This is for example an IpAddress.\n\nexports.parseArray = function (buf) {\n    var i, nelem, array;\n\n    if (buf[0] !== T.IpAddress) {\n        throw new Error('Buffer does not appear to be an array type.');\n    }\n\n    nelem = buf[1];\n    array = [];\n\n    for (i = 0; i < buf[1]; i++) {\n        array.push(buf[i + 2]);\n    }\n\n    return array;\n};\n\n// Parse a buffer containing a representation of an opaque type.\n// This is for example an IpAddress.\n\nexports.parseOpaque = function (buf) {\n    var hdr;\n\n    hdr = typeAndLength(buf);\n\n    if (hdr.type !== T.Opaque) {\n        throw new Error('Buffer does not appear to be an opaque type.');\n    }\n\n    return '0x' + buf.slice(hdr.header).toString('hex');\n};\n\n/*globals exports: false*/\n"
  },
  {
    "path": "lib/snmp.js",
    "content": "// Introduction\n// -----\n// This is `node-snmp-native`, a native (Javascript) implementation of an SNMP\n// client library targeted at Node.js. It's MIT licensed and available at\n// https://github.com/calmh/node-snmp-native\n//\n// (c) 2012 Jakob Borg, Nym Networks\n\n\"use strict\";\n\n// Code\n// -----\n// This file implements a structure representing an SNMP message\n// and routines for converting to and from the network representation.\n\n// Define our external dependencies.\nvar assert = require('assert');\nvar dgram = require('dgram');\nvar events = require('events');\n\n// We also need our ASN.1 BER en-/decoding routines.\nvar asn1ber = require('./asn1ber');\n\nexports.PduTypes = asn1ber.pduTypes;\nexports.DataTypes = asn1ber.types;\nexports.Errors = asn1ber.errors;\n\nvar versions = {\n    SNMPv1: 0,\n    SNMPv2c: 1\n};\nexports.Versions = versions;\n\n// Basic structures\n// ----\n\n// A `VarBind` is the innermost structure, containing an OID-Value pair.\nfunction VarBind() {\n    this.type = 5;\n    this.value = null;\n}\n\n// The `PDU` contains the SNMP request or response fields and a list of `VarBinds`.\nfunction PDU() {\n    this.type = asn1ber.pduTypes.GetRequestPDU;\n    this.reqid = 1;\n    this.error = 0;\n    this.errorIndex = 0;\n    this.varbinds = [ new VarBind() ];\n}\n\n// The `Packet` contains the SNMP version and community and the `PDU`.\nfunction Packet() {\n    this.version = versions.SNMPv2c;\n    this.community = 'public';\n    this.pdu = new PDU();\n}\n\n// Allow consumers to create packet structures from scratch.\nexports.Packet = Packet;\n\n// Private helper functions\n// ----\n\n// Concatenate several buffers to one.\nfunction concatBuffers(buffers) {\n    var total, cur = 0, buf;\n\n    // First we calculate the total length,\n    total = buffers.reduce(function (tot, b) {\n        return tot + b.length;\n    }, 0);\n\n    // then we allocate a new Buffer large enough to contain all data,\n    buf = new Buffer(total);\n    buffers.forEach(function (buffer) {\n        // finally we copy the data into the new larger buffer.\n        buffer.copy(buf, cur, 0);\n        cur += buffer.length;\n    });\n\n    return buf;\n}\n\n// Clear a pending packet when it times out or is successfully received.\n\nfunction clearRequest(reqs, reqid) {\n    var self = this;\n\n    var entry = reqs[reqid];\n    if (entry) {\n        if (entry.timeout) {\n            clearTimeout(entry.timeout);\n        }\n        delete reqs[reqid];\n    }\n}\n\n// Convert a string formatted OID to an array, leaving anything non-string alone.\n\nfunction parseSingleOid(oid) {\n    if (typeof oid !== 'string') {\n        return oid;\n    }\n\n    if (oid[0] !== '.') {\n        throw new Error('Invalid OID format');\n    }\n\n    oid = oid.split('.')\n        .filter(function (s) {\n            return s.length > 0;\n        })\n        .map(function (s) {\n            return parseInt(s, 10);\n        });\n\n    return oid;\n}\n\n// Fix any OIDs in the 'oid' or 'oids' objects that are passed as strings.\n\nfunction parseOids(options) {\n    if (options.oid) {\n        options.oid = parseSingleOid(options.oid);\n    }\n    if (options.oids) {\n        options.oids = options.oids.map(parseSingleOid);\n    }\n}\n\n// Update targ with attributes from _defs.\n// Any existing attributes on targ are untouched.\n\nfunction defaults(targ, _defs) {\n    [].slice.call(arguments, 1).forEach(function (def) {\n        Object.keys(def).forEach(function (key) {\n            if (!targ.hasOwnProperty(key)) {\n                targ[key] = def[key];\n            }\n        });\n    });\n}\n\n// Encode structure to ASN.1 BER\n// ----\n\n// Return an ASN.1 BER encoding of a Packet structure.\n// This is suitable for transmission on a UDP socket.\nfunction encode(pkt) {\n    var version, community, reqid, err, erridx, vbs, pdu, message;\n\n    // We only support SNMPv1 and SNMPv2c, so enforce those version stamps.\n    if (pkt.version !== versions.SNMPv1 && pkt.version !== versions.SNMPv2c) {\n        throw new Error('Only SNMPv1 and SNMPv2c are supported.');\n    }\n\n    // Encode the message header fields.\n    version = asn1ber.encodeInteger(pkt.version);\n    community = asn1ber.encodeOctetString(pkt.community);\n\n    // Encode the PDU header fields.\n    reqid = asn1ber.encodeInteger(pkt.pdu.reqid);\n    err = asn1ber.encodeInteger(pkt.pdu.error);\n    erridx = asn1ber.encodeInteger(pkt.pdu.errorIndex);\n\n    // Encode the PDU varbinds.\n    vbs = [];\n    pkt.pdu.varbinds.forEach(function (vb) {\n        var oid = asn1ber.encodeOid(vb.oid), val;\n\n        if (vb.type === asn1ber.types.Null || vb.value === null) {\n            val = asn1ber.encodeNull();\n        } else if (vb.type === asn1ber.types.Integer) {\n            val = asn1ber.encodeInteger(vb.value);\n        } else if (vb.type === asn1ber.types.Gauge) {\n            val = asn1ber.encodeGauge(vb.value);\n        } else if (vb.type === asn1ber.types.IpAddress) {\n            val = asn1ber.encodeIpAddress(vb.value);\n        } else if (vb.type === asn1ber.types.OctetString) {\n            val = asn1ber.encodeOctetString(vb.value);\n        } else if (vb.type === asn1ber.types.ObjectIdentifier) {\n            val = asn1ber.encodeOid(vb.value, true);\n        } else if (vb.type === asn1ber.types.Counter) {\n            val = asn1ber.encodeCounter(vb.value);\n        } else if (vb.type === asn1ber.types.TimeTicks) {\n            val = asn1ber.encodeTimeTicks(vb.value);\n        } else if (vb.type === asn1ber.types.NoSuchObject) {\n            val = asn1ber.encodeNoSuchObject();\n        } else if (vb.type === asn1ber.types.NoSuchInstance) {\n            val = asn1ber.encodeNoSuchInstance();\n        } else if (vb.type === asn1ber.types.EndOfMibView) {\n            val = asn1ber.encodeEndOfMibView();\n        } else {\n            throw new Error('Unknown varbind type \"' + vb.type + '\" in encoding.');\n        }\n        vbs.push(asn1ber.encodeSequence(concatBuffers([oid, val])));\n    });\n\n    // Concatenate all the varbinds together.\n    vbs = asn1ber.encodeSequence(concatBuffers(vbs));\n\n    // Create the PDU by concatenating the inner fields and adding a request structure around it.\n    pdu = asn1ber.encodeRequest(pkt.pdu.type, concatBuffers([reqid, err, erridx, vbs]));\n\n    // Create the message by concatenating the header fields and the PDU.\n    message = asn1ber.encodeSequence(concatBuffers([version, community, pdu]));\n\n    return message;\n}\n\nexports.encode = encode;\n\n// Parse ASN.1 BER into a structure\n// -----\n\n// Parse an SNMP packet into its component fields.\n// We don't do a lot of validation so a malformed packet will probably just\n// make us blow up.\n\nfunction parse(buf) {\n    var pkt, oid, bvb, vb, hdr, vbhdr;\n\n    pkt = new Packet();\n\n    // First we have a sequence marker (two bytes).\n    // We don't care about those, so cut them off.\n    hdr = asn1ber.typeAndLength(buf);\n    assert.equal(asn1ber.types.Sequence, hdr.type);\n    buf = buf.slice(hdr.header);\n\n    // Then comes the version field (integer). Parse it and slice it.\n    pkt.version = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));\n    buf = buf.slice(2 + buf[1]);\n\n    // We then get the community. Parse and slice.\n    pkt.community = asn1ber.parseOctetString(buf.slice(0, buf[1] + 2));\n    buf = buf.slice(2 + buf[1]);\n\n    // Here's the PDU structure. We're interested in the type. Slice the rest.\n    hdr = asn1ber.typeAndLength(buf);\n    assert.ok(hdr.type >= 0xA0);\n    pkt.pdu.type = hdr.type - 0xA0;\n    buf = buf.slice(hdr.header);\n\n    // The request id field.\n    pkt.pdu.reqid = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));\n    buf = buf.slice(2 + buf[1]);\n\n    // The error field.\n    pkt.pdu.error = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));\n    buf = buf.slice(2 + buf[1]);\n\n    // The error index field.\n    pkt.pdu.errorIndex = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));\n    buf = buf.slice(2 + buf[1]);\n\n    // Here's the varbind list. Not interested.\n    hdr = asn1ber.typeAndLength(buf);\n    assert.equal(asn1ber.types.Sequence, hdr.type);\n    buf = buf.slice(hdr.header);\n\n    // Now comes the varbinds. There might be many, so we loop for as long as we have data.\n    pkt.pdu.varbinds = [];\n    while (buf[0] === asn1ber.types.Sequence) {\n        vb = new VarBind();\n\n        // Slice off the sequence header.\n        hdr = asn1ber.typeAndLength(buf);\n        assert.equal(asn1ber.types.Sequence, hdr.type);\n        bvb = buf.slice(hdr.header, hdr.len + hdr.header);\n\n        // Parse and save the ObjectIdentifier.\n        vb.oid = asn1ber.parseOid(bvb);\n\n        // Parse the value. We use the type marker to figure out\n        // what kind of value it is and call the appropriate parser\n        // routine. For the SNMPv2c error types, we simply set the\n        // value to a text representation of the error and leave handling\n        // up to the user.\n        var vb_name_hdr = asn1ber.typeAndLength(bvb);\n        bvb = bvb.slice(vb_name_hdr.header + vb_name_hdr.len);\n        var vb_value_hdr = asn1ber.typeAndLength(bvb);\n        vb.type = vb_value_hdr.type;\n        if (vb.type === asn1ber.types.Null) {\n            // Null type.\n            vb.value = null;\n        } else if (vb.type === asn1ber.types.OctetString) {\n            // Octet string type.\n            vb.value = asn1ber.parseOctetString(bvb);\n        } else if (vb.type === asn1ber.types.Integer ||\n            vb.type === asn1ber.types.Counter ||\n            vb.type === asn1ber.types.Counter64 ||\n            vb.type === asn1ber.types.TimeTicks ||\n            vb.type === asn1ber.types.Gauge) {\n            // Integer type and it's derivatives that behave in the same manner.\n            vb.value = asn1ber.parseInteger(bvb);\n        } else if (vb.type === asn1ber.types.ObjectIdentifier) {\n            // Object identifier type.\n            vb.value = asn1ber.parseOid(bvb);\n        } else if (vb.type === asn1ber.types.IpAddress) {\n            // IP Address type.\n            vb.value = asn1ber.parseArray(bvb);\n        } else if (vb.type === asn1ber.types.Opaque) {\n            // Opaque type. The 'parsing' here is very light; basically we return a\n            // string representation of the raw bytes in hex.\n            vb.value = asn1ber.parseOpaque(bvb);\n        } else if (vb.type === asn1ber.types.EndOfMibView) {\n            // End of MIB view error, returned when attempting to GetNext beyond the end\n            // of the current view.\n            vb.value = 'endOfMibView';\n        } else if (vb.type === asn1ber.types.NoSuchObject) {\n            // No such object error, returned when attempting to Get/GetNext an OID that doesn't exist.\n            vb.value = 'noSuchObject';\n        } else if (vb.type === asn1ber.types.NoSuchInstance) {\n            // No such instance error, returned when attempting to Get/GetNext an instance\n            // that doesn't exist in a given table.\n            vb.value = 'noSuchInstance';\n        } else {\n            // Something else that we can't handle, so throw an error.\n            // The error will be caught and presented in a useful manner on stderr,\n            // with a dump of the message causing it.\n            throw new Error('Unrecognized value type ' + vb.type);\n        }\n\n        // Take the raw octet string value and preseve it as a buffer and hex string.\n        vb.valueRaw = bvb.slice(vb_value_hdr.header, vb_value_hdr.header + vb_value_hdr.len);\n        vb.valueHex = vb.valueRaw.toString('hex');\n\n        // Add the request id to the varbind (even though it doesn't really belong)\n        // so that it will be availble to the end user.\n        vb.requestId = pkt.pdu.reqid;\n\n        // Push whatever we parsed to the varbind list.\n        pkt.pdu.varbinds.push(vb);\n\n        // Go fetch the next varbind, if there seems to be any.\n        if (buf.length > hdr.header + hdr.len) {\n            buf = buf.slice(hdr.header + hdr.len);\n        } else {\n            break;\n        }\n    }\n\n    return pkt;\n}\n\nexports.parse = parse;\n\n// Utility functions\n// -----\n\n// Compare two OIDs, returning -1, 0 or +1 depending on the relation between\n// oidA and oidB.\n\nfunction compareOids (oidA, oidB) {\n    var mlen, i;\n\n    // The undefined OID, if there is any, is deemed lesser.\n    if (typeof oidA === 'undefined' && typeof oidB !== 'undefined') {\n        return 1;\n    } else if (typeof oidA !== 'undefined' && typeof oidB === 'undefined') {\n        return -1;\n    }\n\n    // Check each number part of the OIDs individually, and if there is any\n    // position where one OID is larger than the other, return accordingly.\n    // This will only check up to the minimum length of both OIDs.\n    mlen = Math.min(oidA.length, oidB.length);\n    for (i = 0; i < mlen; i++) {\n        if (oidA[i] > oidB[i]) {\n            return -1;\n        } else if (oidB[i] > oidA[i]) {\n            return 1;\n        }\n    }\n\n    // If there is one OID that is longer than the other after the above comparison,\n    // consider the shorter OID to be lesser.\n    if (oidA.length > oidB.length) {\n        return -1;\n    } else if (oidB.length > oidA.length) {\n        return 1;\n    } else {\n        // The OIDs are obviously equal.\n        return 0;\n    }\n}\n\nexports.compareOids = compareOids;\n\n// Communication functions\n// -----\n\n// This is called for when we receive a message.\n\nfunction msgReceived(msg, rinfo) {\n    var self = this, now = Date.now(), pkt, entry;\n\n    if (msg.length === 0) {\n        // Not sure why we sometimes receive an empty message.\n        // As far as I'm concerned it shouldn't happen, but we'll ignore it\n        // and if it's necessary a retransmission of the request will be\n        // made later.\n        return;\n    }\n\n    // Parse the packet, or call the informative\n    // parse error display if we fail.\n    try {\n        pkt = parse(msg);\n    } catch (error) {\n        return self.emit('error', error);\n    }\n\n    // If this message's request id matches one we've sent,\n    // cancel any outstanding timeout and call the registered\n    // callback.\n    entry = self.reqs[pkt.pdu.reqid];\n    if (entry) {\n        clearRequest(self.reqs, pkt.pdu.reqid);\n\n        if (typeof entry.callback === 'function') {\n            if (pkt.pdu.error !== 0) {\n                // An error response should be reported as an error to the callback.\n                // We try to find the error description, or in worst case call it\n                // just \"Unknown Error <number>\".\n                var errorDescr = Object.keys(asn1ber.errors).filter(function (key) {\n                    return asn1ber.errors[key] === pkt.pdu.error;\n                })[0] || 'Unknown Error ' + pkt.pdu.error;\n                return entry.callback(new Error(errorDescr));\n            }\n\n            pkt.pdu.varbinds.forEach(function (vb) {\n                vb.receiveStamp = now;\n                vb.sendStamp = entry.sendStamp;\n            });\n\n            entry.callback(null, pkt.pdu.varbinds);\n        }\n    }\n}\n\n// Default options for new sessions and operations.\nexports.defaultOptions = {\n    host: 'localhost',\n    port: 161,\n    bindPort: 0,\n    community: 'public',\n    family: 'udp4',\n    timeouts: [ 5000, 5000, 5000, 5000 ],\n    version: versions.SNMPv2c\n};\n\n// This creates a new SNMP session.\n\nfunction Session(options) {\n    var self = this;\n\n    self.options = options || {};\n    defaults(self.options, exports.defaultOptions);\n\n    self.reqs = {};\n    self.socket = dgram.createSocket(self.options.family);\n    self.socket.on('message', self.options.msgReceived || msgReceived.bind(self));\n    self.socket.on('close', function () {\n        // Remove the socket so we don't try to send a message on\n        // it when it's closed.\n        self.socket = undefined;\n    });\n    self.socket.on('error', function () {\n        // Errors will be emitted here as well as on the callback to the send function.\n        // We handle them there, so doing anything here is unnecessary.\n        // But having no error handler trips up the test suite.\n    });\n    // If exclusive is false (default), then cluster workers will use the same underlying handle,\n    // allowing connection handling duties to be shared.\n    // When exclusive is true, the handle is not shared, and attempted port sharing results in an error.\n    self.socket.bind({\n        port: self.options.bindPort, // unless otherwise specified, get a random port automatically\n        exclusive: true // you should not share the same port, otherwise yours packages will be screwed up between workers\n    });\n}\n\n// We inherit from EventEmitter so that we can emit error events\n// on fatal errors.\nSession.prototype = Object.create(events.EventEmitter.prototype);\nexports.Session = Session;\n\n// Generate a request ID. It's best kept within a signed 32 bit integer.\n// Uses the current time in ms, shifted left ten bits, plus a counter.\n// This gives us space for 1 transmit every microsecond and wraps every\n// ~1000 seconds. This is OK since we only need to keep unique ID:s for in\n// flight packets and they should be safely timed out by then.\n\nSession.prototype.requestId = function () {\n    var self = this, now = Date.now();\n\n    if (!self.prevTs) {\n        self.prevTs = now;\n        self.counter = 0;\n    }\n\n    if (now === self.prevTs) {\n        self.counter += 1;\n        if (self.counter > 1023) {\n            throw new Error('Request ID counter overflow. Adjust algorithm.');\n        }\n    } else {\n        self.prevTs = now;\n        self.counter = 0;\n    }\n\n    return ((now & 0x1fffff) << 10) + self.counter;\n};\n\n// Send a message. Can be used after manually constructing a correct Packet structure.\n\nSession.prototype.sendMsg = function (pkt, options, callback) {\n    var self = this, buf, reqid, retrans = 0;\n\n    defaults(options, self.options);\n\n    reqid = self.requestId();\n    pkt.pdu.reqid = reqid;\n\n    buf = encode(pkt);\n\n    function transmit() {\n        if (!self.socket || !self.reqs[reqid]) {\n            // The socket has already been closed, perhaps due to an error that ocurred while a timeout\n            // was scheduled. We can't do anything about it now.\n            clearRequest(self.reqs, reqid);\n            return;\n        } else if (!options.timeouts[retrans]){\n            // If there is no other configured retransmission attempt, we raise a final timeout error\n            clearRequest(self.reqs, reqid);\n            return callback(new Error('Timeout'));\n        }\n\n        // Send the message.\n        self.socket.send(buf, 0, buf.length, options.port, options.host, function (err, bytes) {\n            var entry = self.reqs[reqid];\n\n            if (err) {\n                clearRequest(self.reqs, reqid);\n                return callback(err);\n            } else if (entry) {\n                // Set timeout and record the timer so that we can (attempt to) cancel it when we receive the reply.\n                entry.sendStamp = Date.now();\n                entry.timeout = setTimeout(transmit, options.timeouts[retrans]);\n                retrans += 1;\n            }\n        });\n    }\n\n    // Register the callback to call when we receive a reply.\n    self.reqs[reqid] = { callback: callback };\n    // Transmit the message.\n    transmit();\n};\n\n// Shortcut to create a GetRequest and send it, while registering a callback.\n// Needs `options.oid` to be an OID in array form.\n\nSession.prototype.get = function (options, callback) {\n    var self = this, pkt;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    if (!options.oid) {\n        return callback(null, []);\n    }\n\n    pkt = new Packet();\n    pkt.community = options.community;\n    pkt.version = options.version;\n    pkt.pdu.varbinds[0].oid = options.oid;\n    self.sendMsg(pkt, options, callback);\n};\n\n// Shortcut to create a SetRequest and send it, while registering a callback.\n// Needs `options.oid` to be an OID in array form, `options.value` to be an\n// integer and `options.type` to be asn1ber.T.Integer (2).\n\nSession.prototype.set = function (options, callback) {\n    var self = this, pkt;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    if (!options.oid) {\n        throw new Error('Missing required option `oid`.');\n    } else if (options.value === undefined) {\n        throw new Error('Missing required option `value`.');\n    } else if (!options.type) {\n        throw new Error('Missing required option `type`.');\n    }\n\n    pkt = new Packet();\n    pkt.community = options.community;\n    pkt.version = options.version;\n    pkt.pdu.type = asn1ber.pduTypes.SetRequestPDU;\n    pkt.pdu.varbinds[0].oid = options.oid;\n    pkt.pdu.varbinds[0].type = options.type;\n    pkt.pdu.varbinds[0].value = options.value;\n    self.sendMsg(pkt, options, callback);\n};\n\n// Shortcut to get all OIDs in the `options.oids` array sequentially. The\n// callback is called when the entire operation is completed.  If\n// options.abortOnError is truish, an error while getting any of the values\n// will cause the callback to be called with error status. When\n// `options.abortOnError` is falsish (the default), any errors will be ignored\n// and any successfully retrieved values sent to the callback.\n\nSession.prototype.getAll = function (options, callback) {\n    var self = this, results = [],\n        combinedTimeoutTimer = null, combinedTimeoutExpired = false;\n\n    defaults(options, self.options, { abortOnError: false });\n    parseOids(options);\n\n    if (!options.oids || options.oids.length === 0) {\n        return callback(null, []);\n    }\n\n    function getOne(c) {\n        var oid, pkt, m, vb;\n\n        pkt = new Packet();\n        pkt.community = options.community;\n        pkt.version = options.version;\n        pkt.pdu.varbinds = [];\n\n        // Push up to 16 varbinds in the same message.\n        // The number 16 isn't really that magical, it's just a nice round\n        // number that usually seems to fit withing a single packet and gets\n        // accepted by the switches I've tested it on.\n        for (m = 0; m < 16 && c < options.oids.length; m++) {\n            vb = new VarBind();\n            vb.oid = options.oids[c];\n            pkt.pdu.varbinds.push(vb);\n            c++;\n        }\n\n        self.sendMsg(pkt, options, function (err, varbinds) {\n            if (combinedTimeoutExpired) {\n                return;\n            }\n            if (options.abortOnError && err) {\n                clearTimeout(combinedTimeoutTimer);\n                callback(err);\n            } else {\n                if (varbinds) {\n                    results = results.concat(varbinds);\n                }\n                if (c < options.oids.length) {\n                    getOne(c);\n                } else {\n                    clearTimeout(combinedTimeoutTimer);\n                    callback(null, results);\n                }\n            }\n        });\n    }\n\n    if (options.combinedTimeout) {\n        var combinedTimeoutEvent = function() {\n            combinedTimeoutExpired = true;\n            return callback(new Error('Timeout'), results);\n        };\n        combinedTimeoutTimer = setTimeout(combinedTimeoutEvent, options.combinedTimeout);\n    }\n\n    getOne(0);\n};\n\n// Shortcut to create a GetNextRequest and send it, while registering a callback.\n// Needs `options.oid` to be an OID in array form.\n\nSession.prototype.getNext = function (options, callback) {\n    var self = this, pkt;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    if (!options.oid) {\n        return callback(null, []);\n    }\n\n    pkt = new Packet();\n    pkt.community = options.community;\n    pkt.version = options.version;\n    pkt.pdu.type = 1;\n    pkt.pdu.varbinds[0].oid = options.oid;\n    self.sendMsg(pkt, options, callback);\n};\n\n// Shortcut to get all entries below the specified OID.\n// The callback will be called once with the list of\n// varbinds that was collected, or with an error object.\n// Needs `options.oid` to be an OID in array form.\n\nSession.prototype.getSubtree = function (options, callback) {\n    var self = this, vbs = [],\n        combinedTimeoutTimer = null, combinedTimeoutExpired = false;\n\n    defaults(options, self.options);\n    parseOids(options);\n\n    if (!options.oid) {\n        return callback(null, []);\n    }\n\n    options.startOid = options.oid;\n\n    // Helper to check whether `oid` in inside the tree rooted at\n    // `root` or not.\n    function inTree(root, oid) {\n        var i;\n        if (oid.length <= root.length) {\n            return false;\n        }\n        for (i = 0; i < root.length; i++) {\n            if (oid[i] !== root[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    // Helper to handle the result of getNext and call the user's callback\n    // as appropriate. The callback will see one of the following patterns:\n    //  - callback([an Error object], undefined) -- an error ocurred.\n    //  - callback(null, [a Packet object]) -- data from under the tree.\n    //  - callback(null, null) -- end of tree.\n    function result(error, varbinds) {\n        if (combinedTimeoutExpired) {\n            return;\n        }\n        if (error) {\n            clearTimeout(combinedTimeoutTimer);\n            callback(error);\n        } else {\n            if (inTree(options.startOid, varbinds[0].oid)) {\n                if (varbinds[0].value === 'endOfMibView' || varbinds[0].value === 'noSuchObject' || varbinds[0].value === 'noSuchInstance') {\n                    clearTimeout(combinedTimeoutTimer);\n                    callback(null, vbs);\n                } else if (vbs.length && compareOids(vbs.slice(-1)[0].oid, varbinds[0].oid) !== 1) {\n                    return callback(new Error('OID not increasing'));\n                } else {\n                    vbs.push(varbinds[0]);\n                    var next = { oid: varbinds[0].oid };\n                    defaults(next, options);\n                    self.getNext(next, result);\n                }\n            } else {\n                clearTimeout(combinedTimeoutTimer);\n                callback(null, vbs);\n            }\n        }\n    }\n\n    if (options.combinedTimeout) {\n        var combinedTimeoutEvent = function() {\n            combinedTimeoutExpired = true;\n            return callback(new Error('Timeout'), vbs);\n        };\n        combinedTimeoutTimer = setTimeout(combinedTimeoutEvent, options.combinedTimeout);\n    }\n\n    self.getNext(options, result);\n};\n\n// Close the socket. Necessary to finish the event loop and exit the program.\nSession.prototype.close = function () {\n    var self = this;\n    for (var reqid in self.reqs) {\n      if (self.reqs[reqid].callback) {\n        self.reqs[reqid].callback(new Error('Cancelled'));\n      }\n      clearRequest(self.reqs, reqid);\n    }\n    this.socket.close();\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"snmp-native\",\n  \"description\": \"A native Javascript SNMP implementation for Node.js\",\n  \"author\": \"Jakob Borg <jakob@nym.se> (http://nym.se/)\",\n  \"keywords\": [\n    \"snmp\",\n    \"asn.1\",\n    \"asn1\",\n    \"network\",\n    \"monitoring\"\n  ],\n  \"homepage\": \"http://nym.se/node-snmp-native/docs/\",\n  \"version\": \"1.2.0\",\n  \"license\": \"MIT\",\n  \"main\": \"lib/snmp.js\",\n  \"scripts\": {\n    \"test\": \"NODE_PATH=lib mocha -R spec\",\n    \"hint\": \"jshint *.js lib/*.js\",\n    \"doc\": \"docco lib/* example.js 2>/dev/null\",\n    \"cov\": \"jscoverage lib lib-cov && EXPRESS_COV=1 NODE_PATH=lib-cov mocha -R html-cov > docs/coverage.html\"\n  },\n  \"dependencies\": {},\n  \"devDependencies\": {\n    \"docco\": \"~0.6.2\",\n    \"jscoverage\": \"~0.3.6\",\n    \"jshint\": \"~1.1.0\",\n    \"mocha\": \"~1.9.0\",\n    \"should\": \"~1.2.2\",\n    \"snmpjs\": \"~0.1.3\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/calmh/node-snmp-native.git\"\n  },\n  \"bugs\": {\n    \"url\": \"http://github.com/calmh/node-snmp-native/issues\",\n    \"email\": \"snmp@nym.se\"\n  }\n}\n"
  },
  {
    "path": "test/asn1ber.js",
    "content": "var assert = require('assert');\nvar asn1ber = require('../lib/asn1ber');\n\ndescribe('asn1ber', function () {\n    describe('encodeInteger()', function () {\n        it('returns one byte for zero', function () {\n            var correct = '020100';\n            var buf = asn1ber.encodeInteger(0);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns one byte for one', function () {\n            var buf = asn1ber.encodeInteger(1);\n            assert.equal(3, buf.length);\n            assert.equal(2, buf[0]); // Integer\n            assert.equal(1, buf[1]); // Length\n            assert.equal(1, buf[2]); // Value\n        });\n        it('does not return first byte and first bit of second byte all ones', function () {\n            var correct = '020300ff94';\n            var buf = asn1ber.encodeInteger(0xff94);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('does not return a negative-looking integer', function () {\n            var correct = '02020088';\n            var buf = asn1ber.encodeInteger(0x88);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns correctly for larger integer', function () {\n            var buf = asn1ber.encodeInteger(1234567890);\n            assert.equal(6, buf.length);\n            assert.equal(2, buf[0]); // Integer\n            assert.equal(4, buf[1]); // Length\n            assert.equal(73, buf[2]); // Value\n            assert.equal(150, buf[3]); // Value\n            assert.equal(2, buf[4]); // Value\n            assert.equal(210, buf[5]); // Value\n        });\n        it('encodes a negative integer', function () {\n            assert.equal('0201fe', asn1ber.encodeInteger(-2).toString('hex'));\n            assert.equal('0202fdda', asn1ber.encodeInteger(-550).toString('hex'));\n            assert.equal('0203ed2979', asn1ber.encodeInteger(-1234567).toString('hex'));\n            assert.equal('0204f8a432eb', asn1ber.encodeInteger(-123456789).toString('hex'));\n        });\n    });\n\n    describe('encodeGauge()', function () {\n        it('returns one byte for zero', function () {\n            var correct = '420100';\n            var buf = asn1ber.encodeGauge(0);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns one byte for one', function () {\n            var buf = asn1ber.encodeGauge(1);\n            assert.equal(3, buf.length);\n            assert.equal(0x42, buf[0]); // Gauge\n            assert.equal(1, buf[1]); // Length\n            assert.equal(1, buf[2]); // Value\n        });\n        it('does not return first byte and first bit of second byte all ones', function () {\n            var correct = '420300ff94';\n            var buf = asn1ber.encodeGauge(0xff94);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('does not return a negative-looking integer', function () {\n            var correct = '42020088';\n            var buf = asn1ber.encodeGauge(0x88);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns correctly for larger integer', function () {\n            var buf = asn1ber.encodeGauge(1234567890);\n            assert.equal(6, buf.length);\n            assert.equal(0x42, buf[0]); // Gauge\n            assert.equal(4, buf[1]); // Length\n            assert.equal(73, buf[2]); // Value\n            assert.equal(150, buf[3]); // Value\n            assert.equal(2, buf[4]); // Value\n            assert.equal(210, buf[5]); // Value\n        });\n    });\n\n\n    describe('encodeCounter()', function () {\n        it('returns one byte for zero', function () {\n            var correct = '410100';\n            var buf = asn1ber.encodeCounter(0);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns one byte for one', function () {\n            var buf = asn1ber.encodeCounter(1);\n            assert.equal(3, buf.length);\n            assert.equal(0x41, buf[0]); // Gauge\n            assert.equal(1, buf[1]); // Length\n            assert.equal(1, buf[2]); // Value\n        });\n        it('does not return first byte and first bit of second byte all ones', function () {\n            var correct = '410300ff94';\n            var buf = asn1ber.encodeCounter(0xff94);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('does not return a negative-looking integer', function () {\n            var correct = '41020088';\n            var buf = asn1ber.encodeCounter(0x88);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns correctly for larger integer', function () {\n            var buf = asn1ber.encodeCounter(1234567890);\n            assert.equal(6, buf.length);\n            assert.equal(0x41, buf[0]); // Gauge\n            assert.equal(4, buf[1]); // Length\n            assert.equal(73, buf[2]); // Value\n            assert.equal(150, buf[3]); // Value\n            assert.equal(2, buf[4]); // Value\n            assert.equal(210, buf[5]); // Value\n        });\n    });\n\n    describe('encodeTimeTicks()', function () {\n        it('returns one byte for zero', function () {\n            var correct = '430100';\n            var buf = asn1ber.encodeTimeTicks(0);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns one byte for one', function () {\n            var buf = asn1ber.encodeTimeTicks(1);\n            assert.equal(3, buf.length);\n            assert.equal(0x43, buf[0]); // Gauge\n            assert.equal(1, buf[1]); // Length\n            assert.equal(1, buf[2]); // Value\n        });\n        it('does not return first byte and first bit of second byte all ones', function () {\n            var correct = '430300ff94';\n            var buf = asn1ber.encodeTimeTicks(0xff94);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('does not return a negative-looking integer', function () {\n            var correct = '43020088';\n            var buf = asn1ber.encodeTimeTicks(0x88);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns correctly for larger integer', function () {\n            var buf = asn1ber.encodeTimeTicks(1234567890);\n            assert.equal(6, buf.length);\n            assert.equal(0x43, buf[0]); // Gauge\n            assert.equal(4, buf[1]); // Length\n            assert.equal(73, buf[2]); // Value\n            assert.equal(150, buf[3]); // Value\n            assert.equal(2, buf[4]); // Value\n            assert.equal(210, buf[5]); // Value\n        });\n    });\n\n    describe('encodeNull()', function () {\n        it('returns the null representation', function () {\n            var buf = asn1ber.encodeNull();\n            assert.equal(2, buf.length);\n            assert.equal(5, buf[0]); // Null\n            assert.equal(0, buf[1]); // Zero\n        });\n    });\n\n    describe('encodeNoSuchObject()', function() {\n        it('returns the noSuchObject representation', function () {\n            var buf = asn1ber.encodeNoSuchObject();\n            assert.equal(2, buf.length);\n            assert.equal(0x80, buf[0]); // Null\n            assert.equal(0, buf[1]); // Zero\n        });\n    });\n\n    describe('encodeNoSuchInstance()', function() {\n        it('returns the noSuchInstance representation', function () {\n            var buf = asn1ber.encodeNoSuchInstance();\n            assert.equal(2, buf.length);\n            assert.equal(0x81, buf[0]); // Null\n            assert.equal(0, buf[1]); // Zero\n        });\n    });\n\n    describe('encodeEndOfMibView()', function() {\n        it('returns the endOfMibView representation', function () {\n            var buf = asn1ber.encodeEndOfMibView();\n            assert.equal(2, buf.length);\n            assert.equal(0x82, buf[0]); // Null\n            assert.equal(0, buf[1]); // Zero\n        });\n    });\n\n    describe('encodeSequence()', function () {\n        it('returns an empty sequence', function () {\n            var buf = asn1ber.encodeSequence(new Buffer(0));\n            assert.equal(2, buf.length);\n            assert.equal(0x30, buf[0]); // Sequence\n            assert.equal(0, buf[1]); // Zero length\n        });\n        it('returns wrapped sequence', function () {\n            var buf = asn1ber.encodeSequence(new Buffer(10));\n            assert.equal(12, buf.length);\n            assert.equal(0x30, buf[0]); // Sequence\n            assert.equal(10, buf[1]); // Length\n        });\n        it('returns correctly wrapped long sequence', function () {\n            var buf = asn1ber.encodeSequence(new Buffer(1024));\n            assert.equal(1024 + 1 + 3, buf.length);\n            assert.equal(0x30, buf[0]); // Sequence\n            assert.equal(128 + 2, buf[1]); // Length\n            assert.equal(0x04, buf[2]); // Length\n            assert.equal(0x00, buf[3]); // Length\n        });\n        it('does not modify the passed data', function () {\n            var orig = new Buffer(10);\n            for (i = 0; i < 10; i++) {\n                orig[i] = i;\n            }\n\n            var buf = asn1ber.encodeSequence(orig);\n            var i;\n            assert.equal(12, buf.length);\n            assert.equal(0x30, buf[0]); // Sequence\n            assert.equal(10, buf[1]); // Length\n            for (i = 0; i < 10; i++) {\n                assert.equal(i, buf[i + 2]);\n            }\n        });\n    });\n\n    describe('encodeOctetString()', function () {\n        it('returns an empty string', function () {\n            var buf = asn1ber.encodeOctetString('');\n            assert.equal(2, buf.length);\n            assert.equal(4, buf[0]); // OctetString\n            assert.equal(0, buf[1]); // Zero length\n        });\n        it('returns a simple string correctly', function () {\n            var str = 'abc';\n            var buf = asn1ber.encodeOctetString(str);\n            var i;\n            assert.equal(5, buf.length);\n            assert.equal(4, buf[0]); // OctetString\n            assert.equal(str.length, buf[1]); // Length\n            for (i = 0; i < str.length; i++) {\n                assert.equal(str.charCodeAt(i), buf[i + 2]);\n            }\n        });\n        it('returns a simple buffer correctly', function () {\n            var orig = new Buffer('0123456789', 'hex');\n            var buf = asn1ber.encodeOctetString(orig);\n            var i;\n            assert.equal(7, buf.length);\n            assert.equal(4, buf[0]); // OctetString\n            assert.equal(orig.length, buf[1]); // Length\n            for (i = 0; i < orig.length; i++) {\n                assert.equal(orig[i], buf[i + 2]);\n            }\n        });\n        it('throws an exception for unknown source types', function (done) {\n            try {\n                asn1ber.encodeOctetString(12);\n            } catch (err) {\n                done();\n            }\n        });\n    });\n\n    describe('encodeOid()', function () {\n        it('throws an exception on empty OID', function (done) {\n            try {\n                asn1ber.encodeOid([]);\n            } catch (err) {\n                assert.equal(\"Minimum OID length is two.\", err.message);\n                done();\n            }\n        });\n        it('throws an exception for incorrect SNMP OIDs', function (done) {\n            try {\n                asn1ber.encodeOid([8, 8, 6, 7, 8]);\n            } catch (err) {\n                assert.equal(\"Invalid OID\", err.message);\n                done();\n            }\n        });\n        it('returns an oid correctly', function () {\n            var oid = [1, 3, 6, 1, 4, 1, 2680, 1234567, 2, 7, 3, 2, 0];\n            var correct = '06 0f 2b 06 01 04 01 94 78 cb ad 07 02 07 03 02 00'.replace(/ /g, '');\n            var buf = asn1ber.encodeOid(oid);\n            assert.equal(correct, buf.toString('hex'));\n        });\n        it('returns an oid correctly even though the oid doesn\\'t start with .1.3', function () {\n            var oid = [2, 77, 8802, 1, 1, 2, 1, 4, 1, 1, 9];\n            var correct = '06 0b 9d c4 62 01 01 02 01 04 01 01 09'.replace(/ /g, '');\n            var buf = asn1ber.encodeOid(oid);\n            assert.equal(correct, buf.toString('hex'));\n        });\n    });\n\n    describe('encodeRequest()', function () {\n        it('returns a get request sequence', function () {\n            var buf = asn1ber.encodeRequest(0, new Buffer(0));\n            assert.equal(2, buf.length);\n            assert.equal(160, buf[0]); // GetRequest\n            assert.equal(0, buf[1]); // Zero length\n        });\n    });\n\n    describe('parseInteger()', function () {\n        it('throws an exception when passed a non-integer buffer', function (done) {\n            try {\n                var buf = new Buffer('040100', 'hex');\n                asn1ber.parseInteger(buf);\n            } catch (err) {\n                done();\n            }\n        });\n        it('returns zero for an encoded zero', function () {\n            var buf = new Buffer('020100', 'hex');\n            var int = asn1ber.parseInteger(buf);\n            assert.equal(0, int);\n        });\n        it('returns one for an encoded one', function () {\n            var buf = new Buffer('020101', 'hex');\n            var int = asn1ber.parseInteger(buf);\n            assert.equal(1, int);\n        });\n        it('correctly parses a random larger integer', function () {\n            var buf = new Buffer('0204499602d2', 'hex');\n            var int = asn1ber.parseInteger(buf);\n            assert.equal(1234567890, int);\n        });\n        it('correctly parses a negative integer', function () {\n            assert.equal(-2, asn1ber.parseInteger(new Buffer('0201fe', 'hex')));\n            assert.equal(-550, asn1ber.parseInteger(new Buffer('0202fdda', 'hex')));\n            assert.equal(-1234567, asn1ber.parseInteger(new Buffer('0203ed2979', 'hex')));\n            assert.equal(-123456789, asn1ber.parseInteger(new Buffer('0204f8a432eb', 'hex')))\n        });\n    });\n\n    describe('parseOctetString()', function () {\n        it('throws an exception when passed a non-octetstring buffer', function (done) {\n            try {\n                var buf = new Buffer('020100', 'hex');\n                asn1ber.parseOctetString(buf);\n            } catch (err) {\n                done();\n            }\n        });\n        it('returns an empty string', function () {\n            var buf = new Buffer('0400', 'hex');\n            var str = asn1ber.parseOctetString(buf);\n            assert.equal('', str);\n        });\n        it('correctly parses a random string', function () {\n            var buf = new Buffer('0407536f6c61726973', 'hex');\n            var str = asn1ber.parseOctetString(buf);\n            assert.equal('Solaris', str);\n        });\n        it('correctly parses a long string', function () {\n            var buf = new Buffer('0481cf302d3031323334353637383920312d3031323334353637383920322d3031323334353637383920332d3031323334353637383920342d3031323334353637383920352d3031323334353637383920362d3031323334353637383920372d3031323334353637383920382d3031323334353637383920392d3031323334353637383920412d3031323334353637383920422d3031323334353637383920432d3031323334353637383920442d3031323334353637383920452d3031323334353637383920462d30313233343536373839', 'hex');\n            var str = asn1ber.parseOctetString(buf);\n            assert.equal('0-0123456789 1-0123456789 2-0123456789 3-0123456789 4-0123456789 5-0123456789 6-0123456789 7-0123456789 8-0123456789 9-0123456789 A-0123456789 B-0123456789 C-0123456789 D-0123456789 E-0123456789 F-0123456789', str);\n\n            var veryLongString = \"\";\n            for (var i = 0; i < 512; i++) {\n                veryLongString = veryLongString + \"foo\"+i;\n            }\n            buf = asn1ber.encodeOctetString(veryLongString);\n            str = asn1ber.parseOctetString(buf);\n            assert.equal(veryLongString,str);\n        });\n\n    });\n\n    describe('parseOid()', function () {\n        it('throws an exception when passed a non-oid buffer', function (done) {\n            try {\n                var buf = new Buffer('020100', 'hex');\n                asn1ber.parseOid(buf);\n            } catch (err) {\n                done();\n            }\n        });\n        it('returns the shortest possible oid', function () {\n            var buf = new Buffer('06012b', 'hex');\n            var oid = asn1ber.parseOid(buf);\n            assert.deepEqual([1, 3], oid);\n        });\n        it('correctly parses a random oid', function () {\n            var correct = [1, 3, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0];\n            var buf = new Buffer('06 0d 2b 06 01 04 01 94 78 01 02 07 03 02 00'.replace(/ /g, ''), 'hex');\n            var oid = asn1ber.parseOid(buf);\n            assert.deepEqual(correct, oid);\n        });\n        it('correctly parses a long oid with a large component', function () {\n            var correct = [1, 3, 6, 1, 2, 1, 7, 7, 1, 8, 2, 16, 32, 1, 4, 112, 0, 39, 4, 214, 0, 0, 0, 0, 0, 0, 0, 2, 123, 0, 0, 0, 4179634304];\n            var buf = new Buffer('06 252b 0601 0201 0707 0108 0210 2001 0470 0027 0481 5600 0000 0000 0000 027b 0000 008f c980 d100 0500'.replace(/ /g, ''), 'hex');\n            var oid = asn1ber.parseOid(buf);\n            assert.deepEqual(correct, oid);\n        });\n        it('correctly parses an oid with a second octet > 39', function () {\n            var correct = [2, 77, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0];\n            var buf = new Buffer('06 0d 9d 06 01 04 01 94 78 01 02 07 03 02 00'.replace(/ /g, ''), 'hex');\n            var oid = asn1ber.parseOid(buf);\n            assert.deepEqual(correct, oid);\n        });\n    });\n\n    describe('parseArray()', function () {\n        it('throws an exception when passed a non-array buffer', function (done) {\n            try {\n                var buf = new Buffer('020100', 'hex');\n                asn1ber.parseArray(buf);\n            } catch (err) {\n                done();\n            }\n        });\n        it('correctly parses a random array', function () {\n            var correct = [0x30, 0x40, 0x16, 0x32];\n            var buf = new Buffer('40 04 30 40 16 32'.replace(/ /g, ''), 'hex');\n            var oid = asn1ber.parseArray(buf);\n            assert.deepEqual(correct, oid);\n        });\n    });\n\n    describe('parseOpaque()', function () {\n        it('throws an exception when passed a non-opaque buffer', function (done) {\n            try {\n                var buf = new Buffer('020100', 'hex');\n                asn1ber.parseOpaque(buf);\n            } catch (err) {\n                done();\n            }\n        });\n        it('return the hex representation of an opaque value', function () {\n            var correct = '0x9f78043e920000';\n            var buf = new Buffer('44079f78043e920000', 'hex');\n            var str = asn1ber.parseOpaque(buf);\n            assert.deepEqual(correct, str);\n        });\n    });\n\n    describe('lengthArray()', function () {\n        it('returns the length directly if it\\'s 127 or less', function () {\n            assert.deepEqual([ 0 ], asn1ber.unittest.lengthArray(0));\n            assert.deepEqual([ 47 ], asn1ber.unittest.lengthArray(47));\n            assert.deepEqual([ 127 ], asn1ber.unittest.lengthArray(127));\n        });\n        it('returns the length as an encoded integer if greater than 127', function () {\n            assert.deepEqual([ 128 + 1, 128 ], asn1ber.unittest.lengthArray(128));\n            assert.deepEqual([ 128 + 2, 0x04, 0x01 ], asn1ber.unittest.lengthArray(1025));\n        });\n    });\n});\n"
  },
  {
    "path": "test/integration.js",
    "content": "/*globals it:false, describe:false before:false after:false beforeEach:false\n */\n\nvar assert = require('assert');\nvar dgram = require('dgram');\nvar should = require('should');\nvar snmp = require('../lib/snmp');\nvar snmpsrv = require('snmpjs');\n\nvar agent = snmpsrv.createAgent();\n\nvar data = { '1.3.6.42.1.2.3': // No leading dot!\n{\n    '1': {\n        '1': { type: 'OctetString', value: 'system description' },\n        '2': { type: 'Counter64', value: 1234567890 },\n        '3': { type: 'Integer', value: 1234567890 },\n        '4': { type: 'TimeTicks', value: 1234567890 },\n        '5': { type: 'Null', value: null },\n        '6': { type: 'OctetString', value: new Buffer('001122334455', 'hex') },\n        '7': { type: 'Counter32', value: 4294967295 },\n        '8': { type: 'Counter64', value: { lo: 0xffffffff, hi: 0xffffffff }}, // As close to 2^64-1 as Javascript can get...\n    }\n},\n    '1.3.6.42.1.2.4': {\n        '1': {\n            '1': { type: 'Opaque', value: new Buffer('11223344', 'hex') }\n        }\n    }\n};\n\nfunction setupResponder(agent, data) {\n    Object.keys(data).forEach(function (oid) {\n        var responses = data[oid];\n        var columns = Object.keys(responses).map(function (x) {\n            return parseInt(x, 10);\n        });\n        var handler = function (prq) {\n            var lastPartOfOid, parts, col, inst, ival, val, vb, nextOid;\n\n            lastPartOfOid = prq.oid.replace(oid, '').replace(/^\\./, '');\n            parts = lastPartOfOid.split('.').filter(function (s) {\n                return s.length > 0;\n            }).map(function (x) {\n                return parseInt(x, 10);\n            });\n\n            if (prq.op === snmpsrv.pdu.GetRequest) {\n                col = parts[0].toString();\n                inst = parts[1].toString();\n                ival = responses[col][inst].value;\n                if (typeof ival === 'function') {\n                    ival = ival();\n                }\n                val = snmpsrv.data.createData({ type: responses[col][inst].type, value: ival });\n                vb = snmpsrv.varbind.createVarbind({ oid: prq.oid, data: val });\n                prq.done(vb);\n            } else if (prq.op === snmpsrv.pdu.GetNextRequest) {\n                if (parts.length === 0 || parts.length > 2) {\n                    col = columns[0];\n                    inst = Object.keys(responses[col])[0];\n                } else if (parts.length === 1) {\n                    col = parts[0].toString();\n                    inst = Object.keys(responses[col])[0];\n                } else if (parts.length === 2) {\n                    col = parts[0].toString();\n                    inst = (parts[1] + 1).toString();\n                    if (!responses[col][inst]) {\n                        col = (parts[0] + 1).toString();\n                        if (!responses[col]) {\n                            return prq.done();\n                        }\n                        inst = Object.keys(responses[col])[0];\n                    }\n                }\n                if (!col || !inst) {\n                    prq.done()\n                } else if (responses[col][inst]) {\n                    nextOid = oid + '.' + col + '.' + inst;\n                    ival = responses[col][inst].value;\n                    if (typeof ival === 'function') {\n                        ival = ival();\n                    }\n                    val = snmpsrv.data.createData({ type: responses[col][inst].type, value: ival });\n                    vb = snmpsrv.varbind.createVarbind({ oid: nextOid, data: val });\n                    prq.done(vb);\n                } else {\n                    prq.done();\n                }\n            }\n        };\n        agent.request({ oid: oid, columns: columns, handler: handler });\n    });\n}\n\nsetupResponder(agent, data);\n\nagent.request({ oid: '.1.3.6.12.1.2.4', columns: [ 1 ], handler: function (prq) {\n    var val, vb;\n\n    if (!prq.instance) {\n        return prq.done();\n    }\n\n    val = snmpsrv.data.createData({ type: 'Integer', value: prq.instance[0] });\n    vb = snmpsrv.varbind.createVarbind({ oid: prq.oid, data: val });\n    setTimeout(function () {\n        prq.done(vb);\n    }, prq.instance[0]);\n} });\n\n// Create a fake server that reponds with nonsense.\n\nvar server = dgram.createSocket('udp4');\nserver.on('message', function (msg, rinfo) {\n    server.send(new Buffer(100), 0, 100, rinfo.port, rinfo.address);\n});\nserver.bind(1162);\n\ndescribe('integration', function () {\n    before(function () {\n        agent.bind({ family: 'udp4', port: 1161 });\n    });\n\n    after(function () {\n        try {\n            server.close();\n            agent.close();\n        } catch (err) {\n        }\n    });\n\n    describe('get', function () {\n        it('sets valid send and receive timestamps', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            var now = Date.now();\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 1] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].sendStamp.should.be.within(now, now + 50);\n                    varbinds[0].receiveStamp.should.be.within(varbinds[0].sendStamp, now + 150);\n                    done();\n                }\n            });\n        });\n        it('parses a single OctetString value', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 1] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 1]);\n                    varbinds[0].value.should.equal('system description');\n                    varbinds[0].valueHex.should.equal('73797374656d206465736372697074696f6e');\n                    done();\n                }\n            });\n        });\n        it('parses a binary OctetString value', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 6] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 6]);\n                    varbinds[0].valueHex.should.equal('001122334455');\n                    done();\n                }\n            });\n        });\n        it('parses a single Counter64 value', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 2] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 2]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n        it('parses a single Integer value', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 3] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 3]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n        it('parses a single TimeTicks value', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 4] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 4]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n        it('parses a single null value', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 5] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 5]);\n                    should.not.exist(varbinds[0].value);\n                    done();\n                }\n            });\n        });\n        it('handles OIDs in string form', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: '.1.3.6.42.1.2.3.1.3' }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 3]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n        it('gracefully handles undefined oid', function (done) {\n            var session = new snmp.Session();\n            session.get({ }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(0);\n                    done();\n                }\n            });\n        });\n        it('correctly understands a 2^32-1 Counter32', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: '.1.3.6.42.1.2.3.1.7' }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].value.should.equal(4294967295); // 2^32 - 1\n                    done();\n                }\n            });\n        });\n        it('correctly understands a 2^64-1 Counter64', function (done) {\n            var session = new snmp.Session({ port: 1161 });\n            session.get({ oid: '.1.3.6.42.1.2.3.1.8' }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].value.should.equal(18446744073709552000); // 2^64 - 1, or as close as Javascripts float type comes.\n                    done();\n                }\n            });\n        });\n    });\n\n    describe('timouts', function () {\n        it('should encode the send time in the request id', function (done) {\n            var now = Date.now(), req;\n            var session = new snmp.Session({ port: 1161, timeouts: [ 50 ] });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 1] }, function (err, varbinds) {\n                should.not.exist(err);\n                should.exist(varbinds);\n                varbinds.length.should.equal(1);\n                // Truncate to 22 bits\n                now &= 0x1fffff;\n                // The request id should be the truncated time in millis, shifted\n                // ten bits to the left.\n                req = varbinds[0].requestId >>> 10;\n                (now - req).should.be.within(-5, 0);\n                // The leftmost ten bits should be increasing for packets\n                // sent the same millisecond. It should be at most two.\n                req = varbinds[0].requestId & 0x3ff;\n                req.should.be.within(1, 2);\n                done();\n            });\n        });\n        it('times out when the response takes longer than specified', function (done) {\n            var session = new snmp.Session({ port: 1161, timeouts: [ 50 ] });\n            session.get({ oid: [1, 3, 6, 12, 1, 2, 4, 1, 100] }, function (err, varbinds) {\n                should.not.exist(varbinds);\n                should.exist(err);\n                done();\n            });\n        });\n        it('does not time out when the timeout value is sufficient', function (done) {\n            var session = new snmp.Session({ port: 1161, timeouts: [ 150 ] });\n            session.get({ oid: [1, 3, 6, 12, 1, 2, 4, 1, 100] }, function (err, varbinds) {\n                should.not.exist(err);\n                should.exist(varbinds);\n                done();\n            });\n        });\n        it('does not time out when retransmits work', function (done) {\n            var session = new snmp.Session({ port: 1161, timeouts: [ 50, 125 ] });\n            session.get({ oid: '.1.3.6.12.1.2.4.1.100' }, function (err, varbinds) {\n                should.not.exist(err);\n                should.exist(varbinds);\n                done();\n            });\n        });\n    });\n\n    describe('options', function () {\n        beforeEach(function () {\n            snmp.defaultOptions.host = 'localhost';\n            snmp.defaultOptions.port = 161;\n        });\n\n        it('gets a response given global default values', function (done) {\n            snmp.defaultOptions.host = 'localhost';\n            snmp.defaultOptions.port = 1161;\n\n            var session = new snmp.Session();\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 3] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 3]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n        it('gets a response given session default values', function (done) {\n            snmp.defaultOptions.host = 'example.com';\n            snmp.defaultOptions.port = 999;\n\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 3] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 3]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n        it('gets a response given explicit values', function (done) {\n            snmp.defaultOptions.host = 'example.com';\n            snmp.defaultOptions.port = 999;\n\n            var session = new snmp.Session({ host: 'example.com', port: 999 });\n            session.get({ host: 'localhost', port: 1161, oid: [1, 3, 6, 42, 1, 2, 3, 1, 3] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 3]);\n                    varbinds[0].value.should.equal(1234567890);\n                    done();\n                }\n            });\n        });\n    });\n\n    describe('getAll', function () {\n        it('should get an array of oids', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            var oids = [\n                [1, 3, 6, 42, 1, 2, 3, 1, 1],\n                [1, 3, 6, 42, 1, 2, 3, 1, 2],\n                [1, 3, 6, 42, 1, 2, 3, 1, 3],\n                [1, 3, 6, 42, 1, 2, 3, 1, 4],\n                [1, 3, 6, 42, 1, 2, 3, 1, 5]\n            ];\n            // We need more than 16 oids to test sending more than one packet.\n            var manyOids = [].concat(oids, oids, oids, oids);\n            assert.equal(20, manyOids.length);\n            session.getAll({ oids: manyOids }, function (err, vbs) {\n                if (err) {\n                    done(err);\n                } else {\n                    vbs.length.should.equal(20);\n                    for (var i = 0; i < 4; i++) {\n                        vbs[5 * i + 0].value.should.equal('system description');\n                        vbs[5 * i + 1].value.should.equal(1234567890);\n                        vbs[5 * i + 2].value.should.equal(1234567890);\n                        vbs[5 * i + 3].value.should.equal(1234567890);\n                        should.not.exist(vbs[5 * i + 4].value);\n                    }\n                    done();\n                }\n            });\n        });\n        it('should get an array of oids in string form', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            var oids = [ '.1.3.6.42.1.2.3.1.1', '.1.3.6.42.1.2.3.1.2', '.1.3.6.42.1.2.3.1.3', '.1.3.6.42.1.2.3.1.4', '.1.3.6.42.1.2.3.1.5' ];\n            session.getAll({ oids: oids }, function (err, vbs) {\n                if (err) {\n                    done(err);\n                } else {\n                    vbs.length.should.equal(5);\n                    vbs[0].value.should.equal('system description');\n                    vbs[1].value.should.equal(1234567890);\n                    vbs[2].value.should.equal(1234567890);\n                    vbs[3].value.should.equal(1234567890);\n                    should.not.exist(vbs[4].value);\n                    done();\n                }\n            });\n        });\n        it('should get an array of oids from specific host and community', function (done) {\n            var session = new snmp.Session();\n            var oids = [\n                [1, 3, 6, 42, 1, 2, 3, 1, 1],\n                [1, 3, 6, 42, 1, 2, 3, 1, 2],\n                [1, 3, 6, 42, 1, 2, 3, 1, 3],\n                [1, 3, 6, 42, 1, 2, 3, 1, 4],\n                [1, 3, 6, 42, 1, 2, 3, 1, 5]\n            ];\n            session.getAll({ oids: oids, host: 'localhost', community: 'any', port: 1161 }, function (err, vbs) {\n                if (err) {\n                    done(err);\n                } else {\n                    vbs.length.should.equal(5);\n                    vbs[0].value.should.equal('system description');\n                    vbs[1].value.should.equal(1234567890);\n                    vbs[2].value.should.equal(1234567890);\n                    vbs[3].value.should.equal(1234567890);\n                    should.not.exist(vbs[4].value);\n                    done();\n                }\n            });\n        });\n        it('gracefully handles undefined oids', function (done) {\n            var session = new snmp.Session();\n            session.getAll({ }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(0);\n                    done();\n                }\n            });\n        });\n        it('gracefully handles empty oids list', function (done) {\n            var session = new snmp.Session();\n            session.getAll({ oids: [] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(0);\n                    done();\n                }\n            });\n        });\n        it('should throw an error for invalid oid', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.getNext({ oids: [ '1.3.6.42.1.2.3.1' ] }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Invalid OID format/);\n        });\n    });\n\n    describe('getNext', function () {\n        it('should get a new value', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.getNext({ oid: [1, 3, 6, 42, 1, 2, 3, 1, 5] }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 6]);\n                    varbinds[0].valueHex.should.equal('001122334455');\n                    done();\n                }\n            });\n        });\n        it('should get a new value with oid in string form', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.getNext({ oid: '.1.3.6.42.1.2.3.1.5' }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(1);\n                    varbinds[0].oid.should.eql([1, 3, 6, 42, 1, 2, 3, 1, 6]);\n                    varbinds[0].valueHex.should.equal('001122334455');\n                    done();\n                }\n            });\n        });\n        it('gracefully handles undefined oid', function (done) {\n            var session = new snmp.Session();\n            session.getNext({ }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(0);\n                    done();\n                }\n            });\n        });\n        it('should throw an error for invalid oid', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.getNext({ oid: '1.3.6.42.1.2.3.1' }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Invalid OID format/);\n        });\n    });\n\n    describe('getSubtree', function () {\n        it('should get a complete tree', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.getSubtree({ oid: [1, 3, 6, 42, 1, 2, 3, 1] }, function (err, vbs) {\n                if (err) {\n                    done(err);\n                } else {\n                    vbs.length.should.equal(8);\n                    vbs[0].value.should.equal('system description');\n                    vbs[1].value.should.equal(1234567890);\n                    vbs[2].value.should.equal(1234567890);\n                    vbs[3].value.should.equal(1234567890);\n                    should.not.exist(vbs[4].value);\n                    vbs[5].valueHex.should.equal('001122334455');\n                    done();\n                }\n            });\n        });\n        it('should get a complete tree with oid in string form', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.getSubtree({ oid: '.1.3.6.42.1.2.4.1' }, function (err, vbs) {\n                if (err) {\n                    done(err);\n                } else {\n                    vbs.length.should.equal(1);\n                    vbs[0].value.should.equal('0x11223344'); // Opaque\n                    done();\n                }\n            });\n        });\n        it('gracefully handles undefined oid', function (done) {\n            var session = new snmp.Session();\n            session.getSubtree({ }, function (err, varbinds) {\n                if (err) {\n                    done(err);\n                } else {\n                    varbinds.length.should.equal(0);\n                    done();\n                }\n            });\n        });\n        it('should throw an error for invalid oid', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.get({ oid: '1.3.6.42.1.2.3.1' }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Invalid OID format/);\n        });\n    });\n\n    describe('set', function () {\n        it('should throw an error for unknown value types', function () {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            var test = function () {\n                session.set({ oid: [1, 3, 6, 42, 1, 2, 3, 1], value: 5, type: 4 }, function (err, vbs) {\n                });\n            };\n            test.should.throw();\n        });\n        it('should not throw an error for integer type', function () {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.set({ oid: [1, 3, 6, 42, 1, 2, 3, 1], value: 5, type: 2 }, function (err, vbs) {\n            });\n        });\n        it('should gracefully handle an undefined callback', function () {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.set({ oid: [1, 3, 6, 42, 1, 2, 3, 1], value: 5, type: 2 });\n        });\n        it('should not throw an error for string oid', function () {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            var test = function () {\n                session.set({ oid: '.1.3.6.42.1.2.3.1', value: 5, type: 2 }, function (err, vbs) {\n                });\n            };\n            test.should.not.throw();\n        });\n        it('should not throw an error for value zero', function () {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            var test = function () {\n                session.set({ oid: '.1.3.6.42.1.2.3.1', value: 0, type: 2 }, function (err, vbs) {\n                });\n            };\n            test.should.not.throw();\n        });\n        it('should not throw an error for IP number value', function () {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            var test = function () {\n                session.set({ oid: '.1.3.6.42.1.2.3.1', value: '172.16.32.64', type: 0x40 }, function (err, vbs) {\n                });\n            };\n            test.should.not.throw();\n        });\n        it('should throw an error for missing oid', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.set({ value: 5, type: 2 }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Missing required option/);\n        });\n        it('should throw an error for invalid oid', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.set({ oid: '1.3.6.42.1.2.3.1', value: 5, type: 2 }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Invalid OID format/);\n        });\n        it('should throw an error for missing value', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.set({ oid: '.1.3.6.42.1.2.3.1', type: 2 }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Missing required option/);\n        });\n        it('should throw an error for missing type', function () {\n            var session = new snmp.Session();\n            var test = function () {\n                session.set({ oid: '.1.3.6.42.1.2.3.1', value: 42 }, function (err, vbs) {\n                });\n            };\n            test.should.throw(/Missing required option/);\n        });\n    });\n\n    describe('errors', function () {\n        it('should return a noSuchObject varbind', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.get({ oid: [1, 3, 6, 0] }, function (err, varbinds) {\n                should.not.exist(err);\n                should.exist(varbinds);\n                varbinds.length.should.equal(1);\n                varbinds[0].type.should.equal(128);\n                varbinds[0].value.should.equal('noSuchObject');\n                done();\n            });\n        });\n        it('should return a noSuchInstance varbind', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1161 });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1] }, function (err, varbinds) {\n                should.not.exist(err);\n                should.exist(varbinds);\n                varbinds.length.should.equal(1);\n                varbinds[0].type.should.equal(129);\n                varbinds[0].value.should.equal('noSuchInstance');\n                done();\n            });\n        });\n        it('should return an error for nonexistant host', function (done) {\n            var session = new snmp.Session({ host: '1.2.427.5' });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1] }, function (err, varbinds) {\n                should.exist(err);\n                should.not.exist(varbinds);\n                done();\n            });\n        });\n        it('should return an error for host of the wrong address family', function (done) {\n            // This actually results in a timeout. That works, I guess, since it indicates\n            // a communication problem. I would have expected something more immediate.\n            var session = new snmp.Session({ family: 'udp4', host: '2001:db8::1', timeouts: [ 100 ] });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1] }, function (err, varbinds) {\n                should.exist(err);\n                should.not.exist(varbinds);\n                done();\n            });\n        });\n        it('should throw a parse error when the recieved data makes no sense', function (done) {\n            var session = new snmp.Session({ host: 'localhost', port: 1162 });\n            session.on('error', function () {\n                done();\n            });\n            session.get({ oid: [1, 3, 6, 42, 1, 2, 3, 1] }, function (err, varbinds) {\n            });\n        });\n    });\n});\n\n"
  },
  {
    "path": "test/snmp.js",
    "content": "var assert = require('assert');\nvar snmp = require('../lib/snmp');\n\n// A packet as generated by this library, lightly modified by hand to contain easily\n// distinguishable fields.\nvar ex1 = new Buffer('30 2c 02 01 47 04 07 70 72 69 76 61 74 65 a4 1e 02 01 33 02 01 44 02 01 55 30 13 30 11 06 0d 2b 06 01 04 01 94 78 01 02 07 03 02 00 05 00'.replace(/ /g, ''), 'hex');\n// A OctetString GetResponse from Net-SNMP\nvar ex2 = new Buffer('304a 0201 0104 066e 796d 2e73 65a2 3d02 0459 8559 7002 0100 0201 0030 2f30 2d06 082b 0601 0201 0101 0004 2153 6f6c 6172 6973 2061 6e74 6f2e 6e79 6d2e 7365 2031 312e 3020 7068 7973 6963 616c'.replace(/ /g, ''), 'hex');\n// A Counter32 GetResponse from Net-SNMP\nvar ex3 = new Buffer('302e 0201 0104 0770 7269 7661 7465 a220 0204 12a1 7180 0201 0002 0100 3012 3010 060b 2b06 0102 011f 0101 0102 0141 0146'.replace(/ /g, ''), 'hex');\n// A Counter64 GetResponse from Net-SNMP\nvar ex4 = new Buffer('3030 0201 0104 0770 7269 7661 7465 a222 0204 07ba d0c8 0201 0002 0100 3014 3012 060b 2b06 0102 011f 0101 0106 0146 0305 369d'.replace(/ /g, ''), 'hex');\n// A Gauge32 GetResponse from Net-SNMP\nvar ex5 = new Buffer('3030 0201 0104 0770 7269 7661 7465 a222 0204 15fc af68 0201 0002 0100 3014 3012 060a 2b06 0102 0102 0201 0507 4204 3b9a ca00'.replace(/ /g, ''), 'hex');\n// A TimeTicks GetResponse from Net-SNMP\nvar ex6 = new Buffer('302e 0201 0104 0770 7269 7661 7465 a220 0204 72eb 6a85 0201 0002 0100 3012 3010 0609 2b06 0102 0119 0101 0043 0304 74ec'.replace(/ /g, ''), 'hex');\n// A large SysDescr response.\nvar ex7 = new Buffer('3081 ab02 0101 0407 7072 6976 6174 65a2 819c 0204 5d7f aeee 0201 0002 0100 3081 8d30 818a 0608 2b06 0102 0101 0100 047e 4461 7277 696e 206a 626f 7267 2d6d 6270 2031 312e 322e 3020 4461 7277 696e 204b 6572 6e65 6c20 5665 7273 696f 6e20 3131 2e32 2e30 3a20 5475 6520 4175 6720 2039 2032 303a 3534 3a30 3020 5044 5420 3230 3131 3b20 726f 6f74 3a78 6e75 2d31 3639 392e 3234 2e38 7e31 2f52 454c 4541 5345 5f58 3836 5f36 3420 7838 365f 3634'.replace(/ /g, ''), 'hex');\n// A OID GetNextReponse\nvar ex8 = new Buffer('30 35 02 01 01 04 07 70 72 69 76 61 74 65 a2 27 02 04 e6 34 17 a0 02 01 00 02 01 00 30 19 30 17 06 08 2b 06 01 02 01 01 02 00 06 0b 2b 06 01 04 01 bf 08 03 02 81 7f'.replace(/ /g, ''), 'hex');\n// An IpAddress GetNextResponse\nvar ex9 = new Buffer('30 36 02 01 01 04 07 70 72 69 76 61 74 65 a2 28 02 04 45 20 95 bb 02 01 00 02 01 00 30 1a 30 18 06 10 2b 06 01 02 01 03 01 01 03 04 01 81 2c 14 0a 01 40 04 ac 14 0a 01'.replace(/ /g, ''), 'hex');\n// Some random dudes error packet\nvar ex10 = new Buffer('30 82 00 61 02 01 01 04 06 70 75 62 6c 69 63 a2 82 00 52 02 04 2a 96 a4 01 02 01 00 02 01 00 30 82 00 42 30 82 00 1f 06 82 00 08 2b 06 01 02 01 01 05 00 04 11 44 6f 63 75 50 72 69 6e 74 20 43 4d 32 30 35 20 66 30 82 00 1b 06 82 00 0b 2b 06 01 02 01 2b 05 01 01 11 01 04 0a 57 46 47 2d 30 31 33 34 37 35'.replace(/ /g, ''), 'hex');\n\ndescribe('snmp', function () {\n    describe('encode()', function () {\n        it('returns a correctly formatted buffer from a packet description', function () {\n            var correct = '30 2c 02 01 01 04 07 70 72 69 76 61 74 65 a0 1e 02 01 05 02 01 06 02 01 07 30 13 30 11 06 0d 2b 06 01 04 01 94 78 01 02 07 03 02 00 05 00'.replace(/ /g, '');\n            var pkt = new snmp.Packet(); // A default getrequest\n            pkt.community = 'private';\n            pkt.pdu.reqid = 5;\n            pkt.pdu.error = 6;\n            pkt.pdu.errorIndex = 7;\n            pkt.pdu.varbinds[0].oid = [1, 3, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0];\n            var msg = snmp.encode(pkt);\n            assert.equal(msg.toString('hex'), correct);\n        });\n        it('returns a correctly formatted buffer from a packet description of a set request', function () {\n            var correct = '302d 0201 0104 0770 7269 7661 7465 a31f 0204 380b b460 0201 0002 0100 3011 300f 060a 2b06 0102 0102 0201 0701 0201 02'.replace(/ /g, '');\n            var pkt = new snmp.Packet(); // A default getrequest\n            pkt.community = 'private';\n            pkt.pdu.reqid = 940291168;\n            pkt.pdu.type = 3;\n            pkt.pdu.varbinds[0].oid = [1, 3, 6, 1, 2, 1, 2, 2, 1, 7, 1];\n            pkt.pdu.varbinds[0].type = 2;\n            pkt.pdu.varbinds[0].value = 2;\n            var msg = snmp.encode(pkt);\n            assert.equal(msg.toString('hex'), correct);\n        });\n        it('returns a correctly formatted buffer from a NoSuchObject packet', function () {\n            var correct = '302c 0201 0104 0770 7269 7661 7465 a01e 0201 0502 0106 0201 0730 1330 1106 0d2b 0601 0401 9478 0102 0703 0200 8000'.replace(/ /g, '');\n            var pkt = new snmp.Packet(); // A default getrequest\n            pkt.community = 'private';\n            pkt.pdu.reqid = 5;\n            pkt.pdu.error = 6;\n            pkt.pdu.errorIndex = 7;\n            pkt.pdu.varbinds = [{\n                type: 0x80,\n                oid: [1, 3, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0]\n            }];\n            var msg = snmp.encode(pkt);\n            assert.equal(msg.toString('hex'), correct);\n        });\n        it('returns a correctly formatted buffer from a NoSuchInstance packet', function () {\n            var correct = '302c 0201 0104 0770 7269 7661 7465 a01e 0201 0502 0106 0201 0730 1330 1106 0d2b 0601 0401 9478 0102 0703 0200 8100'.replace(/ /g, '');\n            var pkt = new snmp.Packet(); // A default getrequest\n            pkt.community = 'private';\n            pkt.pdu.reqid = 5;\n            pkt.pdu.error = 6;\n            pkt.pdu.errorIndex = 7;\n            pkt.pdu.varbinds = [{\n                type: 0x81,\n                oid: [1, 3, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0]\n            }];\n            var msg = snmp.encode(pkt);\n            assert.equal(msg.toString('hex'), correct);\n        });\n        it('returns a correctly formatted buffer from a NoSuchObject packet', function () {\n            var correct = '302c 0201 0104 0770 7269 7661 7465 a01e 0201 0502 0106 0201 0730 1330 1106 0d2b 0601 0401 9478 0102 0703 0200 8200'.replace(/ /g, '');\n            var pkt = new snmp.Packet(); // A default getrequest\n            pkt.community = 'private';\n            pkt.pdu.reqid = 5;\n            pkt.pdu.error = 6;\n            pkt.pdu.errorIndex = 7;\n            pkt.pdu.varbinds = [{\n                type: 0x82,\n                oid: [1, 3, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0]\n            }];\n            var msg = snmp.encode(pkt);\n            assert.equal(msg.toString('hex'), correct);\n        });\n    });\n\n    describe('parse()', function () {\n        it('throws a parse error for invalid packets', function (done) {\n            try {\n                snmp.parse(new Buffer('00112233445566', 'hex'));\n            } catch (err) {\n                done();\n            }\n        });\n        it('returns a snmp.Packet structure', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal('Packet', pkt.constructor.name);\n        });\n        it('returns a correct SNMP version field', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal(0x47, pkt.version);\n        });\n        it('returns a correct SNMP community field', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal('private', pkt.community);\n        });\n        it('returns a correct pdu type field', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal(4, pkt.pdu.type);\n        });\n        it('returns a correct request id field', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal(0x33, pkt.pdu.reqid);\n        });\n        it('returns a correct error field', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal(0x44, pkt.pdu.error);\n        });\n        it('returns a correct error index field', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal(0x55, pkt.pdu.errorIndex);\n        });\n        it('returns a correct varbind list', function () {\n            var pkt = snmp.parse(ex1);\n            assert.equal(1, pkt.pdu.varbinds.length);\n            assert.deepEqual([1, 3, 6, 1, 4, 1, 2680, 1, 2, 7, 3, 2, 0], pkt.pdu.varbinds[0].oid);\n            assert.equal(5, pkt.pdu.varbinds[0].type); // Null type\n            assert.equal(null, pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed Net-SNMP OctetString GetResponse', function () {\n            var pkt = snmp.parse(ex2);\n            assert.equal(4, pkt.pdu.varbinds[0].type);\n            assert.equal('Solaris anto.nym.se 11.0 physical', pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed Net-SNMP Counter32 GetResponse', function () {\n            var pkt = snmp.parse(ex3);\n            assert.equal(65, pkt.pdu.varbinds[0].type);\n            assert.equal(70, pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed Net-SNMP Counter64 GetResponse', function () {\n            var pkt = snmp.parse(ex4);\n            assert.equal(70, pkt.pdu.varbinds[0].type);\n            assert.equal(341661, pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed Net-SNMP Gauge32 GetResponse', function () {\n            var pkt = snmp.parse(ex5);\n            assert.equal(66, pkt.pdu.varbinds[0].type);\n            assert.equal(1000000000, pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed Net-SNMP TimeTicks GetResponse', function () {\n            var pkt = snmp.parse(ex6);\n            assert.equal(67, pkt.pdu.varbinds[0].type);\n            assert.equal(292076, pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed large OctetString response', function () {\n            var pkt = snmp.parse(ex7);\n            assert.equal(4, pkt.pdu.varbinds[0].type);\n            assert.equal(\"Darwin jborg-mbp 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug  9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64\", pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed ObjectId response', function () {\n            var pkt = snmp.parse(ex8);\n            assert.equal(6, pkt.pdu.varbinds[0].type);\n            assert.deepEqual([1,3,6,1,4,1,8072,3,2,255], pkt.pdu.varbinds[0].value);\n        });\n        it('returns a correctly parsed IpAddress response', function () {\n            var pkt = snmp.parse(ex9);\n            assert.equal(64, pkt.pdu.varbinds[0].type);\n            assert.deepEqual([172,20,10,1], pkt.pdu.varbinds[0].value);\n        });\n        it('does not error out on a random packet', function () {\n            var pkt = snmp.parse(ex10);\n            assert.equal(\"DocuPrint CM205 f\", pkt.pdu.varbinds[0].value);\n            assert.equal(\"WFG-013475\", pkt.pdu.varbinds[1].value);\n        });\n    });\n\n    describe('compareOids()', function () {\n        it('returns zero for two empty OIDs', function () {\n            assert.equal(0, snmp.compareOids([], []));\n        });\n        it('returns in the favour of the non-undefinedOID', function () {\n            assert.equal(1, snmp.compareOids(undefined, []));\n            assert.equal(-1, snmp.compareOids([], undefined));\n        });\n        it('returns in the favour of the non-empty OID', function () {\n            assert.equal(1, snmp.compareOids([], [0]));\n            assert.equal(-1, snmp.compareOids([0], []));\n        });\n        it('returns in the favour of the larger OID', function () {\n            assert.equal(1, snmp.compareOids([1,2,1,2,1,2,1,2], [1,2,1,2,5,2]));\n            assert.equal(-1, snmp.compareOids([1,2,1,2,5,2], [1,2,1,2,1,2,1,2]));\n        });\n        it('returns in the favour of the longer OID', function () {\n            assert.equal(1, snmp.compareOids([1,2,1,2,1,2,1,2], [1,2,1,2,1,2,1,2,1,2]));\n            assert.equal(-1, snmp.compareOids([1,2,1,2,1,2,1,2,1,2,1,2], [1,2,1,2,1,2,1,2]));\n        });\n    });\n});\n"
  }
]