mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
TMP: compiles and runs
This commit is contained in:
parent
8ea2e991fa
commit
03ab2a89c0
3
lib/ip.h
3
lib/ip.h
@ -145,6 +145,9 @@ static inline ip4_addr ip4_xor(ip4_addr a, ip4_addr b)
|
||||
static inline ip4_addr ip4_not(ip4_addr a)
|
||||
{ return _MI4(~_I(a)); }
|
||||
|
||||
static inline int ip4_less(ip4_addr a, ip4_addr b)
|
||||
{ return _I(a) < _I(b); }
|
||||
|
||||
|
||||
static inline int ip6_equal(ip6_addr a, ip6_addr b)
|
||||
{ return _I0(a) == _I0(b) && _I1(a) == _I1(b) && _I2(a) == _I2(b) && _I3(a) == _I3(b); }
|
||||
|
@ -1,4 +1,4 @@
|
||||
src := snmp.c subagent.c
|
||||
src := snmp.c subagent.c bgp_mib.c
|
||||
obj := $(src-o-files)
|
||||
$(all-daemon)
|
||||
$(cf-local)
|
||||
|
@ -25,41 +25,38 @@
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
#include "bgp_mib.h"
|
||||
#include "snmp.h"
|
||||
#include "subagent.h"
|
||||
#include "bgp_mib.h"
|
||||
|
||||
void
|
||||
snmp_bgp_register()
|
||||
{}
|
||||
|
||||
static inline int
|
||||
is_bgp_peer_entry(struct oid *o)
|
||||
{
|
||||
if (o->ids[2] == BGP4_PEER_ENTRY &&
|
||||
o->ids[3] > 0 &&
|
||||
/* do not include bgpPeerInUpdatesElapsedTime
|
||||
and bgpPeerFsmEstablishedTime */
|
||||
o->ids[3] < SNMP_BGP_IN_UPDATE_ELAPSED_TIME &&
|
||||
o->ids[3] != SNMP_BGP_FSM_ESTABLISHED_TIME)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
snmp_bgp_is_supported(struct oid *o)
|
||||
{
|
||||
if (o->prefix == 2 && o->ids[0] == 1)
|
||||
if (o->prefix == 2 && o->n_subid > 0 && o->ids[0] == 1)
|
||||
{
|
||||
if (o->ids[1] == BGP4_MIB_VERSION ||
|
||||
o->ids == BGP4_MIB_LOCAL_AS)
|
||||
if (o->n_subid == 2 && o->ids[1] == BGP4_MIB_VERSION ||
|
||||
o->ids[1] == BGP4_MIB_LOCAL_AS)
|
||||
return 1;
|
||||
else if (o->ids[1] == BGP4_PEER_TABLE)
|
||||
return is_bgp_peer_entry(o)
|
||||
else if (o->n_subid > 2 && o->ids[1] == BGP4_PEER_TABLE &&
|
||||
o->ids[2] == BGP4_PEER_ENTRY)
|
||||
{
|
||||
if (o->n_subid == 3)
|
||||
return 1;
|
||||
if (o->n_subid == 8 &&
|
||||
o->ids[3] > 0 &&
|
||||
/* do not include bgpPeerInUpdatesElapsedTime
|
||||
and bgpPeerFsmEstablishedTime */
|
||||
o->ids[3] < SNMP_BGP_IN_UPDATE_ELAPSED_TIME &&
|
||||
o->ids[3] != SNMP_BGP_FSM_ESTABLISHED_TIME)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef _BIRD_SNMP_BGP_MIB_H_
|
||||
#define _BIRD_SNMP_BGP_MIB_H_
|
||||
|
||||
#include "snmp.h"
|
||||
|
||||
/* peers attributes */
|
||||
enum BGP4_MIB {
|
||||
SNMP_BGP_IDENTIFIER = 1,
|
||||
|
@ -43,6 +43,7 @@ snmp_proto_start: proto_start SNMP
|
||||
this_proto = proto_config_new(&proto_snmp, $1);
|
||||
|
||||
init_list(&SNMP_CFG->bgp_entries);
|
||||
SNMP_CFG->bonds = 0;
|
||||
|
||||
SNMP_CFG->local_ip = IPA_NONE;
|
||||
SNMP_CFG->remote_ip = ipa_build4(127,0,0,1);
|
||||
@ -61,14 +62,12 @@ snmp_bgp_bond: BGP symbol
|
||||
struct snmp_bond *this_bond = cfg_alloc(sizeof(struct snmp_bond));
|
||||
this_bond->type = SNMP_BGP;
|
||||
|
||||
struct proto_config *pc;
|
||||
WALK_LIST(pc, this_proto->global->protos)
|
||||
if (!strcmp(pc->name, $2->name) && pc->protocol == &proto_bgp
|
||||
&& !ipa_zero(((struct bgp_proto *) pc)->remote_ip))
|
||||
this_bond->proto = pc;
|
||||
cf_assert_symbol($2, SYM_PROTO);
|
||||
this_bond->proto = $2->proto;
|
||||
|
||||
if (!this_bond->proto) cf_error("BGP protocol %s not found", $2->name);
|
||||
add_tail(&SNMP_CFG->bgp_entries, (node *) this_bond);
|
||||
add_tail(&SNMP_CFG->bgp_entries, NODE this_bond);
|
||||
SNMP_CFG->bonds++;
|
||||
}
|
||||
|
||||
CF_CODE
|
||||
|
@ -22,7 +22,9 @@
|
||||
static void snmp_connected(sock *sk);
|
||||
static void snmp_sock_err(sock *sk, int err);
|
||||
static void snmp_ping_timer(struct timer *tm);
|
||||
static void snmp_retry_timer(struct timer *tm);
|
||||
static void snmp_startup(struct snmp_proto *p);
|
||||
static void snmp_startup_timeout(timer *t);
|
||||
static void snmp_start_locked(struct object_lock *lock);
|
||||
|
||||
static struct proto *
|
||||
snmp_init(struct proto_config *CF)
|
||||
@ -48,6 +50,31 @@ snmp_init(struct proto_config *CF)
|
||||
return P;
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_startup_timeout(timer *t)
|
||||
{
|
||||
snmp_startup(t->data);
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_startup(struct snmp_proto *p)
|
||||
{
|
||||
/* starting agentX communicaiton channel */
|
||||
log(L_INFO "preparing lock");
|
||||
struct object_lock *lock;
|
||||
lock = p->lock = olock_new(p->p.pool);
|
||||
|
||||
lock->type = OBJLOCK_TCP;
|
||||
lock->hook = snmp_start_locked;
|
||||
lock->data = p;
|
||||
|
||||
olock_acquire(lock);
|
||||
log(L_INFO "lock acquiring");
|
||||
|
||||
log(L_INFO "local ip: %I:%u, remote ip: %I:%u",
|
||||
p->local_ip, p->local_port, p->remote_ip, p->remote_port);
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_start_locked(struct object_lock *lock)
|
||||
{
|
||||
@ -61,7 +88,7 @@ snmp_start_locked(struct object_lock *lock)
|
||||
s->dport = p->remote_port;
|
||||
s->rbsize = SNMP_RX_BUFFER_SIZE;
|
||||
s->tbsize = SNMP_TX_BUFFER_SIZE;
|
||||
|
||||
|
||||
//s->tos = IP_PREC_INTERNET_CONTROL
|
||||
//s->rx_hook = snmp_connected;
|
||||
s->tx_hook = snmp_connected;
|
||||
@ -70,9 +97,14 @@ snmp_start_locked(struct object_lock *lock)
|
||||
p->sock = s;
|
||||
s->data = p;
|
||||
|
||||
if (sk_open(s) < 0)
|
||||
p->to_send = 0;
|
||||
p->errs = 0;
|
||||
|
||||
snmp_startup(p);
|
||||
|
||||
if (sk_open(s) < 0)
|
||||
log(L_ERR "Cannot open listening socket");
|
||||
|
||||
|
||||
log(L_INFO "socket ready!, trying to connect");
|
||||
}
|
||||
|
||||
@ -97,17 +129,18 @@ snmp_connected(sock *sk)
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_sock_err(sock *sk UNUSED, int err UNUSED)
|
||||
snmp_sock_err(sock *sk, int err)
|
||||
{
|
||||
log(L_INFO "snmp_sock_err() %s - err no: %d", strerror(err), err);
|
||||
|
||||
struct snmp_proto *p = sk->data;
|
||||
tm_stop(p->ping_timer);
|
||||
|
||||
rfree(p->sock);
|
||||
p->sock = NULL;
|
||||
|
||||
p->state = SNMP_ERR;
|
||||
if (p->p.proto_state == PS_UP)
|
||||
proto_notify_state(&p->p, PS_START);
|
||||
|
||||
tm_set(p->retry_timer, current_time() + 5 S);
|
||||
tm_start(p->startup_timer, 15 S);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -117,10 +150,17 @@ snmp_start(struct proto *P)
|
||||
struct snmp_proto *p = (void *) P;
|
||||
struct snmp_config *cf = (struct snmp_config *) P->cf;
|
||||
|
||||
p->startup_timer = tm_new_init(p->p.pool, snmp_startup_timeout, p, 0, 0);
|
||||
|
||||
p->to_send = 0;
|
||||
p->errs = 0;
|
||||
|
||||
p->pool = lp_new(p->p.pool);
|
||||
p->bgp_trie = f_new_trie(p->pool, cf->bonds);
|
||||
|
||||
p->ping_timer = tm_new_init(p->p.pool, snmp_ping_timer, p, 0, 0);
|
||||
tm_set(p->ping_timer, current_time() + 2 S);
|
||||
|
||||
p->retry_timer = tm_new_init(p->p.pool, snmp_retry_timer, p, 0, 0);
|
||||
|
||||
/* starting agentX communicaiton channel */
|
||||
log(L_INFO "preparing lock");
|
||||
@ -137,12 +177,10 @@ 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->bgp_hash, p->p.pool, 10);
|
||||
|
||||
struct snmp_bond *b, *b2;
|
||||
struct snmp_bond *b;
|
||||
WALK_LIST(b, cf->bgp_entries)
|
||||
{
|
||||
struct bgp_config *bc = (struct bgp_config *) b->proto;
|
||||
@ -150,20 +188,19 @@ snmp_start(struct proto *P)
|
||||
{
|
||||
struct snmp_bgp_peer *peer =
|
||||
mb_allocz(p->p.pool, sizeof(struct snmp_bgp_peer));
|
||||
peer->bond = b;
|
||||
peer->config = (struct bgp_config *) b->proto;
|
||||
peer->peer_ip = bc->remote_ip;
|
||||
|
||||
struct net_addr *net = mb_allocz(p->p.pool, sizeof(struct net_addr));
|
||||
net_fill_ip4(net, ipa_to_ip4(peer->peer_ip), IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
trie_add_prefix(p->bgp_trie, net, IP4_MAX_PREFIX_LENGTH, IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
HASH_INSERT(p->bgp_hash, SNMP_HASH, peer);
|
||||
|
||||
b2 = mb_allocz(p->p.pool, sizeof(struct snmp_bond));
|
||||
b2->proto = b->proto;
|
||||
b2->type = b->type;
|
||||
add_tail(&p->bgp_entries, NODE b2);
|
||||
mb_free(peer);
|
||||
}
|
||||
}
|
||||
|
||||
return PS_START;
|
||||
|
||||
return PS_START;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -183,8 +220,9 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
|
||||
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 PS_START;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void snmp_show_proto_info(struct proto *P)
|
||||
{
|
||||
//struct snmp_proto *sp = (void *) P;
|
||||
@ -263,37 +301,15 @@ static void
|
||||
snmp_ping_timer(struct timer *tm)
|
||||
{
|
||||
log(L_INFO "snmp_ping_timer() ");
|
||||
struct snmp_proto *p = tm->data;
|
||||
struct snmp_proto *p = tm->data;
|
||||
|
||||
if (p->state == SNMP_CONN)
|
||||
{
|
||||
snmp_ping(p);
|
||||
}
|
||||
|
||||
//tm_set(tm, current_time() + (7 S_));
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_retry_timer(struct timer *tm)
|
||||
{
|
||||
log(L_INFO "snmp_retry_timer()");
|
||||
|
||||
struct snmp_proto *p = tm->data;
|
||||
|
||||
/* starting agentX communicaiton channel */
|
||||
log(L_INFO "preparing lock");
|
||||
struct object_lock *lock;
|
||||
lock = p->lock = olock_new(p->p.pool);
|
||||
|
||||
lock->type = OBJLOCK_TCP;
|
||||
lock->hook = snmp_start_locked;
|
||||
lock->data = p;
|
||||
|
||||
olock_acquire(lock);
|
||||
log(L_INFO "lock acquired");
|
||||
|
||||
log(L_INFO "local ip: %I:%u, remote ip: %I:%u",
|
||||
p->local_ip, p->local_port, p->remote_ip, p->remote_port);
|
||||
//tm_set(tm, current_time() + (15 S));
|
||||
tm_set(tm, current_time() + 15 S);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -303,7 +319,7 @@ snmp_shutdown(struct proto *P)
|
||||
p->state = SNMP_INIT;
|
||||
|
||||
tm_stop(p->ping_timer);
|
||||
tm_stop(p->retry_timer);
|
||||
tm_stop(p->startup_timer);
|
||||
|
||||
snmp_stop_subagent(p);
|
||||
return PS_DOWN;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "lib/timer.h"
|
||||
#include "nest/bird.h"
|
||||
#include "nest/protocol.h"
|
||||
#include "filter/data.h"
|
||||
#include "proto/bgp/bgp.h"
|
||||
|
||||
|
||||
@ -28,13 +29,11 @@
|
||||
#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
|
||||
|
||||
#define SNMP_ERR 0
|
||||
#define SNMP_DELAY 1
|
||||
#define SNMP_INIT 2
|
||||
#define SNMP_REGISTR 3
|
||||
#define SNMP_CONN 4
|
||||
|
||||
/* hash table macros */
|
||||
#define SNMP_HASH_KEY(n) n->peer_ip
|
||||
@ -42,6 +41,12 @@
|
||||
#define SNMP_HASH_EQ(ip1, ip2) ipa_equal(ip1, ip2)
|
||||
#define SNMP_HASH_FN(ip) ipa_hash(ip)
|
||||
|
||||
#define SNMP_HASH_LESS4(ip1, ip2) ip4_less(ip1, ip2)
|
||||
#define SNMP_HASH_LESS6(ip1, ip2) ip6_less(ip1, ip2)
|
||||
|
||||
/* hash table only store ip4 addresses */
|
||||
#define SNMP_HASH_LESS(ip1, ip2) SNMP_HASH_LESS4(ip1,ip2)
|
||||
|
||||
struct snmp_bond {
|
||||
node n;
|
||||
struct proto_config *proto;
|
||||
@ -58,10 +63,11 @@ struct snmp_config {
|
||||
u8 timeout;
|
||||
//struct iface *iface;
|
||||
list bgp_entries;
|
||||
u32 bonds;
|
||||
};
|
||||
|
||||
struct snmp_bgp_peer {
|
||||
struct snmp_bond *bond;
|
||||
struct bgp_config *config;
|
||||
ip_addr peer_ip;
|
||||
struct snmp_bgp_peer *next;
|
||||
};
|
||||
@ -69,7 +75,8 @@ struct snmp_bgp_peer {
|
||||
struct snmp_proto {
|
||||
struct proto p;
|
||||
struct object_lock *lock;
|
||||
|
||||
struct linpool *pool;
|
||||
|
||||
ip_addr local_ip;
|
||||
ip_addr remote_ip;
|
||||
u16 local_port;
|
||||
@ -85,27 +92,18 @@ struct snmp_proto {
|
||||
|
||||
//struct iface *iface;
|
||||
// map goes here
|
||||
struct f_trie *bgp_trie;
|
||||
HASH(struct snmp_bgp_peer) bgp_hash;
|
||||
struct tbf rl_gen;
|
||||
|
||||
timer *ping_timer;
|
||||
timer *retry_timer;
|
||||
|
||||
uint startup_delay;
|
||||
timer *startup_timer;
|
||||
u8 state;
|
||||
|
||||
list bgp_entries;
|
||||
uint to_send;
|
||||
uint errs;
|
||||
};
|
||||
|
||||
/*
|
||||
struct snmp_channel_config {
|
||||
struct channel_config c;
|
||||
struct bgp_config *bgp;
|
||||
u8 type;
|
||||
};
|
||||
|
||||
struct snmp_channel {
|
||||
struct channel c;
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -16,7 +16,7 @@
|
||||
* Problems
|
||||
* ------------------------------------------------------------
|
||||
*
|
||||
* change of remote ip -> no notification, no update
|
||||
* change of remote ip -> no notification, no update
|
||||
* same ip, different ports
|
||||
* distinct VRF (two interfaces with overlapping private addrs)
|
||||
* posible link-local addresses in LOCAL_IP
|
||||
@ -24,19 +24,18 @@
|
||||
*/
|
||||
|
||||
static int parse_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static void header_update_len(byte *buf, u32 len);
|
||||
static inline uint oid_size(struct oid *o);
|
||||
static inline uint vb_size(struct agentx_varbind *vb);
|
||||
static int snmp_stop_ack(sock *sk, uint size);
|
||||
static void do_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static int parse_get_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
static int parse_gets_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
//static void response_fail(struct snmp_proto *p, u16 err_no, u16 index);
|
||||
static uint parse_get_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
static uint parse_gets_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
static byte *prepare_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static void response_err_ind(byte *buf, uint err, uint ind);
|
||||
static struct oid *bgp_search(struct oid *o_start, struct oid *o_end, struct oid *o_curr);
|
||||
static struct oid *bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr);
|
||||
static struct oid *prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
|
||||
static inline byte *find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord);
|
||||
static byte *no_such_object(byte *buf, struct agentx_varbind *vb);
|
||||
|
||||
static const char * const snmp_errs[] = {
|
||||
#define SNMP_ERR_SHIFT 256
|
||||
@ -132,8 +131,17 @@ put_oid(byte *buf, struct oid *oid)
|
||||
return buf + (oid->n_subid << 2);
|
||||
}
|
||||
|
||||
static void
|
||||
oid_ip4_index(struct oid *o, ip4_addr addr)
|
||||
{
|
||||
u32 temp = ip4_to_u32(addr);
|
||||
STORE(o->ids[5], temp >> 24);
|
||||
STORE(o->ids[6], (temp & 0x00FF0000) >> 16);
|
||||
STORE(o->ids[7], (temp & 0x0000FF00) >> 8);
|
||||
STORE(o->ids[8], temp & 0x000000FF);
|
||||
}
|
||||
|
||||
/* paste data at first byte in message
|
||||
/* paste data at first byte in message
|
||||
* with 3B of padding
|
||||
*/
|
||||
static byte *
|
||||
@ -179,11 +187,11 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
int ret = sk_send(sk, pkt - buf);
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sleep");
|
||||
log(L_INFO "sk_send sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "err %d", ret);
|
||||
log(L_INFO "sk_send err %d", ret);
|
||||
else
|
||||
log(L_INFO "ok !!! ");
|
||||
log(L_INFO "sk_send ok !!! ");
|
||||
}
|
||||
|
||||
else
|
||||
@ -266,11 +274,11 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
|
||||
int ret = sk_send(sk, pkt - buf);
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sleep");
|
||||
log(L_INFO "sk_send sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "err %d", ret);
|
||||
log(L_INFO "sk_send err %d", ret);
|
||||
else
|
||||
log(L_INFO "ok !!");
|
||||
log(L_INFO "sk_send ok !!");
|
||||
}
|
||||
|
||||
else
|
||||
@ -286,7 +294,7 @@ snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len)
|
||||
|
||||
|
||||
/* unregister pdu */
|
||||
static void
|
||||
static void UNUSED
|
||||
snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len)
|
||||
{
|
||||
un_register_pdu(p, oid, index, len, AGENTX_UNREGISTER_PDU);
|
||||
@ -319,11 +327,11 @@ close_pdu(struct snmp_proto *p, u8 reason)
|
||||
int ret = sk_send(sk, pkt - buf);
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sleep");
|
||||
log(L_INFO "sk_send sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "err");
|
||||
else
|
||||
log(L_INFO, "ok !!");
|
||||
log(L_INFO "sk_send err");
|
||||
else
|
||||
log(L_INFO, "sk_send ok !!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,6 +349,7 @@ parse_pkt(struct snmp_proto *p, byte *buf, uint size)
|
||||
if (size < AGENTX_HEADER_SIZE)
|
||||
return 0;
|
||||
|
||||
uint len = 0;
|
||||
struct agentx_header *h = (void *) buf;
|
||||
log(L_INFO "parse_pkt got type %u", h->type);
|
||||
switch (h->type)
|
||||
@ -356,13 +365,33 @@ parse_pkt(struct snmp_proto *p, byte *buf, uint size)
|
||||
|
||||
case AGENTX_GET_PDU:
|
||||
case AGENTX_GET_NEXT_PDU:
|
||||
case AGENTX_GET_BULK_PDU:
|
||||
refresh_ids(p, h);
|
||||
return parse_gets_pdu(p, buf, size);
|
||||
len = parse_gets_pdu(p, buf, size);
|
||||
break;
|
||||
|
||||
/* should not happen */
|
||||
default:
|
||||
die("unknown packet type %u", h->type);
|
||||
}
|
||||
|
||||
log(L_INFO "parsed, sending ... to addr %I:%u -> %I:%u",
|
||||
p->sock->saddr, p->sock->sport, p->sock->daddr, p->sock->dport);
|
||||
if (len && p->state != SNMP_ERR)
|
||||
{
|
||||
p->to_send = len;
|
||||
int ret = sk_send(p->sock, len);
|
||||
log(L_INFO "message sent");
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sk_send sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "sk_send err no: %d '%s'", ret, strerror(ret));
|
||||
else
|
||||
log("sk_send OK ! !!");
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -448,6 +477,24 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
||||
// register first line in BGP4-MIB bgpPeerTable
|
||||
// TODO register all bind bgp connections
|
||||
snmp_register(p, o2, 9, 24);
|
||||
|
||||
log(L_INFO "before hash walk");
|
||||
HASH_WALK(p->bgp_hash, next, peer)
|
||||
{
|
||||
oid_ip4_index(o2, ipa_to_ip4(peer->peer_ip));
|
||||
|
||||
log(L_INFO "");
|
||||
log(L_INFO "o2 n_subid %u prefix %u include %u", o2->n_subid,
|
||||
o2->prefix, o2->include);
|
||||
for (int i = 0; i < o2->n_subid; i++)
|
||||
log(L_INFO "%d: %u", i, o2->ids[i]);
|
||||
log(L_INFO "");
|
||||
|
||||
snmp_register(p, o2, 9, 24);
|
||||
}
|
||||
HASH_WALK_END;
|
||||
log(L_INFO "after hash walk");
|
||||
|
||||
mb_free(o2);
|
||||
|
||||
p->state = SNMP_REGISTR;
|
||||
@ -466,7 +513,7 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
static uint UNUSED
|
||||
parse_get_pdu(struct snmp_proto *p, byte *buf, uint size)
|
||||
{
|
||||
log(L_INFO "parse_get_pdu()");
|
||||
@ -548,23 +595,23 @@ parse_get_pdu(struct snmp_proto *p, byte *buf, uint size)
|
||||
log(L_INFO "res->payload %u (loaded) %u, trying to send: %u",
|
||||
rh->payload, LOAD(rh->payload, rh->flags & AGENTX_NETWORK_BYTE_ORDER),
|
||||
res_pkt - res + 4);
|
||||
|
||||
|
||||
int ret = sk_send(sk, res_pkt - res);
|
||||
log(L_INFO "message sent");
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sleep");
|
||||
log(L_INFO "sk_send sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "err no: %d", ret);
|
||||
log(L_INFO "sk_send err no: %d", ret);
|
||||
else
|
||||
log(L_INFO "OK !!");
|
||||
log(L_INFO "sk_send OK !!");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* req is request */
|
||||
static int
|
||||
static uint
|
||||
parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
{
|
||||
log(L_INFO "parse_gets_pdu");
|
||||
@ -605,22 +652,26 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
/* advertised size of oid is greater then size of message */
|
||||
if (oid_size(o_start) > size || oid_size(o_end) > size)
|
||||
{
|
||||
err = -1; /* parse error too big n_subid */
|
||||
log(L_INFO "too big o_start or o_end");
|
||||
err = -1; /* parse error too big n_subid (greater than message) */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (h->type)
|
||||
{
|
||||
case AGENTX_GET_PDU:
|
||||
log(L_INFO "type Get-PDU");
|
||||
res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord);
|
||||
break;
|
||||
|
||||
case AGENTX_GET_NEXT_PDU:
|
||||
o_start = bgp_search(o_start, o_end, NULL);
|
||||
log(L_INFO "type GetNext-PDU");
|
||||
o_start = bgp_search(p, o_start, o_end, NULL);
|
||||
if (o_start)
|
||||
res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord);
|
||||
else
|
||||
{
|
||||
log(L_INFO "null o_start GetNext-PDU");
|
||||
err = -2;
|
||||
continue;
|
||||
}
|
||||
@ -628,16 +679,18 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
|
||||
case AGENTX_GET_BULK_PDU:
|
||||
{
|
||||
log(L_INFO "type GetBulk-PDU");
|
||||
struct oid *o_curr = NULL;
|
||||
/* TODO add res packet size limiting logic */
|
||||
while ((o_curr = bgp_search(o_start, o_end, o_curr)) != NULL)
|
||||
while ((o_curr = bgp_search(p, o_start, o_end, o_curr)) != NULL)
|
||||
{
|
||||
res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord);
|
||||
res_pkt = find_n_fill(p, o_curr, res_pkt, rsize, 0, byte_ord);
|
||||
}
|
||||
|
||||
/* no item found */
|
||||
if (res_pkt == res + sizeof(struct agentx_response))
|
||||
{
|
||||
log(L_INFO "no item found ");
|
||||
err = -2;
|
||||
continue;
|
||||
}
|
||||
@ -665,32 +718,17 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
break;
|
||||
}
|
||||
|
||||
log(L_INFO " pasting size");
|
||||
struct agentx_header *rh = (void *) res;
|
||||
SNMP_UPDATE(rh, pkt_len(res, res_pkt));
|
||||
|
||||
int ret = sk_send(sk, res_pkt - res);
|
||||
log(L_INFO "message sent");
|
||||
log(L_INFO "%p %lu", p->sock->ttx, res_pkt - res);
|
||||
log(L_INFO "%p %p", res_pkt, res);
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "err no: %d", ret);
|
||||
else
|
||||
log("OK ! !!");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
header_update_len(byte *buf, u32 len)
|
||||
{
|
||||
struct agentx_header *h = (void *) buf;
|
||||
put_u32(&h->payload, len);
|
||||
log(L_INFO "header_update_len() %d 0x%02X 0x%02X 0x%02X 0x%02X", len, *((unsigned char
|
||||
*) &h->payload), *(((unsigned char *) &h->payload) + 1), *(((unsigned char *)
|
||||
&h->payload) + 2), *(((unsigned char *) &h->payload) + 3));
|
||||
for (int i = 0; i < res_pkt - res; i++)
|
||||
log(L_INFO "%p: %02X", res + i, *(res + i));
|
||||
|
||||
return res_pkt - res;
|
||||
}
|
||||
|
||||
void
|
||||
@ -702,7 +740,6 @@ snmp_start_subagent(struct snmp_proto *p)
|
||||
struct oid *o = mb_allocz(p->p.pool, sizeof(struct oid));
|
||||
open_pdu(p, o);
|
||||
mb_free(o);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
@ -719,6 +756,7 @@ snmp_stop_subagent(struct snmp_proto *p)
|
||||
}
|
||||
}
|
||||
|
||||
/* return number of bytes used by @o */
|
||||
static inline uint
|
||||
oid_size(struct oid *o)
|
||||
{
|
||||
@ -726,6 +764,7 @@ oid_size(struct oid *o)
|
||||
return 4 + (o->n_subid << 2);
|
||||
}
|
||||
|
||||
/* return number of bytes used by @vb */
|
||||
static inline uint
|
||||
vb_size(struct agentx_varbind *vb)
|
||||
{
|
||||
@ -735,27 +774,27 @@ vb_size(struct agentx_varbind *vb)
|
||||
|
||||
int
|
||||
snmp_rx(sock *sk, uint size)
|
||||
{
|
||||
{
|
||||
log(L_INFO "snmp_rx()");
|
||||
struct snmp_proto *p = sk->data;
|
||||
byte *pkt = sk->rbuf;
|
||||
|
||||
// 1 means all done; 0 means to be continued
|
||||
return parse_pkt(p, pkt, size);
|
||||
/*
|
||||
/*
|
||||
while (end >= pkt + AGENTX_HEADER_SIZE)
|
||||
{
|
||||
parse_header(p);
|
||||
parse_pkt(p, );
|
||||
}
|
||||
*/
|
||||
*/
|
||||
}
|
||||
|
||||
/* ping pdu */
|
||||
void
|
||||
snmp_ping(struct snmp_proto *p)
|
||||
{
|
||||
/* this does not support non-default context */
|
||||
/* this does not support non-default context */
|
||||
sock *sk = p->sock;
|
||||
byte *pkt = sk->tbuf;
|
||||
uint size = sk->tbsize;
|
||||
@ -771,12 +810,13 @@ snmp_ping(struct snmp_proto *p)
|
||||
|
||||
/* sending only header => pkt - buf */
|
||||
int ret = sk_send(sk, AGENTX_HEADER_SIZE);
|
||||
|
||||
if (ret == 0)
|
||||
log(L_INFO "sleep");
|
||||
log(L_INFO "sk_send sleep");
|
||||
else if (ret < 0)
|
||||
log(L_INFO "err %d", ret);
|
||||
log(L_INFO "sk_send err %d", ret);
|
||||
else
|
||||
log("ok ! !");
|
||||
log("sk_send ok ! !");
|
||||
}
|
||||
|
||||
else
|
||||
@ -812,48 +852,129 @@ snmp_agent_reconfigure(void)
|
||||
{
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
static int
|
||||
compare(struct oid *left, struct oid *right)
|
||||
{
|
||||
const u32 INTERNET_PREFIX[] = {1, 3, 6, 1};
|
||||
|
||||
if (left->prefix == 0 && right->prefix == 0)
|
||||
goto test_ids;
|
||||
|
||||
if (right->prefix == 0)
|
||||
{
|
||||
struct oid *temp = left;
|
||||
left = right;
|
||||
right = temp;
|
||||
}
|
||||
|
||||
if (left->prefix == 0)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
if (left->ids[i] < INTERNET_PREFIX[i])
|
||||
return -1;
|
||||
else if (left->ids[i] > INTERNET_PREFIX[i])
|
||||
return 1;
|
||||
|
||||
for (int i = 0; i < MIN(left->n_subid - 4, right->n_subid); i++)
|
||||
if (left->ids[i + 4] < right->ids[i])
|
||||
return -1;
|
||||
else if (left->ids[i + 4] > right->ids[i])
|
||||
return 1;
|
||||
|
||||
goto all_same;
|
||||
}
|
||||
|
||||
if (left->prefix < right->prefix)
|
||||
return -1;
|
||||
|
||||
else if (left->prefix > right->prefix)
|
||||
return 1;
|
||||
|
||||
test_ids:
|
||||
for (int i = 0; i < MIN(left->n_subid, right->n_subid); i++)
|
||||
{
|
||||
if (left->ids[i] < right->ids[i])
|
||||
return -1;
|
||||
else if (left->ids[i] > right->ids[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
all_same:
|
||||
/ * shorter sequence is before longer in lexicografical order * /
|
||||
if (left->n_subid < right->n_subid)
|
||||
return -1;
|
||||
else if (left->n_subid > right->n_subid)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
static inline int
|
||||
is_bgp4_mib_prefix(struct oid *o)
|
||||
{
|
||||
if (o->prefix == 2 && o->ids[0] == 15)
|
||||
return 1;
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct oid *
|
||||
bgp_search(struct oid *o_start, struct oid *e_end, struct oid *o_curr)
|
||||
static inline int
|
||||
has_inet_prefix(struct oid *o)
|
||||
{
|
||||
if (o_start->include);
|
||||
// if valid o_start
|
||||
return (o->n_subid > 4 && o->ids[0] == 1 &&
|
||||
o->ids[1] == 3 && o->ids[2] == 6 &&
|
||||
o->ids[3] == 1);
|
||||
}
|
||||
|
||||
// search o_start.0 (resp. o_start.1)
|
||||
return o_start;
|
||||
static inline struct ip4_addr
|
||||
ip4_from_oid(const struct oid *o)
|
||||
{
|
||||
return (o->n_subid == 9) ? ip4_build(o->ids[5], o->ids[6], o->ids[7],
|
||||
o->ids[8]) : IP4_NONE;
|
||||
}
|
||||
|
||||
/* tree is tree with "internet" prefix .1.3.6.1 */
|
||||
static struct oid *
|
||||
bgp_search(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr)
|
||||
{
|
||||
ip4_addr ip4 = ip4_from_oid(o_start);
|
||||
ip4_addr dest = ip4_from_oid(o_end);
|
||||
|
||||
net_addr *net = mb_allocz(p->p.pool, sizeof(struct net_addr));
|
||||
net_fill_ip4(net, ip4, IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
log(L_INFO "o_start n_sub %u prefix %u include %u",
|
||||
o_start->n_subid, o_start->prefix, o_start->include);
|
||||
for (int i = 0; i < o_start->n_subid; i++)
|
||||
log(L_INFO "n_subid %u: %u", i, o_start->ids[i]);
|
||||
log(L_INFO "preparing include /sive> return %d %d %d",
|
||||
!o_curr,(int) o_start->include, trie_match_net(p->bgp_trie, net));
|
||||
if (!o_curr && o_start->include && trie_match_net(p->bgp_trie, net))
|
||||
return o_start;
|
||||
|
||||
log(L_INFO "doesn't returned");
|
||||
|
||||
if (o_curr)
|
||||
net_fill_ip4(net, dest, IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
struct f_trie_walk_state *ws = mb_allocz(p->p.pool,
|
||||
sizeof(struct f_trie_walk_state));
|
||||
|
||||
struct oid *o = mb_allocz(p->p.pool, sizeof(struct oid) + 8 * sizeof(u32));
|
||||
o->n_subid = 9;
|
||||
trie_walk_init(ws, p->bgp_trie, NULL);
|
||||
if (trie_walk_next(ws, net) && ip4_less(net4_prefix(net), dest))
|
||||
{
|
||||
memcpy(o, o_start, oid_size(o_start));
|
||||
oid_ip4_index(o, net4_prefix(net));
|
||||
return o;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static byte *
|
||||
find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size, uint contid)
|
||||
find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size UNUSED, uint contid UNUSED)
|
||||
{
|
||||
struct bgp_conn *b_conn = bp->conn;
|
||||
struct bgp_conn *b_in = &bp->incoming_conn;
|
||||
@ -868,16 +989,16 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size, uint co
|
||||
b_state = b_conn->state;
|
||||
else if (MAX(b_in->state, b_out->state) == BS_CLOSE &&
|
||||
MIN(b_in->state, b_out->state) != BS_CLOSE)
|
||||
b_state = MIN(b_in->state, b_out->state);
|
||||
b_state = MIN(b_in->state, b_out->state);
|
||||
/* BS_CLOSE is unsupported by BGP4-MIB */
|
||||
else if (MIN(b_in->state, b_out->state) == BS_CLOSE)
|
||||
b_state = BS_IDLE;
|
||||
else
|
||||
b_state = MAX(b_in->state, b_out->state);
|
||||
|
||||
|
||||
struct agentx_varbind *vb = (void *) pkt;
|
||||
pkt += vb_size(vb);
|
||||
|
||||
|
||||
switch (o->ids[4])
|
||||
{
|
||||
case SNMP_BGP_IDENTIFIER:
|
||||
@ -888,12 +1009,12 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size, uint co
|
||||
}
|
||||
else
|
||||
{
|
||||
STORE_PTR(pkt, ipa_to_u32(IPA_NONE));
|
||||
put_blank(pkt); /* store 4B of zeroes */
|
||||
BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt);
|
||||
}
|
||||
break;
|
||||
|
||||
case SNMP_BGP_STATE:
|
||||
|
||||
case SNMP_BGP_STATE:
|
||||
STORE_PTR(pkt, b_state);
|
||||
BGP_DATA(vb, AGENTX_INTEGER, pkt);
|
||||
break;
|
||||
@ -1020,9 +1141,7 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size, uint co
|
||||
|
||||
case SNMP_BGP_FSM_ESTABLISHED_TIME:
|
||||
case SNMP_BGP_IN_UPDATE_ELAPSED_TIME:
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
/* pkt += 0; no data */
|
||||
break;
|
||||
return no_such_object(pkt, vb);
|
||||
|
||||
/* no default */
|
||||
}
|
||||
@ -1046,7 +1165,7 @@ snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint
|
||||
/* real size is 8 but we already shifted the pkt by 4 */
|
||||
BGP_DATA(vb, AGENTX_OCTET_STRING, pkt);
|
||||
break;
|
||||
|
||||
|
||||
case BGP4_MIB_LOCAL_AS:
|
||||
// XXX local as to use
|
||||
STORE_PTR(pkt, p->local_as);
|
||||
@ -1054,29 +1173,26 @@ snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint
|
||||
break;
|
||||
|
||||
case BGP4_PEER_TABLE:
|
||||
/* end part of .1.3.6.1.2.1.15.3.1.x.a.b.c.d */
|
||||
/* end part of .1.3.6.1.2.1.15.3.1.x.a.b.c.d */
|
||||
if (o->n_subid < 9 || o->ids[3] != BGP4_PEER_ENTRY
|
||||
|| o->ids[4] == 0 || o->ids[4] > 24)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return buf + vb_size(vb);
|
||||
}
|
||||
return no_such_object(pkt, vb);
|
||||
|
||||
// TODO enumerate range requests
|
||||
ip_addr addr = ipa_build4(o->ids[5], o->ids[6], o->ids[7], o->ids[8]);
|
||||
ip_addr addr = ipa_build4(o->ids[5], o->ids[6], o->ids[7], o->ids[8]);
|
||||
struct snmp_bgp_peer *pe =
|
||||
HASH_FIND(p->bgp_hash, SNMP_HASH, addr);
|
||||
|
||||
struct bgp_proto *bp = NULL;
|
||||
if (pe && pe->bond->proto->proto &&
|
||||
if (pe && ((struct proto_config *)pe->config)->proto &&
|
||||
ipa_equal(addr,
|
||||
((struct bgp_proto *) pe->bond->proto->proto)->remote_ip))
|
||||
(((struct bgp_proto *) ((struct proto_config *)pe->config)->proto)->remote_ip)))
|
||||
{
|
||||
bp = (void *) pe->bond->proto->proto;
|
||||
bp = (void *) ((struct proto_config *) pe->config)->proto;
|
||||
}
|
||||
|
||||
/* IF WE CONSIDER CHANGES OF REMOTE IP
|
||||
else
|
||||
else
|
||||
{
|
||||
struct snmp_bond *b;
|
||||
WALK_LIST(b, p->bgp_entries)
|
||||
@ -1087,37 +1203,41 @@ snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint
|
||||
*/
|
||||
|
||||
if (!bp)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
/* pkt += 0; no data */
|
||||
return pkt;
|
||||
}
|
||||
|
||||
return find_bgp_one(bp, o, buf, size, contid);
|
||||
return no_such_object(pkt, vb);
|
||||
|
||||
return find_bgp_one(bp, o, buf, size, contid);
|
||||
break;
|
||||
|
||||
default:
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
/* pkt += 0; no data */
|
||||
break;
|
||||
/* pkt += 0; no data */
|
||||
return no_such_object(pkt, vb);
|
||||
}
|
||||
|
||||
return pkt;
|
||||
}
|
||||
|
||||
/*
|
||||
static byte *
|
||||
find_ospf_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size)
|
||||
{
|
||||
// TODO XXX
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
static byte *
|
||||
unsupported_oid(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid)
|
||||
no_such_object(byte *buf, struct agentx_varbind *vb)
|
||||
{
|
||||
struct agentx_varbind *vb = (void *) buf;
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return buf + vb_size(vb);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static byte * UNUSED
|
||||
no_such_instance(byte *buf, struct agentx_varbind *vb)
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_INSTANCE;
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline byte *
|
||||
@ -1126,58 +1246,25 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint co
|
||||
struct agentx_varbind *vb = (void *) buf;
|
||||
|
||||
memcpy(&vb->name, o, oid_size(o));
|
||||
|
||||
|
||||
/* SNMPv2 mgmt mib-2 */
|
||||
if (o->n_subid < 2 || (o->prefix != 2 && o->ids[0] != 1))
|
||||
{
|
||||
vb->type = AGENTX_NO_SUCH_OBJECT;
|
||||
return buf + vb_size(vb);
|
||||
}
|
||||
|
||||
no_such_object(buf + vb_size(vb), vb);
|
||||
|
||||
switch (o->ids[1])
|
||||
{
|
||||
case SNMP_BGP4_MIB:
|
||||
if (snmp_bgp_is_supported(o))
|
||||
return snmp_bgp_record(p, o, buf, size, contid);
|
||||
else
|
||||
return unsupported_oid(p, o, buf, size, contid);
|
||||
return snmp_bgp_record(p, o, buf, size, contid);
|
||||
|
||||
case SNMP_OSPFv3_MIB:
|
||||
return unsupported_oid(p, o, buf, size, contid);
|
||||
return no_such_object(buf, vb);
|
||||
//return find_ospf_record(p, o, buf, size);
|
||||
|
||||
default:
|
||||
return unsupported_oid(p, o, buf, size, contid);
|
||||
log(L_INFO "unsupported oid");
|
||||
break;
|
||||
return no_such_object(buf, vb);
|
||||
}
|
||||
}
|
||||
|
||||
/* tests if there is present canonical "internet" prefix .1.3.6.1
|
||||
and if so it shortens the oid to the ``prefix'' form */
|
||||
static int
|
||||
prefixize_in_place(struct oid *o, int byte_ord)
|
||||
{
|
||||
const u32 prefix[] = {1, 3, 6, 1};
|
||||
|
||||
/* NETWORK_BYTE_ORDER */
|
||||
if (byte_ord)
|
||||
/* prefix len == 4 */
|
||||
for (uint i = 0; i < 4; i++)
|
||||
if (get_u32(&o->ids[i]) != prefix[i]) return 0;
|
||||
|
||||
else
|
||||
/* prefix len == 4 */
|
||||
for (uint i = 0; i < 4; i++)
|
||||
if (o->ids[i] != prefix[i]) return 0;
|
||||
|
||||
o->n_subid -= 5;
|
||||
o->prefix = o->ids[4];
|
||||
/* n_subid contains number of elements, not bytes */
|
||||
memmove(&o->ids, &o->ids[5], o->n_subid << 2);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct oid *
|
||||
prefixize(struct snmp_proto *p, struct oid *o, int byte_ord)
|
||||
{
|
||||
@ -1208,12 +1295,11 @@ find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint cont
|
||||
{
|
||||
struct oid *new;
|
||||
if (!o->prefix && (new = prefixize(p, o, byte_ord)) != NULL)
|
||||
find_prefixed(p, new, buf, size, contid);
|
||||
return find_prefixed(p, new, buf, size, contid);
|
||||
else if (o->prefix)
|
||||
find_prefixed(p, o, buf, size, contid);
|
||||
else
|
||||
// TODO handle unprefixable oids
|
||||
return NULL;
|
||||
return find_prefixed(p, o, buf, size, contid);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static byte *
|
||||
@ -1241,7 +1327,7 @@ prepare_response(struct snmp_proto *p, byte *buf, uint size)
|
||||
static void
|
||||
response_err_ind(byte *buf, uint err, uint ind)
|
||||
{
|
||||
log(L_INFO "reponse_err_ind()");
|
||||
log(L_INFO "reponse_err_ind() %u %u", err, ind);
|
||||
struct agentx_response *res = (void *) buf;
|
||||
|
||||
res->err = err;
|
||||
|
Loading…
Reference in New Issue
Block a user