0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-23 18:21:54 +00:00
bird/proto/snmp/subagent.h

348 lines
10 KiB
C
Raw Normal View History

#ifndef _BIRD_SNMP_SUBAGENT_H_
#define _BIRD_SNMP_SUBAGENT_H_
2022-08-10 15:31:32 +00:00
#include "nest/bird.h"
#include "snmp.h"
2022-08-10 15:31:32 +00:00
void snmp_start_subagent(struct snmp_proto *p);
void snmp_stop_subagent(struct snmp_proto *p);
2022-09-06 16:04:29 +00:00
void snmp_ping(struct snmp_proto *p);
#define AGENTX_VERSION 1
2022-11-05 15:29:00 +00:00
#define SNMP_STATE_START 0
#define SNMP_STATE_BGP 1
#define SNMP_STATE_INVALID 2
2023-09-04 11:51:29 +00:00
#define SNMP_ISO 1 /* last of oid .1 */
#define SNMP_ORG 3 /* last of oid .1.3 */
#define SNMP_DOD 6 /* last of oid .1.3.6 */
#define SNMP_INTERNET 1 /* last of oid .1.3.6.1 */
#define SNMP_MGMT 2 /* last of oid .1.3.6.1.2 */
#define SNMP_MIB_2 1 /* last of oid .1.3.6.1.2.1 */
#define SNMP_OSPF_MIB 14 /* part of oid .1.3.6.1.2.1.14 */
#define SNMP_BGP4_MIB 15 /* part of oid .1.3.6.1.2.1.15 */
#define SNMP_OSPFv3_MIB 192 /* part of oid .1.3.6.1.2.1.192 */
extern u32 snmp_internet[4];
2022-09-06 16:04:29 +00:00
#define SNMP_DEFAULT_CONTEXT 0
2022-11-05 15:29:00 +00:00
enum SNMP_CLASSES {
SNMP_CLASS_INVALID = 0,
SNMP_CLASS_BGP = 1,
SNMP_CLASS_OSPF,
SNMP_CLASS_END,
};
2023-07-26 12:02:23 +00:00
#define BGP4_VERSIONS ((char[]) { 0x10 })
2022-09-20 12:28:57 +00:00
2022-09-06 16:04:29 +00:00
enum agentx_type {
2022-09-20 12:28:57 +00:00
AGENTX_INTEGER = 2,
AGENTX_OCTET_STRING = 4,
AGENTX_NULL = 5,
AGENTX_OBJECT_ID = 6,
AGENTX_IP_ADDRESS = 64,
AGENTX_COUNTER_32 = 65,
AGENTX_GAUGE_32 = 66,
AGENTX_TIME_TICKS = 67,
AGENTX_OPAQUE = 68,
AGENTX_COUNTER_64 = 70,
AGENTX_NO_SUCH_OBJECT = 128,
AGENTX_NO_SUCH_INSTANCE = 129,
AGENTX_END_OF_MIB_VIEW = 130,
2022-09-06 16:04:29 +00:00
} PACKED;
2022-08-10 15:31:32 +00:00
2023-07-26 12:02:23 +00:00
enum snmp_search_res {
SNMP_SEARCH_OK = 0,
SNMP_SEARCH_NO_OBJECT = 1,
SNMP_SEARCH_NO_INSTANCE = 2,
SNMP_SEARCH_END_OF_VIEW = 3,
};
2022-09-06 16:04:29 +00:00
#define AGENTX_ADMIN_STOP 1
#define AGENTX_ADMIN_START 2
2022-08-10 15:31:32 +00:00
#define AGENTX_PRIORITY 127
#define SNMP_REGISTER_TREE 0
#define SNMP_REGISTER_INSTANCE 1
2022-09-06 16:04:29 +00:00
#define SNMP_NATIVE
#ifdef SNMP_NATIVE
2023-07-26 12:02:23 +00:00
#define STORE_U32(dest, val) ((dest) = (u32) (val))
#define STORE_U16(dest, val) ((dest) = (u16) (val))
#define STORE_U8(dest, val) ((dest) = (u8) (val))
#define STORE_PTR(ptr, val) (*((u32 *) (ptr)) = (u32) (val))
2022-09-06 16:04:29 +00:00
#else
2023-07-26 12:02:23 +00:00
#define STORE_U32(dest, val) put_u32(&(dest), (val))
#define STORE_U16(dest, val) put_u16(&(dest), (val))
#define STORE_U8(dest, val) put_u8(&(dest), (val))
#define STORE_PTR(ptr, val) put_u32(ptr, val)
2022-09-06 16:04:29 +00:00
#endif
/* storing byte (u8) is always the same */
#define SNMP_HEADER_(h, v, t, f) \
put_u8(&h->version, v); \
put_u8(&h->type, t); \
put_u8(&h->flags, f); \
put_u8(&h->pad, 0); \
STORE_U32(h->payload, 0)
2022-09-06 16:04:29 +00:00
#ifdef SNMP_NATIVE
#define SNMP_HEADER(h,t,f) SNMP_HEADER_(h, AGENTX_VERSION, t, f)
#else
#define SNMP_HEADER(h,t,f) \
SNMP_HEADER_(h, AGENTX_VERSION, t, f | SNMP_NETWORK_BYTE_ORDER)
#endif
2023-07-26 12:02:23 +00:00
#define SNMP_BLANK_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
2022-09-06 16:04:29 +00:00
#define SNMP_SESSION(h, p) \
2023-07-26 12:02:23 +00:00
STORE_U32(h->session_id, p->session_id); \
STORE_U32(h->transaction_id, p->transaction_id); \
STORE_U32(h->packet_id, p->packet_id)
#define LOAD_U32(v, bo) ((bo) ? get_u32(&v) : (u32) (v))
#define LOAD_U16(v, bo) ((bo) ? get_u16(&v) : (u16) (v))
2023-07-26 12:30:34 +00:00
#define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : *((u32 *) v))
#define LOAD_STR(/* byte * */buf, str, length, byte_ord) ({ \
length = LOAD_PTR(buf, byte_ord); \
length > 0 ? (str = buf + 4) : (str = NULL); })
#define COPY_STR(proto, buf, str, length, byte_order) ({ \
2023-07-26 12:30:34 +00:00
length = LOAD_PTR(buf, byte_order); \
2023-10-18 16:06:24 +00:00
/*log(L_INFO "LOAD_STR(), %p %u", proto->pool, length + 1); */ \
2023-10-18 14:51:21 +00:00
str = mb_alloc(proto->pool, length + 1); \
memcpy(str, buf+4, length); \
2023-07-26 12:30:34 +00:00
str[length] = '\0'; /* set term. char */ \
buf += 4 + snmp_str_size_from_len(length); })
#define SNMP_LOAD_CONTEXT(hdr, buf, cont, cont_len) ({ \
if ((hdr)->flags & AGENTX_NON_DEFAULT_CONTEXT) \
LOAD_STR((buf), (cont), (cont_len), \
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER); })
2023-07-26 12:30:34 +00:00
#define SNMP_COPY_CONTEXT(proto, hdr, buf, cont, cont_len) ({ \
2023-07-26 12:30:34 +00:00
cont = NULL; cont_len = 0; \
if (hdr->flags & AGENTX_NON_DEFAULT_CONTEXT) \
COPY_STR(proto, buf, cont, cont_len, \
(hdr)->flags & AGENTX_NETWORK_BYTE_ORDER) })
2023-07-26 12:30:34 +00:00
#define SNMP_HAS_CONTEXT(hdr) \
hdr->flags |= AGENTX_NON_DEFAULT_CONTEXT
#define SNMP_NON_DEFAULT_CONTEXT(hdr,pdu,contid) ({ \
if (contid) { \
SNMP_HAS_CONTEXT(hdr); \
snmp_put_str((c).buffer, (sc)->context); \
ADVANCE((c).buffer, (c).size, snmp_str_size((sc)->context)); \
} })
#define SNMP_PUT_OID(buf, size, oid, byte_ord) \
({ \
struct agentx_varbind *vb = (void *) buf; \
SNMP_FILL_VARBIND(vb, oid, byte_ord); \
2023-07-26 12:02:23 +00:00
})
#define SNMP_FILL_VARBIND(vb, oid, byte_ord) \
2023-07-26 12:02:23 +00:00
snmp_oid_copy(&(vb)->name, (oid), (byte_ord)), snmp_oid_size((oid))
#define SNMP_VB_DATA(varbind) \
2023-07-26 12:02:23 +00:00
(((void *)(varbind)) + snmp_varbind_header_size(varbind))
2022-08-10 15:31:32 +00:00
2023-09-04 11:46:02 +00:00
#define SNMP_PDU_CONTEXT(sk) { \
.buffer = sk->tpos, \
.size = sk->tbuf + sk->tbsize - sk->tpos, \
.error = AGENTX_RES_NO_ERROR, \
.context = 0, \
}
2022-08-10 15:31:32 +00:00
struct agentx_header {
u8 version;
u8 type;
u8 flags;
u8 pad;
2023-07-26 12:30:34 +00:00
u32 session_id; /* AgentX sessionID established by Open-PDU */
u32 transaction_id; /* last transactionID seen/used */
u32 packet_id; /* last packetID seen/used */
u32 payload; /* payload_length of the packet without header */
2022-08-10 15:31:32 +00:00
};
#define AGENTX_HEADER_SIZE sizeof(struct agentx_header)
struct oid {
u8 n_subid;
u8 prefix;
u8 include;
u8 pad;
2022-09-06 16:04:29 +00:00
u32 ids[];
2022-08-10 15:31:32 +00:00
};
struct agentx_varbind {
u16 type;
u16 pad;
/* oid part */
struct oid name;
};
2022-09-06 16:04:29 +00:00
/* this does not work */
2022-08-10 15:31:32 +00:00
struct agentx_search_range {
struct oid start;
struct oid end;
};
struct agentx_getbulk {
u16 non_repeaters;
u16 max_repetitions;
};
2022-08-10 15:31:32 +00:00
struct agentx_response {
struct agentx_header h;
u32 uptime;
2023-07-26 12:30:34 +00:00
u16 error;
2022-08-10 15:31:32 +00:00
u16 index;
};
2022-09-06 16:04:29 +00:00
struct agentx_close_pdu {
struct agentx_header h;
u8 reason;
};
struct agentx_un_register_hdr {
2022-09-06 16:04:29 +00:00
u8 timeout;
u8 priority;
u8 range_subid;
u8 pad;
2022-09-06 16:04:29 +00:00
};
2022-08-10 15:31:32 +00:00
2022-11-19 22:00:02 +00:00
struct agentx_bulk_state {
struct agentx_getbulk getbulk;
u16 index;
u16 repetition;
u32 repeaters;
2022-11-19 22:00:02 +00:00
};
2022-08-10 15:31:32 +00:00
enum agentx_pdu {
AGENTX_OPEN_PDU = 1,
AGENTX_CLOSE_PDU = 2,
AGENTX_REGISTER_PDU = 3,
AGENTX_UNREGISTER_PDU = 4,
AGENTX_GET_PDU = 5,
AGENTX_GET_NEXT_PDU = 6,
AGENTX_GET_BULK_PDU = 7,
AGENTX_TEST_SET_PDU = 8,
AGENTX_COMMIT_SET_PDU = 9,
AGENTX_UNDO_SET_PDU = 10,
AGENTX_CLEANUP_SET_PDU = 11,
AGENTX_NOTIFY_PDU = 12,
AGENTX_PING_PDU = 13,
AGENTX_INDEX_ALLOCATE_PDU = 14,
AGENTX_INDEX_DEALLOCATE_PDU = 15,
AGENTX_ADD_AGENT_CAPS_PDU = 16,
AGENTX_REMOVE_AGENT_CAPS_PDU = 17,
AGENTX_RESPONSE_PDU = 18,
} PACKED;
#define AGENTX_FLAGS_MASK 0x1F
enum agentx_flags {
2022-09-06 16:04:29 +00:00
AGENTX_FLAG_BLANK = 0x00,
2022-08-10 15:31:32 +00:00
AGENTX_FLAG_INSTANCE_REGISTRATION = 0x01,
AGENTX_FLAG_NEW_INDEX = 0x02,
AGENTX_FLAG_ANY_INDEX = 0x04,
AGENTX_NON_DEFAULT_CONTEXT = 0x08,
AGENTX_NETWORK_BYTE_ORDER = 0x10,
} PACKED;
#define AGENTX_FLAGS (AGENTX_FLAG_INSTANCE_REGISTRATION \
| AGENTX_FLAG_NEW_INDEX \
| AGENTX_FLAG_ANY_INDEX \
| AGENTX_NON_DEFAULT_CONTEXT \
| AGENTX_NETWORK_BYTE_ORDER)
2022-08-10 15:31:32 +00:00
/* CLOSE_PDU close reasons */
enum agentx_close_reasons {
AGENTX_CLOSE_OTHER = 1,
AGENTX_CLOSE_PARSE_ERROR = 2,
AGENTX_CLOSE_PROTOCOL_ERROR = 3,
AGENTX_CLOSE_TIMEOUTS = 4,
AGENTX_CLOSE_SHUTDOWN = 5,
AGENTX_CLOSE_BY_MANAGER = 6,
} PACKED;
/* RESPONSE_PDU - result error */
enum agentx_response_err {
2023-07-26 12:30:34 +00:00
/* response OK master <-> subagent */
2022-09-20 12:28:57 +00:00
AGENTX_RES_NO_ERROR = 0,
2023-07-26 12:30:34 +00:00
/* TEST_SET_PDU response errors (subagent -> master) */
2022-09-20 12:28:57 +00:00
AGENTX_RES_GEN_ERROR = 5,
AGENTX_RES_NO_ACCESS = 6,
AGENTX_RES_WRONG_TYPE = 7,
AGENTX_RES_WRONG_LENGTH = 8,
AGENTX_RES_WRONG_ENCODING = 9,
AGENTX_RES_WRONG_VALUE = 10,
AGENTX_RES_NO_CREATION = 11,
AGENTX_RES_INCONSISTENT_VALUE = 12,
AGENTX_RES_RESOURCE_UNAVAILABLE = 13,
AGENTX_RES_NOT_WRITEABLE = 17,
AGENTX_RES_INCONSISTENT_NAME = 18,
2023-07-26 12:30:34 +00:00
/* end of TEST_SET_PDU resonse errs (master -> subagent) */
2022-09-20 12:28:57 +00:00
AGENTX_RES_OPEN_FAILED = 256,
AGENTX_RES_NOT_OPEN = 257,
AGENTX_RES_INDEX_WRONG_TYPE = 258,
AGENTX_RES_INDEX_ALREADY_ALLOC = 259,
AGENTX_RES_INDEX_NONE_AVAIL = 260,
AGENTX_RES_NOT_ALLOCATED = 261,
AGENTX_RES_UNSUPPORTED_CONTEXT = 262,
2022-12-17 17:16:19 +00:00
AGENTX_RES_DUPLICATE_REGISTER = 263,
AGENTX_RES_UNKNOWN_REGISTER = 264,
2022-09-20 12:28:57 +00:00
AGENTX_RES_UNKNOWN_AGENT_CAPS = 265,
AGENTX_RES_PARSE_ERROR = 266,
AGENTX_RES_REQUEST_DENIED = 267,
AGENTX_RES_PROCESSING_ERR = 268,
2022-08-10 15:31:32 +00:00
} PACKED;
/* SNMP PDU buffer info */
struct snmp_pdu {
2023-07-26 12:02:23 +00:00
byte *buffer; /* pointer to buffer */
uint size; /* unused space in buffer */
uint context; /* context hash */
int byte_ord; /* flag signaling NETWORK_BYTE_ORDER */
enum agentx_response_err error; /* storage for result of current action */
};
struct agentx_alloc_context {
u8 is_instance; /* flag INSTANCE_REGISTRATION */
u8 new_index; /* flag NEW_INDEX */
u8 any_index; /* flag ANY_INDEX */
char *context; /* context to allocate in */
uint clen; /* length of context string */
};
2022-08-10 15:31:32 +00:00
int snmp_rx(sock *sk, uint size);
2022-12-17 17:16:19 +00:00
int snmp_rx_stop(sock *sk, uint size);
void snmp_down(struct snmp_proto *p);
void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance, uint contid);
void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len, uint contid);
2023-09-04 12:01:08 +00:00
void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime);
2022-11-05 15:29:00 +00:00
void snmp_manage_tbuf(struct snmp_proto *p, struct snmp_pdu *c);
2023-07-26 12:02:23 +00:00
struct oid *snmp_prefixize(struct snmp_proto *p, const struct oid *o, int byte_ord);
u8 snmp_get_mib_class(const struct oid *oid);
2023-09-04 11:53:45 +00:00
2022-12-10 12:22:37 +00:00
// debug wrapper
2023-10-18 16:06:24 +00:00
#if 0
2022-12-10 12:22:37 +00:00
#define snmp_log(...) log(L_INFO "snmp " __VA_ARGS__)
2023-10-18 16:06:24 +00:00
#else
#define snmp_log(...) do { } while(0)
#endif
2022-12-10 12:22:37 +00:00
#endif