initial
This commit is contained in:
98
ts/snmp/encoder.ts
Normal file
98
ts/snmp/encoder.ts
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
* SNMP encoding utilities
|
||||
* Contains helper methods for encoding SNMP data
|
||||
*/
|
||||
export class SnmpEncoder {
|
||||
/**
|
||||
* Convert OID string to array of integers
|
||||
* @param oid OID string in dotted notation (e.g. "1.3.6.1.2.1")
|
||||
* @returns Array of integers representing the OID
|
||||
*/
|
||||
public static oidToArray(oid: string): number[] {
|
||||
return oid.split('.').map(n => parseInt(n, 10));
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode an SNMP integer
|
||||
* @param value Integer value to encode
|
||||
* @returns Buffer containing the encoded integer
|
||||
*/
|
||||
public static encodeInteger(value: number): Buffer {
|
||||
const buf = Buffer.alloc(4);
|
||||
buf.writeInt32BE(value, 0);
|
||||
|
||||
// Find first non-zero byte
|
||||
let start = 0;
|
||||
while (start < 3 && buf[start] === 0) {
|
||||
start++;
|
||||
}
|
||||
|
||||
// Handle negative values
|
||||
if (value < 0 && buf[start] === 0) {
|
||||
start--;
|
||||
}
|
||||
|
||||
return buf.slice(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode an OID
|
||||
* @param oid Array of integers representing the OID
|
||||
* @returns Buffer containing the encoded OID
|
||||
*/
|
||||
public static encodeOID(oid: number[]): Buffer {
|
||||
// First two numbers are encoded as 40*x+y
|
||||
let encodedOid = Buffer.from([40 * (oid[0] || 0) + (oid[1] || 0)]);
|
||||
|
||||
// Encode remaining numbers
|
||||
for (let i = 2; i < oid.length; i++) {
|
||||
const n = oid[i];
|
||||
|
||||
if (n < 128) {
|
||||
// Simple case: number fits in one byte
|
||||
encodedOid = Buffer.concat([encodedOid, Buffer.from([n])]);
|
||||
} else {
|
||||
// Number needs multiple bytes
|
||||
const bytes = [];
|
||||
let value = n;
|
||||
|
||||
// Create bytes array in reverse order
|
||||
do {
|
||||
bytes.unshift(value & 0x7F);
|
||||
value >>= 7;
|
||||
} while (value > 0);
|
||||
|
||||
// Set high bit on all but the last byte
|
||||
for (let j = 0; j < bytes.length - 1; j++) {
|
||||
bytes[j] |= 0x80;
|
||||
}
|
||||
|
||||
encodedOid = Buffer.concat([encodedOid, Buffer.from(bytes)]);
|
||||
}
|
||||
}
|
||||
|
||||
return encodedOid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an ASN.1 integer
|
||||
* @param buffer Buffer containing the encoded integer
|
||||
* @param offset Offset in the buffer
|
||||
* @param length Length of the integer in bytes
|
||||
* @returns Decoded integer value
|
||||
*/
|
||||
public static decodeInteger(buffer: Buffer, offset: number, length: number): number {
|
||||
if (length === 1) {
|
||||
return buffer[offset];
|
||||
} else if (length === 2) {
|
||||
return buffer.readInt16BE(offset);
|
||||
} else if (length === 3) {
|
||||
return (buffer[offset] << 16) | (buffer[offset + 1] << 8) | buffer[offset + 2];
|
||||
} else if (length === 4) {
|
||||
return buffer.readInt32BE(offset);
|
||||
} else {
|
||||
// For longer integers, we'll just return a simple value
|
||||
return buffer[offset];
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user