UNPKG

snmp-node

Version:

A native Javascript SNMP implementation for Node.js

341 lines 151 kB
<!DOCTYPE html><html><head><title>Coverage</title><script>

headings = [];

onload = function(){
  headings = document.querySelectorAll('h2');
};

onscroll = function(e){
  var heading = find(window.scrollY);
  if (!heading) return;
  var links = document.querySelectorAll('#menu a')
    , link;

  for (var i = 0, len = links.length; i < len; ++i) {
    link = links[i];
    link.className = link.getAttribute('href') == '#' + heading.id
      ? 'active'
      : '';
  }
};

function find(y) {
  var i = headings.length
    , heading;

  while (i--) {
    heading = headings[i];
    if (y >= heading.offsetTop) {
      return heading;
    }
  }
}
</script>
<style>

body {
  font: 14px/1.6 "Helvetica Neue", Helvetica, Arial, sans-serif;
  margin: 0;
  color: #2C2C2C;
  border-top: 2px solid #ddd;
}

#coverage {
  padding: 60px;
}

h1 a {
  color: inherit;
  font-weight: inherit;
}

h1 a:hover {
  text-decoration: none;
}

.onload h1 {
  opacity: 1;
}

h2 {
  width: 80%;
  margin-top: 80px;
  margin-bottom: 0;
  font-weight: 100;
  letter-spacing: 1px;
  border-bottom: 1px solid #eee;
}

a {
  color: #8A6343;
  font-weight: bold;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

ul {
  margin-top: 20px;
  padding: 0 15px;
  width: 100%;
}

ul li {
  float: left;
  width: 40%;
  margin-top: 5px;
  margin-right: 60px;
  list-style: none;
  border-bottom: 1px solid #eee;
  padding: 5px 0;
  font-size: 12px;
}

ul::after {
  content: '.';
  height: 0;
  display: block;
  visibility: hidden;
  clear: both;
}

code {
  font: 12px monaco, monospace;
}

pre {
  margin: 30px;
  padding: 30px;
  border: 1px solid #eee;
  border-bottom-color: #ddd;
  -webkit-border-radius: 2px;
  -moz-border-radius: 2px;
  -webkit-box-shadow: inset 0 0 10px #eee;
  -moz-box-shadow: inset 0 0 10px #eee;
  overflow-x: auto;
}

img {
  margin: 30px;
  padding: 1px;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  -webkit-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
  -moz-box-shadow: 0 3px 10px #dedede, 0 1px 5px #888;
  max-width: 100%;
}

footer {
  background: #eee;
  width: 100%;
  padding: 50px 0;
  text-align: right;
  border-top: 1px solid #ddd;
}

footer span {
  display: block;
  margin-right: 30px;
  color: #888;
  font-size: 12px;
}

#menu {
  position: fixed;
  font-size: 12px;
  overflow-y: auto;
  top: 0;
  right: 0;
  margin: 0;
  height: 100%;
  padding: 15px 0;
  text-align: right;
  border-left: 1px solid #eee;
  -moz-box-shadow: 0 0 2px #888
     , inset 5px 0 20px rgba(0,0,0,.5)
     , inset 5px 0 3px rgba(0,0,0,.3);
  -webkit-box-shadow: 0 0 2px #888
     , inset 5px 0 20px rgba(0,0,0,.5)
     , inset 5px 0 3px rgba(0,0,0,.3);
  -webkit-font-smoothing: antialiased;
  background: url("data:image/png;base64,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");
}

#menu::after {
  display: block;
  content: '';
  padding-top: 80px;
}

#logo {
  position: fixed;
  bottom: 10px;
  right: 10px;
  background: rgba(255,255,255,.1);
  font-size: 11px;
  display: block;
  width: 20px;
  height: 20px;
  line-height: 20px;
  text-align: center;
  -webkit-border-radius: 20px;
  -moz-border-radius: 20px;
  -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2);
  -moz-box-shadow: 0 0 3px rgba(0,0,0,.2);
  color: inherit;
}

#menu li a {
  display: block;
  color: white;
  padding: 0 35px 0 25px;
  -webkit-transition: background 300ms;
  -moz-transition: background 300ms;
}

#menu li {
  position: relative;
  list-style: none;
}

#menu a:hover,
#menu a.active {
  text-decoration: none;
  background: rgba(255,255,255,.1);
}

#menu li:hover .cov {
  opacity: 1;
}

#menu li .dirname {
  opacity: .60;
  padding-right: 2px;
}

#menu li .basename {
  opacity: 1;
}

#menu .cov {
  background: rgba(0,0,0,.4);
  position: absolute;
  top: 0;
  right: 8px;
  font-size: 9px;
  opacity: .6;
  text-align: left;
  width: 17px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  padding: 2px 3px;
  text-align: center;
}

#stats:nth-child(2n) {
  display: inline-block;
  margin-top: 15px;
  border: 1px solid #eee;
  padding: 10px;
  -webkit-box-shadow: inset 0 0 2px #eee;
  -moz-box-shadow: inset 0 0 2px #eee;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
}

#stats div {
  float: left;
  padding: 0 5px;
}

#stats::after {
  display: block;
  content: '';
  clear: both;
}

#stats .sloc::after {
  content: ' SLOC';
  color: #b6b6b6;
}

#stats .percentage::after {
  content: ' coverage';
  color: #b6b6b6;
}

#stats .hits,
#stats .misses {
  display: none;
}

.high {
  color: #00d4b4;
}
.medium {
  color: #e87d0d;
}
.low {
  color: #d4081a;
}
.terrible {
  color: #d4081a;
  font-weight: bold;
}

table {
  width: 80%;
  margin-top: 10px;
  border-collapse: collapse;
  border: 1px solid #cbcbcb;
  color: #363636;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
}

table thead {
  display: none;
}

table td.line,
table td.hits {
  width: 20px;
  background: #eaeaea;
  text-align: center;
  font-size: 11px;
  padding: 0 10px;
  color: #949494;
}

table td.hits {
  width: 10px;
  padding: 2px 5px;
  color: rgba(0,0,0,.2);
  background: #f0f0f0;
}

tr.miss td.line,
tr.miss td.hits {
  background: #e6c3c7;
}

tr.miss td {
  background: #f8d5d8;
}

td.source {
  padding-left: 15px;
  line-height: 15px;
  white-space: pre;
  font: 12px monaco, monospace;
}

code .comment { color: #ddd }
code .init { color: #2F6FAD }
code .string { color: #5890AD }
code .keyword { color: #8A6343 }
code .number { color: #2F6FAD }
</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>