mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2025-03-11 17:08:46 +00:00
tmp
This commit is contained in:
parent
2a4fedb6e0
commit
23b467318c
@ -15,7 +15,7 @@
|
||||
#include "subagent.h"
|
||||
#include "bgp_mib.h"
|
||||
|
||||
static const char * const debug_bgp_states[] = {
|
||||
static const char * const debug_bgp_states[] UNUSED = {
|
||||
[BGP_INTERNAL_INVALID] = "BGP_INTERNAL_INVALID",
|
||||
[BGP_INTERNAL_BGP] = "BGP_INTERNAL_BGP",
|
||||
[BGP_INTERNAL_VERSION] = "BGP_INTERNAL_VERSION",
|
||||
@ -55,17 +55,17 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
{
|
||||
snmp_log("snmp_bgp_register()");
|
||||
|
||||
u32 arr_bgp[] = {1, 15, 1};
|
||||
u32 bgp_mib_prefix[] = {1, 15, 1};
|
||||
|
||||
{ /* registering whole BGP4-MIB subtree */
|
||||
snmp_log("snmp_proto %p (%p)", p, p->p.pool);
|
||||
//snmp_log("snmp_proto %p (%p)", p, p->p.pool);
|
||||
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
|
||||
|
||||
struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(2));
|
||||
put_u8(&oid->n_subid, 2);
|
||||
put_u8(&oid->prefix, 2);
|
||||
|
||||
memcpy(oid->ids, arr_bgp, 2 * sizeof(u32));
|
||||
memcpy(oid->ids, bgp_mib_prefix, 2 * sizeof(u32));
|
||||
|
||||
registering->oid = oid;
|
||||
add_tail(&p->register_queue, ®istering->n);
|
||||
@ -76,14 +76,14 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
|
||||
// TODO squash bgpVersion and bgpLocalAs to one PDU
|
||||
{ /* registering BGP4-MIB::bgpVersion */
|
||||
snmp_log("snmp_proto %p (%p)", p, p->p.pool);
|
||||
//snmp_log("snmp_proto %p (%p)", p, p->p.pool);
|
||||
struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
|
||||
|
||||
struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(3));
|
||||
put_u8(&oid->n_subid, 3);
|
||||
put_u8(&oid->prefix, 2);
|
||||
|
||||
memcpy(oid->ids, arr_bgp, 3 * sizeof(u32));
|
||||
memcpy(oid->ids, bgp_mib_prefix, 3 * sizeof(u32));
|
||||
|
||||
registering->oid = oid;
|
||||
add_tail(&p->register_queue, ®istering->n);
|
||||
@ -99,7 +99,7 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
put_u8(&oid->n_subid, 3);
|
||||
put_u8(&oid->prefix, 2);
|
||||
|
||||
memcpy(oid->ids, arr_bgp, 2 * sizeof(u32));
|
||||
memcpy(oid->ids, bgp_mib_prefix, 2 * sizeof(u32));
|
||||
STORE(oid->ids[2], 2);
|
||||
|
||||
registering->oid = oid;
|
||||
@ -116,7 +116,7 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
put_u8(&oid->n_subid, 3);
|
||||
put_u8(&oid->prefix, 2);
|
||||
|
||||
memcpy(oid->ids, arr_bgp, 2 * sizeof(u32));
|
||||
memcpy(oid->ids, bgp_mib_prefix, 2 * sizeof(u32));
|
||||
STORE(oid->ids[2], 3);
|
||||
|
||||
registering->oid = oid;
|
||||
@ -128,7 +128,7 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
|
||||
/* register dynamic BGP4-MIB::bgpPeerEntry.* */
|
||||
|
||||
u32 arr_with_prefix[] = { 1, 15, 3, 1, 1};
|
||||
u32 bgp_peer_entry[] = { 1, 15, 3, 1, 1};
|
||||
snmp_log("before hash walk - registering dynamic parts");
|
||||
HASH_WALK(p->bgp_hash, next, peer)
|
||||
{
|
||||
@ -139,7 +139,7 @@ snmp_bgp_register(struct snmp_proto *p)
|
||||
put_u8(&oid->n_subid, 9);
|
||||
put_u8(&oid->prefix, 2);
|
||||
|
||||
memcpy(oid->ids, arr_with_prefix, 5 * sizeof(u32));
|
||||
memcpy(oid->ids, bgp_peer_entry, 5 * sizeof(u32));
|
||||
|
||||
snmp_oid_ip4_index(oid, 5, ipa_to_ip4(peer->peer_ip));
|
||||
|
||||
@ -262,6 +262,7 @@ print_bgp_record_all(struct snmp_proto *p)
|
||||
print_bgp_record(peer->config);
|
||||
}
|
||||
HASH_WALK_END;
|
||||
snmp_log("dumping watched end");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -569,33 +570,53 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_en
|
||||
ip4_addr ip4 = ip4_from_oid(o_start);
|
||||
ip4_addr dest = ip4_from_oid(o_end);
|
||||
|
||||
snmp_log("ip addresses build");
|
||||
snmp_log("ip addresses build (ip4) %I (dest) %I", ip4, dest);
|
||||
|
||||
// why am I allocated dynamically ?!
|
||||
net_addr *net = mb_allocz(p->p.pool, sizeof(struct net_addr));
|
||||
net_fill_ip4(net, ip4, IP4_MAX_PREFIX_LENGTH);
|
||||
|
||||
snmp_log("dynamic part of BGP mib");
|
||||
|
||||
// why am I allocated dynamically ?!
|
||||
struct f_trie_walk_state *ws = mb_allocz(p->p.pool,
|
||||
sizeof(struct f_trie_walk_state));
|
||||
|
||||
trie_walk_init(ws, p->bgp_trie, NULL);
|
||||
|
||||
if (trie_walk_next(ws, net) && ip4_less(net4_prefix(net), dest))
|
||||
snmp_log("walk init");
|
||||
|
||||
if (trie_walk_next(ws, net)) // && ip4_less(net4_prefix(net), dest))
|
||||
{
|
||||
struct oid *o = mb_allocz(p->p.pool, snmp_oid_sizeof(9));
|
||||
o->n_subid = 9;
|
||||
snmp_log("trie_walk_next() returned true");
|
||||
if (ip4_less(net4_prefix(net), dest)) // <- delete me
|
||||
{
|
||||
snmp_log("ip4_less() returned treu");
|
||||
struct oid *o = mb_allocz(p->p.pool, snmp_oid_sizeof(9));
|
||||
o->n_subid = 9;
|
||||
|
||||
memcpy(o, o_start, snmp_oid_size(o_start));
|
||||
snmp_oid_ip4_index(o, 5, net4_prefix(net));
|
||||
memcpy(o, o_start, snmp_oid_size(o_start));
|
||||
snmp_oid_ip4_index(o, 5, net4_prefix(net));
|
||||
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
|
||||
return o;
|
||||
return o;
|
||||
}
|
||||
|
||||
// delete me
|
||||
else
|
||||
{
|
||||
snmp_log("ip4_less() returned false");
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
}
|
||||
// delete me end
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
snmp_log("trie_walk_next() returned false, cleaning");
|
||||
mb_free(net);
|
||||
mb_free(ws);
|
||||
}
|
||||
@ -607,6 +628,8 @@ static struct oid *
|
||||
search_bgp_dynamic(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uint contid
|
||||
UNUSED, u8 next_state)
|
||||
{
|
||||
snmp_log("search_bgp_dynamic() dynamic part Yaaay!");
|
||||
|
||||
/* TODO can be remove after implementing all BGP4-MIB::bgpPeerTable columns */
|
||||
struct oid *copy = o_start;
|
||||
do {
|
||||
@ -630,13 +653,13 @@ search_bgp_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uin
|
||||
//u8 state_end = (o_end) ? snmp_bgp_state(o_end) : 0;
|
||||
|
||||
|
||||
|
||||
// print debugging information
|
||||
print_bgp_record_all(p);
|
||||
|
||||
if (o_start->include && snmp_bgp_has_value(start_state) &&
|
||||
!is_dynamic(start_state) && o_start->n_subid == 3)
|
||||
{
|
||||
snmp_log("search_bgp_mib() first search element (due to include field) returned");
|
||||
o_start->include = 0; /* disable including for next time */
|
||||
return o_start;
|
||||
}
|
||||
@ -644,9 +667,13 @@ search_bgp_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, uin
|
||||
/* if state is_dynamic() then has more value and need find the right one */
|
||||
else if (!is_dynamic(start_state))
|
||||
{
|
||||
snmp_log("seach_bgp_mib() static part");
|
||||
u8 next_state = snmp_bgp_next_state(start_state);
|
||||
o_start = update_bgp_oid(o_start, next_state);
|
||||
|
||||
snmp_log("search_bgp_mib() is NOT next_state dynamic %s",
|
||||
!is_dynamic(next_state) ? "true" : "false");
|
||||
|
||||
if (!is_dynamic(next_state))
|
||||
return o_start;
|
||||
|
||||
@ -689,6 +716,7 @@ UNUSED, uint contid UNUSED, int byte_ord UNUSED, u8 state)
|
||||
ipa_equal(addr, ((struct bgp_proto *) proto)->remote_ip))
|
||||
{
|
||||
bgp_proto = (struct bgp_proto *) proto;
|
||||
snmp_log("bgp_dynamic_fill() using bgp_proto %p", bgp_proto);
|
||||
}
|
||||
|
||||
/* binded bgp protocol not found */
|
||||
|
@ -25,11 +25,14 @@ static void snmp_start_locked(struct object_lock *lock);
|
||||
|
||||
|
||||
static const char * const snmp_state[] = {
|
||||
[SNMP_ERR] = "SNMP ERROR",
|
||||
[SNMP_DELAY] = "SNMP DELAY",
|
||||
[SNMP_INIT] = "SNMP INIT",
|
||||
[SNMP_REGISTR] = "SNMP REGISTERING",
|
||||
[SNMP_CONN] = "SNMP CONNECTED",
|
||||
[SNMP_ERR] = "SNMP ERROR",
|
||||
[SNMP_DELAY] = "SNMP DELAY",
|
||||
[SNMP_INIT] = "SNMP INIT",
|
||||
[SNMP_REGISTER] = "SNMP REGISTERING",
|
||||
[SNMP_CONN] = "SNMP CONNECTED",
|
||||
[SNMP_STOP] = "SNMP STOP",
|
||||
[SNMP_DOWN] = "SNMP DOWN",
|
||||
[SNMP_LISTEN] = "SNMP LISTEN",
|
||||
};
|
||||
|
||||
static struct proto *
|
||||
@ -57,14 +60,26 @@ snmp_init(struct proto_config *CF)
|
||||
return P;
|
||||
}
|
||||
|
||||
static void snmp_down(struct snmp_proto *p)
|
||||
static inline void
|
||||
snmp_cleanup(struct snmp_proto *p)
|
||||
{
|
||||
rfree(p->startup_timer);
|
||||
rfree(p->ping_timer);
|
||||
|
||||
if (p->sock != NULL)
|
||||
mb_free(p->sock);
|
||||
rfree(p->sock);
|
||||
|
||||
if (p->lock != NULL)
|
||||
rfree(p->lock);
|
||||
|
||||
p->state = SNMP_DOWN;
|
||||
}
|
||||
|
||||
void
|
||||
snmp_down(struct snmp_proto *p)
|
||||
{
|
||||
snmp_cleanup(p);
|
||||
|
||||
proto_notify_state(&p->p, PS_DOWN);
|
||||
}
|
||||
|
||||
@ -75,13 +90,23 @@ snmp_startup_timeout(timer *t)
|
||||
snmp_startup(t->data);
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_stop_timeout(timer *t)
|
||||
{
|
||||
snmp_log("stop timer triggered");
|
||||
|
||||
struct snmp_proto *p = t->data;
|
||||
|
||||
snmp_down(p);
|
||||
}
|
||||
|
||||
static void
|
||||
snmp_startup(struct snmp_proto *p)
|
||||
{
|
||||
//snmp_log("changing proto_snmp state to INIT");
|
||||
|
||||
if (p->state == SNMP_CONN ||
|
||||
p->state == SNMP_REGISTR)
|
||||
p->state == SNMP_REGISTER)
|
||||
{
|
||||
snmp_log("startup() with invalid state %u", p->state);
|
||||
return;
|
||||
@ -118,7 +143,7 @@ snmp_startup(struct snmp_proto *p)
|
||||
static void
|
||||
snmp_start_locked(struct object_lock *lock)
|
||||
{
|
||||
snmp_log("snmp_start_locked() - lock acquired; preparing socket ");
|
||||
snmp_log("snmp_start_locked() - lock acquired; preparing socket");
|
||||
struct snmp_proto *p = lock->data;
|
||||
|
||||
sock *s = sk_new(p->p.pool);
|
||||
@ -189,6 +214,7 @@ snmp_sock_err(sock *sk, int err)
|
||||
|
||||
snmp_log("changing proto_snmp state to ERR[OR]");
|
||||
p->state = SNMP_ERR;
|
||||
|
||||
// TODO ping interval
|
||||
tm_start(p->startup_timer, 15 S);
|
||||
}
|
||||
@ -381,13 +407,31 @@ snmp_shutdown(struct proto *P)
|
||||
{
|
||||
snmp_log("snmp_shutdown()");
|
||||
struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
|
||||
p->state = SNMP_INIT;
|
||||
|
||||
tm_stop(p->ping_timer);
|
||||
tm_stop(p->startup_timer);
|
||||
|
||||
snmp_stop_subagent(p);
|
||||
return PS_DOWN;
|
||||
/* connection established => close the connection */
|
||||
if (p->state == SNMP_CONN)
|
||||
{
|
||||
p->state = SNMP_STOP;
|
||||
|
||||
/* startup time is reused for connection closing */
|
||||
p->startup_timer->hook = snmp_stop_timeout;
|
||||
|
||||
// TODO timeout duration ??
|
||||
tm_set(p->startup_timer, 15 S);
|
||||
|
||||
snmp_stop_subagent(p);
|
||||
|
||||
return PS_STOP;
|
||||
}
|
||||
|
||||
/* no connection to close */
|
||||
else
|
||||
{
|
||||
snmp_cleanup(p);
|
||||
return PS_DOWN;
|
||||
}
|
||||
}
|
||||
|
||||
struct protocol proto_snmp = {
|
||||
|
@ -29,11 +29,16 @@
|
||||
#define SNMP_RX_BUFFER_SIZE 2048
|
||||
#define SNMP_TX_BUFFER_SIZE 2048
|
||||
|
||||
#define SNMP_ERR 0
|
||||
#define SNMP_DELAY 1
|
||||
#define SNMP_INIT 2
|
||||
#define SNMP_REGISTR 3
|
||||
#define SNMP_CONN 4
|
||||
enum snmp_proto_state {
|
||||
SNMP_ERR = 0,
|
||||
SNMP_DELAY,
|
||||
SNMP_INIT,
|
||||
SNMP_REGISTER,
|
||||
SNMP_CONN,
|
||||
SNMP_STOP,
|
||||
SNMP_DOWN,
|
||||
SNMP_LISTEN,
|
||||
};
|
||||
|
||||
/* hash table macros */
|
||||
#define SNMP_HASH_KEY(n) n->peer_ip
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include "snmp_utils.h"
|
||||
|
||||
/**
|
||||
* snmp_is_oid_empty - check if oid is null-valued
|
||||
* snmp_is_oid_empty - check if oid is null-valued
|
||||
* @oid: object identifier to check
|
||||
*
|
||||
* Test if the oid header is full of zeroes. For @oid NULL returns 0.
|
||||
@ -347,6 +347,8 @@ snmp_register_same(struct snmp_register *r, struct agentx_header *h, u8 class)
|
||||
void
|
||||
snmp_register_ack(struct snmp_proto *p, struct agentx_header *h)
|
||||
{
|
||||
snmp_log("snmp_register_ack()");
|
||||
|
||||
struct snmp_register *reg;
|
||||
WALK_LIST(reg, p->register_queue)
|
||||
{
|
||||
@ -361,11 +363,24 @@ snmp_register_ack(struct snmp_proto *p, struct agentx_header *h)
|
||||
ro->oid = reg->oid;
|
||||
|
||||
rem_node(®->n);
|
||||
mb_free(reg);
|
||||
p->register_to_ack--;
|
||||
|
||||
add_tail(&p->bgp_registered, &ro->n);
|
||||
|
||||
snmp_log(" register note find %u", list_length(&p->bgp_registered));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
snmp_log("unknown registration");
|
||||
}
|
||||
|
||||
void
|
||||
snmp_dump_packet(byte *pkt, uint size)
|
||||
{
|
||||
snmp_log("dump");
|
||||
for (int i = 0; i < size; i += 4)
|
||||
snmp_log("pkt [%d] 0x%02x%02x%02x%02x", i, pkt[i],pkt[i+1],pkt[i+2],pkt[i+3]);
|
||||
snmp_log("end dump");
|
||||
}
|
||||
|
@ -39,4 +39,6 @@ struct oid *snmp_prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
|
||||
struct snmp_register *snmp_register_create(struct snmp_proto *p, u8 mib_class);
|
||||
|
||||
void snmp_register_ack(struct snmp_proto *p, struct agentx_header *h);
|
||||
|
||||
void snmp_dump_packet(byte *pkt, uint size);
|
||||
#endif
|
||||
|
@ -28,31 +28,31 @@ static byte *snmp_mib_fill(struct snmp_proto *p, struct oid *oid, u8 mib_class,
|
||||
byte *buf, uint size, struct snmp_error *error, uint contid, int byte_ord);
|
||||
|
||||
static int parse_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static int snmp_stop_ack(sock *sk, uint size);
|
||||
static void do_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
static uint parse_get_pdu(struct snmp_proto *p, byte *buf, uint size);
|
||||
// static int snmp_stop_ack(sock *sk, uint size);
|
||||
static int do_response(struct snmp_proto *p, byte *buf, uint size);
|
||||
// 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 *search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, u8 mib_class, uint contid);
|
||||
static inline byte *find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, 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 const char * const snmp_errs[] = {
|
||||
#define SNMP_ERR_SHIFT 256
|
||||
[AGENTX_RES_OPEN_FAILED - SNMP_ERR_SHIFT] = "Open failed",
|
||||
[AGENTX_RES_NOT_OPEN - SNMP_ERR_SHIFT] = "Not open",
|
||||
[AGENTX_RES_INDEX_WRONG_TYPE - SNMP_ERR_SHIFT] = "Index wrong type",
|
||||
[AGENTX_RES_OPEN_FAILED - SNMP_ERR_SHIFT] = "Open failed",
|
||||
[AGENTX_RES_NOT_OPEN - SNMP_ERR_SHIFT] = "Not open",
|
||||
[AGENTX_RES_INDEX_WRONG_TYPE - SNMP_ERR_SHIFT] = "Index wrong type",
|
||||
[AGENTX_RES_INDEX_ALREADY_ALLOC - SNMP_ERR_SHIFT] = "Index already allocated",
|
||||
[AGENTX_RES_INDEX_NONE_AVAIL - SNMP_ERR_SHIFT] = "Index none availlable",
|
||||
[AGENTX_RES_NOT_ALLOCATED - SNMP_ERR_SHIFT] = "Not allocated",
|
||||
[AGENTX_RES_INDEX_NONE_AVAIL - SNMP_ERR_SHIFT] = "Index none availlable",
|
||||
[AGENTX_RES_NOT_ALLOCATED - SNMP_ERR_SHIFT] = "Not allocated",
|
||||
[AGENTX_RES_UNSUPPORTED_CONTEXT - SNMP_ERR_SHIFT] = "Unsupported contex",
|
||||
[AGENTX_RES_DUPLICATE_REGISTR - SNMP_ERR_SHIFT] = "Duplicate registration",
|
||||
[AGENTX_RES_UNKNOWN_REGISTR - SNMP_ERR_SHIFT] = "Unknown registration",
|
||||
[AGENTX_RES_UNKNOWN_AGENT_CAPS - SNMP_ERR_SHIFT] = "Unknown agent caps",
|
||||
[AGENTX_RES_PARSE_ERROR - SNMP_ERR_SHIFT] = "Parse error",
|
||||
[AGENTX_RES_REQUEST_DENIED - SNMP_ERR_SHIFT] = "Request denied",
|
||||
[AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error",
|
||||
[AGENTX_RES_DUPLICATE_REGISTER - SNMP_ERR_SHIFT] = "Duplicate registration",
|
||||
[AGENTX_RES_UNKNOWN_REGISTER - SNMP_ERR_SHIFT] = "Unknown registration",
|
||||
[AGENTX_RES_UNKNOWN_AGENT_CAPS - SNMP_ERR_SHIFT] = "Unknown agent caps",
|
||||
[AGENTX_RES_PARSE_ERROR - SNMP_ERR_SHIFT] = "Parse error",
|
||||
[AGENTX_RES_REQUEST_DENIED - SNMP_ERR_SHIFT] = "Request denied",
|
||||
[AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error",
|
||||
};
|
||||
|
||||
static const char * const snmp_pkt_type[] = {
|
||||
@ -114,7 +114,7 @@ open_pdu(struct snmp_proto *p, struct oid *oid)
|
||||
else if (ret < 0)
|
||||
snmp_log("sk_send err %d", ret);
|
||||
else
|
||||
snmp_log("sk_send ok !!! ");
|
||||
snmp_log("sk_send ok !!!");
|
||||
}
|
||||
|
||||
else
|
||||
@ -318,12 +318,20 @@ parse_pkt(struct snmp_proto *p, byte *buf, uint size)
|
||||
log("sk_send OK ! !!");
|
||||
}
|
||||
|
||||
return len;
|
||||
/* whole buffer was parsed while generating response */
|
||||
if (len == size)
|
||||
return 1; /* meaning buffer is empty */
|
||||
else
|
||||
return 0; /* meaning buffer stil contain some data to be parsed, parsing is not finished */
|
||||
}
|
||||
|
||||
static int
|
||||
parse_response(struct snmp_proto *p, byte *buf, uint size)
|
||||
{
|
||||
snmp_log("parse_response() g%u h%u", size, sizeof(struct agentx_header));
|
||||
|
||||
snmp_dump_packet(buf, size);
|
||||
|
||||
if (size < sizeof(struct agentx_response))
|
||||
return 0;
|
||||
|
||||
@ -332,15 +340,16 @@ parse_response(struct snmp_proto *p, byte *buf, uint size)
|
||||
|
||||
snmp_log(" endianity: %s, session %u, transaction: %u", (h->flags & AGENTX_NETWORK_BYTE_ORDER) ? "big end":
|
||||
"little end", h->session_id, h->transaction_id);
|
||||
snmp_log(" sid: %3u\ttid: %3u\tpid: %3u\t", p->session_id, p->transaction_id,
|
||||
snmp_log(" sid: %3u\ttid: %3u\tpid: %3u", p->session_id, p->transaction_id,
|
||||
p->packet_id);
|
||||
|
||||
snmp_log(" pkt size %u", h->payload);
|
||||
// snmp_log("uptime: %u s", r->uptime);
|
||||
|
||||
if (r->err == AGENTX_RES_NO_ERROR)
|
||||
do_response(p, buf, size);
|
||||
return do_response(p, buf, size);
|
||||
else
|
||||
// TODO handle corrupted packets properly (and return appropriate retval)
|
||||
snmp_log("an error occured '%s'", snmp_errs[get_u16(&r->err) -
|
||||
SNMP_ERR_SHIFT]);
|
||||
|
||||
@ -350,6 +359,7 @@ SNMP_ERR_SHIFT]);
|
||||
static inline int
|
||||
snmp_registered_all(struct snmp_proto *p)
|
||||
{
|
||||
snmp_log("snmp_registered_all() %u", list_length(&p->register_queue));
|
||||
return p->register_to_ack == 0;
|
||||
}
|
||||
|
||||
@ -362,21 +372,21 @@ snmp_register_mibs(struct snmp_proto *p) {
|
||||
snmp_log("registering all done");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
static int
|
||||
do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
||||
{
|
||||
snmp_log("do_response()");
|
||||
struct agentx_response *r = (void *) buf;
|
||||
struct agentx_header *h = &r->h;
|
||||
|
||||
int network_byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER;
|
||||
|
||||
/* TODO make it asynchronous for better speed */
|
||||
switch (p->state)
|
||||
{
|
||||
case SNMP_INIT:
|
||||
/* parse open_pdu response */
|
||||
if (h->flags & AGENTX_NETWORK_BYTE_ORDER)
|
||||
if (network_byte_ord)
|
||||
{
|
||||
p->session_id = get_u32(&h->session_id);
|
||||
p->transaction_id = get_u32(&h->transaction_id);
|
||||
@ -387,14 +397,19 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
||||
memcpy(&p->session_id, &h->session_id, 12);
|
||||
}
|
||||
|
||||
snmp_register_mibs(p);
|
||||
/* the state needs to be changed before sending registering PDUs to
|
||||
* use correct do_response action on them
|
||||
*/
|
||||
snmp_log("changing state to REGISTER");
|
||||
p->state = SNMP_REGISTR;
|
||||
p->state = SNMP_REGISTER;
|
||||
snmp_register_mibs(p);
|
||||
snmp_log("do_response state SNMP_INIT register list %u", list_length(&p->register_queue));
|
||||
|
||||
break;
|
||||
|
||||
case SNMP_REGISTR:
|
||||
snmp_register_ack(p, h);
|
||||
case SNMP_REGISTER:
|
||||
snmp_log("do_response state SNMP_REGISTER register list %u", list_length(&p->register_queue));
|
||||
snmp_register_ack(p ,h);
|
||||
|
||||
if (snmp_registered_all(p)) {
|
||||
snmp_log("changing proto_snmp state to CONNECTED");
|
||||
@ -406,11 +421,28 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
|
||||
// proto_notify_state(&p->p, PS_UP);
|
||||
break;
|
||||
|
||||
case SNMP_STOP:
|
||||
/* do nothing here */
|
||||
break;
|
||||
|
||||
default:
|
||||
die("unkonwn SNMP state");
|
||||
}
|
||||
|
||||
uint pkt_size = LOAD(h->payload, network_byte_ord) + sizeof(struct agentx_header);
|
||||
snmp_log("do_response size %u pkt_size %u", size, pkt_size);
|
||||
if (size > pkt_size)
|
||||
{
|
||||
memmove(buf, buf + pkt_size, size - pkt_size);
|
||||
snmp_dump_packet(buf, size - pkt_size);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
/* all parsed */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static uint UNUSED
|
||||
parse_get_pdu(struct snmp_proto *p, byte *buf, uint size)
|
||||
{
|
||||
@ -506,6 +538,7 @@ parse_get_pdu(struct snmp_proto *p, byte *buf, uint size)
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static u8
|
||||
get_mib_class(struct oid *oid)
|
||||
@ -620,7 +653,7 @@ snmp_get_bulk(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, byte
|
||||
pkt += snmp_varbind_size(vb);
|
||||
vb->type = AGENTX_END_OF_MIB_VIEW;
|
||||
}
|
||||
|
||||
|
||||
return pkt;
|
||||
#endif
|
||||
}
|
||||
@ -722,7 +755,7 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
|
||||
break;
|
||||
|
||||
case AGENTX_GET_BULK_PDU:
|
||||
case AGENTX_GET_BULK_PDU:
|
||||
res_pkt = snmp_get_bulk(p, o_start, o_end, res_pkt, rsize, &bulk_state, 0, byte_ord);
|
||||
break;
|
||||
|
||||
@ -750,7 +783,7 @@ parse_gets_pdu(struct snmp_proto *p, byte *req, uint size)
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
mb_free(o_start);
|
||||
@ -803,14 +836,10 @@ void
|
||||
snmp_stop_subagent(struct snmp_proto *p)
|
||||
{
|
||||
snmp_log("snmp_stop_subagent() state %s", p->state);
|
||||
sock *sk = p->sock;
|
||||
// sock *sk = p->sock;
|
||||
|
||||
if (p->state == SNMP_CONN)
|
||||
{
|
||||
if (p->state == SNMP_STOP)
|
||||
close_pdu(p, AGENTX_CLOSE_SHUTDOWN);
|
||||
|
||||
sk->rx_hook = snmp_stop_ack;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -873,7 +902,7 @@ snmp_ping(struct snmp_proto *p)
|
||||
snmp_log("ping_pdu() insufficient size");
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static int
|
||||
snmp_stop_ack(sock *sk, uint size)
|
||||
{
|
||||
@ -883,9 +912,10 @@ snmp_stop_ack(sock *sk, uint size)
|
||||
if (size < AGENTX_HEADER_SIZE)
|
||||
return 0;
|
||||
|
||||
// TODO FIXME parse_response could return 0 even if waiting packet was parsed
|
||||
if (parse_response(p, buf, size))
|
||||
{
|
||||
p->p.disabled = 1;
|
||||
// p->p.disabled = 1;
|
||||
proto_notify_state(&p->p, PS_DOWN);
|
||||
|
||||
//sk->tx_hook = NULL;
|
||||
@ -895,6 +925,7 @@ snmp_stop_ack(sock *sk, uint size)
|
||||
/* all done */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
void
|
||||
@ -976,12 +1007,31 @@ has_inet_prefix(struct oid *o)
|
||||
o->ids[3] == 1);
|
||||
}
|
||||
|
||||
/* tree is tree with "internet" prefix .1.3.6.1
|
||||
working only with o_start, o_end allocated in heap (not from buffer)*/
|
||||
static struct oid *
|
||||
search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, u8 mib_class, uint contid UNUSED)
|
||||
/**
|
||||
* upper_bound_check - check if oid is before SearchRange end
|
||||
*
|
||||
* @found: best oid found in MIB tree
|
||||
* @bound: upper bound specified in SearchRange
|
||||
*
|
||||
* check if found oid meet the SearchRange upper bound condition in
|
||||
* lexicographical order, returns boolean value
|
||||
*/
|
||||
static int
|
||||
upper_bound_check(struct oid *found, struct oid *bound)
|
||||
{
|
||||
snmp_log("search_mib()");
|
||||
if (snmp_is_oid_empty(bound))
|
||||
return 1;
|
||||
|
||||
if (snmp_oid_compare(found, bound) < 0)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct oid *
|
||||
search_mib_unchecked(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, u8 mib_class UNUSED, uint contid UNUSED)
|
||||
{
|
||||
snmp_log("search_mib_unchecked()");
|
||||
|
||||
if (!o_start)
|
||||
return NULL;
|
||||
@ -1004,7 +1054,7 @@ search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct
|
||||
if (o_curr != NULL)
|
||||
return o_curr;
|
||||
|
||||
|
||||
|
||||
/* fall through */
|
||||
|
||||
/*
|
||||
@ -1015,7 +1065,7 @@ search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct
|
||||
return o_curr;
|
||||
// fall through
|
||||
*/
|
||||
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
@ -1024,6 +1074,23 @@ search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* tree is tree with "internet" prefix .1.3.6.1
|
||||
working only with o_start, o_end allocated in heap (not from buffer)*/
|
||||
static struct oid *
|
||||
search_mib(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, struct oid *o_curr, u8 mib_class, uint contid UNUSED)
|
||||
{
|
||||
struct oid *found = search_mib_unchecked(p, o_start, o_end, o_curr, mib_class, contid);
|
||||
|
||||
if (upper_bound_check(found, o_end))
|
||||
return found;
|
||||
else {
|
||||
mb_free(found);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// XXX moved to bgp_mib.c
|
||||
#if 0
|
||||
static byte *
|
||||
find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size UNUSED, uint contid UNUSED)
|
||||
{
|
||||
@ -1199,7 +1266,9 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size UNUSED, u
|
||||
|
||||
return pkt;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* contid - context identification number */
|
||||
static byte *
|
||||
snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid)
|
||||
@ -1269,6 +1338,7 @@ snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint
|
||||
|
||||
return pkt;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
static byte *
|
||||
@ -1279,6 +1349,7 @@ find_ospf_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size)
|
||||
}
|
||||
*/
|
||||
|
||||
#if 0
|
||||
static inline byte *
|
||||
find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid)
|
||||
{
|
||||
@ -1311,6 +1382,7 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint co
|
||||
//return snmp_no_such_object(buf, vb);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* snmp_prefixize - return prefixed oid copy if possible
|
||||
@ -1367,6 +1439,7 @@ snmp_prefixize(struct snmp_proto *proto, struct oid *oid, int byte_ord)
|
||||
return new;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline byte *
|
||||
find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord)
|
||||
{
|
||||
@ -1378,6 +1451,7 @@ find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint cont
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* snmp_mib_fill -
|
||||
|
@ -264,8 +264,8 @@ enum agentx_response_err {
|
||||
AGENTX_RES_INDEX_NONE_AVAIL = 260,
|
||||
AGENTX_RES_NOT_ALLOCATED = 261,
|
||||
AGENTX_RES_UNSUPPORTED_CONTEXT = 262,
|
||||
AGENTX_RES_DUPLICATE_REGISTR = 263,
|
||||
AGENTX_RES_UNKNOWN_REGISTR = 264,
|
||||
AGENTX_RES_DUPLICATE_REGISTER = 263,
|
||||
AGENTX_RES_UNKNOWN_REGISTER = 264,
|
||||
AGENTX_RES_UNKNOWN_AGENT_CAPS = 265,
|
||||
AGENTX_RES_PARSE_ERROR = 266,
|
||||
AGENTX_RES_REQUEST_DENIED = 267,
|
||||
@ -273,6 +273,8 @@ enum agentx_response_err {
|
||||
} PACKED;
|
||||
|
||||
int snmp_rx(sock *sk, uint size);
|
||||
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);
|
||||
void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user