function parse(buf) {
    var pkt, oid, bvb, vb, hdr, vbhdr;

    pkt = new Packet();

    // First we have a sequence marker (two bytes).
    // We don't care about those, so cut them off.
    hdr = asn1ber.typeAndLength(buf);
    assert.equal(asn1ber.types.Sequence, hdr.type);
    buf = buf.slice(hdr.header);

    // Then comes the version field (integer). Parse it and slice it.
    pkt.version = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    // We then get the community. Parse and slice.
    pkt.community = asn1ber.parseOctetString(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    // Here's the PDU structure. We're interested in the type. Slice the rest.
    hdr = asn1ber.typeAndLength(buf);
    assert.ok(hdr.type >= 0xA0);
    pkt.pdu.type = hdr.type - 0xA0;
    buf = buf.slice(hdr.header);

    // The request id field.
    pkt.pdu.reqid = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    // The error field.
    pkt.pdu.error = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    // The error index field.
    pkt.pdu.errorIndex = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    // Here's the varbind list. Not interested.
    hdr = asn1ber.typeAndLength(buf);
    assert.equal(asn1ber.types.Sequence, hdr.type);
    buf = buf.slice(hdr.header);

    // Now comes the varbinds. There might be many, so we loop for as long as we have data.
    pkt.pdu.varbinds = [];
    while (buf[0] === asn1ber.types.Sequence) {
        vb = new VarBind();

        // Slice off the sequence header.
        hdr = asn1ber.typeAndLength(buf);
        assert.equal(asn1ber.types.Sequence, hdr.type);
        bvb = buf.slice(hdr.header, hdr.len + hdr.header);

        // Parse and save the ObjectIdentifier.
        vb.oid = asn1ber.parseOid(bvb);

        // Parse the value. We use the type marker to figure out
        // what kind of value it is and call the appropriate parser
        // routine. For the SNMPv2c error types, we simply set the
        // value to a text representation of the error and leave handling
        // up to the user.
        var vb_name_hdr = asn1ber.typeAndLength(bvb);
        bvb = bvb.slice(vb_name_hdr.header + vb_name_hdr.len);
        var vb_value_hdr = asn1ber.typeAndLength(bvb);
        vb.type = vb_value_hdr.type;
        if (vb.type === asn1ber.types.Null) {
            // Null type.
            vb.value = null;
        } else if (vb.type === asn1ber.types.OctetString) {
            // Octet string type.
            vb.value = asn1ber.parseOctetString(bvb);
        } else if (vb.type === asn1ber.types.Integer ||
            vb.type === asn1ber.types.Counter ||
            vb.type === asn1ber.types.Counter64 ||
            vb.type === asn1ber.types.TimeTicks ||
            vb.type === asn1ber.types.Gauge) {
            // Integer type and it's derivatives that behave in the same manner.
            vb.value = asn1ber.parseInteger(bvb);
        } else if (vb.type === asn1ber.types.ObjectIdentifier) {
            // Object identifier type.
            vb.value = asn1ber.parseOid(bvb);
        } else if (vb.type === asn1ber.types.IpAddress) {
            // IP Address type.
            vb.value = asn1ber.parseArray(bvb);
        } else if (vb.type === asn1ber.types.Opaque) {
            // Opaque type. The 'parsing' here is very light; basically we return a
            // string representation of the raw bytes in hex.
            vb.value = asn1ber.parseOpaque(bvb);
        } else if (vb.type === asn1ber.types.EndOfMibView) {
            // End of MIB view error, returned when attempting to GetNext beyond the end
            // of the current view.
            vb.value = 'endOfMibView';
        } else if (vb.type === asn1ber.types.NoSuchObject) {
            // No such object error, returned when attempting to Get/GetNext an OID that doesn't exist.
            vb.value = 'noSuchObject';
        } else if (vb.type === asn1ber.types.NoSuchInstance) {
            // No such instance error, returned when attempting to Get/GetNext an instance
            // that doesn't exist in a given table.
            vb.value = 'noSuchInstance';
        } else {
            // Something else that we can't handle, so throw an error.
            // The error will be caught and presented in a useful manner on stderr,
            // with a dump of the message causing it.
            throw new Error('Unrecognized value type ' + vb.type);
        }

        // Take the raw octet string value and preseve it as a buffer and hex string.
        vb.valueRaw = bvb.slice(vb_value_hdr.header, vb_value_hdr.header + vb_value_hdr.len);
        vb.valueHex = vb.valueRaw.toString('hex');

        // Add the request id to the varbind (even though it doesn't really belong)
        // so that it will be availble to the end user.
        vb.requestId = pkt.pdu.reqid;

        // Push whatever we parsed to the varbind list.
        pkt.pdu.varbinds.push(vb);

        // Go fetch the next varbind, if there seems to be any.
        if (buf.length > hdr.header + hdr.len) {
            buf = buf.slice(hdr.header + hdr.len);
        } else {
            break;
        }
    }

    return pkt;
}
function parse(buf) {
    var pkt, oid, bvb, vb, hdr, vbhdr;

    pkt = new Packet();

    
    
    hdr = asn1ber.typeAndLength(buf);
    assert.equal(asn1ber.types.Sequence, hdr.type);
    buf = buf.slice(hdr.header);

    
    pkt.version = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    
    pkt.community = asn1ber.parseOctetString(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    
    hdr = asn1ber.typeAndLength(buf);
    assert.ok(hdr.type >= 0xA0);
    pkt.pdu.type = hdr.type - 0xA0;
    buf = buf.slice(hdr.header);

    
    pkt.pdu.reqid = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    
    pkt.pdu.error = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    
    pkt.pdu.errorIndex = asn1ber.parseInteger(buf.slice(0, buf[1] + 2));
    buf = buf.slice(2 + buf[1]);

    
    hdr = asn1ber.typeAndLength(buf);
    assert.equal(asn1ber.types.Sequence, hdr.type);
    buf = buf.slice(hdr.header);

    
    pkt.pdu.varbinds = [];
    while (buf[0] === asn1ber.types.Sequence) {
        vb = new VarBind();

        
        hdr = asn1ber.typeAndLength(buf);
        assert.equal(asn1ber.types.Sequence, hdr.type);
        bvb = buf.slice(hdr.header, hdr.len + hdr.header);

        
        vb.oid = asn1ber.parseOid(bvb);

        
        
        
        
        
        var vb_name_hdr = asn1ber.typeAndLength(bvb);
        bvb = bvb.slice(vb_name_hdr.header + vb_name_hdr.len);
        var vb_value_hdr = asn1ber.typeAndLength(bvb);
        vb.type = vb_value_hdr.type;
        if (vb.type === asn1ber.types.Null) {
            
            vb.value = null;
        } else if (vb.type === asn1ber.types.OctetString) {
            
            vb.value = asn1ber.parseOctetString(bvb);
        } else if (vb.type === asn1ber.types.Integer ||
            vb.type === asn1ber.types.Counter ||
            vb.type === asn1ber.types.Counter64 ||
            vb.type === asn1ber.types.TimeTicks ||
            vb.type === asn1ber.types.Gauge) {
            
            vb.value = asn1ber.parseInteger(bvb);
        } else if (vb.type === asn1ber.types.ObjectIdentifier) {
            
            vb.value = asn1ber.parseOid(bvb);
        } else if (vb.type === asn1ber.types.IpAddress) {
            
            vb.value = asn1ber.parseArray(bvb);
        } else if (vb.type === asn1ber.types.Opaque) {
            
            
            vb.value = asn1ber.parseOpaque(bvb);
        } else if (vb.type === asn1ber.types.EndOfMibView) {
            
            
            vb.value = 'endOfMibView';
        } else if (vb.type === asn1ber.types.NoSuchObject) {
            
            vb.value = 'noSuchObject';
        } else if (vb.type === asn1ber.types.NoSuchInstance) {
            
            
            vb.value = 'noSuchInstance';
        } else {
            
            
            
            throw new Error('Unrecognized value type ' + vb.type);
        }

        
        vb.valueRaw = bvb.slice(vb_value_hdr.header, vb_value_hdr.header + vb_value_hdr.len);
        vb.valueHex = vb.valueRaw.toString('hex');

        
        
        vb.requestId = pkt.pdu.reqid;

        
        pkt.pdu.varbinds.push(vb);

        
        if (buf.length > hdr.header + hdr.len) {
            buf = buf.slice(hdr.header + hdr.len);
        } else {
            break;
        }
    }

    return pkt;
}
function parse ( buf ) { var pkt , oid , bvb , vb , hdr , vbhdr ; pkt = new Packet ( ) ; // First we have a sequence marker (two bytes). // We don't care about those, so cut them off. hdr = asn1ber . typeAndLength ( buf ) ; assert . equal ( asn1ber . types . Sequence , hdr . type ) ; buf = buf . slice ( hdr . header ) ; // Then comes the version field (integer). Parse it and slice it. pkt . version = asn1ber . parseInteger ( buf . slice ( 0 , buf [ 1 ] + 2 ) ) ; buf = buf . slice ( 2 + buf [ 1 ] ) ; // We then get the community. Parse and slice. pkt . community = asn1ber . parseOctetString ( buf . slice ( 0 , buf [ 1 ] + 2 ) ) ; buf = buf . slice ( 2 + buf [ 1 ] ) ; // Here's the PDU structure. We're interested in the type. Slice the rest. hdr = asn1ber . typeAndLength ( buf ) ; assert . ok ( hdr . type >= 0xA0 ) ; pkt . pdu . type = hdr . type - 0xA0 ; buf = buf . slice ( hdr . header ) ; // The request id field. pkt . pdu . reqid = asn1ber . parseInteger ( buf . slice ( 0 , buf [ 1 ] + 2 ) ) ; buf = buf . slice ( 2 + buf [ 1 ] ) ; // The error field. pkt . pdu . error = asn1ber . parseInteger ( buf . slice ( 0 , buf [ 1 ] + 2 ) ) ; buf = buf . slice ( 2 + buf [ 1 ] ) ; // The error index field. pkt . pdu . errorIndex = asn1ber . parseInteger ( buf . slice ( 0 , buf [ 1 ] + 2 ) ) ; buf = buf . slice ( 2 + buf [ 1 ] ) ; // Here's the varbind list. Not interested. hdr = asn1ber . typeAndLength ( buf ) ; assert . equal ( asn1ber . types . Sequence , hdr . type ) ; buf = buf . slice ( hdr . header ) ; // Now comes the varbinds. There might be many, so we loop for as long as we have data. pkt . pdu . varbinds = [ ] ; while ( buf [ 0 ] === asn1ber . types . Sequence ) { vb = new VarBind ( ) ; // Slice off the sequence header. hdr = asn1ber . typeAndLength ( buf ) ; assert . equal ( asn1ber . types . Sequence , hdr . type ) ; bvb = buf . slice ( hdr . header , hdr . len + hdr . header ) ; // Parse and save the ObjectIdentifier. vb . oid = asn1ber . parseOid ( bvb ) ; // Parse the value. We use the type marker to figure out // what kind of value it is and call the appropriate parser // routine. For the SNMPv2c error types, we simply set the // value to a text representation of the error and leave handling // up to the user. var vb_name_hdr = asn1ber . typeAndLength ( bvb ) ; bvb = bvb . slice ( vb_name_hdr . header + vb_name_hdr . len ) ; var vb_value_hdr = asn1ber . typeAndLength ( bvb ) ; vb . type = vb_value_hdr . type ; if ( vb . type === asn1ber . types . Null ) { // Null type. vb . value = null ; } else if ( vb . type === asn1ber . types . OctetString ) { // Octet string type. vb . value = asn1ber . parseOctetString ( bvb ) ; } else if ( vb . type === asn1ber . types . Integer || vb . type === asn1ber . types . Counter || vb . type === asn1ber . types . Counter64 || vb . type === asn1ber . types . TimeTicks || vb . type === asn1ber . types . Gauge ) { // Integer type and it's derivatives that behave in the same manner. vb . value = asn1ber . parseInteger ( bvb ) ; } else if ( vb . type === asn1ber . types . ObjectIdentifier ) { // Object identifier type. vb . value = asn1ber . parseOid ( bvb ) ; } else if ( vb . type === asn1ber . types . IpAddress ) { // IP Address type. vb . value = asn1ber . parseArray ( bvb ) ; } else if ( vb . type === asn1ber . types . Opaque ) { // Opaque type. The 'parsing' here is very light; basically we return a // string representation of the raw bytes in hex. vb . value = asn1ber . parseOpaque ( bvb ) ; } else if ( vb . type === asn1ber . types . EndOfMibView ) { // End of MIB view error, returned when attempting to GetNext beyond the end // of the current view. vb . value = 'endOfMibView' ; } else if ( vb . type === asn1ber . types . NoSuchObject ) { // No such object error, returned when attempting to Get/GetNext an OID that doesn't exist. vb . value = 'noSuchObject' ; } else if ( vb . type === asn1ber . types . NoSuchInstance ) { // No such instance error, returned when attempting to Get/GetNext an instance // that doesn't exist in a given table. vb . value = 'noSuchInstance' ; } else { // Something else that we can't handle, so throw an error. // The error will be caught and presented in a useful manner on stderr, // with a dump of the message causing it. throw new Error ( 'Unrecognized value type ' + vb . type ) ; } // Take the raw octet string value and preseve it as a buffer and hex string. vb . valueRaw = bvb . slice ( vb_value_hdr . header , vb_value_hdr . header + vb_value_hdr . len ) ; vb . valueHex = vb . valueRaw . toString ( 'hex' ) ; // Add the request id to the varbind (even though it doesn't really belong) // so that it will be availble to the end user. vb . requestId = pkt . pdu . reqid ; // Push whatever we parsed to the varbind list. pkt . pdu . varbinds . push ( vb ) ; // Go fetch the next varbind, if there seems to be any. if ( buf . length > hdr . header + hdr . len ) { buf = buf . slice ( hdr . header + hdr . len ) ; } else { break ; } } return pkt ; }
Parse an SNMP packet into its component fields. We don't do a lot of validation so a malformed packet will probably just make us blow up.
Parse an SNMP packet into its component fields . We don t do a lot of validation so a malformed packet will probably just make us blow up .