0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 09:41:54 +00:00

TMP new snmp PDUs

This commit is contained in:
Vojtech Vilimek 2022-09-06 18:04:29 +02:00
parent 7961bbb26a
commit eb5a749046
7 changed files with 895 additions and 258 deletions

View File

@ -1,6 +1,5 @@
src := snmp.c subagent.c
obj := $(src-o-files)
LIBS += `net-snmp-config --agent-libs`
$(all-daemon)
$(cf-local)
$(call proto-build,snmp_build)

View File

@ -2,30 +2,32 @@
#define _BIRD_SNMP_BGP_MIB_H_
/* peers attributes */
#define SNMP_BGP_IDENTIFIER 1
#define SNMP_BGP_STATE 2
#define SNMP_BGP_ADMIN_STATUS 3 /* in read-only mode */
#define SNMP_BGP_VERSION 4
#define SNMP_BGP_LOCAL_ADDR 5
#define SNMP_BGP_LOCAL_PORT 6
#define SNMP_BGP_REMOTE_ADDR 7
#define SNMP_BGP_REMOTE_PORT 8
#define SNMP_BGP_REMOTE_AS 9
#define SNMP_BGP_RX_UPDATES 10 /* in updates */
#define SNMP_BGP_TX_UPDATES 11 /* out updates */
#define SNMP_BGP_RX_MESSAGES 12 /* in total messages */
#define SNMP_BGP_TX_MESSAGES 13 /* out total messages */
#define SNMP_BGP_LAST_ERROR 14 /* UNSUPPORTED */
#define SNMP_BGP_FSM_TRANSITIONS 15 /* FSM established transitions */
#define SNMP_BGP_FSM_ESTABLISHED_TIME 16 /* UNSUPPORTED FSM established time */
#define SNMP_BGP_RETRY_INTERVAL 17
#define SNMP_BGP_HOLD_TIME 18
#define SNMP_BGP_KEEPALIVE 19
#define SNMP_BGP_HOLD_TIME_CONFIGURED 20
#define SNMP_BGP_KEEPALIVE_CONFIGURED 21
#define SNMP_BGP_ORIGINATION_INTERVAL 22 /* UNSUPPORTED */
#define SNMP_BGP_MIN_ROUTE_ADVERTISEMENT 23 /* UNSUPPORTED */
#define SNMP_BGP_MIN_UPDATE_ELAPSED_TIME 24 /* UNSUPPORTED */
enum BGP4_MIB {
SNMP_BGP_IDENTIFIER = 1;
SNMP_BGP_STATE = 2;
SNMP_BGP_ADMIN_STATUS = 3; /* in read-only mode */
SNMP_BGP_VERSION = 4;
SNMP_BGP_LOCAL_ADDR = 5;
SNMP_BGP_LOCAL_PORT = 6;
SNMP_BGP_REMOTE_ADDR = 7;
SNMP_BGP_REMOTE_PORT = 8;
SNMP_BGP_REMOTE_AS = 9;
SNMP_BGP_RX_UPDATES = 10; /* in updates */
SNMP_BGP_TX_UPDATES = 11; /* out updates */
SNMP_BGP_RX_MESSAGES = 12; /* in total messages */
SNMP_BGP_TX_MESSAGES = 13; /* out total messages */
SNMP_BGP_LAST_ERROR = 14;
SNMP_BGP_FSM_TRANSITIONS = 15; /* FSM established transitions */
SNMP_BGP_FSM_ESTABLISHED_TIME = 16; /* UNSUPPORTED FSM established time */
SNMP_BGP_RETRY_INTERVAL = 17;
SNMP_BGP_HOLD_TIME = 18;
SNMP_BGP_KEEPALIVE = 19;
SNMP_BGP_HOLD_TIME_CONFIGURED = 20;
SNMP_BGP_KEEPALIVE_CONFIGURED = 21;
SNMP_BGP_ORIGINATION_INTERVAL = 22; /* UNSUPPORTED 0 */
SNMP_BGP_MIN_ROUTE_ADVERTISEMENT = 23; /* UNSUPPORTED 0*/
SNMP_BGP_MIN_UPDATE_ELAPSED_TIME = 24; /* UNSUPPORTED */
} PACKED;
void snmp_init_bgp_table(void);
void snmp_del_bgp_table(void);

View File

@ -61,7 +61,8 @@ snmp_bgp_bond: BGP symbol
struct proto_config *pc;
WALK_LIST(pc, this_proto->global->protos)
if (!strcmp(pc->name, $2->name) && pc->protocol == &proto_bgp)
if (!strcmp(pc->name, $2->name) && pc->protocol == &proto_bgp
&& !ipa_zero(((struct bgp_proto *) pc)->remote_ip))
this_bond->proto = pc;
if (!this_bond->proto) cf_error("BGP protocol %s not found", $2->name);

View File

@ -35,6 +35,7 @@ snmp_init(struct proto_config *CF)
p->remote_ip = cf->remote_ip;
p->local_port = cf->local_port;
p->remote_port = cf->remote_port;
p->state = SNMP_INIT;
// p->timeout = cf->timeout;
p->timeout = 15;
@ -59,7 +60,7 @@ snmp_start_locked(struct object_lock *lock)
s->rbsize = SNMP_RX_BUFFER_SIZE;
s->tbsize = SNMP_TX_BUFFER_SIZE;
// s->tos = IP_PREC_INTERNET_CONTROL
//s->tos = IP_PREC_INTERNET_CONTROL
//s->rx_hook = snmp_connected;
s->tx_hook = snmp_connected;
s->err_hook = snmp_sock_err;
@ -76,7 +77,7 @@ snmp_start_locked(struct object_lock *lock)
static void
snmp_tx(sock *sk UNUSED)
{
log(L_INFO "snmp_tx() recieved something, yay!");
log(L_INFO "snmp_tx() something, yay!");
}
@ -96,7 +97,8 @@ snmp_connected(sock *sk)
static void
snmp_sock_err(sock *sk UNUSED, int err UNUSED)
{
log(L_INFO "snmp_sock_err() ");
log(L_INFO "snmp_sock_err() %s - err no: %d", strerror(err), err);
die("socket error");
}
static int
@ -104,9 +106,10 @@ snmp_start(struct proto *P)
{
log(L_INFO "snmp_start() - starting timer (almost)");
struct snmp_proto *p = (void *) P;
struct snmp_config *cf = P->cf;
p->ping_timer = tm_new_init(p->p.pool, snmp_ping_timer, p, 0, 0);
tm_set(p->ping_timer, current_time() + (7 S_));
tm_set(p->ping_timer, current_time() + (2 S_));
/* starting agentX communicaiton channel */
log(L_INFO "preparing lock");
@ -122,7 +125,30 @@ snmp_start(struct proto *P)
log(L_INFO "local ip: %I:%u, remote ip: %I:%u",
p->local_ip, p->local_port, p->remote_ip, p->remote_port);
init_list(p->bgp_entries);
/* create copy of bonds to bgp */
HASH_INIT(p->peer_hash, p->p.pool, 10);
struct snmp_bond *b;
WALK_LIST(b, cf->bgp_entries)
{
struct bgp_config *bc = b->proto;
if (bc && !ipa_zero(bc->remote_ip))
{
struct snmp_bgp_peer_entry pe = {
.bond = b;
.peer_ip = bc->remote_ip;
.next = NULL;
};
HASH_INSERT(p->peer_hash, SNMP_HASH, pe)
add_tail(&p->bgp_entries, b);
}
}
return PS_START;
}
@ -138,13 +164,13 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
p->remote_port = cf->remote_port;
p->timeout = 15;
/* TODO walk all bind protocols and find their (new) IP
to update HASH table */
log(L_INFO "snmp_reconfigure() lip: %I:%u rip: %I:%u",
p->local_ip, p->local_port, p->remote_ip, p->remote_port);
return 0;
return PS_START;
}
static void
snmp_show_proto_info(struct proto *P)
static void snmp_show_proto_info(struct proto *P)
{
//struct snmp_proto *sp = (void *) P;
struct snmp_config *c = (void *) P->cf;
@ -217,16 +243,17 @@ snmp_ping_timer(struct timer *tm)
log(L_INFO "snmp_ping_timer() ");
struct snmp_proto *p = tm->data;
// ping here
ping_pdu(p);
snmp_ping(p);
//tm_set(tm, current_time() + (7 S_));
}
/* snmp_shutdown already occupied by net-snmp */
static int
snmp_shutdown(struct proto *P)
{
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
snmp_stop_subagent(p);
return PS_DOWN;
}
struct protocol proto_snmp = {
@ -242,7 +269,6 @@ struct protocol proto_snmp = {
.show_proto_info = snmp_show_proto_info,
};
/* strange name because of conflict with net-snmp lib snmp_lib() */
void
snmp_build(void)
{

View File

@ -28,6 +28,20 @@
#define SNMP_RX_BUFFER_SIZE 2048
#define SNMP_TX_BUFFER_SIZE 2048
#define SNMP_INIT 1
#define SNMP_REGISTR 2
#define SNMP_CONN 3
#define SNMP_ERR 4
#define SNMP_OFF 0
/* hash table macros */
#define SNMP_HASH_KEY(n) n->peer_ip;
#define SNMP_HASH_NEXT(n) n->next;
#define SNMP_HASH_EQ(ip1, ip2) ipa_equal(ip1, ip2)
#define SNMP_HASH_FN(ip) ipa_hash(ip)
struct snmp_bond {
node n;
struct proto_config *proto;
@ -45,24 +59,40 @@ struct snmp_config {
list bgp_entries;
};
struct snmp_bgp_peer_entry {
struct snmp_bond *bond;
ip_addr peer_ip;
struct snmp_bgp_peer_entry *next;
}
struct snmp_proto {
struct proto p;
struct object_lock *lock;
ip_addr local_ip;
ip_addr remote_ip;
u16 local_port;
u16 remote_port;
sock *sock;
u8 timeout;
u32 session_id;
u32 transaction_id;
u32 packet_id;
//struct iface *iface;
// map goes here
HASH(struct snmp_bgp_peer_entry) bgp_hash;
struct tbf rl_gen;
timer *ping_timer;
u8 state;
list bgp_entries;
};
/*
struct snmp_channel_config {
struct channel_config c;
struct bgp_config *bgp;
@ -72,7 +102,7 @@ struct snmp_channel_config {
struct snmp_channel {
struct channel c;
};
*/
#endif

File diff suppressed because it is too large Load Diff

View File

@ -6,36 +6,111 @@
void snmp_start_subagent(struct snmp_proto *p);
void snmp_stop_subagent(struct snmp_proto *p);
void snmp_ping(struct snmp_proto *p);
#define AGENTX_INTEGER 2
#define AGENTX_OCTET_STRING 4
#define AGENTX_NULL 5
#define AGENTX_OBJECT_ID 6
#define AGENTX_IP_ADDRESS 64
#define AGENTX_COUNTER_32 65
#define AGENTX_GAUGE_32 66
#define AGENTX_TIME_TICKS 67
#define AGENTX_OPAQUE 68
#define AGENTX_COUNTER_64 70
#define AGENTX_NO_SUCH_OBJECT 128
#define AGENTX_NO_SUCH_INSTANCE 129
#define AGENTX_END_OF_MIB_VIEW 130
#define AGENTX_VERSION 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 */
enum agentx_type {
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;
} PACKED;
#define AGENTX_ADMIN_STOP 1
#define AGENTX_ADMIN_START 2
#define AGENTX_PRIORITY 127
#define MAX_STR 0xFFFFFFFF
#define PASTE_HEADER_(buf, v, t, f, s) \
memset(buf, 0, sizeof(struct agentx_header)); \
struct agentx_header *h = (void *) buf; \
log(L_INFO "value : %d", (void *) h == buf? 1:0); \
h->version = v; \
h->type = t; \
h->flags = f; \
h->pad = 0; \
ADVANCE(buf, s, sizeof(struct agentx_header)); \
#define SNMP_NATIVE
#define PASTE_HEADER(buf, t, f, s) PASTE_HEADER_(buf, AGENTX_VERSION, t, f, s)
#define U32_CPY(w, u) memcpy((w), (u), 4); ADVANCE((w), 4, 4);
#ifdef SNMP_NATIVE
#define STORE(v,c) (v) = (u32) (c)
#define STORE_16(v,c) (v) = (u16) (c)
#define STORE_PTR(v,c) *((u32 *) (v)) = (u32) (c)
#define SNMP_UPDATE(h,l) \
STORE((h)->payload, l)
#else
#define STORE(v, c) put_u32(&v, c)
#define STORE_16(v,c) put_u32(&v, c)
#define STORE_PTR(v,c) put_u32(v, c)
#define SNMP_UPDATE(h,l) \
STORE(h->payload, l)
#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);
#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
#define SNMP_B_HEADER(h, t) SNMP_HEADER(h, t, AGENTX_FLAG_BLANK)
#define SNMP_SESSION(h, p) \
STORE(h->session_id, p->session_id); \
STORE(h->transaction_id, p->transaction_id); \
p->transaction_id++; \
STORE(h->packet_id, p->packet_id);
#define SNMP_CREATE(b, t, n) \
n = (void *) (b); \
memset(n, 0, sizeof(t)); \
(b) += sizeof(t);
#define LOAD(v, bo) ((bo) ? get_u32(&v) : (u32) (v))
#define LOAD_16(v, bo) ((bo) ? get_u16(&v) : (u16) (v))
#define LOAD_PTR(v, bo) ((bo) ? get_u32(v) : (u32) *(v))
#define LOAD_STR(p, b, s, l, bo) \
l = LOAD(*((u32 *) b), bo); \
log(L_INFO "LOAD_STR(), %p %u", p->p.pool, l + 1); \
s = mb_allocz(p->p.pool, l + 1); \
memcpy(s, b, l); \
b += str_size(s);
#define SNMP_LOAD_CONTEXT(p, h, b, s, l) \
if (h->flags & AGENTX_NON_DEFAULT_CONTEXT) \
{ log(L_INFO "encountered non-default context"); \
LOAD_STR(p, b, s, l, h->flags & AGENTX_NETWORK_BYTE_ORDER); }
#define SNMP_COPY_OID(b, o) \
memcpy(b, o, oid_size(o)); \
b += oid_size(o);
#define SNMP_COPY_VB(b, s, e) \
memcpy(b, s, 4); \
b += 4; \
SNMP_COPY_OID(b, &s->name) \
SNMP_COPY_OID(b, e)
#define BGP_DATA_(v, d, p, o) \
(v)->type = d; \
p += o;
#define BGP_DATA(v, d, p) BGP_DATA(v, d, p, 4)
struct agentx_header {
u8 version;
@ -50,17 +125,12 @@ struct agentx_header {
#define AGENTX_HEADER_SIZE sizeof(struct agentx_header)
struct subid{
u32 len;
u32 ids[];
};
struct oid {
u8 n_subid;
u8 prefix;
u8 include;
u8 pad;
struct subid subid;
u32 ids[];
};
struct agentx_varbind {
@ -70,6 +140,7 @@ struct agentx_varbind {
struct oid name;
};
/* this does not work */
struct agentx_search_range {
struct oid start;
struct oid end;
@ -82,7 +153,18 @@ struct agentx_response {
u16 index;
};
#define AGENTX_VERSION 1
struct agentx_close_pdu {
struct agentx_header h;
u8 reason;
};
struct agentx_un_register_pdu {
struct agentx_header h;
u8 timeout;
u8 priority;
u8 range_subid;
u8 padd;
};
enum agentx_pdu {
AGENTX_OPEN_PDU = 1,
@ -108,6 +190,7 @@ enum agentx_pdu {
#define AGENTX_FLAGS_MASK 0x1F
enum agentx_flags {
AGENTX_FLAG_BLANK = 0x00,
AGENTX_FLAG_INSTANCE_REGISTRATION = 0x01,
AGENTX_FLAG_NEW_INDEX = 0x02,
AGENTX_FLAG_ANY_INDEX = 0x04,