Agent Extensibility (AgentX) Protocol Version 1
obsoletes
- rfc-2257 — Agent Extensibility (AgentX) Protocol Version 1
Extracted elements (31)
AgentX PDUs use a flat binary byte-stream rather than BER/ASN.1, with data organized for natural 32-bit alignment from the PDU start. This permits direct integer access without BER parsing overhead and reflects that AgentX is primarily an IPC mechanism between co-located processes rather than a network protocol.
Subagents encode PDUs in the native byte order of the local processor (indicated by NETWORK_BYTE_ORDER), avoiding byte-swap overhead in the common case where master and subagents share the same host. The master agent detects and adapts to the sender's byte order from the flag.
The master agent is MIB-ignorant and SNMP-omniscient while subagents are SNMP-ignorant and MIB-omniscient. This division of labor allows independently developed subagents to integrate without knowledge of each other or of SNMP protocol internals.
Transparency to SNMP managers is a fundamental requirement: from a manager's perspective, an extensible AgentX agent behaves identically to a monolithic agent with equivalent MIB instrumentation. This distinguishes AgentX subagents from SNMP proxy agents, where the proxy relationship is externally visible.
RFC 2741 obsoletes RFC 2257. Two wire-level changes affect interoperability: agentx-Notify-PDU and agentx-Close-PDU now generate an agentx-Response-PDU (previously they did not), and three new error codes are defined: parseFailed(266), requestDenied(267), processingError(268).
h.payload_length must always be 0 or a multiple of 4, reflecting the 4-byte alignment constraint imposed by AgentX encodings.
If r.subtree in an agentx-Register-PDU is a fully qualified instance name, the INSTANCE_REGISTRATION bit in h.flags must be set; otherwise it must be cleared.
In an agentx-Response-PDU, h.packetID must equal the h.packetID of the received AgentX PDU to which it responds, allowing senders to correlate responses to batched requests.
Multiple AgentX PDUs dispatched by the master agent in response to a single SNMP request on the same session must carry the same h.transactionID; PDUs from distinct SNMP requests on the same session must have distinct transaction IDs (within the 32-bit field).
The master agent must implement MIB view application and access control policy; these are not delegated to subagents. Subagents are shielded from SNMP protocol details and must not be exposed to raw SNMP messages.
The NETWORK_BYTE_ORDER bit in h.flags must govern byte ordering for all multi-byte integer values in the entire AgentX packet. If set, network (big-endian) byte order is used; if not set, little-endian is used. This bit applies to all AgentX PDUs.
AgentX defines 18 PDU types split into administrative PDUs (Open/1, Close/2, Register/3, Unregister/4, Notify/12, Ping/13, IndexAllocate/14, IndexDeallocate/15, AddAgentCaps/16, RemoveAgentCaps/17) and SNMP-request processing PDUs (Get/5, GetNext/6, GetBulk/7, TestSet/8, CommitSet/9, UndoSet/10, CleanupSet/11, Response/18).
AgentX defines two standard transport mappings: TCP using well-known port 705, and UNIX-domain sockets using the well-known path /var/agentx/master. Both provide reliable ordered byte-stream delivery; UNIX-domain sockets are preferred when master and subagents are co-located.
SNMP Set operations use a four-PDU sequence: agentx-TestSet-PDU (validation), agentx-CommitSet-PDU (apply), agentx-UndoSet-PDU (rollback on failure), agentx-CleanupSet-PDU (resource release). The CommitSet, UndoSet, and CleanupSet PDUs consist of the AgentX header only.
The agentx-Close-PDU terminates a session and carries a c.reason code: reasonOther(1), reasonParseError(2), reasonProtocolError(3), reasonTimeouts(4), reasonShutdown(5), reasonByManager(6). Both master agent and subagent may initiate closure; the receiver must send an agentx-Response-PDU.
The agentx-IndexAllocate-PDU lets a subagent request index value allocation from the master agent before registering a table row. Flags NEW_INDEX and ANY_INDEX control whether a new unique value or any available value is requested. agentx-IndexDeallocate-PDU releases previously allocated values.
The agentx-Notify-PDU is sent by a subagent to cause the master agent to forward a notification. The VarBindList must include snmpTrapOID.0 (mandatory); if sysUpTime.0 is also provided it must be the first varbind and snmpTrapOID.0 the second.
The agentx-Open-PDU initiates a session from subagent to master agent, carrying o.timeout (default per-session response timeout in seconds; 0 means no default), o.id (OID identifying the subagent), and o.descr (a DisplayString).
The agentx-Register-PDU allows a subagent to claim a MIB region, with fields r.timeout (per-region timeout override), r.priority (1–255, lower wins, default 127), r.subtree (OID), and optionally r.range_subid and r.upper_bound to register a range of sub-identifier values in a single PDU.
The h.flags byte carries five defined bits: INSTANCE_REGISTRATION (0), NEW_INDEX (1), ANY_INDEX (2), NON_DEFAULT_CONTEXT (3), NETWORK_BYTE_ORDER (4). The NETWORK_BYTE_ORDER bit governs byte ordering for all multi-byte integers in the entire packet including the remaining header fields.
The SearchRange defines a [start, end) OID interval for GetNext and GetBulk operations. The starting OID's include field (0 or 1) indicates whether the start is inclusive; a null ending OID means an unbounded range.
The session ID is assigned by the master agent in the agentx-Response-PDU to an Open request; the subagent-supplied value is ignored. All subsequent PDUs on the session carry the assigned session ID. In master agents supporting multiple transports, session IDs should be globally unique.
The transaction ID (h.transactionID) uniquely identifies a single SNMP management request within a session. All AgentX PDUs dispatched by the master agent for one SNMP request must carry the same transaction ID; distinct SNMP requests must use distinct transaction IDs. It is not the SNMP request-id or msgID.
AgentX provides no authentication or encryption between master agent and subagents at the protocol level. Security relies entirely on the transport: UNIX-domain socket file permissions provide OS-enforced access control, while TCP-based deployments must restrict access via firewall or bind only to loopback. Unauthorized subagent connections could manipulate MIB data seen by SNMP managers.
Session States: Closed → Open (agentx-Open-PDU accepted by master) → Closed (agentx-Close-PDU exchanged, or transport connection lost). On session closure, the master removes all registrations, index allocations, and agent capability advertisements associated with that session.
Set Transaction States: Idle → TestSet dispatched to each subagent → all respond noError → CommitSet dispatched → success: CleanupSet dispatched → Idle; failure at CommitSet: UndoSet dispatched → CleanupSet → Idle. The master must complete each phase across all participating subagents before advancing.
Transport Connection States: Closed → Open (TCP connect or UNIX socket accept) → Closed (disconnect or error). Loss of transport connection triggers implicit closure of all AgentX sessions multiplexed over that connection.
A VarBind is encoded as a 2-byte v.type field (plus 2 reserved bytes), an Object Identifier v.name, and type-dependent v.data. Integer/Counter32/Gauge32/TimeTicks are 4 bytes; Counter64 is 8 bytes; Null, noSuchObject, noSuchInstance, and endOfMibView carry no data bytes.
An Object Identifier is encoded as a 4-byte header (n_subid, prefix, include, reserved) followed by n_subid 4-byte unsigned sub-identifiers. A non-zero prefix value x implies an implicit 1.3.6.1.x prefix, compressing common internet OID encodings.
An Octet String is encoded as a 4-byte length field followed by the octets, zero-padded to the next 4-byte boundary. Padding must be added 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). All multi-byte fields are encoded per the NETWORK_BYTE_ORDER flag in h.flags.