Files

236 lines
6.0 KiB
TypeScript
Raw Permalink Normal View History

/**
* SNMP Feature
* Provides SNMP query capability for network management
*/
import { Feature, type TDeviceReference } from './feature.abstract.js';
import type {
TSnmpVersion,
ISnmpVarbind,
ISnmpFeatureInfo,
IFeatureOptions,
} from '../interfaces/feature.interfaces.js';
/**
* Options for creating an SnmpFeature
*/
export interface ISnmpFeatureOptions extends IFeatureOptions {
version?: TSnmpVersion;
community?: string;
// SNMPv3 options
username?: string;
authProtocol?: 'md5' | 'sha';
authKey?: string;
privProtocol?: 'des' | 'aes';
privKey?: string;
}
/**
* SNMP Feature - provides SNMP query capability
*
* Allows querying devices via SNMP for monitoring and management.
* Many network devices (printers, switches, UPS) support SNMP.
*
* @example
* ```typescript
* const snmp = device.getFeature<SnmpFeature>('snmp');
* if (snmp) {
* const sysDescr = await snmp.get('1.3.6.1.2.1.1.1.0');
* console.log(`System: ${sysDescr.value}`);
*
* const interfaces = await snmp.walk('1.3.6.1.2.1.2.2.1');
* console.log(`Found ${interfaces.length} interface entries`);
* }
* ```
*/
export class SnmpFeature extends Feature {
public readonly type = 'snmp' as const;
public readonly protocol = 'snmp';
// Configuration
public readonly version: TSnmpVersion;
public readonly community: string;
// System info (populated after connect)
public sysDescr?: string;
public sysObjectId?: string;
public sysName?: string;
public sysLocation?: string;
public sysContact?: string;
public sysUpTime?: number;
constructor(
device: TDeviceReference,
port: number,
options?: ISnmpFeatureOptions
) {
super(device, port ?? 161, options);
this.version = options?.version ?? 'v2c';
this.community = options?.community ?? 'public';
}
// ============================================================================
// Connection
// ============================================================================
protected async doConnect(): Promise<void> {
// Test connection by getting system description
try {
const result = await this.get('1.3.6.1.2.1.1.1.0'); // sysDescr
if (result) {
this.sysDescr = String(result.value);
}
} catch {
// Connection test failed
throw new Error('SNMP connection failed');
}
}
protected async doDisconnect(): Promise<void> {
// SNMP is connectionless, nothing to disconnect
}
// ============================================================================
// SNMP Operations
// ============================================================================
/**
* Get a single OID value
*/
public async get(oid: string): Promise<ISnmpVarbind> {
// This would use the SNMP library to perform the query
// Placeholder implementation
return {
oid,
type: 0,
value: null,
};
}
/**
* Get multiple OID values
*/
public async getMultiple(oids: string[]): Promise<ISnmpVarbind[]> {
const results: ISnmpVarbind[] = [];
for (const oid of oids) {
results.push(await this.get(oid));
}
return results;
}
/**
* Get next OID in MIB tree
*/
public async getNext(oid: string): Promise<ISnmpVarbind> {
// Placeholder
return {
oid,
type: 0,
value: null,
};
}
/**
* Walk a subtree of the MIB
*/
public async walk(baseOid: string): Promise<ISnmpVarbind[]> {
const results: ISnmpVarbind[] = [];
// This would iterate through the MIB tree using getNext
return results;
}
/**
* Bulk get (SNMPv2c/v3)
*/
public async getBulk(
oids: string[],
nonRepeaters: number = 0,
maxRepetitions: number = 10
): Promise<ISnmpVarbind[]> {
if (this.version === 'v1') {
throw new Error('getBulk not supported in SNMPv1');
}
// Placeholder
return [];
}
/**
* Set an OID value
*/
public async set(oid: string, type: number, value: unknown): Promise<ISnmpVarbind> {
// Placeholder
return {
oid,
type,
value,
};
}
// ============================================================================
// System Info
// ============================================================================
/**
* Get all system info OIDs
*/
public async getSystemInfo(): Promise<{
sysDescr?: string;
sysObjectId?: string;
sysName?: string;
sysLocation?: string;
sysContact?: string;
sysUpTime?: number;
}> {
const oids = [
'1.3.6.1.2.1.1.1.0', // sysDescr
'1.3.6.1.2.1.1.2.0', // sysObjectID
'1.3.6.1.2.1.1.3.0', // sysUpTime
'1.3.6.1.2.1.1.4.0', // sysContact
'1.3.6.1.2.1.1.5.0', // sysName
'1.3.6.1.2.1.1.6.0', // sysLocation
];
const results = await this.getMultiple(oids);
return {
sysDescr: results[0]?.value as string,
sysObjectId: results[1]?.value as string,
sysUpTime: results[2]?.value as number,
sysContact: results[3]?.value as string,
sysName: results[4]?.value as string,
sysLocation: results[5]?.value as string,
};
}
// ============================================================================
// Serialization
// ============================================================================
public getFeatureInfo(): ISnmpFeatureInfo {
return {
...this.getBaseFeatureInfo(),
type: 'snmp',
version: this.version,
community: this.version !== 'v3' ? this.community : undefined,
sysDescr: this.sysDescr,
sysName: this.sysName,
sysLocation: this.sysLocation,
};
}
// ============================================================================
// Static Factory
// ============================================================================
public static fromDiscovery(
device: TDeviceReference,
port: number,
metadata: Record<string, unknown>
): SnmpFeature {
return new SnmpFeature(device, port ?? 161, {
version: metadata.version as TSnmpVersion ?? 'v2c',
community: metadata.community as string ?? 'public',
});
}
}