Agent Extensibility (AgentX) Protocol Version 1
obsoleted by
- rfc-2741 — Agent Extensibility (AgentX) Protocol Version 1
Extracted elements (29)
AgentX uses native byte-order encoding with the NETWORK_BYTE_ORDER flag to indicate which order is in use, rather than mandating network byte order. Since master and subagents typically reside on the same host and AgentX is more an IPC mechanism than a network protocol, native byte order avoids unnecessary byte-swapping overhead.
Subagent-to-subagent communication is explicitly excluded as a non-goal due to security implications and added complexity. Subagent access to MIB variables via the master is also out of scope since other mechanisms exist; AgentX is narrowly scoped to cover only subagent-to-master communication.
The master agent is 'MIB ignorant and SNMP omniscient' while each subagent is 'SNMP ignorant and MIB omniscient'. This clean division ensures master agents handle all SNMP protocol operations and access control, while subagents focus exclusively on management instrumentation without needing SNMP knowledge.
AgentX PDUs are not BER-encoded (unlike SNMP PDUs), but transmitted as a contiguous byte stream organized for 32-bit natural alignment from the PDU start, permitting direct integer access. This is a fundamental wire-format difference from all SNMP PDU encodings.
The r.priority field (1-255, lower value = higher precedence) in agentx-Register-PDU enables deterministic dispatching when independently developed subagents register overlapping or identical OID regions. Subagents with no priority preference should register at the default value of 255.
If r.region is a fully qualified instance name in an agentx-Register-PDU, the INSTANCE_REGISTRATION bit in h.flags must be set; otherwise it must be cleared. The master agent may use this information to optimize operational dispatching.
In an agentx-Response-PDU, h.packetID must equal the packetID of the PDU to which it responds. All AgentX PDUs sent by the master agent with the same sessionID for a single SNMP management request must carry the same h.transactionID; PDUs from distinct requests must have distinct transactionIDs.
The master agent must enforce MIB views and access control policy; subagents are explicitly shielded from these responsibilities. From an SNMP manager's perspective, the extensible agent must behave identically to a monolithic agent with equivalent instrumentation.
When a subagent sends an agentx-Notify-PDU, if sysUpTime.0 is present it must be the first varbind, and snmpTrapOID.0 must be present as the second varbind (or first if sysUpTime.0 is absent).
agentx-AddAgentCaps-PDU (h.type=16) and agentx-RemoveAgentCaps-PDU (h.type=17) allow subagents to advertise AGENT-CAPABILITIES invocation OIDs (a.id) and descriptions (a.descr), which the master exports as sysORID and sysORDescr values for the indicated context.
AgentX defines two standard transport mappings: TCP with a well-known port (Section 8.1) and UNIX-domain sockets with a well-known socket path (Section 8.2). UNIX-domain sockets are the preferred transport when master and subagents reside on the same host, providing lower overhead than TCP.
agentx-IndexAllocate-PDU (h.type=14) and agentx-IndexDeallocate-PDU (h.type=15) allow subagents to request and release specific index object values from the master agent, coordinating table-row uniqueness among independently developed subagents sharing the same conceptual table.
SNMP SET operations are implemented as a four-PDU two-phase commit: agentx-TestSet-PDU (type 8) validates the request; agentx-CommitSet-PDU (type 9) applies changes; agentx-UndoSet-PDU (type 10) rolls back on commit failure; agentx-CleanupSet-PDU (type 11) releases resources. CommitSet, UndoSet, and CleanupSet contain only the PDU header.
The agentx-Close-PDU (h.type=2) terminates a session; either side may send it. The c.reason field takes values: reasonOther(1), reasonParseError(2), reasonProtocolError(3), reasonTimeouts(4), reasonShutdown(5), or reasonByManager(6). reasonByManager may only be used by the master agent in response to an SNMP Set.
The agentx-Notify-PDU (h.type=12) is sent by a subagent to cause the master to forward a notification. snmpTrapOID.0 must be present; if sysUpTime.0 is supplied it must be the first varbind, with snmpTrapOID.0 second.
The agentx-Open-PDU (h.type=1) is sent by a subagent to establish a session. It carries o.timeout (subagent-wide default timeout in seconds, 0 means no override), o.id (OID identifying the subagent), and o.descr (DisplayString description). The master assigns the sessionID in the agentx-Response-PDU.
The agentx-Ping-PDU (h.type=13) is sent by a subagent to verify the master agent can send and receive PDUs over the session. An optional context field allows retrieval of the sysUpTime value for a specific non-default context.
The agentx-Register-PDU (h.type=3) claims a MIB region. Key fields: r.timeout (region-specific timeout override), r.priority (1-255, lower takes precedence, default 255), r.region (OID), optional r.range_subid and r.upper_bound to register a conceptual row range in a single PDU.
The context mechanism allows AgentX operations to reference non-default SNMP contexts. When NON_DEFAULT_CONTEXT is set in h.flags, an Octet String context field immediately follows the AgentX header. Applicable to Register, Unregister, Get, GetNext, GetBulk, TestSet, Notify, Ping, IndexAllocate, IndexDeallocate, AddAgentCaps, and RemoveAgentCaps PDUs.
The h.flags bitmask in the PDU header defines: INSTANCE_REGISTRATION (bit 0), NEW_INDEX (bit 1), ANY_INDEX (bit 2), NON_DEFAULT_CONTEXT (bit 3), NETWORK_BYTE_ORDER (bit 4). The NETWORK_BYTE_ORDER bit applies to all multi-byte integer values in the entire AgentX packet including remaining header fields.
The h.sessionID uniquely identifies an AgentX session. It has no defined value in the subagent's agentx-Open-PDU; the master assigns a unique value in the corresponding agentx-Response-PDU. Thereafter, the same sessionID appears in every PDU exchanged over that session. In multi-transport master agents, sessionIDs should be globally unique.
AgentX is designed for use between co-located processes on a single managed node and provides no built-in authentication or encryption. Security depends entirely on the underlying transport; deployments using TCP across a network must apply external network-level security controls to prevent unauthorized subagent connections.
Session states: Closed → Opening (subagent sends agentx-Open-PDU) → Open (master responds with assigned sessionID) → Closing (agentx-Close-PDU sent by either side or connection lost) → Closed. Session close triggers release of all MIB registrations, index allocations, and advertised agent capabilities.
Set transaction states: Idle → testSetReceived (on agentx-TestSet dispatch) → commitSetReceived (CommitSet succeeds) or undoSetReceived (CommitSet fails, UndoSet sent) → cleanupSetReceived (CleanupSet received). A subagent must be able to receive CleanupSet in any non-Idle state.
A SearchRange consists of two Object Identifiers: a starting OID whose 'include' field (boolean) indicates whether the range start is inclusive, and a non-inclusive end OID whose 'include' field is always 0. Used in Get, GetNext, and GetBulk PDUs to bound subagent response scope.
A VarBind encodes a variable binding as a 2-byte v.type field, a reserved 2-byte field, a v.name Object Identifier, and v.data. Integer, Counter32, Gauge32, and TimeTicks are 4 bytes; Counter64 is 8 bytes; Null, noSuchObject, noSuchInstance, and endOfMibView carry no value data.
An Object Identifier is encoded as a 4-byte header (n_subid: 1 byte, prefix: 1 byte, include: 1 byte, reserved: 1 byte) followed by n_subid 4-byte sub-identifiers. A non-zero prefix value x implies an implicit prefix 1.3.6.1.x, reducing encoding length.
An Octet String is encoded as a 4-byte length field followed by the octets, zero-padded to 4-byte alignment. Padding must be appended even if the Octet String is the last item in the PDU.
The AgentX PDU header is a fixed 20-octet structure: h.version (1 byte), h.type (1 byte), h.flags (1 byte), reserved (1 byte), h.sessionID (4 bytes), h.transactionID (4 bytes), h.packetID (4 bytes), h.payload_length (4 bytes). The payload_length is always 0 or a multiple of 4.