From: Vojtech Vilimek Date: Tue, 9 Jul 2024 14:56:16 +0000 (+0200) Subject: SNMP: tmp X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b7989aa453923c3a439bd28385dde2ecda8bc48;p=thirdparty%2Fbird.git SNMP: tmp --- diff --git a/proto/snmp/bgp4_mib.c b/proto/snmp/bgp4_mib.c index 5cd896c2b..9cf4c230c 100644 --- a/proto/snmp/bgp4_mib.c +++ b/proto/snmp/bgp4_mib.c @@ -59,148 +59,6 @@ snmp_bgp_last_error(const struct bgp_proto *bgp, char err[2]) err[1] = bgp->last_error_code & 0x000000FF; } -static u8 -bgp_get_candidate(u32 field) -{ - const u8 translation_table[] = { - [BGP4_MIB_PEER_IDENTIFIER] = BGP4_MIB_S_PEER_IDENTIFIER, - [BGP4_MIB_STATE] = BGP4_MIB_S_STATE, - [BGP4_MIB_ADMIN_STATUS] = BGP4_MIB_S_ADMIN_STATUS, - [BGP4_MIB_NEGOTIATED_VERSION] = BGP4_MIB_S_NEGOTIATED_VERSION, - [BGP4_MIB_LOCAL_ADDR] = BGP4_MIB_S_LOCAL_ADDR, - [BGP4_MIB_LOCAL_PORT] = BGP4_MIB_S_LOCAL_PORT, - [BGP4_MIB_REMOTE_ADDR] = BGP4_MIB_S_REMOTE_ADDR, - [BGP4_MIB_REMOTE_PORT] = BGP4_MIB_S_REMOTE_PORT, - [BGP4_MIB_REMOTE_AS] = BGP4_MIB_S_REMOTE_AS, - [BGP4_MIB_RX_UPDATES] = BGP4_MIB_S_RX_UPDATES, - [BGP4_MIB_TX_UPDATES] = BGP4_MIB_S_TX_UPDATES, - [BGP4_MIB_RX_MESSAGES] = BGP4_MIB_S_RX_MESSAGES, - [BGP4_MIB_TX_MESSAGES] = BGP4_MIB_S_TX_MESSAGES, - [BGP4_MIB_LAST_ERROR] = BGP4_MIB_S_LAST_ERROR, - [BGP4_MIB_FSM_TRANSITIONS] = BGP4_MIB_S_FSM_TRANSITIONS, - [BGP4_MIB_FSM_ESTABLISHED_TIME] = BGP4_MIB_S_FSM_ESTABLISHED_TIME, - [BGP4_MIB_RETRY_INTERVAL] = BGP4_MIB_S_RETRY_INTERVAL, - [BGP4_MIB_HOLD_TIME] = BGP4_MIB_S_HOLD_TIME, - [BGP4_MIB_KEEPALIVE] = BGP4_MIB_S_KEEPALIVE, - [BGP4_MIB_HOLD_TIME_CONFIGURED] = BGP4_MIB_S_HOLD_TIME_CONFIGURED, - [BGP4_MIB_KEEPALIVE_CONFIGURED] = BGP4_MIB_S_KEEPALIVE_CONFIGURED, - [BGP4_MIB_ORIGINATION_INTERVAL] = BGP4_MIB_S_ORIGINATION_INTERVAL, - [BGP4_MIB_MIN_ROUTE_ADVERTISEMENT] = BGP4_MIB_S_MIN_ROUTE_ADVERTISEMENT, - [BGP4_MIB_IN_UPDATE_ELAPSED_TIME] = BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME, - }; - - /* - * First value is in secord cell of array translation_table, as the - * SNMP_BGP_IDENTIFIER == 1 - */ - if (field > 0 && field <= ARRAY_SIZE(translation_table)- 1) - return translation_table[field]; - else if (field == 0) - return BGP4_MIB_S_PEER_ENTRY; - else - return BGP4_MIB_S_PEER_TABLE_END; -} - -/** - * snmp_bgp_state - linearize oid from BGP4-MIB - * @oid: prefixed object identifier from BGP4-MIB::bgp subtree - * - * Returns linearized state for Get-PDU, GetNext-PDU and GetBulk-PDU packets. - */ -static u8 -snmp_bgp_state(const struct oid *oid) -{ - /* - * Ids of Object Identifier that are already checked: - * internet oid.prefix - * v...... v - * (*oid): .1.3.6.1.2.1.15 - * -> BGP4-MIB::bgp (root) - */ - - if (snmp_is_oid_empty(oid)) - return BGP4_MIB_S_END; - - u8 state = BGP4_MIB_S_NO_VALUE; - - u8 candidate; - switch (oid->n_subid) - { - default: - if (oid->n_subid < 2) - { - state = BGP4_MIB_S_INVALID; - break; - } - - /* fall through */ - - /* - * Between ids[5] and ids[8] (n_subid == 9) should be IP address. - * Validity is checked later in execution because - * this field also could mean a query boundry (upper or lower). - */ - case 9: - case 8: - case 7: - case 6: - case 5: - state = bgp_get_candidate(oid->ids[4]); - - /* fall through */ - - case 4: - if (oid->ids[3] == BGP4_MIB_PEER_ENTRY) - state = (state == BGP4_MIB_S_NO_VALUE) ? - BGP4_MIB_S_PEER_ENTRY : state; - else - state = BGP4_MIB_S_NO_VALUE; - - /* fall through */ - - case 3: - /* u8 candidate; */ - switch (oid->ids[2]) - { - - case BGP4_MIB_VERSION: - state = BGP4_MIB_S_VERSION; - break; - case BGP4_MIB_LOCAL_AS: - state = BGP4_MIB_S_LOCAL_AS; - break; - case BGP4_MIB_PEER_TABLE: - /* We use candidate to avoid overriding more specific state */ - candidate = BGP4_MIB_S_PEER_TABLE; - break; - case BGP4_MIB_IDENTIFIER: - state = BGP4_MIB_S_IDENTIFIER; - break; - - default: /* test fails */ - /* We force state invalidation */ - if (oid->ids[2] < BGP4_MIB_VERSION) - { - state = BGP4_MIB_S_NO_VALUE; - candidate = BGP4_MIB_S_NO_VALUE; - } - else /* oid->ids[2] > BGP4_MIB_PEER_TABLE */ - state = BGP4_MIB_S_END; - } - state = (state == BGP4_MIB_S_NO_VALUE) ? - candidate : state; - - /* fall through */ - - case 2: /* We found bare BGP4-MIB::bgp ObjectId */ - if (state == BGP4_MIB_S_NO_VALUE || - state == BGP4_MIB_S_INVALID) - state = BGP4_MIB_S_BGP; - } - - return state; -} - static void snmp_bgp_reg_ok(struct snmp_proto *p, const struct agentx_response *res, struct snmp_registration *reg) { @@ -430,10 +288,9 @@ ip4_to_oid(struct oid *o, ip4_addr addr) STORE_U32(o->ids[8], (tmp & 0x000000FF) >> 0); } -static void +static void UNUSED print_bgp_record(const struct bgp_proto *bgp_proto) { - //struct proto_config *cf = bgp_proto->p.cf; struct bgp_conn *conn = bgp_proto->conn; DBG(" name: %s", cf->name); @@ -473,130 +330,6 @@ print_bgp_record(const struct bgp_proto *bgp_proto) DBG(" incoming_conn state: %u", bgp_proto->incoming_conn.state + 1); } -static void UNUSED -print_bgp_record_all(struct snmp_proto *p) -{ - DBG("dumping watched bgp status"); - HASH_WALK(p->bgp_hash, next, peer) - { - print_bgp_record(peer->bgp_proto); - } - HASH_WALK_END; - DBG("dumping watched end"); -} - - - -/* - * is_dynamic - is state dependent on runtime BGP peer state - * @state: tested bgp4_mib state - * - * Used to distinguish states that depend on runtime BGP peer states. - * - * Return nonzero for states with value that may change at runtime. - */ -static inline int -is_dynamic(u8 state) -{ - return (state >= BGP4_MIB_S_PEER_IDENTIFIER && - state <= BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME); -} - -/* - * is_static - logical inverse of is_dynamic() for states with value - * @state: tested bgp4_mib state - * - * Return nonzero for states with value that do not change at runtime. - */ -static inline int -is_static(u8 state) -{ - return (state == BGP4_MIB_S_VERSION || - state == BGP4_MIB_S_LOCAL_AS || - state == BGP4_MIB_S_IDENTIFIER); -} - -static inline int -snmp_bgp_has_value(u8 state) -{ - if (state <= BGP4_MIB_S_BGP || - state == BGP4_MIB_S_PEER_TABLE || - state == BGP4_MIB_S_PEER_ENTRY || - state == BGP4_MIB_S_PEER_TABLE_END || - state >= BGP4_MIB_S_END) - return 0; - else - return 1; -} - -/** - * snmp_bgp_get_valid - only states with valid value - * @state: BGP linearized state - * - * Returns @state if has value in BGP4-MIB, zero otherwise. Used for Get-PDU - * packets. - */ -u8 -snmp_bgp_get_valid(u8 state) -{ - if (state == BGP4_MIB_S_INVALID || - state == BGP4_MIB_S_BGP || - state == BGP4_MIB_S_PEER_TABLE || - state == BGP4_MIB_S_PEER_ENTRY || - state == BGP4_MIB_S_PEER_TABLE_END || - state >= BGP4_MIB_S_END) - return 0; - else - return state; -} - -/** - * snmp_bgp_next_state - next state that has value - * @state: BGP linearized state - * - * Returns successor state of @state with valid value in BG4-MIB. Used for - * GetNext-PDU and GetBulk-PDU packets. - */ -u8 -snmp_bgp_next_state(u8 state) -{ - switch (state) - { - case BGP4_MIB_S_LOCAL_AS: - case BGP4_MIB_S_PEER_TABLE: - case BGP4_MIB_S_PEER_ENTRY: - return BGP4_MIB_S_PEER_IDENTIFIER; - - case BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME: - case BGP4_MIB_S_PEER_TABLE_END: - return BGP4_MIB_S_IDENTIFIER; - - case BGP4_MIB_S_IDENTIFIER: - case BGP4_MIB_S_END: - return BGP4_MIB_S_END; - - default: - return state + 1; - } -} - -static int -oid_state_compare(const struct oid *oid, u8 state) -{ - ASSUME(oid != NULL); - if (state >= BGP4_MIB_S_PEER_IDENTIFIER && - state <= BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME) - return (oid->n_subid > 9) - (oid->n_subid < 9); - if ((state >= BGP4_MIB_S_VERSION && state <= BGP4_MIB_S_PEER_TABLE) || - (state == BGP4_MIB_S_IDENTIFIER)) - return (oid->n_subid > 3) - (oid->n_subid < 3); - if (state == BGP4_MIB_S_PEER_ENTRY) - return (oid->n_subid > 4) - (oid->n_subid < 4); - if (state == BGP4_MIB_S_BGP) - return (oid->n_subid > 2) - (oid->n_subid < 2); - - return -1; -} static inline enum snmp_search_res populate_bgp4(struct snmp_data *d, ip4_addr *addr, const struct bgp_proto **proto, const struct bgp_conn @@ -1050,652 +783,10 @@ fill_local_id(struct mib_walk_state *walk UNUSED, struct snmp_data *d) return SNMP_SEARCH_OK; } -static struct oid * -update_bgp_vb(struct snmp_proto *p, struct agentx_varbind **vb, u8 state, struct snmp_pdu *c) -{ - struct oid *oid = &(*vb)->name; - - if (state == BGP4_MIB_S_END || state == BGP4_MIB_S_INVALID || - state == BGP4_MIB_S_NO_VALUE) - return &(*vb)->name; - - /* No need to reallocate anything if the OID has same lin. state */ - if (snmp_bgp_state(oid) == state) - { - if (state >= BGP4_MIB_S_PEER_IDENTIFIER && - state <= BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME && - oid->n_subid == 9) - return oid; - if (state >= BGP4_MIB_S_VERSION && - state <= BGP4_MIB_S_PEER_TABLE && oid->n_subid == 3) - return oid; - if (state == BGP4_MIB_S_PEER_ENTRY && oid->n_subid == 4) - return oid; - if (state == BGP4_MIB_S_BGP && oid->n_subid == 2) - return oid; - } - - switch (state) - { - case BGP4_MIB_S_BGP: - /* This could potentially destroy same old data */ - if (oid->n_subid != 2) - oid = snmp_varbind_set_name_len(p, vb, 2, c); - - oid->ids[0] = SNMP_MIB_2; - oid->ids[1] = BGP4_MIB; - break; - - case BGP4_MIB_S_VERSION: - if (oid->n_subid != 3) - oid = snmp_varbind_set_name_len(p, vb, 3, c); - - oid->ids[2] = BGP4_MIB_VERSION; - break; - - case BGP4_MIB_S_LOCAL_AS: - if (oid->n_subid != 3) - oid =snmp_varbind_set_name_len(p, vb, 3, c); - - oid->ids[2] = BGP4_MIB_LOCAL_AS; - break; - - case BGP4_MIB_S_PEER_IDENTIFIER: - if (oid->n_subid != 9) - { - u8 n_subid = LOAD_U8(oid->n_subid); - oid = snmp_varbind_set_name_len(p, vb, 9, c); - - if (n_subid < 6) - oid->ids[5] = 0; - if (n_subid < 7) - oid->ids[6] = 0; - if (n_subid < 8) - oid->ids[7] = 0; - if (n_subid < 9) - oid->ids[8] = 0; - } - - oid->ids[2] = BGP4_MIB_PEER_TABLE; - oid->ids[3] = BGP4_MIB_PEER_ENTRY; - - oid->ids[4] = BGP4_MIB_PEER_IDENTIFIER; - break; - -#define SNMP_UPDATE_CASE(num, update) \ - case num: \ - if (oid->n_subid != 9) \ - { \ - u8 n_subid = LOAD_U8(oid->n_subid); \ - oid = snmp_varbind_set_name_len(p, vb, 9, c); \ - \ - if (n_subid < 6) \ - oid->ids[5] = 0; \ - if (n_subid < 7) \ - oid->ids[6] = 0; \ - if (n_subid < 8) \ - oid->ids[7] = 0; \ - if (n_subid < 9) \ - oid->ids[8] = 0; \ - } \ - \ - oid->n_subid = 9; \ - oid->ids[4] = update; \ - break; - - SNMP_UPDATE_CASE(BGP4_MIB_S_STATE, BGP4_MIB_STATE) - - SNMP_UPDATE_CASE(BGP4_MIB_S_ADMIN_STATUS, BGP4_MIB_ADMIN_STATUS) - - SNMP_UPDATE_CASE(BGP4_MIB_S_NEGOTIATED_VERSION, BGP4_MIB_NEGOTIATED_VERSION) - - SNMP_UPDATE_CASE(BGP4_MIB_S_LOCAL_ADDR, BGP4_MIB_LOCAL_ADDR) - - SNMP_UPDATE_CASE(BGP4_MIB_S_LOCAL_PORT, BGP4_MIB_LOCAL_PORT) - - SNMP_UPDATE_CASE(BGP4_MIB_S_REMOTE_ADDR, BGP4_MIB_REMOTE_ADDR) - - SNMP_UPDATE_CASE(BGP4_MIB_S_REMOTE_PORT, BGP4_MIB_REMOTE_PORT) - - SNMP_UPDATE_CASE(BGP4_MIB_S_REMOTE_AS, BGP4_MIB_REMOTE_AS) - - SNMP_UPDATE_CASE(BGP4_MIB_S_RX_UPDATES, BGP4_MIB_RX_UPDATES) - - SNMP_UPDATE_CASE(BGP4_MIB_S_TX_UPDATES, BGP4_MIB_TX_UPDATES) - - SNMP_UPDATE_CASE(BGP4_MIB_S_RX_MESSAGES, BGP4_MIB_RX_MESSAGES) - - SNMP_UPDATE_CASE(BGP4_MIB_S_TX_MESSAGES, BGP4_MIB_TX_MESSAGES) - - SNMP_UPDATE_CASE(BGP4_MIB_S_LAST_ERROR, BGP4_MIB_LAST_ERROR) - - SNMP_UPDATE_CASE(BGP4_MIB_S_FSM_TRANSITIONS, BGP4_MIB_FSM_TRANSITIONS) - - SNMP_UPDATE_CASE(BGP4_MIB_S_FSM_ESTABLISHED_TIME, BGP4_MIB_FSM_ESTABLISHED_TIME) - - SNMP_UPDATE_CASE(BGP4_MIB_S_RETRY_INTERVAL, BGP4_MIB_RETRY_INTERVAL) - - SNMP_UPDATE_CASE(BGP4_MIB_S_HOLD_TIME, BGP4_MIB_HOLD_TIME) - - SNMP_UPDATE_CASE(BGP4_MIB_S_KEEPALIVE, BGP4_MIB_KEEPALIVE) - - SNMP_UPDATE_CASE(BGP4_MIB_S_HOLD_TIME_CONFIGURED, BGP4_MIB_HOLD_TIME_CONFIGURED) - - SNMP_UPDATE_CASE(BGP4_MIB_S_KEEPALIVE_CONFIGURED, BGP4_MIB_KEEPALIVE_CONFIGURED) - - SNMP_UPDATE_CASE(BGP4_MIB_S_ORIGINATION_INTERVAL, BGP4_MIB_ORIGINATION_INTERVAL) - - SNMP_UPDATE_CASE(BGP4_MIB_S_MIN_ROUTE_ADVERTISEMENT, BGP4_MIB_MIN_ROUTE_ADVERTISEMENT) - - SNMP_UPDATE_CASE(BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME, BGP4_MIB_IN_UPDATE_ELAPSED_TIME) - - case BGP4_MIB_S_IDENTIFIER: - if (oid->n_subid != 3) - oid = snmp_varbind_set_name_len(p, vb, 3, c); - - oid->n_subid = 3; - oid->ids[2] = 4; - break; - - default: - /* intentionally left blank */ - break; - } - - return oid; -#undef SNMP_UPDATE_CASE -} - - -/** - * snmp_bgp_find_next_oid - walk bgp peer addresses and update @o_start oid - * - * @p: - * @oid: - * @contid: - */ -static int -snmp_bgp_find_next_oid(struct snmp_proto *p, struct oid *oid, uint UNUSED contid) -{ - ip4_addr ip4 = ip4_from_oid(oid); - - net_addr net; - net_fill_ip4(&net, ip4, IP4_MAX_PREFIX_LENGTH); - struct f_trie_walk_state ws; - - int match = trie_walk_init(&ws, p->bgp_trie, &net, 1); - - if (match && oid->include) - { - oid->include = 0; - return 1; - } - - /* We skip the first match as we should not include ip address in oid */ - if (match) - { - trie_walk_next(&ws, &net); - } - - if (trie_walk_next(&ws, &net)) - { - ASSUME(oid->n_subid == 9); - ip4_addr res = ipa_to_ip4(net_prefix(&net)); - ip4_to_oid(oid, res); - return 1; - } - - return 0; -} - -static enum snmp_search_res UNUSED -snmp_bgp_search_dynamic(struct snmp_proto *p, struct oid **searched, const struct oid *o_end, uint UNUSED contid, u8 next_state, struct snmp_pdu *c) -{ - struct oid *oid = *searched; - u8 end_state = MIN(snmp_bgp_state(o_end), BGP4_MIB_S_PEER_TABLE_END); - - ASSUME(end_state <= BGP4_MIB_S_END); - ASSUME(oid != NULL); - - // TODO TODO remove me - struct agentx_varbind data = { 0 }; - struct agentx_varbind *vb = &data; - - oid = update_bgp_vb(p, &vb, next_state, c); - //oid = update_bgp_oid(oid, next_state); - - int found; - while (!(found = snmp_bgp_find_next_oid(p, oid, contid)) && next_state <= end_state) - { - next_state = snmp_bgp_next_state(next_state); - if (next_state == BGP4_MIB_S_IDENTIFIER) - break; - //oid = update_bgp_oid(oid, next_state); - oid = update_bgp_vb(p, &vb, next_state, c); - /* In case of search for next bgp state, we want to start from beginning. */ - oid->ids[5] = oid->ids[6] = oid->ids[7] = oid->ids[8] = 0; - } - - if (next_state < BGP4_MIB_S_PEER_TABLE_END && next_state <= end_state) - { - *searched = oid; - return SNMP_SEARCH_OK; - } - - return SNMP_SEARCH_END_OF_VIEW; -} - -enum snmp_search_res -snmp_bgp_search(struct snmp_proto *p, struct agentx_varbind **vb_search, const struct oid *o_end, struct snmp_pdu *c) -{ - (void)p; - (void)vb_search; - (void)o_end; - (void)c; - return SNMP_SEARCH_END_OF_VIEW; -#if 0 - enum snmp_search_res r = SNMP_SEARCH_END_OF_VIEW; - u8 bgp_state = snmp_bgp_state(*searched); - u8 state; - - if (bgp_state == BGP4_MIB_S_END) - { - return SNMP_SEARCH_NO_OBJECT; - } - - if (is_static(bgp_state) && (*searched)->include) - { - return SNMP_SEARCH_OK; - } - - state = snmp_bgp_next_state(bgp_state); - if (is_static(state) && !is_dynamic(bgp_state)) - { - *searched = update_bgp_oid(*searched, state); - return SNMP_SEARCH_OK; - } - - if (is_dynamic(state) && !is_dynamic(bgp_state)) - { - for (uint i = 5; i < MIN(9, (*searched)->n_subid); i++) - (*searched)->ids[i] = 0; - r = snmp_bgp_search_dynamic(p, searched, o_end, contid, state); - if (r != SNMP_SEARCH_END_OF_VIEW) - return r; - } - - if (is_dynamic(bgp_state)) - { - r = snmp_bgp_search_dynamic(p, searched, o_end, contid, bgp_state); - - if (r != SNMP_SEARCH_END_OF_VIEW) - return r; - } - - state = snmp_bgp_next_state(bgp_state); - if (state <= BGP4_MIB_S_IDENTIFIER) - { - *searched = update_bgp_oid(*searched, state); - return SNMP_SEARCH_OK; - } - - // TODO add route table - - /* end not found */ - return SNMP_SEARCH_END_OF_VIEW; -#endif -} - -static void -bgp_fill_dynamic(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu *c, u8 state) -{ - struct oid *oid = &(*vb)->name; - //byte *pkt; - - ip4_addr addr; - if (oid_state_compare(oid, state) == 0 && snmp_bgp_valid_ip4(oid)) - addr = ip4_from_oid(oid); - else - { - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE); - return; - } - - struct snmp_bgp_peer *pe = snmp_hash_find(p, addr); - - if (!pe) - { - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE); - return; - } - - const struct bgp_proto *bgp_proto = pe->bgp_proto; - if (!ipa_is_ip4(bgp_proto->remote_ip)) - { - log(L_ERR, "%s: Found BGP protocol instance with IPv6 address", bgp_proto->p.name); - c->error = AGENTX_RES_GEN_ERROR; - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE); - return; - } - - ip4_addr proto_ip = ipa_to_ip4(bgp_proto->remote_ip); - if (!ip4_equal(proto_ip, pe->peer_ip)) - { - /* Here, we could be in problem as the bgp_proto IP address could be changed */ - log(L_ERR, "%s: Stored hash key IP address and peer remote address differ.", - bgp_proto->p.name); - c->error = AGENTX_RES_GEN_ERROR; - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE); - return; - } - - //const struct bgp_conn *bgp_conn = bgp_proto->conn; - //const struct bgp_stats *bgp_stats = &bgp_proto->stats; - const struct bgp_config *bgp_conf = bgp_proto->cf; - - uint fsm_state = snmp_bgp_fsm_state(bgp_proto); - - char last_error[2]; - snmp_bgp_last_error(bgp_proto, last_error); - - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE); - switch (state) - { - case BGP4_MIB_S_PEER_IDENTIFIER: - if (c->size < AGENTX_TYPE_IP4_SIZE) - { - snmp_log("BGP4-MIB small buffer"); - snmp_manage_tbuf(p, c); - } - - if (fsm_state == BGP4_MIB_OPENCONFIRM || fsm_state == BGP4_MIB_ESTABLISHED) - // TODO last - {} //snmp_varbind_ip4(*vb, c, ip4_from_u32(bgp_proto->remote_id)); - else - {} //snmp_varbind_ip4(*vb, c, IP4_NONE); - break; - - case BGP4_MIB_S_STATE: - if (c->size < AGENTX_TYPE_INT_SIZE) - { - snmp_log("BGP4-MIB small buffer 2"); - snmp_manage_tbuf(p, c); - } - - //snmp_varbind_int(*vb, c, fsm_state); - break; - - case BGP4_MIB_S_ADMIN_STATUS: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - if (bgp_proto->p.disabled) - {} //snmp_varbind_int(*vb, c, AGENTX_ADMIN_STOP); - else - {} //snmp_varbind_int(*vb, c, AGENTX_ADMIN_START); - - break; - - case BGP4_MIB_S_NEGOTIATED_VERSION: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - uint fsm_state = snmp_bgp_fsm_state(bgp_proto); - - if (fsm_state == BGP4_MIB_ESTABLISHED || fsm_state == BGP4_MIB_ESTABLISHED) - {} //snmp_varbind_int(*vb, c, BGP4_MIB_NEGOTIATED_VER_VALUE); - else - {} //snmp_varbind_int(*vb, c, BGP4_MIB_NEGOTIATED_VER_NO_VALUE); - - break; - - case BGP4_MIB_S_LOCAL_ADDR: - if (c->size < AGENTX_TYPE_IP4_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_ip4(*vb, c, ipa_to_ip4(bgp_proto->local_ip)); - break; - - case BGP4_MIB_S_LOCAL_PORT: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_int(*vb, c, bgp_conf->local_port); - break; - - case BGP4_MIB_S_REMOTE_ADDR: - if (c->size < AGENTX_TYPE_IP4_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_ip4(*vb, c, ipa_to_ip4(bgp_proto->remote_ip)); - break; - - case BGP4_MIB_S_REMOTE_PORT: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_int(*vb, c, bgp_conf->remote_port); - break; - - case BGP4_MIB_S_REMOTE_AS: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_int(*vb, c, bgp_proto->remote_as); - break; - - case BGP4_MIB_S_RX_UPDATES: /* bgpPeerInUpdates */ - if (c->size < AGENTX_TYPE_COUNTER32_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_counter32(*vb, c, bgp_stats->rx_updates); - break; - - case BGP4_MIB_S_TX_UPDATES: /* bgpPeerOutUpdate */ - if (c->size < AGENTX_TYPE_COUNTER32_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_counter32(*vb, c, bgp_stats->tx_updates); - break; - - case BGP4_MIB_S_RX_MESSAGES: /* bgpPeerInTotalMessages */ - if (c->size < AGENTX_TYPE_COUNTER32_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_counter32(*vb, c, bgp_stats->rx_messages); - break; - - case BGP4_MIB_S_TX_MESSAGES: /* bgpPeerOutTotalMessages */ - if (c->size < AGENTX_TYPE_COUNTER32_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_counter32(*vb, c, bgp_stats->tx_messages); - break; - - case BGP4_MIB_S_LAST_ERROR: - if (c->size < snmp_str_size_from_len(2)) - SNMP_MANAGE_TBUF(p, vb, c); - - {} //snmp_varbind_nstr(*vb, c, last_error, 2); - break; - - case BGP4_MIB_S_FSM_TRANSITIONS: - if (c->size < AGENTX_TYPE_COUNTER32_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_counter32(*vb, c, - // bgp_stats->fsm_established_transitions); - break; - - case BGP4_MIB_S_FSM_ESTABLISHED_TIME: - if (c->size < AGENTX_TYPE_COUNTER32_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - - //snmp_varbind_gauge32(*vb, c, - // (current_time() - bgp_proto->last_established) TO_S); - break; - - case BGP4_MIB_S_RETRY_INTERVAL: /* retry inverval value should be != 0 */ - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_int(*vb, c, bgp_conf->connect_retry_time); - break; - - case BGP4_MIB_S_HOLD_TIME: /* hold time should be == 0 or in 3..65535 */ - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_int(*vb, c, (bgp_conn) ? bgp_conn->hold_time : 0); - break; - - case BGP4_MIB_S_KEEPALIVE: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - if (!bgp_conf->hold_time) - {} //snmp_varbind_int(*vb, c, 0); - else - {} //snmp_varbind_int(*vb, c, - // (bgp_conn) ? bgp_conn->keepalive_time : 0); - break; - - case BGP4_MIB_S_HOLD_TIME_CONFIGURED: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_int(*vb, c, bgp_conf->hold_time); - break; - - case BGP4_MIB_S_KEEPALIVE_CONFIGURED: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - - if (!bgp_conf->keepalive_time) - {} //snmp_varbind_int(*vb, c, 0); - else - {} //snmp_varbind_int(*vb, c, - // (bgp_conn) ? bgp_conn->keepalive_time : 0); - break; - - case BGP4_MIB_S_ORIGINATION_INTERVAL: - /* value should be in 1..65535 but is not supported by bird */ - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_int(*vb, c, 0); - break; - - case BGP4_MIB_S_MIN_ROUTE_ADVERTISEMENT: - /* value should be in 1..65535 but is not supported by bird */ - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_int(*vb, c, 0); - break; - - case BGP4_MIB_S_IN_UPDATE_ELAPSED_TIME: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_gauge32(*vb, c, - //(current_time() - bgp_proto->last_rx_update) TO_S - //); - break; - - case BGP4_MIB_S_END: - break; - - case BGP4_MIB_S_INVALID: - break; - - case BGP4_MIB_S_BGP: - break; - case BGP4_MIB_S_PEER_TABLE: - break; - case BGP4_MIB_S_PEER_ENTRY: - break; - case BGP4_MIB_S_NO_VALUE: - break; - } -} - - -void -bgp_fill_static(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu *c, u8 state) -{ - (void)p; - ASSUME(c->buffer == snmp_varbind_data(*vb)); - - struct oid *oid = &(*vb)->name; - - /* - * snmp_bgp_state() check only prefix. To be sure on OID equivalence we need to - * compare the oid->n_subid length. All BGP static fields have same n_subid. - */ - if (oid_state_compare(oid, state) < 0 || state == BGP4_MIB_S_END) - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_OBJECT); - else if (oid_state_compare(oid, state) > 0) - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_INSTANCE); - - switch (state) - { - case BGP4_MIB_S_VERSION:; - uint sz = snmp_str_size_from_len(1); - if (c->size < sz) - SNMP_MANAGE_TBUF(p, vb, c); - - c->size -= sz; - //snmp_varbind_nstr(*vb, c, BGP4_VERSIONS, 1); - break; - - case BGP4_MIB_S_LOCAL_AS: - if (c->size < AGENTX_TYPE_INT_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_int(*vb, c, p->bgp_local_as); - break; - - case BGP4_MIB_S_IDENTIFIER: - if (c->size < AGENTX_TYPE_IP4_SIZE) - SNMP_MANAGE_TBUF(p, vb, c); - - //snmp_varbind_ip4(*vb, c, p->bgp_local_id); - break; - - default: - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_OBJECT); - break; - } -} - -void -snmp_bgp_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu *c) -{ - ASSERT(vb != NULL); - u8 state = snmp_bgp_state(&((*vb)->name)); - - if (is_static(state)) - { - bgp_fill_static(p, vb, c, state); - return; - } - - if (is_dynamic(state)) - { - bgp_fill_dynamic(p, vb, c, state); - return; - } - - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_OBJECT); -} - /* * bgp4_next_peer */ -static int UNUSED +static int bgp4_next_peer(struct mib_walk_state *state, struct snmp_data *data) { //struct agentx_varbind *vb = data->c->sr_vb_start; diff --git a/proto/snmp/mib_tree.c b/proto/snmp/mib_tree.c index 5af26e394..d5dae3633 100644 --- a/proto/snmp/mib_tree.c +++ b/proto/snmp/mib_tree.c @@ -629,7 +629,7 @@ mib_tree_walk_to_oid(const struct mib_walk_state *walk, struct oid *result, u32 * return +1 if walk_oid > oid * */ -// TODO tests +// TODO tests, doc string int mib_tree_walk_oid_compare(const struct mib_walk_state *walk, const struct oid *oid) { diff --git a/proto/snmp/mib_tree.h b/proto/snmp/mib_tree.h index 082c942f2..4b15e6d0e 100644 --- a/proto/snmp/mib_tree.h +++ b/proto/snmp/mib_tree.h @@ -26,8 +26,6 @@ struct mib_node { struct mib_walk_state; -//typedef enum snmp_search_res (*snmp_filler_hook_t)(struct mib_walk_state *state, struct snmp_data *data); - struct mib_leaf { struct mib_node_core c; @@ -99,7 +97,6 @@ struct mib_tree { }; void mib_tree_init(pool *p, struct mib_tree *t); -// TODO: remove need for argument include_root void mib_tree_walk_init(struct mib_walk_state *state, const struct mib_tree *t); int mib_tree_walk_to_oid(const struct mib_walk_state *state, struct oid *result, u32 subids); int mib_tree_walk_oid_compare(const struct mib_walk_state *state, const struct oid *oid); diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index 61c54dbd8..f08386fbe 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -119,6 +119,10 @@ #include "snmp_utils.h" #include "mib_tree.h" +// TODO: remove me +#include "proto/bgp/bgp.h" + + static void snmp_start_locked(struct object_lock *lock); static void snmp_sock_err(sock *sk, int err); static void snmp_stop_timeout(timer *tm); diff --git a/proto/snmp/snmp.h b/proto/snmp/snmp.h index 386e23a5b..1f2552a5f 100644 --- a/proto/snmp/snmp.h +++ b/proto/snmp/snmp.h @@ -17,7 +17,6 @@ #include "nest/bird.h" #include "nest/protocol.h" #include "filter/data.h" -#include "proto/bgp/bgp.h" // TODO remove me #define SNMP_UNDEFINED 0 #define SNMP_BGP 1 diff --git a/proto/snmp/snmp_utils.c b/proto/snmp/snmp_utils.c index 540870362..394df7588 100644 --- a/proto/snmp/snmp_utils.c +++ b/proto/snmp/snmp_utils.c @@ -107,7 +107,6 @@ snmp_is_oid_empty(const struct oid *oid) /* We intentionaly ignore padding that should be zeroed */ if (oid != NULL) return LOAD_U8(oid->n_subid) == 0 && LOAD_U8(oid->prefix) == 0; - // && LOAD_U8(oid->include) == 0; else return 0; } @@ -178,19 +177,6 @@ snmp_oid_copy2(struct oid *dest, const struct oid *src) memcpy(dest->ids, src->ids, LOAD_U8(src->n_subid) * sizeof(u32)); } -/* - * snmp_oid_update - * - */ -void -snmp_oid_update(struct oid *dest, const struct oid *src) -{ - dest->prefix = src->prefix; - dest->include = src->include; - dest->reserved = 0; - memcpy(dest->ids, src->ids, MIN(dest->n_subid, src->n_subid) * sizeof(u32)); -} - /* * snmp_oid_duplicate - duplicate an OID from memory pool * @pool: pool to use @@ -514,15 +500,6 @@ snmp_create_varbind(byte *buf, struct oid *oid) return vb; } -#if 0 -byte * -snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new) -{ - memcpy(&vb->name, new, snmp_oid_size(new)); - return (void *) vb + snmp_varbind_header_size(vb); -} -#endif - /** * snmp_oid_ip4_index - check IPv4 address validity in oid * @o: object identifier holding ip address @@ -675,7 +652,7 @@ int snmp_oid_compare(const struct oid *left, const struct oid *right) { const u8 left_subids = LOAD_U8(left->n_subid); - u8 right_subids = LOAD_U8(right->n_subid); // see hack for more info + u8 right_subids = LOAD_U8(right->n_subid); /* see hack for more info */ const u8 left_prefix = LOAD_U8(left->prefix); const u8 right_prefix = LOAD_U8(right->prefix); @@ -764,7 +741,6 @@ snmp_registration_create(struct snmp_proto *p, u8 mib_class) r->session_id = p->session_id; /* will be incremented by snmp_session() macro during packet assembly */ r->transaction_id = p->transaction_id; - // TODO where is incremented? is this valid? r->packet_id = p->packet_id + 1; snmp_log("using registration packet_id %u", r->packet_id); @@ -873,7 +849,6 @@ snmp_varbind_ip4(struct snmp_pdu *c, ip4_addr addr) c->buffer = snmp_put_ip4(snmp_varbind_data(c->sr_vb_start), addr); } -// TODO doc string, we have already the varbind prepared inline byte * snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len) { @@ -1180,7 +1155,6 @@ snmp_walk_fill(struct mib_leaf *leaf, struct mib_walk_state *walk, struct snmp_d struct agentx_varbind *vb = data->c->sr_vb_start; if (!leaf) - //if (!leaf || mib_tree_walk_is_oid_descendant(walk, &vb->name) < 0) return SNMP_SEARCH_NO_OBJECT; uint size = 0; diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 3c012a4f4..d3094b5ee 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -62,17 +62,12 @@ * */ -//static void snmp_mib_fill(struct snmp_proto *p, struct oid *oid, struct snmp_pdu *c); -static void snmp_mib_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu *c); static uint parse_response(struct snmp_proto *p, byte *buf); static void do_response(struct snmp_proto *p, byte *buf); static uint parse_gets_pdu(struct snmp_proto *p, byte *pkt); static struct agentx_response *prepare_response(struct snmp_proto *p, struct snmp_pdu *c); static void response_err_ind(struct snmp_proto *p, struct agentx_response *res, enum agentx_response_errs err, u16 ind); static uint update_packet_size(struct agentx_header *start, byte *end); -//static struct oid *search_mib2(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end, struct oid *o_curr, struct snmp_pdu *c, enum snmp_search_res *result); - -static enum snmp_search_res search_mib(struct snmp_proto *p, struct agentx_varbind **vb_search, const struct oid *o_end, struct snmp_pdu *c); /* standard SNMP internet prefix (1.3.6.1) */ const u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET }; @@ -254,7 +249,6 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in struct snmp_pdu c; snmp_pdu_context(&c, sk); -// TODO use more readable anonymous structure decl. #define UPTIME_SIZE \ sizeof( struct { u32 vb_type; u32 oid_hdr; u32 ids[4]; } ) #define TRAP0_HEADER_SIZE \ @@ -431,7 +425,7 @@ snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 i * * For more detailed description see un_register_pdu() function. */ -void UNUSED +void snmp_unregister(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, uint contid) { un_register_pdu(p, oid, bound, index, AGENTX_UNREGISTER_PDU, 0, contid); @@ -442,7 +436,7 @@ snmp_unregister(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, ui * @p: SNMP protocol instance * @reason: reason for closure */ -static void UNUSED +static void close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason) { sock *sk = p->sock; @@ -511,43 +505,6 @@ parse_close_pdu(struct snmp_proto *p, byte * const pkt_start) } -/* - * snmp_testset - check possibility of VarBind name and data setting - * @p: SNMP protocol instance - * @vb: checked VarBind - * @oid: pool-allocated prefixed copy of VarBind name - * @pkt_size: number of not parsed bytes in processed PDU - * - * Check done by specialized function for specific MIB subtree whether - * the VarBind is valid for set action (changing to current value to value - * in VarBind). - * - * Return 1 if the VarBind setting is possible, 0 otherwise. - */ -/* MUCH better signature would be - static int snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, uint pkt_size); - */ -static int UNUSED -snmp_testset(struct snmp_proto *p, const struct agentx_varbind *vb, struct oid *oid, uint pkt_size) -{ - /* Hard-coded no support for writing */ - (void)p;(void)vb;(void)oid;(void)pkt_size; - snmp_simple_response(p, AGENTX_RES_NOT_WRITABLE, 1); - return pkt_size + AGENTX_HEADER_SIZE; -#if 0 - if (!oid) - return 0; - - switch (oid->ids[1]) - { - case SNMP_BGP4_MIB: - return snmp_bgp_testset(p, vb, oid, pkt_size); - default: - return 0; - } -#endif -} - /* * refresh_ids - Copy current ids from packet to protocol * @p: SNMP protocol instance @@ -578,7 +535,6 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start) struct agentx_header *h = (void *) pkt; pkt += AGENTX_HEADER_SIZE; - //uint pkt_size = LOAD_U32(h->payload); sock *sk = p->sock; struct snmp_pdu c; @@ -598,42 +554,6 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start) * variables, when implementing the mentioned support, change the initializer * to 1 */ -#if 0 - // TODO think about future value setting data structure - //struct agentx_transaction *tr = mb_alloc(...); - void *tr = mb_alloc(p->pool, 16); - - struct agentx_varbind *vb; - uint sz; - while (size > 0 && all_possible) - { - vb = (void *) pkt; - sz = snmp_varbind_size(vb, size); - - if (sz > pkt_size) - { - c.error = AGENTX_RES_PARSE_ERROR; - all_possible = 0; - break; - } - - /* Unknown VarBind type check */ - if (!snmp_test_varbind(vb)) - { - c.error = AGENTX_RES_PARSE_ERROR; - all_possible = 0; - break; - } - ADVANCE(pkt, size, snmp_varbind_size(vb, size)); - - // TODO remove the mb_alloc() in prefixize() - struct oid *work = snmp_prefixize(p, &vb->name); - (void)work; - all_possible = snmp_testset(p, vb, tr, work, pkt_size); - mb_free(work); - } - mb_free(tr); -#endif s = update_packet_size(h, c.buffer); if (c.error != AGENTX_RES_NO_ERROR) @@ -678,7 +598,6 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons snmp_simple_response(p, AGENTX_RES_PARSE_ERROR, 0); // TODO best solution for possibly malicious pkt_size return AGENTX_HEADER_SIZE; - // use varbind_list_size()?? } struct snmp_pdu c; @@ -1036,285 +955,6 @@ snmp_get_mib_class(const struct oid *oid) } } -/* - * snmp_get_next - process single agentx-GetNext-PDU search range - * @p: SNMP protocol instance - * @o_start: SearchRange start OID - * @o_end: SearchRange end OID - * @c: transmit PDU context to use - * - * Return 0 if the created VarBind type is endOfMibView, 1 otherwise. - */ -// TODO remove me -static int UNUSED -snmp_get_next2(struct snmp_proto *p, struct agentx_varbind **vb_search, struct oid *o_end, struct snmp_pdu *c) -{ - enum snmp_search_res r; - - //struct oid *o_copy = search_mib(p, o_start, o_end, NULL, c, &r); - r = search_mib(p, vb_search, o_end, c); - struct oid *o_start = &(*vb_search)->name; - - switch (r) - { - case SNMP_SEARCH_NO_OBJECT: - case SNMP_SEARCH_NO_INSTANCE: - case SNMP_SEARCH_END_OF_VIEW:; - snmp_set_varbind_type(*vb_search, AGENTX_END_OF_MIB_VIEW); - return 0; - - case SNMP_SEARCH_OK: - default: - break; - } - - // TODO TODO different API - snmp_mib_fill(p, vb_search, c); - - /* override the error for GetNext-PDU object not find */ - switch ((*vb_search)->type) - { - case AGENTX_NO_SUCH_OBJECT: - case AGENTX_NO_SUCH_INSTANCE: - case AGENTX_END_OF_MIB_VIEW: - (*vb_search)->type = AGENTX_END_OF_MIB_VIEW; - return 0; - - default: - return 1; - } - - o_start = &(*vb_search)->name; - if (c->size < snmp_varbind_hdr_size_from_oid(o_start)) - { - snmp_log("get_next2 small buffer"); - snmp_manage_tbuf(p, c); - } - - snmp_set_varbind_type(*vb_search, AGENTX_END_OF_MIB_VIEW); - return 0; -} - -#if 0 -/* - * snmp_get_next - process single agentx-GetNext-PDU search range - * @p: SNMP protocol instance - * @o_start: SearchRange start OID - * @o_end: SearchRange end OID - * @c: transmit PDU context to use - * - * Return 0 if the created VarBind type is endOfMibView, 1 otherwise. - */ -static int -snmp_get_next3(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, - struct snmp_pdu *c) -{ - enum snmp_search_res r; - struct oid *o_copy = search_mib2(p, o_start, o_end, NULL, c, &r); - - struct agentx_varbind *vb = NULL; - switch (r) - { - case SNMP_SEARCH_NO_OBJECT: - case SNMP_SEARCH_NO_INSTANCE: - case SNMP_SEARCH_END_OF_VIEW:; - uint sz = snmp_varbind_hdr_size_from_oid(o_start); - - if (c->size < sz && c->size >= sizeof(struct agentx_varbind)) - { - struct agentx_varbind *vb_null = snmp_create_varbind_null(c->buffer); - ADVANCE(c->buffer, c->size, snmp_varbind_size_unsafe(vb_null)); - c->error = AGENTX_RES_GEN_ERROR; - return 0; - } - else if (c->size < sz) - { - c->error = AGENTX_RES_GEN_ERROR; - return 0; - } - - vb = snmp_create_varbind(c->buffer, o_start); - vb->type = AGENTX_END_OF_MIB_VIEW; - ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb)); - return 0; - - case SNMP_SEARCH_OK: - default: - break; - } - - if (o_copy) - { - /* basicaly snmp_create_varbind(c->buffer, o_copy), but without any copying */ - vb = (void *) c->buffer; - snmp_mib_fill(p, o_copy, c); - - /* override the error for GetNext-PDU object not find */ - switch (vb->type) - { - case AGENTX_NO_SUCH_OBJECT: - case AGENTX_NO_SUCH_INSTANCE: - case AGENTX_END_OF_MIB_VIEW: - vb->type = AGENTX_END_OF_MIB_VIEW; - return 0; - - default: - return 1; - } - } - - if (c->size < snmp_varbind_hdr_size_from_oid(o_start)) - { - snmp_manage_tbuf(p, c); - } - - vb = snmp_create_varbind(c->buffer, o_start); - vb->type = AGENTX_END_OF_MIB_VIEW; - ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb)); - return 0; -} -#endif - -#if 0 -/* - * snmp_get_bulk - process one iteration of get bulk PDU - * @p: SNMP protocol instance - * @o_start: SearchRange start OID - * @o_end: SearchRange end OID - * @state: state of get bulk PDU processing - * @c: transmit PDU context to use - * - * Return 0 if the created VarBind has type endOfMibView, 1 otherwise. - */ -static int -snmp_get_bulk2(struct snmp_proto *p, struct oid *o_start, struct oid *o_end, - struct agentx_bulk_state *state, struct snmp_pdu *c) -{ - struct oid *o_curr = NULL; - struct oid *o_predecessor = NULL; - enum snmp_search_res r; - - uint i = 0; - do - { - o_predecessor = o_curr; - o_curr = search_mib(p, o_start, o_end, o_curr, c, &r); - i++; - } while (o_curr && i < state->repetition); - - // TODO check if the approach below works - // it need to generate varbinds that will be only of type endOfMibView - /* Object Identifier fall-backs */ - if (!o_curr) - o_curr = o_predecessor; - - if (!o_curr) - o_curr = o_start; - - uint sz = snmp_varbind_hdr_size_from_oid(o_curr); - - if (c->size < sz) - { - c->error = AGENTX_RES_GEN_ERROR; - return 0; - } - - /* we need the varbind handle to be able to override it's type */ - struct agentx_varbind *vb = (void *) c->buffer; - vb->type = AGENTX_END_OF_MIB_VIEW; - - if (r == SNMP_SEARCH_OK) - /* the varbind will be recreated inside the snmp_mib_fill() */ - snmp_mib_fill(p, o_curr, c); - else - ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb)); - - /* override the error for GetBulk-PDU object not found */ - switch (vb->type) - { - case AGENTX_NO_SUCH_OBJECT: - case AGENTX_NO_SUCH_INSTANCE: - case AGENTX_END_OF_MIB_VIEW: - vb->type = AGENTX_END_OF_MIB_VIEW; - return 0; - - default: - return 1; - } -} -#endif - -#if 0 -static int -snmp_get_bulk2(struct snmp_proto *p, struct agentx_varbind **vb_search, const struct oid *o_end, struct agentx_bulk_state *state, struct snmp_pdu *c) -{ - //struct oid *o_curr = NULL; - //struct oid *o_predecessor = NULL; - enum snmp_search_res r; - - uint i = 0; - r = search_mib(p, vb_search, o_end, c); - while (r != SNMP_SEARCH_END_OF_VIEW && i < state->repetition) - { - snmp_mib_fill(p, vb_search, c); - - snmp_varbind_duplicate_hdr(p, vb_search, c); - // renew all pointers here - r = search_mib(p, vb_search, o_end, c); - } - - return r == SNMP_SEARCH_END_OF_VIEW; - do - { - r = search_mib(p, vb_search, o_end, c); - snmp_mib_fill(p, vb_search, ; - o_predecessor = o_curr; - o_curr = search_mib(p, o_start, o_end, o_curr, c, &r); - i++; - } while (r != SNMP_SEARCH_END_OF_VIEW && i < state->repetition); - - // TODO check if the approach below works - // it need to generate varbinds that will be only of type endOfMibView - /* Object Identifier fall-backs */ - if (!o_curr) - o_curr = o_predecessor; - - if (!o_curr) - o_curr = o_start; - - uint sz = snmp_varbind_hdr_size_from_oid(o_curr); - - if (c->size < sz) - { - c->error = AGENTX_RES_GEN_ERROR; - return 0; - } - - /* we need the varbind handle to be able to override it's type */ - struct agentx_varbind *vb = (void *) c->buffer; - vb->type = AGENTX_END_OF_MIB_VIEW; - - if (r == SNMP_SEARCH_OK) - /* the varbind will be recreated inside the snmp_mib_fill() */ - snmp_mib_fill(p, o_curr, c); - else - ADVANCE(c->buffer, c->size, snmp_varbind_header_size(vb)); - - /* override the error for GetBulk-PDU object not found */ - switch (vb->type) - { - case AGENTX_NO_SUCH_OBJECT: - case AGENTX_NO_SUCH_INSTANCE: - case AGENTX_END_OF_MIB_VIEW: - vb->type = AGENTX_END_OF_MIB_VIEW; - return 0; - - default: - return 1; - } -} -#endif - static inline struct oid * snmp_oid_prefixize_unsafe(struct oid *dest, const struct oid *src) { @@ -1330,36 +970,6 @@ snmp_oid_prefixize_unsafe(struct oid *dest, const struct oid *src) return dest; } -#if 0 -/* - * snmp_oid_prefixize - convert oid to prefixed form - * @p: SNMP protocol instance - * @oid: object identifier to convert - * @c: PDU context - * - * The function assumes that the supplied @oid is prefixable. The resulting OID - * is allocated from PDU buffer inside @c. - */ -struct oid * -snmp_oid_prefixize(struct snmp_proto *p, const struct oid *oid, struct snmp_pdu *c) -{ - /* It may be beneficial to move to snmp_utils.c */ - uint subids = LOAD_U8(oid->n_subid) - 5; - uint oid_size = snmp_oid_size(oid); - - if (c->size < oid_size) - { - snmp_manage_tbuf(p, c); - } - - // TODO check if the @oid is prefixable - ASSERT(c->size >= oid_size); - struct oid *result = c->buffer; - ADVANCE(c->buffer, c->size, oid_size); - return snmp_oid_prefixize_unsafe(result, oid); -} -#endif - /* * snmp_vb_to_tx - create varbind from RX buffer OID * @p: SNMP protocol instance @@ -1646,26 +1256,14 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) { case AGENTX_GET_PDU: snmp_get_pdu(p, &c, start_rx, &walk); - //snmp_mib_fill(p, &vb_start, &c); break; case AGENTX_GET_NEXT_PDU: snmp_get_next_pdu(p, &c, start_rx, &walk); - //snmp_get_next2(p, &vb_start, o_end, &c); break; case AGENTX_GET_BULK_PDU: snmp_get_bulk_pdu(p, &c, start_rx, &walk, &bulk_state); - #if 0 - if (c.index >= bulk_state.getbulk.non_repeaters) - bulk_state.repeaters++; - - // store the o_start, o_end - - /* The behavior of GetBulk pdu in the first iteration is - * identical to GetNext pdu. */ - has_any = snmp_get_next2(p, &vb_start, o_end, &c) || has_any; - #endif break; default: @@ -1682,19 +1280,6 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) if (h->type == AGENTX_GET_BULK_PDU) { - #if 0 - // TODO - for (bulk_state.repetition++; - has_any && bulk_state.repetition < bulk_state.getbulk.max_repetitions; - bulk_state.repetition++) - { - vb_start = snmp_vb_copy_to_tx(p, vb_start, &c); - has_any = 0; - for (bulk_state.index = 0; bulk_state.index < bulk_state.repeaters; - bulk_state.repeaters++) - has_any = snmp_get_bulk2(p, &vb_start, end, &bulk_state, &c) || has_any; - } - #endif } /* We update the error, index pair on the beginning of the packet. */ @@ -1739,7 +1324,7 @@ snmp_stop_subagent(struct snmp_proto *p) { tm_stop(p->ping_timer); /* This cause problems with net-snmp daemon witch halts afterwards */ - //close_pdu(p, AGENTX_CLOSE_SHUTDOWN); + close_pdu(p, AGENTX_CLOSE_SHUTDOWN); } /* @@ -1820,7 +1405,6 @@ snmp_ping(struct snmp_proto *p) if (unused < AGENTX_HEADER_SIZE) return; - //struct agentx_header *h = (void *) sk->tpos; struct agentx_header *h = (void *) c.buffer; ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); snmp_blank_header(h, AGENTX_PING_PDU); @@ -1852,248 +1436,6 @@ snmp_search_check_end_oid(const struct oid *found, const struct oid *bound) return (snmp_oid_compare(found, bound) < 0); } -/* - * search_mib - search for successor of given OID - * @p: SNMP protocol instance - * @o_start: search starting OID - * @o_end: search ending OID - * @o_curr: current OID inside @o_start, @o_end interval - * @c: transmit PDU context to use - * @result: search result state - * - * Perform a search in MIB tree in SearchRange from @o_start to @o_end. - * If the @o_start has set include the search is inclusive, the @o_end has - * always the include flag cleared. For agentx-GetNext-PDU, the o_curr is always - * NULL, for agentx-GetBulk-PDU it could have non-NULL value. In such case the - * @o_curr effectively replaces the role of @o_start. It is mandatory to pass - * @o_start and @o_end only allocated from @p protocol's memory pool. - * - * Return found OID or 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 enum snmp_search_res -search_mib(struct snmp_proto *p, struct agentx_varbind **vb_search, const struct oid *o_end, struct snmp_pdu *c) -{ - ASSUME(vb_search != NULL); - struct oid *o_start = &(*vb_search)->name; - ASSUME(o_start != NULL); - - (void)p; - (void)o_end; - (void)c; - // TODO TODO -#if 0 - enum snmp_search_res r; - switch (o_curr->ids[1]) - { - case SNMP_BGP4_MIB: - r = snmp_bgp_search(p, &o_curr, o_end, 0); - - if (r == SNMP_SEARCH_OK) - { - *result = r; - break; - return o_curr; - } - - // TODO add early break for o_end less then thinkable maximum in each tree - - /* fall through */ - - default: - if (o_curr) mb_free(o_curr); - o_curr = snmp_oid_duplicate(p->pool, o_start); - *result = SNMP_SEARCH_END_OF_VIEW; - break; - } - - if (o_end == blank) - /* cast drops const qualifier */ - mb_free((struct oid *)blank); - - return o_curr; -#endif - return SNMP_SEARCH_NO_OBJECT; -} - -/* - * search_mib - search for successor of given OID - * @p: SNMP protocol instance - * @o_start: search starting OID - * @o_end: search ending OID - * @o_curr: current OID inside @o_start, @o_end interval - * @c: transmit PDU context to use - * @result: search result state - * - * Perform a search in MIB tree in SearchRange from @o_start to @o_end. - * If the @o_start has set include the search is inclusive, the @o_end has - * always the include flag cleared. For agentx-GetNext-PDU, the o_curr is always - * NULL, for agentx-GetBulk-PDU it could have non-NULL value. In such case the - * @o_curr effectively replaces the role of @o_start. It is mandatory to pass - * @o_start and @o_end only allocated from @p protocol's memory pool. - * - * Return found OID or NULL. - */ -/* tree is tree with "internet" prefix .1.3.6.1 - working only with o_start, o_end allocated in heap (not from buffer)*/ -#if 0 -static struct oid * -search_mib2(struct snmp_proto *p, const struct oid *o_start, const struct oid *o_end, - struct oid *o_curr, struct snmp_pdu UNUSED *c, - enum snmp_search_res *result) -{ - // TODO flip retval and result (maybe on more place to stay consistent) - // TODO remove unnecessary o_start/o_curr duplication - ASSUME(o_start != NULL); - - if (o_curr && (o_curr->n_subid < 2 || o_curr->ids[0] != 1)) - return NULL; - if (!o_curr && (o_start->n_subid < 2 || o_start->ids[0] != 1)) - return NULL; - - if (!o_curr) - { - o_curr = snmp_oid_duplicate(p->pool, o_start); - // XXX is it right time to free o_start right now (here) ? - // not for use in snmp_get_next2() the o_start comes and ends in _gets_() - } - - const struct oid *blank = NULL; - if (!snmp_is_oid_empty(o_end) && - snmp_get_mib_class(o_curr) < snmp_get_mib_class(o_end)) - { - o_end = blank = snmp_oid_blank(p); - } - - enum snmp_search_res r; - switch (o_curr->ids[1]) - { - case SNMP_BGP4_MIB: - r = snmp_bgp_search(p, &o_curr, o_end, 0); - - if (r == SNMP_SEARCH_OK) - { - *result = r; - break; - return o_curr; - } - - // TODO add early break for o_end less then thinkable maximum in each tree - - /* fall through */ - - default: - if (o_curr) mb_free(o_curr); - o_curr = snmp_oid_duplicate(p->pool, o_start); - *result = SNMP_SEARCH_END_OF_VIEW; - break; - } - - if (o_end == blank) - /* cast drops const qualifier */ - mb_free((struct oid *)blank); - - return o_curr; -} -#endif - - - -#if 0 -/** - * snmp_prefixize - return prefixed OID copy if possible - * @proto: allocation pool holder - * @oid: from packet loaded object identifier - * - * Return prefixed (meaning with nonzero prefix field) oid copy of @oid if - * possible, NULL otherwise. Returned pointer is always allocated from @proto's - * pool not a pointer to RX-buffer (from which is most likely @oid). - */ -struct oid * -snmp_prefixize(struct snmp_proto *proto, const struct oid *oid) -{ - ASSUME(oid != NULL); - - if (snmp_is_oid_empty(oid)) - { - /* allocate new zeroed oid */ - return snmp_oid_blank(proto); - } - - /* already in prefixed form */ - else if (oid->prefix != 0) { - struct oid *new = snmp_oid_duplicate(proto->pool, oid); - return new; - } - - if (oid->n_subid < 5) - return NULL; - - for (int i = 0; i < 4; i++) - if (LOAD_U32(oid->ids[i]) != snmp_internet[i]) - return NULL; - - /* validity check here */ - if (oid->ids[4] >= 256) - return NULL; - - struct oid *new = mb_alloc(proto->pool, - sizeof(struct oid) + MAX((oid->n_subid - 5) * sizeof(u32), 0)); - - memcpy(new, oid, sizeof(struct oid)); - new->n_subid = oid->n_subid - 5; - - /* validity check before allocation => ids[4] < 256 - and can be copied to one byte new->prefix */ - new->prefix = oid->ids[4]; - - memcpy(&new->ids, &oid->ids[5], new->n_subid * sizeof(u32)); - return new; -} -#endif - -/* - * snmp_mib_fill - append a AgentX VarBind to PDU - * @p: SNMP protocol instance - * @vb: indirect pointer to destination varbind - * @c: transmit PDU context to use - * - * Append new AgentX VarBind at the end of created PDU. The content (v.data) - * is handled in function specialized for given MIB subtree. The binding is - * created only if the v.name matches some variable name precisely. - */ -static void -snmp_mib_fill(struct snmp_proto *p, struct agentx_varbind **vb, struct snmp_pdu *c) -{ - (void) p; - ASSUME(vb != NULL && *vb != NULL); - - struct oid *oid = &((*vb)->name); - - if (oid->n_subid < 2 || (oid->prefix != SNMP_MGMT && oid->ids[0] != SNMP_MIB_2)) - { - snmp_set_varbind_type(*vb, AGENTX_NO_SUCH_OBJECT); - ADVANCE(c->buffer, c->size, snmp_varbind_header_size(*vb)); - return; - } - - u8 mib_class = snmp_get_mib_class(oid); - switch (mib_class) - { - case SNMP_CLASS_BGP: - //snmp_bgp_fill(p, vb, c); - break; - - case SNMP_CLASS_INVALID: - case SNMP_CLASS_END: - default: - break; - (*vb)->type = AGENTX_NO_SUCH_OBJECT; - ADVANCE(c->buffer, c->size, snmp_varbind_header_size(*vb)); - } -} - /* * snmp_manage_tbuf - TODO */ diff --git a/proto/snmp/subagent.h b/proto/snmp/subagent.h index 138c43f7d..09ac3e537 100644 --- a/proto/snmp/subagent.h +++ b/proto/snmp/subagent.h @@ -338,16 +338,6 @@ struct snmp_packet_info { void *data; }; -#if 0 -struct agentx_alloc_context { - u8 is_instance; /* flag INSTANCE_REGISTRATION */ - u8 new_index; /* flag NEW_INDEX */ - u8 any_index; /* flag ANY_INDEX */ - char *context; /* context to allocate in */ - uint clen; /* length of context string */ -}; -#endif - int snmp_rx(sock *sk, uint size); int snmp_rx_stop(sock *sk, uint size); void snmp_down(struct snmp_proto *p);