From: Vojtech Vilimek Date: Sat, 17 Dec 2022 17:16:19 +0000 (+0100) Subject: tmp X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=23b467318c67220196912f529f864515edb60454;p=thirdparty%2Fbird.git tmp --- diff --git a/proto/snmp/bgp_mib.c b/proto/snmp/bgp_mib.c index 07026a059..4f2d5ef82 100644 --- a/proto/snmp/bgp_mib.c +++ b/proto/snmp/bgp_mib.c @@ -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 */ diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index e383f85d6..8525d572c 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -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 = { diff --git a/proto/snmp/snmp.h b/proto/snmp/snmp.h index 8f4eede89..acf1db20b 100644 --- a/proto/snmp/snmp.h +++ b/proto/snmp/snmp.h @@ -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 diff --git a/proto/snmp/snmp_utils.c b/proto/snmp/snmp_utils.c index 225efd4c5..9b044f05a 100644 --- a/proto/snmp/snmp_utils.c +++ b/proto/snmp/snmp_utils.c @@ -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"); } diff --git a/proto/snmp/snmp_utils.h b/proto/snmp/snmp_utils.h index f624fbd0f..3c38827d3 100644 --- a/proto/snmp/snmp_utils.h +++ b/proto/snmp/snmp_utils.h @@ -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 diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 44040a61f..c37e9e483 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -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 - diff --git a/proto/snmp/subagent.h b/proto/snmp/subagent.h index 27c878f74..431ce7598 100644 --- a/proto/snmp/subagent.h +++ b/proto/snmp/subagent.h @@ -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);