diff --git a/proto/snmp/bgp4_mib.c b/proto/snmp/bgp4_mib.c index b13ed463..9a0418fd 100644 --- a/proto/snmp/bgp4_mib.c +++ b/proto/snmp/bgp4_mib.c @@ -144,7 +144,7 @@ snmp_bgp_notify_common(struct snmp_proto *p, uint type, ip4_addr ip4, char last_ addr->ids[ENTRY_TYPE] = BGP4_MIB_REMOTE_ADDR; ip4_to_oid(addr, ip4); } - /* We have enough space inside the TX-buffer prepared */ + /* We have enough space inside the TX buffer prepared */ struct snmp_pdu dummy = { 0 }; dummy.sr_vb_start = addr_vb; snmp_varbind_ip4(&dummy, ip4); @@ -248,6 +248,7 @@ snmp_bgp4_register(struct snmp_proto *p) STORE_U8(oid->n_subid, ARRAY_SIZE(bgp_mib_prefix)); STORE_U8(oid->prefix, SNMP_MGMT); + // TODO use STATIC_OID memcpy(oid->ids, bgp_mib_prefix, sizeof(bgp_mib_prefix)); reg->oid = oid; reg->reg_hook_ok = snmp_bgp_reg_ok; @@ -257,7 +258,7 @@ snmp_bgp4_register(struct snmp_proto *p) * We set both upper bound and index to zero, therefore only single OID * is being registered. */ - snmp_register(p, oid, 0, 0, SNMP_REGISTER_TREE, SNMP_DEFAULT_CONTEXT); + snmp_register(p, oid, 0, 0, SNMP_REGISTER_TREE); } } @@ -267,7 +268,6 @@ snmp_bgp_valid_ip4(const struct oid *o) return snmp_valid_ip4_index(o, 5); } - static inline ip4_addr ip4_from_oid(const struct oid *o) { @@ -332,7 +332,6 @@ print_bgp_record(const struct bgp_proto *bgp_proto) DBG(" incoming_conn state: %u", bgp_proto->incoming_conn.state + 1); } - static inline enum snmp_search_res populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto, const struct bgp_conn **conn, const struct bgp_stats **stats, const struct bgp_config **config) @@ -341,23 +340,16 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto if (snmp_bgp_valid_ip4(oid) && LOAD_U8(oid->n_subid) == 9) *addr = ip4_from_oid(oid); else - { - snmp_log("populate() invalid ip4"); return SNMP_SEARCH_NO_INSTANCE; - } struct snmp_bgp_peer *pe = snmp_hash_find(c->p, *addr); if (!pe) - { - snmp_log("populate() hash find failed"); return SNMP_SEARCH_NO_INSTANCE; - } const struct bgp_proto *bgp_proto; *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; return SNMP_SEARCH_NO_INSTANCE; } @@ -366,8 +358,6 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto 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 " - "(%I, %I).", bgp_proto->p.name, proto_ip, pe->peer_ip); c->error = AGENTX_RES_GEN_ERROR; return SNMP_SEARCH_NO_INSTANCE; } @@ -376,11 +366,9 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto *stats = &bgp_proto->stats; *config = bgp_proto->cf; - snmp_log("populate() ok"); return SNMP_SEARCH_OK; } - /* * * MIB tree fill hooks @@ -390,7 +378,6 @@ populate_bgp4(struct snmp_pdu *c, ip4_addr *addr, const struct bgp_proto **proto static enum snmp_search_res fill_bgp_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill ver"); if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3) return SNMP_SEARCH_NO_INSTANCE; c->size -= snmp_str_size_from_len(1); @@ -401,7 +388,6 @@ fill_bgp_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_local_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill as"); if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3) return SNMP_SEARCH_NO_INSTANCE; snmp_varbind_int(c, c->p->bgp_local_as); @@ -411,7 +397,6 @@ fill_local_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_peer_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill peer id"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -431,7 +416,6 @@ fill_peer_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_peer_state(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill peer state"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -447,7 +431,6 @@ fill_peer_state(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_admin_status(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill adm status"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -464,7 +447,6 @@ fill_admin_status(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_neg_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill neg ver"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -483,13 +465,10 @@ fill_neg_version(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_local_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("bgp4_mib fill local addr"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); - snmp_log("fill local addr result %u", res); - if (res != SNMP_SEARCH_OK) return res; @@ -500,7 +479,6 @@ fill_local_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_local_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("bgp4_mib fill local port"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -514,7 +492,6 @@ fill_local_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_remote_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("bgp4_mib fill remote addr"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -528,7 +505,6 @@ fill_remote_addr(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_remote_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("bgp4_mib fill remote port"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -542,7 +518,6 @@ fill_remote_port(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_remote_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill rem as"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -556,7 +531,6 @@ fill_remote_as(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_in_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill in updates"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -570,7 +544,6 @@ fill_in_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_out_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill out updates"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -584,7 +557,6 @@ fill_out_updates(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_in_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill in total"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -598,7 +570,6 @@ fill_in_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_out_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill out total"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -612,7 +583,6 @@ fill_out_total_msg(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_last_err(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill last err"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -629,7 +599,6 @@ fill_last_err(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_established_trans(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill est trans"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -644,14 +613,12 @@ fill_established_trans(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_established_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill est time"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); if (res != SNMP_SEARCH_OK) return res; - snmp_varbind_gauge32(c, (current_time() - bgp_proto->last_established) TO_S); return SNMP_SEARCH_OK; @@ -660,7 +627,6 @@ fill_established_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_retry_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill retry int"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -674,7 +640,6 @@ fill_retry_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_hold_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill hold time"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -688,7 +653,6 @@ fill_hold_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_keep_alive(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill keepalive"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -706,7 +670,6 @@ fill_keep_alive(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_hold_time_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill hold time c"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -720,14 +683,12 @@ fill_hold_time_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_keep_alive_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill keepalive c"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); if (res != SNMP_SEARCH_OK) return res; - if (!bgp_conf->keepalive_time) snmp_varbind_int(c, 0); else @@ -739,7 +700,6 @@ fill_keep_alive_conf(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_min_as_org_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill min org int"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -754,7 +714,6 @@ fill_min_as_org_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_route_adv_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill rt adv int"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -769,7 +728,6 @@ fill_route_adv_interval(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) static enum snmp_search_res fill_in_update_elapsed_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fil in elapsed"); enum snmp_search_res res; DECLARE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); res = POPULATE_BGP4(addr, bgp_proto, bgp_conn, bgp_stats, bgp_conf); @@ -785,7 +743,6 @@ fill_in_update_elapsed_time(struct mib_walk_state *walk UNUSED, struct snmp_pdu static enum snmp_search_res fill_local_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) { - snmp_log("fill local id"); if (LOAD_U8(c->sr_vb_start->name.n_subid) != 3) return SNMP_SEARCH_NO_INSTANCE; snmp_varbind_ip4(c, c->p->bgp_local_id); @@ -797,7 +754,7 @@ fill_local_id(struct mib_walk_state *walk UNUSED, struct snmp_pdu *c) * @state: MIB tree walk state * @c: SNMP PDU context data * - * Update TX-buffer VarBind name to next peer address. + * Update TX buffer VarBind name to next peer address. */ static int bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c) @@ -831,7 +788,6 @@ bgp4_next_peer(struct mib_walk_state *state, struct snmp_pdu *c) STORE_U8(oid->include, 1); } - ASSUME(oid->n_subid == 9); /* Stack has one more node for empty prefix (tree root) */ ASSUME(state->stack_pos > 10); @@ -903,10 +859,6 @@ snmp_bgp4_start(struct snmp_proto *p) { agentx_available_mibs[BGP4_MIB_ID] = (struct oid *) &bgp4_mib_oid; - snmp_log("snmp_bgp4_start setting bgp4_mib oid %u %p %p %p", - BGP4_MIB_ID, &agentx_available_mibs[BGP4_MIB_ID], agentx_available_mibs[BGP4_MIB_ID], &bgp4_mib_oid); - - struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf); /* Create binding to BGP protocols */ diff --git a/proto/snmp/config.Y b/proto/snmp/config.Y index 3610bdce..a9b25d2e 100644 --- a/proto/snmp/config.Y +++ b/proto/snmp/config.Y @@ -49,9 +49,6 @@ snmp_proto_item: if (SNMP_CFG->trans_type != SNMP_TRANS_DEFAULT) cf_error("Duplicit option remote address"); - // TODO - //if (ip4_zero($3)) cf_error("Invalid remote ip address"); - SNMP_CFG->remote_ip = $3; SNMP_CFG->trans_type = SNMP_TRANS_TCP; } @@ -78,9 +75,11 @@ snmp_proto_item: } | MESSAGE TIMEOUT expr_us { /* TODO */ - if ($3 TO_S > 255) log(L_WARN, "%s: msg", this_proto->name); - if ($3 TO_S < 1) log(L_WARN, "%s: msg", this_proto->name); - if (($3 TO_S) - (int)($3 TO_S) > 0) log(L_WARN, "%s: ", this_proto->name); + if ($3 TO_S > 255 || $3 TO_S < 1) + log(L_WARN "resolution of AgentX message timeout is from 1 to 255 s."); + if (($3 TO_S) - (int)($3 TO_S) > 0) + log(L_WARN "AgentX message timeout cannot use second fraction, " + "will use rounded up value."); SNMP_CFG->timeout = $3; } /* diff --git a/proto/snmp/mib_tree.c b/proto/snmp/mib_tree.c index d5dae363..af0b7c09 100644 --- a/proto/snmp/mib_tree.c +++ b/proto/snmp/mib_tree.c @@ -794,10 +794,7 @@ mib_tree_walk_next_leaf(const struct mib_tree *t, struct mib_walk_state *walk, u (void)t; if (walk->stack_pos == 0) - { - snmp_log("walk next leaf no leafs"); return NULL; - } u32 next_id = skip; mib_node_u *node = walk->stack[walk->stack_pos - 1]; @@ -812,7 +809,6 @@ mib_tree_walk_next_leaf(const struct mib_tree *t, struct mib_walk_state *walk, u { /* walk->stack_pos == 1, so we NULL out the last stack field */ walk->stack[--walk->stack_pos] = NULL; - snmp_log("walk next leaf single leaf"); return NULL; } @@ -822,10 +818,7 @@ continue_while: node = walk->stack[walk->stack_pos - 1]; if (mib_node_is_leaf(node)) - { - snmp_log("walk next leaf %p at level %u", node, walk->stack_pos - 1); return (struct mib_leaf *) node; - } struct mib_node *node_inner = &node->inner; for (u32 id = next_id; id < node_inner->child_len; id++) @@ -845,7 +838,6 @@ continue_while: walk->stack[--walk->stack_pos] = NULL; } - snmp_log("walk next leaf no more leafs"); return NULL; } diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index 889e486d..2200cca2 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -49,7 +49,7 @@ * | SNMP_INIT | entry state after call snmp_start() * +-----------------+ * | - * | acquiring object lock for communication socket + * | acquiring object lock for tcp communication socket * V * +-----------------+ * | SNMP_LOCKED | object lock aquired @@ -61,48 +61,37 @@ * | SNMP_OPEN | socket created, starting subagent * +-----------------+ * | - * | BIRD receive response for Open-PDU + * | BIRD receive response for agentx-Open-PDU * V * +-----------------+ * | SNMP_REGISTER | session was established, subagent registers MIBs * +-----------------+ * | - * | subagent received responses for all registration requests + * | subagent received response for any registration requests * V * +-----------------+ * | SNMP_CONN | everything is set * +-----------------+ * | - * | function snmp_shutdown() is called, BIRD sends Close-PDU + * | received malformed PDU, protocol disabled, + * | BIRD sends agentx-Close-PDU or agentx-Response-PDU with an error * V * +-----------------+ - * | SNMP_STOP | waiting for response + * | SNMP_STOP | waiting until the prepared PDUs are sent * +-----------------+ * | - * | cleaning old state information + * | cleaning protocol state * V * +-----------------+ * | SNMP_DOWN | session is closed * +-----------------+ * * - * +-----------------+ - * | SNMP_RESET | waiting to transmit response to malformed packet - * +-----------------+ - * | - * | response was send, reseting the session (with socket) - * | - * \--> SNMP_LOCKED - * * * Erroneous transitions: - * SNMP is UP in states SNMP_CONN and also in SNMP_REGISTER because the - * session is establised and the GetNext request should be responsed - * without regard to MIB registration. - * - * When the session has been closed for some reason (socket error, receipt of - * Close-PDU) SNMP cleans the session information and message queue and goes - * back to the SNMP_LOCKED state. + * SNMP is UP (PS_UP) in states SNMP_CONN and also in SNMP_REGISTER because + * the session is establised and the GetNext request should be responsed + * without regards to MIB registration. * * Reconfiguration is done in similar fashion to BGP, the reconfiguration * request is declined, the protocols is stoped and started with new @@ -122,9 +111,6 @@ #include "mib_tree.h" #include "bgp4_mib.h" -// TODO: remove me -#include "proto/bgp/bgp.h" - const char agentx_master_addr[] = AGENTX_MASTER_ADDR; const struct oid *agentx_available_mibs[AGENTX_MIB_COUNT + 1] = { 0 }; @@ -133,6 +119,16 @@ static void snmp_sock_err(sock *sk, int err); static void snmp_stop_timeout(timer *tm); static void snmp_cleanup(struct snmp_proto *p); +static const char *snmp_state_str[] = { + [SNMP_INIT] = "acquiring address lock", + [SNMP_LOCKED] = "address lock acquired", + [SNMP_OPEN] = "starting AgentX subagent", + [SNMP_REGISTER] = "registering MIBs", + [SNMP_CONN] = "AgentX session established", + [SNMP_STOP] = "stopping AgentX subagent", + [SNMP_DOWN] = "protocol down", +}; + /* * agentx_get_mib_init - init function for agentx_get_mib() * @p: SNMP instance protocol pool @@ -154,6 +150,7 @@ void agentx_get_mib_init(pool *p) /* * agentx_get_mib - classify an OID based on MIB prefix + * @o: Object Identifier to classify */ enum agentx_mibs agentx_get_mib(const struct oid *o) { @@ -185,29 +182,28 @@ snmp_rx_skip(sock UNUSED *sk, uint UNUSED size) } /* - * snmp_tx_skip - handle empty TX-buffer during session reset + * snmp_tx_skip - handle empty TX buffer during session reset * @sk: communication socket * - * The socket tx_hook is called when the TX-buffer is empty, i.e. all data was + * The socket tx_hook is called when the TX buffer is empty, i.e. all data was * send. This function is used only when we found malformed PDU and we are - * resetting the established session. If called, we are reseting the session. + * resetting the established session. If called, we perform a SNMP protocol + * state change. */ static void snmp_tx_skip(sock *sk) { struct snmp_proto *p = sk->data; - proto_notify_state(&p->p, snmp_set_state(p, SNMP_DOWN)); + proto_notify_state(&p->p, snmp_set_state(p, SNMP_STOP)); } /* * snmp_set_state - change state with associated actions - * @p - SNMP protocol instance - * @state - new SNMP protocol state + * @p: SNMP protocol instance + * @state: new SNMP protocol state * - * This function does not notify the bird about protocol state. It is therefore - * a responsibility of the caller to use the returned value appropriately. - * - * Return current protocol state. + * This function does not notify the bird about protocol state. Return current + * protocol state (PS_UP, ...). */ int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) @@ -215,14 +211,12 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) enum snmp_proto_state last = p->state; const struct snmp_config *cf = (struct snmp_config *) p->p.cf; - TRACE(D_EVENTS, "SNMP changing state to %u", state); - p->state = state; switch (state) { case SNMP_INIT: - DBG("snmp -> SNMP_INIT\n"); + TRACE(D_EVENTS, "TODO"); ASSERT(last == SNMP_DOWN); if (cf->trans_type == SNMP_TRANS_TCP) @@ -230,11 +224,6 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) /* We need to lock the IP address */ struct object_lock *lock; lock = p->lock = olock_new(p->pool); - - /* - * lock->iface - * lock->vrf - */ lock->addr = p->remote_ip; lock->port = p->remote_port; lock->type = OBJLOCK_TCP; @@ -244,18 +233,19 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) return PS_START; } + last = SNMP_INIT; p->state = state = SNMP_LOCKED; /* Fall thru */ case SNMP_LOCKED: - DBG("snmp -> SNMP_LOCKED\n"); - ASSERT(last == SNMP_INIT || SNMP_RESET); + TRACE(D_EVENTS, "snmp %s: address lock acquired", p->p.name); + ASSERT(last == SNMP_INIT); sock *s = sk_new(p->pool); if (cf->trans_type == SNMP_TRANS_TCP) { s->type = SK_TCP_ACTIVE; - s->saddr = ipa_from_ip4(p->local_ip); + //s->saddr = ipa_from_ip4(p->local_ip); s->daddr = p->remote_ip; s->dport = p->remote_port; s->rbsize = SNMP_RX_BUFFER_SIZE; @@ -279,65 +269,69 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) /* Try opening the socket, schedule a retry on fail */ if (sk_open(s) < 0) { + TRACE(D_EVENTS, "opening of communication socket failed"); rfree(s); p->sock = NULL; + // TODO handle 0 timeout tm_start(p->startup_timer, p->timeout); } return PS_START; case SNMP_OPEN: - DBG("snmp -> SNMP_OPEN\n"); + TRACE(D_EVENTS, "communication socket opened, starting AgentX subagent"); ASSERT(last == SNMP_LOCKED); + p->sock->rx_hook = snmp_rx; p->sock->tx_hook = NULL; + snmp_start_subagent(p); + p->startup_timer->hook = snmp_stop_timeout; tm_start(p->startup_timer, 1 S); + return PS_START; case SNMP_REGISTER: - DBG("snmp -> SNMP_REGISTER\n"); + TRACE(D_EVENTS, "registering MIBs"); ASSERT(last == SNMP_OPEN); + tm_stop(p->startup_timer); /* stop timeout */ + + p->sock->rx_hook = snmp_rx; + p->sock->tx_hook = snmp_tx; + snmp_register_mibs(p); return PS_START; case SNMP_CONN: - DBG("snmp -> SNMP_CONN\n"); + TRACE(D_EVENTS, "MIBs registered"); ASSERT(last == SNMP_REGISTER); return PS_UP; case SNMP_STOP: - DBG("snmp -> SNMP_STOP\n"); - ASSUME(last == SNMP_REGISTER || last == SNMP_CONN); - snmp_stop_subagent(p); - // FIXME: special treatment for SNMP_OPEN last state? - p->sock->rx_hook = snmp_rx_skip; - p->sock->tx_hook = snmp_tx_skip; + if (p->sock && p->state != SNMP_OPEN) + { + TRACE(D_EVENTS, "closing AgentX session"); + if (p->state == SNMP_OPEN || p->state == SNMP_REGISTER || + p->state == SNMP_CONN) + snmp_stop_subagent(p); - p->startup_timer->hook = snmp_stop_timeout; - tm_start(p->startup_timer, p->timeout); - return PS_STOP; + p->sock->rx_hook = snmp_rx_skip; + p->sock->tx_hook = snmp_tx_skip; + + p->startup_timer->hook = snmp_stop_timeout; + tm_start(p->startup_timer, 150 MS); + return PS_STOP; + } + + p->state = state = SNMP_DOWN; + /* Fall thru */ case SNMP_DOWN: - DBG("snmp -> SNMP_DOWN\n"); - ASSERT(last == SNMP_STOP || last == SNMP_RESET); + TRACE(D_EVENTS, "AgentX session closed"); snmp_cleanup(p); - // FIXME: handle the state in which we call proto_notify_state and - // immediately return PS_DOWN from snmp_shutdown() return PS_DOWN; - case SNMP_RESET: - // TODO remove SNMP_RESET state - DBG("snmp -> SNMP_RESET\n"); - ASSUME(last == SNMP_REGISTER || last == SNMP_CONN); - ASSUME(p->sock); - snmp_stop_subagent(p); - // FIXME: special treatment for SNMP_OPEN last state? - p->sock->rx_hook = snmp_rx_skip; - p->sock->tx_hook = snmp_tx_skip; - return PS_STOP; - default: die("unknown snmp state transition"); return PS_DOWN; @@ -346,7 +340,7 @@ snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state) /* * snmp_init - preinitialize SNMP instance - * @CF - SNMP configuration generic handle + * @CF: SNMP configuration generic handle * * Returns a generic handle pointing to preinitialized SNMP procotol * instance. @@ -358,7 +352,6 @@ snmp_init(struct proto_config *CF) struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P); p->rl_gen = (struct tbf) TBF_DEFAULT_LOG_LIMITS; - p->state = SNMP_DOWN; return P; @@ -366,12 +359,10 @@ snmp_init(struct proto_config *CF) /* * snmp_cleanup - free all resources allocated by SNMP protocol - * @p - SNMP protocol instance + * @p: SNMP protocol instance * * This function forcefully stops and cleans all resources and memory acqiured * by given SNMP protocol instance, such as timers, lists, hash tables etc. - * Function snmp_cleanup() does not change the protocol state to PS_DOWN for - * practical reasons, it should be done by the caller. */ static inline void snmp_cleanup(struct snmp_proto *p) @@ -407,7 +398,7 @@ snmp_cleanup(struct snmp_proto *p) /* * snmp_connected - start AgentX session on created socket - * @sk - socket owned by SNMP protocol instance + * @sk: socket owned by SNMP protocol instance * * Starts the AgentX communication by sending an agentx-Open-PDU. * This function is internal and shouldn't be used outside the SNMP module. @@ -426,47 +417,35 @@ snmp_connected(sock *sk) * We wait until the last PDU written into the socket is send while ignoring all * incomming PDUs. Then we hard reset the connection by socket closure. The * protocol instance is automatically restarted by nest. + * + * Return protocol state (PS_STOP, ...). */ -void +int snmp_reset(struct snmp_proto *p) { - proto_notify_state(&p->p, snmp_set_state(p, SNMP_RESET)); -} - - -/* - * snmp_stop - close AgentX session - * @p: SNMP protocol instance - * - * We write agentx-Close-PDU into the socket, wait until all written PDUs are - * send and then close the socket. The protocol instance is automatically - * restarted by nest. - */ -void -snmp_stop(struct snmp_proto *p) -{ - // TODO: add option for passing close reason for agentx-Close-PDU - proto_notify_state(&p->p, snmp_set_state(p, SNMP_STOP)); + int proto_state = snmp_set_state(p, SNMP_STOP); + proto_notify_state(&p->p, proto_state); + return proto_state; } /* * snmp_sock_err - handle errors on socket by reopenning the socket - * @sk - socket owned by SNMP protocol instance - * @err - socket error errno + * @sk: socket owned by SNMP protocol instance + * @err: socket error code */ static void snmp_sock_err(sock *sk, int UNUSED err) { struct snmp_proto *p = sk->data; - - TRACE(D_EVENTS, "SNMP socket error %d", err); - snmp_reset(p); + if (err != 0) + TRACE(D_EVENTS, "SNMP socket error (%d)", err); + snmp_set_state(p, SNMP_DOWN); } /* * snmp_start_locked - open the socket on locked address - * @lock - object lock guarding the communication mean (address, ...) + * @lock: object lock guarding the communication mean (address, ...) * * This function is called when the object lock is acquired. Main goal is to set * socket parameters and try to open configured socket. Function @@ -487,29 +466,14 @@ snmp_start_locked(struct object_lock *lock) snmp_set_state(p, SNMP_LOCKED); } -/* - * snmp_reconnect - helper restarting the AgentX session on packet errors - * @tm - the startup_timer holding the SNMP protocol instance - * - * Try to recover from an error by reseting the SNMP protocol. It is a simple - * snmp_reset() wrapper for timers. - */ -void -snmp_reconnect(timer *tm) -{ - struct snmp_proto *p = tm->data; - snmp_reset(p); - return; -} - /* * snmp_startup_timeout - start the initiliazed SNMP protocol - * @tm - the startup_timer holding the SNMP protocol instance. + * @tm: the startup_timer holding the SNMP protocol instance. * * When the timer rings, the function snmp_startup() is invoked. * This function is internal and shouldn't be used outside the SNMP module. - * Used when we delaying the start procedure, or we want to resend - * an agentx-Open-PDU for non-responding master agent. + * Used when we delaying the start procedure, or we want to retry opening + * the communication socket. */ void snmp_startup_timeout(timer *tm) @@ -519,13 +483,13 @@ snmp_startup_timeout(timer *tm) } /* - * snmp_stop_timeout - a timeout for nonresponding master agent - * @tm - the startup_timer holding the SNMP protocol instance. + * snmp_stop_timeout - a timeout for non-responding master agent + * @tm: the startup_timer holding the SNMP protocol instance. * - * We are shutting down the SNMP protocol instance and we sent the - * agentx-Close-PDU. This function forcefully closes the AgentX session and - * stops the SNMP protocol instance. Used only when we did not receive any - * agentx-Response-PDU for the sent closed packet (before timeout). + * We are trying to empty the TX buffer of communication socket. But if it is + * not done in reasonable amount of time, the function is called by timeout + * timer. We down the whole SNMP protocol with cleanup of associated data + * structures. */ static void snmp_stop_timeout(timer *tm) @@ -536,7 +500,7 @@ snmp_stop_timeout(timer *tm) /* * snmp_ping_timeout - send a agentx-Ping-PDU - * @tm - the ping_timer holding the SNMP protocol instance. + * @tm: the ping_timer holding the SNMP protocol instance. * * Send an agentx-Ping-PDU. This function is periodically called by ping * timer. @@ -550,11 +514,11 @@ snmp_ping_timeout(timer *tm) /* * snmp_start - Initialize the SNMP protocol instance - * @P - SNMP protocol generic handle + * @P: SNMP protocol generic handle * * The first step in AgentX subagent startup is protocol initialition. - * We must prepare lists, find BGP peers and finally asynchronously open - * a AgentX subagent session through snmp_startup() function call. + * We must prepare lists, find BGP peers and finally asynchronously start + * a AgentX subagent session. */ static int snmp_start(struct proto *P) @@ -605,7 +569,7 @@ snmp_reconfigure_logic(struct snmp_proto *p, const struct snmp_config *new) { WALK_LIST(b2, old->bgp_entries) { - if (!strcmp(b1->config->name, b2->config->name)) + if (!bstrcmp(b1->config->name, b2->config->name)) goto skip; } @@ -617,10 +581,29 @@ skip: if (bonds != 0) return 0; + if (old->trans_type != new->trans_type + || ip4_compare(old->local_ip, new->local_ip) + || old->local_port != new->local_port + || ipa_compare(old->remote_ip, new->remote_ip) + || !bstrcmp(old->remote_path, new->remote_path) + || old->remote_port != new->remote_port + // TODO can be changed on the fly + || !ip4_compare(old->bgp_local_id, new->bgp_local_id) + || old->bgp_local_as != new->bgp_local_as // TODO can be changed on the fly + || old->timeout != new->timeout + //|| old->startup_delay != new->startup_delay + || old->priority != new->priority + || !strncmp(old->description, new->description, UINT32_MAX)) + return 0; + + return 1; + +/* return !memcmp(((byte *) old) + sizeof(struct proto_config), ((byte *) new) + sizeof(struct proto_config), OFFSETOF(struct snmp_config, description) - sizeof(struct proto_config)) && ! strncmp(old->description, new->description, UINT32_MAX); +*/ } /* @@ -638,6 +621,8 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF) struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P); const struct snmp_config *new = SKIP_BACK(struct snmp_config, cf, CF); + // TODO do not reject reconfiguration when only BGP peer list changed + /* We are searching for configuration changes */ int config_changed = snmp_reconfigure_logic(p, new); @@ -660,7 +645,7 @@ snmp_show_proto_info(struct proto *P) { struct snmp_proto *p = (void *) P; - cli_msg(-1006, " SNMP state %u", p->state); + cli_msg(-1006, " SNMP state: %s", snmp_state_str[p->state]); cli_msg(-1006, " MIBs"); snmp_bgp4_show_info(p); @@ -682,19 +667,16 @@ snmp_postconfig(struct proto_config *CF) /* * snmp_shutdown - Forcefully stop the SNMP protocol instance - * @P - SNMP protocol generic handle + * @P: SNMP protocol generic handle * - * If we have established connection, we firstly stop the subagent and then - * later cleanup the protocol. The subagent stopping consist of sending the - * agentx-Close-PDU and changing the current protocol state to PS_STOP. - * If we have no connection created, we simple do the cleanup. - * The cleanup is transition straight to PS_DOWN state with snmp_cleanup() call. + * Simple cast-like wrapper around snmp_reset(), see more info there. */ static int snmp_shutdown(struct proto *P) { struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P); return snmp_set_state(p, SNMP_DOWN); + return snmp_reset(p); } diff --git a/proto/snmp/snmp.h b/proto/snmp/snmp.h index 23b74d3b..b8c057d2 100644 --- a/proto/snmp/snmp.h +++ b/proto/snmp/snmp.h @@ -10,12 +10,12 @@ #ifndef _BIRD_SNMP_H_ #define _BIRD_SNMP_H_ -#include "lib/ip.h" -#include "lib/socket.h" -#include "lib/resource.h" -#include "lib/timer.h" #include "nest/bird.h" #include "nest/protocol.h" +#include "lib/resource.h" +#include "lib/ip.h" +#include "lib/socket.h" +#include "lib/timer.h" #include "filter/data.h" #define SNMP_UNDEFINED 0 @@ -39,7 +39,6 @@ enum snmp_proto_state { SNMP_REGISTER, SNMP_CONN, SNMP_STOP, - SNMP_RESET, }; struct snmp_bond { @@ -69,7 +68,6 @@ struct snmp_config { btime timeout; btime startup_delay; u8 priority; - //struct iface *iface; TODO u32 bonds; const char *description; /* The order of fields is not arbitrary */ list bgp_entries; /* We want dynamically allocated fields to be @@ -170,9 +168,16 @@ void snmp_startup_timeout(timer *tm); void snmp_reconnect(timer *tm); int snmp_set_state(struct snmp_proto *p, enum snmp_proto_state state); -void snmp_reset(struct snmp_proto *p); -void snmp_stop(struct snmp_proto *p); +int snmp_reset(struct snmp_proto *p); extern const char agentx_master_addr[sizeof(AGENTX_MASTER_ADDR)]; +static inline int +proto_is_snmp(const struct proto *P) +{ + extern struct protocol proto_snmp; + return P->proto == &proto_snmp; +} + + #endif diff --git a/proto/snmp/snmp_utils.c b/proto/snmp/snmp_utils.c index bd4263fa..bb4bb811 100644 --- a/proto/snmp/snmp_utils.c +++ b/proto/snmp/snmp_utils.c @@ -66,10 +66,7 @@ snmp_varbind_set_name_len(struct snmp_pdu *c, struct agentx_varbind **vb, u8 len uint diff_size = (len - LOAD_U8(oid->n_subid)) * sizeof(u32); if (snmp_tbuf_reserve(c, diff_size)) - { - snmp_log("varbind_set_name_len small buffer"); oid = &(*vb)->name; - } ASSERT(c->size >= diff_size); c->size -= diff_size; @@ -82,8 +79,7 @@ snmp_varbind_duplicate_hdr(struct snmp_pdu *c, struct agentx_varbind **vb) { ASSUME(vb != NULL && *vb != NULL); uint hdr_size = snmp_varbind_header_size(*vb); - if (snmp_tbuf_reserve(c, hdr_size)) - snmp_log("varbind_duplicate small buffer"); + (void) snmp_tbuf_reserve(c, hdr_size); ASSERT(c->size >= hdr_size); byte *buffer = c->buffer; @@ -175,6 +171,23 @@ snmp_oid_copy2(struct oid *dest, const struct oid *src) memcpy(dest->ids, src->ids, LOAD_U8(src->n_subid) * sizeof(u32)); } +/* + * snmp_oid_from_buf - copy OID from RX buffer to dest in native byte order + * @dst: destination to use + * @src: OID to be copied from + */ +void +snmp_oid_from_buf(struct oid *dst, const struct oid *src) +{ + dst->n_subid = LOAD_U8(src->n_subid); + dst->prefix = LOAD_U8(src->prefix); + dst->include = LOAD_U8(src->include) ? 1 : 0; + dst->reserved = 0; + + for (uint i = 0; i < dst->n_subid; i++) + dst->ids[i] = LOAD_U32(src->ids[i]); +} + /* * snmp_oid_duplicate - duplicate an OID from memory pool * @pool: pool to use @@ -256,7 +269,7 @@ snmp_varbind_hdr_size_from_oid(const struct oid *oid) /* * snmp_set_varbind_type - set VarBind's type field - * @vb: Varbind inside TX-buffer + * @vb: Varbind inside TX buffer * @t: a valid type to be set * * This function assumes valid @t. @@ -304,10 +317,10 @@ snmp_load_varbind_type(const struct agentx_varbind *vb) /* * snmp_get_varbind_type - loads a VarBind type - * @vb: VarBind pointer to TX-buffer + * @vb: VarBind pointer to TX buffer * * This function assumes VarBind with valid type, always call snmp_test_varbind - * for in TX-buffer VarBinds! + * for in TX buffer VarBinds. */ inline enum agentx_type snmp_get_varbind_type(const struct agentx_varbind *vb) @@ -742,7 +755,6 @@ snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib) r->packet_id = p->packet_id + 1; r->mib = mib; - snmp_log("using registration packet_id %u", r->packet_id); add_tail(&p->registration_queue, &r->n); return r; @@ -751,7 +763,6 @@ snmp_registration_create(struct snmp_proto *p, enum agentx_mibs mib) int snmp_registration_match(struct snmp_registration *r, struct agentx_header *h, enum agentx_mibs mib) { - snmp_log("snmp_reg_same() r->packet_id %u p->packet_id %u", r->packet_id, h->packet_id); return (r->mib == mib) && (r->session_id == h->session_id) && @@ -864,7 +875,7 @@ snmp_varbind_nstr2(struct snmp_pdu *c, uint size, const char *str, uint len) * @len: length of the string @str * * Beware: this function assumes there is enough space in the underlaying - * TX-buffer. The caller has to provide that, see snmp_str_size_from_len() for + * TX buffer. The caller has to provide that, see snmp_str_size_from_len() for * more info. */ void @@ -951,7 +962,7 @@ snmp_oid_log(const struct oid *oid) for (int id = 0; id < oid->n_subid; id++) pos += snprintf(pos, buf + 1024 - pos, ".%u", oid->ids[id]); - snmp_log("%s", buf); + log(L_WARN, "%s", buf); } @@ -1096,10 +1107,7 @@ snmp_walk_next(struct mib_tree *tree, struct mib_walk_state *walk, struct snmp_p int old = snmp_oid_size(&c->sr_vb_start->name); if (mib_tree_walk_to_oid(walk, &c->sr_vb_start->name, 20 * sizeof(u32))) - { - snmp_log("walk_next copy failed"); return NULL; - } int new = snmp_oid_size(&c->sr_vb_start->name); c->buffer += (new - old); @@ -1122,10 +1130,7 @@ snmp_walk_next(struct mib_tree *tree, struct mib_walk_state *walk, struct snmp_p int old = snmp_oid_size(&c->sr_vb_start->name); // TODO autogrow if (mib_tree_walk_to_oid(walk, &c->sr_vb_start->name, 20 * sizeof(u32))) - { - snmp_log("walk_next copy failed"); return NULL; - } int new = snmp_oid_size(&c->sr_vb_start->name); c->buffer += (new - old); @@ -1172,10 +1177,7 @@ snmp_walk_fill(struct mib_leaf *leaf, struct mib_walk_state *walk, struct snmp_p size = leaf->size; } - snmp_log("walk_fill got size %u based on lt %u ls %u, calling filler()", size, leaf->type, leaf->size); - - if (snmp_tbuf_reserve(c, size)) - snmp_log("walk_fill small buffer size"); + (void) snmp_tbuf_reserve(c, size); enum snmp_search_res res = leaf->filler(walk, c); diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 470c283a..af768a9d 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -15,38 +15,19 @@ #include "bgp4_mib.h" /* - * Goals: - * In current situation, we do not handle the dynamic BGP case. - */ - -/** - * * Handling of malformed packet: * * When we find an error in PDU data, we create and send a response with error * defined by the RFC. We await until the packet is send and then we close the - * communication socket. This implicitly closes the established session. We - * chose this approach because we cannot easily mark the boundary between packets. - * When we are reseting the connection, we change the snmp_state to SNMP_RESET. - * In SNMP_RESET state we skip all received bytes and wait for snmp_tx_skip() - * to be called. The socket's tx_hook is called when the TX-buffer is empty, - * meaning our response (agentx-Response-PDU) was send. + * communication socket ignoring any possible response. This implicitly closes + * the established session. We chose this approach because we cannot easily + * mark the boundary between packets. * * * Partial parsing: * * It may happen that we received only staring part of some PDU from the - * communication socket. In most cases, if we recognize this situation we - * immediately return, waiting for rest of the PDU to arrive. But for packets - * like agentx-Get-PDU, agentx-GetNext-PDU and agentx-GetBulk-PDU it could be - * costly as they could hold many VarBinds. We don't want to process these - * packet twice because it is a lot work. We parse all VarBinds until we hit the - * first incomplete one. The logic behind this is to release as much as - * possible space from receive buffer. When we hit the first incomplete VarBind, - * we store information about the parsing state and move the header inside the - * receive buffer. - * - * Transmit packet context + * communication socket. In most cases, if we recognize this situation, we * */ @@ -61,13 +42,13 @@ static uint update_packet_size(struct agentx_header *start, byte *end); const u32 snmp_internet[] = { SNMP_ISO, SNMP_ORG, SNMP_DOD, SNMP_INTERNET }; /* - * snmp_header - store packet information into buffer - * @h: pointer to created packet header in TX-buffer + * snmp_header - store packet header into buffer + * @h: pointer to created packet header in TX buffer * @type: created PDU type * @flags: set flags * * Payload length is set to zero legth. Padding is also zeroed. Real stored - * flags are dependent on compile-time message byte-order configuration. + * flags depend on compile-time message byte order configuration. */ static inline void snmp_header(struct agentx_header *h, enum agentx_pdu_types type, u8 flags) @@ -81,7 +62,7 @@ snmp_header(struct agentx_header *h, enum agentx_pdu_types type, u8 flags) /* * snmp_blank_header - create header with no flags except byte order - * @h: pointer to created header in TX-buffer + * @h: pointer to created header in TX buffer * @type: create PDU type * * Only flag possibly set may be packet byte order configuration. @@ -96,7 +77,7 @@ snmp_blank_header(struct agentx_header *h, enum agentx_pdu_types type) * snmp_register_ack - handle registration response * @p: SNMP protocol instance * @res: header of agentx-Response-PDU - * @mib: MIB subtree identifier + * @oid: MIB subtree Object Identifier */ void snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, const struct oid *oid) @@ -129,8 +110,8 @@ snmp_register_ack(struct snmp_proto *p, struct agentx_response *res, const struc * @error: response PDU error fields value * @index: response PDU error index field value * - * This function assumes that the buffer has enough space to fill in the AgentX - * Response PDU. So it is the responsibility of the caller to provide that. + * This function assumes that the buffer has enough space to fill + * in the agentx-Response-PDU. */ static void snmp_simple_response(struct snmp_proto *p, enum agentx_response_errs error, u16 index) @@ -151,8 +132,8 @@ snmp_simple_response(struct snmp_proto *p, enum agentx_response_errs error, u16 * @p: SNMP protocol instance * @oid: PDU OID description field value * - * Other fields are filled based on @p configuration (timeout, subagent string - * description) + * Other fields are filled based on @p configuration (timeout, subagent + * description). */ static void open_pdu(struct snmp_proto *p, struct oid *oid) @@ -165,11 +146,11 @@ open_pdu(struct snmp_proto *p, struct oid *oid) #define TIMEOUT_SIZE sizeof(u32) /* 1B timeout, 3B zero padding */ - /* Make sure that we have enough space in TX-buffer */ + /* Make sure that we have enough space in TX buffer */ uint s = AGENTX_HEADER_SIZE + TIMEOUT_SIZE + snmp_oid_size(oid) + snmp_str_size(cf->description); - if (snmp_tbuf_reserve(&c, s)) - snmp_log("agentx-Open-PDU small buffer"); + + (void) snmp_tbuf_reserve(&c, s); struct agentx_header *h = (void *) c.buffer; ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); @@ -204,12 +185,15 @@ open_pdu(struct snmp_proto *p, struct oid *oid) * @p: SNMP protocol instance * @oid: PDU notification Varbind name (OID) * @data: PDU Varbind payload - * @size - PDU Varbind payload size + * @size: PDU Varbind payload size * @include_uptime: flag enabling inclusion of sysUpTime.0 OID */ void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime) { + if (!snmp_is_active(p)) + return; + sock *sk = p->sock; struct snmp_pdu c; @@ -224,9 +208,8 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in if (include_uptime) sz += UPTIME_SIZE; - /* Make sure that we have enough space in TX-buffer */ - if (snmp_tbuf_reserve(&c, sz)) - snmp_log("agentx-Notify-PDU small buffer"); + /* Make sure that we have enough space in TX buffer */ + (void) snmp_tbuf_reserve(&c, sz); struct agentx_header *h = (struct agentx_header *) c.buffer; ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); @@ -292,24 +275,23 @@ snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, in * @index: OIDs registration n_subid index * @type: register/unregister PDU type * @is_instance: flag enabling instance registration (used only for register) - * @contid: context ID to register in (currently unsupported) * * Both register and unregister PDUs are capable of specifing a number of OIDs - * by using pair of index and upper bound. The index (r.range_subid) points into + * by using a pair of index and upper bound. The index (r.range_subid) points into * the OID's n_subid array to ID being threated as variable. The upper bound - * (r.upper_bound) determins maximal value for n_subid selected by index. - * The index and upper bound are passed as @index, and @bound respectively. + * (r.upper_bound) determins maximal value for n_subid selected by the index. + * The index and the upper bound are passed as @index, and @bound respectively. * * Zero value for @is_instance means we want to register/unregister OID as a MIB * subtree, for nonzero value we are registering MIB tree an instance (leaf). + * Full name of PDUs are agentx-Register-PDU and agentx-Unregister-PDU. * * This function in internal and shoulnd't be used outside the SNMP module, * see snmp_register() and snmp_unregister() functions. */ static void -un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, enum agentx_pdu_types type, u8 is_instance, uint UNUSED contid) +un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, enum agentx_pdu_types type, u8 is_instance) { - /* used for agentx-Register-PDU and agentx-Unregister-PDU */ const struct snmp_config *cf = SKIP_BACK(struct snmp_config, cf, p->p.cf); sock *sk = p->sock; struct snmp_pdu c; @@ -320,8 +302,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en uint sz = AGENTX_HEADER_SIZE + snmp_oid_size(oid) + ((bound > 1) ? BOUND_SIZE : 0); - if (snmp_tbuf_reserve(&c, sz)) - snmp_log("agentx-Register-PDU small buffer"); + (void) snmp_tbuf_reserve(&c, sz); struct agentx_header *h = (void *) c.buffer; ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); @@ -363,14 +344,13 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, en * @bound: OIDs registration upper bound * @index: OIDs registration n_subid index * @is_instance: flag enabling instance registration - * @contid: context ID to register in (currently unsupported) * * For more detailed description see un_register_pdu() function. */ void -snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 is_instance, uint contid) +snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 is_instance) { - un_register_pdu(p, oid, bound, index, AGENTX_REGISTER_PDU, is_instance, contid); + un_register_pdu(p, oid, bound, index, AGENTX_REGISTER_PDU, is_instance); } /* @@ -379,14 +359,13 @@ snmp_register(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, u8 i * @oid: OID to uregister * @bound: OIDs unregistration upper bound * @index: OIDs unregistration n_subid index - * @contid: context ID to unregister from (currently unsupported) * * For more detailed description see un_register_pdu() function. */ void -snmp_unregister(struct snmp_proto *p, struct oid *oid, u32 bound, uint index, uint contid) +snmp_unregister(struct snmp_proto *p, struct oid *oid, u32 bound, uint index) { - un_register_pdu(p, oid, bound, index, AGENTX_UNREGISTER_PDU, 0, contid); + un_register_pdu(p, oid, bound, index, AGENTX_UNREGISTER_PDU, 0); } /* @@ -402,8 +381,7 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason) snmp_pdu_context(&c, p, sk); #define REASON_SIZE sizeof(u32) - if (snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE + REASON_SIZE)) - snmp_log("agentx-Close-PDU small buffer"); + (void) snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE + REASON_SIZE); struct agentx_header *h = (void *) c.buffer; ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); @@ -424,7 +402,7 @@ close_pdu(struct snmp_proto *p, enum agentx_close_reasons reason) * @p: SNMP protocol instance * @pkt_start: pointer to first byte of PDU * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static uint parse_close_pdu(struct snmp_proto *p, byte * const pkt_start) @@ -440,22 +418,22 @@ parse_close_pdu(struct snmp_proto *p, byte * const pkt_start) { TRACE(D_PACKETS, "SNMP malformed agentx-Close-PDU, closing anyway"); snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0); - snmp_set_state(p, SNMP_RESET); - return MIN(pkt_size + AGENTX_HEADER_SIZE, sizeof(struct agentx_close_pdu)); + snmp_reset(p); + return 0; } if (!snmp_test_close_reason(pdu->reason)) { TRACE(D_PACKETS, "SNMP invalid close reason %u", pdu->reason); snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0); - snmp_set_state(p, SNMP_RESET); - return pkt_size + AGENTX_HEADER_SIZE; + snmp_reset(p); + return 0; } enum agentx_close_reasons reason = (enum agentx_close_reasons) pdu->reason; TRACE(D_PACKETS, "SNMP close reason %u", reason); snmp_simple_response(p, AGENTX_RES_NO_ERROR, 0); - snmp_set_state(p, SNMP_RESET); + snmp_reset(p); return pkt_size + AGENTX_HEADER_SIZE; } @@ -478,15 +456,15 @@ refresh_ids(struct snmp_proto *p, struct agentx_header *h) * @pkt_start: first byte of test set PDU * @size: number of bytes received from a socket * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static inline uint parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start) { TRACE(D_PACKETS, "SNMP received agentx-TestSet-PDU"); - byte *pkt = pkt_start; /* pointer to agentx-TestSet-PDU in RX-buffer */ + byte *pkt = pkt_start; /* pointer to agentx-TestSet-PDU in RX buffer */ uint s; /* final packat size */ - struct agentx_response *res; /* pointer to reponse in TX-buffer */ + struct agentx_response *res; /* pointer to reponse in TX buffer */ struct agentx_header *h = (void *) pkt; pkt += AGENTX_HEADER_SIZE; @@ -495,8 +473,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start) struct snmp_pdu c; snmp_pdu_context(&c, p, sk); - if (snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE)) - snmp_log("agentx-TestSet-PDU small buffer"); + (void) snmp_tbuf_reserve(&c, AGENTX_HEADER_SIZE); res = prepare_response(p, &c); @@ -534,7 +511,7 @@ parse_test_set_pdu(struct snmp_proto *p, byte * const pkt_start) * @pkt_start: pointer to first byte of on of set related PDU * @error: error status to use * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static uint parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_response_errs err) @@ -554,8 +531,7 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons struct snmp_pdu c; snmp_pdu_context(&c, p, p->sock); - if (snmp_tbuf_reserve(&c, sizeof(struct agentx_response))) - snmp_log("parse_sets_pdu small buffer"); + (void) snmp_tbuf_reserve(&c, sizeof(struct agentx_response)); struct agentx_response *r = prepare_response(p, &c); @@ -578,9 +554,9 @@ parse_sets_pdu(struct snmp_proto *p, byte * const pkt_start, enum agentx_respons /* * parse_commit_set_pdu - parse an agentx-CommitSet-PDU * @p: SNMP protocol instance - * @pkt: pointer to first byte of PDU inside RX-buffer + * @pkt: pointer to first byte of PDU inside RX buffer * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static inline uint parse_commit_set_pdu(struct snmp_proto *p, byte *pkt) @@ -594,7 +570,7 @@ parse_commit_set_pdu(struct snmp_proto *p, byte *pkt) /* * parse_undo_set_pdu - parse an agentx-UndoSet-PDU * @p: SNMP protocol instance - * @pkt: pointer to first byte of PDU inside RX-buffer + * @pkt: pointer to first byte of PDU inside RX buffer * * Return number of bytes parsed from buffer. */ @@ -610,9 +586,9 @@ parse_undo_set_pdu(struct snmp_proto *p, byte *pkt) /* * parse_cleanup_set_pdu - parse an agentx-CleanupSet-PDU * @p: SNMP protocol instance - * @pkt_start: pointer to first byte of PDU inside RX-buffer + * @pkt_start: pointer to first byte of PDU inside RX buffer * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static uint parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start) @@ -639,7 +615,7 @@ parse_cleanup_set_pdu(struct snmp_proto *p, byte * const pkt_start) } /* - * space_for_response - check if TX-buffer has space for agentx-Response-PDU + * space_for_response - check if TX buffer has space for agentx-Response-PDU * @sk: communication socket owned by SNMP protocol instance * * In some cases we send only the AgentX header but if we want to signal an @@ -657,10 +633,10 @@ space_for_response(const sock *sk) /** * parse_pkt - parse received AgentX packet * @p: SNMP protocol instance - * @pkt: first byte of PDU inside RX-buffer + * @pkt: first byte of PDU inside RX buffer * @size: number of bytes received from a socket * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static uint parse_pkt(struct snmp_proto *p, byte *pkt, uint size) @@ -685,7 +661,7 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size) TRACE(D_PACKETS, "SNMP received PDU is too long"); snmp_simple_response(p, AGENTX_RES_GEN_ERROR, 0); snmp_reset(p); - return 0; /* no bytes parsed */ + return 0; } /* This guarantees that we have the full packet already received */ @@ -768,9 +744,9 @@ parse_pkt(struct snmp_proto *p, byte *pkt, uint size) /* * parse_response - parse an agentx-Response-PDU * @p: SNMP protocol instance - * @res: pointer of agentx-Response-PDU header in RX-buffer + * @res: pointer of agentx-Response-PDU header in RX buffer * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static uint parse_response(struct snmp_proto *p, byte *res) @@ -778,7 +754,6 @@ parse_response(struct snmp_proto *p, byte *res) struct agentx_response *r = (void *) res; struct agentx_header *h = (void *) r; - // todo reject not compiled byte order uint pkt_size = LOAD_U32(h->payload); switch (r->error) @@ -812,7 +787,8 @@ parse_response(struct snmp_proto *p, byte *res) case AGENTX_RES_PROCESSING_ERR: default: TRACE(D_PACKETS, "SNMP agentx-Response-PDU with unexepected error %u", r->error); - snmp_stop(p); + //snmp_stop(p); + snmp_reset(p); break; } @@ -832,9 +808,9 @@ snmp_register_mibs(struct snmp_proto *p) /* * do_response - act on agentx-Response-PDU and protocol state * @p: SNMP protocol instance - * @pkt: RX-buffer with PDU bytes + * @pkt: RX buffer with PDU bytes * - * Return number of bytes parsed from RX-buffer. + * Return number of bytes parsed from RX buffer. */ static void do_response(struct snmp_proto *p, byte *pkt) @@ -910,8 +886,7 @@ void snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid) { uint vb_hdr_size = snmp_varbind_hdr_size_from_oid(oid); - if (snmp_tbuf_reserve(c, vb_hdr_size)) - snmp_log("SNMP vb_to_tx small buffer"); + (void) snmp_tbuf_reserve(c, vb_hdr_size); ASSERT(c->size >= vb_hdr_size); struct agentx_varbind *vb = (struct agentx_varbind *) c->buffer; @@ -935,12 +910,22 @@ snmp_vb_to_tx(struct snmp_pdu *c, const struct oid *oid) c->sr_vb_start = vb; } +/* + * snmp_fix_vb - fix VarBind's name OID byte order + * @vb: VarBind to use + */ +void +snmp_fix_vb(struct agentx_varbind *vb) +{ + snmp_oid_copy(&vb->name, &vb->name); +} + /* * update_packet_size - set PDU size * @start - pointer to PDU data start (excluding header size) * @end - pointer after the last PDU byte * - * Return number of bytes in TX-buffer (including header size). + * Return number of bytes in TX buffer (including header size). */ static inline uint update_packet_size(struct agentx_header *start, byte *end) @@ -985,18 +970,6 @@ response_err_ind(struct snmp_proto *p, struct agentx_response *res, enum agentx_ STORE_U16(res->index, 0); } -static inline uint -parse_gets_error(struct snmp_proto *p, struct snmp_pdu *c, uint len) -{ - TRACE(D_PACKETS, "SNMP error %u while parsing gets PDU", c->error); - if (c->index > UINT16_MAX) - snmp_simple_response(p, AGENTX_RES_GEN_ERROR, UINT16_MAX); - else - snmp_simple_response(p, AGENTX_RES_GEN_ERROR, c->index); - - return len + AGENTX_HEADER_SIZE; -} - /* * AgentX GetPDU, GetNextPDU and GetBulkPDU */ @@ -1005,18 +978,12 @@ parse_gets_error(struct snmp_proto *p, struct snmp_pdu *c, uint len) void snmp_get_pdu(struct snmp_proto *p, struct snmp_pdu *c, const struct oid *o_start, struct mib_walk_state *walk) { - snmp_log("snmp_get_pdu()"); - struct mib_leaf *leaf; leaf = snmp_walk_init(p->mib_tree, walk, o_start, c); - snmp_log("found node %p", leaf); - enum snmp_search_res res; res = snmp_walk_fill(leaf, walk, c); - snmp_log("fill result %u", res); - if (res != SNMP_SEARCH_OK) snmp_set_varbind_type(c->sr_vb_start, snmp_search_res_to_type(res)); } @@ -1060,7 +1027,6 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c) if ((sz = snmp_oid_size(start)) > pkt_size) { - snmp_log("load_oids start %u / %u", sz, pkt_size); c->error = AGENTX_RES_PARSE_ERROR; *pkt_ptr = pkt; *pkt_sz = pkt_size; @@ -1072,7 +1038,6 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c) const struct oid *end = (const struct oid *) pkt; if ((sz = snmp_oid_size(end)) > pkt_size) { - snmp_log("load_oids end %u / %u", sz, pkt_size); c->error = AGENTX_RES_PARSE_ERROR; *pkt_ptr = pkt; *pkt_sz = pkt_size; @@ -1081,6 +1046,7 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c) ADVANCE(pkt, pkt_size, sz); + // TODO: this does not work if (!snmp_is_oid_empty(end) && snmp_oid_compare(start, end) > 0) { @@ -1106,13 +1072,11 @@ snmp_load_oids(byte **pkt_ptr, uint *pkt_sz, struct snmp_pdu *c) * * Gets PDUs are agentx-Get-PDU, agentx-GetNext-PDU, agentx-GetBulk-PDU. * - * Return number of bytes parsed from RX-buffer + * Return number of bytes parsed from RX buffer */ static uint parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) { - snmp_log("parse_gets_pdu msg"); - // TODO checks for c.size underflow struct mib_walk_state walk; byte *pkt = pkt_start; @@ -1125,18 +1089,20 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) snmp_pdu_context(&c, p, sk); /* - * Get-Bulk processing stops if all the varbind have type END_OF_MIB_VIEW - * has_any is true if some varbind has type other than END_OF_MIB_VIEW + * Get-Bulk processing stops if all the varbind have type endOfMibView + * has_any is true if some varbind has type other than endOfMibView */ struct agentx_bulk_state bulk_state = { 0 }; if (h->type == AGENTX_GET_BULK_PDU) { + die("bulk"); + +#if 0 if (pkt_size < sizeof(struct agentx_getbulk)) { - snmp_log("parse_gets GetBulkPDU prepare"); - c.error = AGENTX_RES_PARSE_ERROR; - c.index = 0; - return parse_gets_error(p, &c, pkt_size); + snmp_simple_response(p, AGENTX_RES_PARSE_ERROR, 0); + snmp_reset(p); + return pkt_size + AGENTX_HEADER_SIZE; } struct agentx_getbulk *bulk_info = (void *) pkt; @@ -1152,6 +1118,7 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) .repetition = 0, .has_any = 0, }; +#endif } struct agentx_response *response_header = prepare_response(p, &c); @@ -1165,8 +1132,10 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) const struct oid *start_rx; if (!(start_rx = snmp_load_oids(&pkt, &pkt_size, &c))) { - snmp_log("snmp_load_oid ends with an error"); - return parse_gets_error(p, &c, pkt_size); + snmp_simple_response(p, c.error, + (c.index > UINT16_MAX) ? UINT16_MAX : c.index); + snmp_reset(p); + return pkt_size + AGENTX_HEADER_SIZE; } switch (h->type) @@ -1195,23 +1164,24 @@ parse_gets_pdu(struct snmp_proto *p, byte * const pkt_start) lp_restore(tmp_linpool, &tmps); +#if 0 if (h->type == AGENTX_GET_BULK_PDU) { // TODO: an error for now + die("bulk"); } +#endif /* We update the error, index pair on the beginning of the packet. */ response_err_ind(p, response_header, c.error, c.index + 1); uint s = update_packet_size(&response_header->h, c.buffer); - /* We send the message in TX-buffer. */ + /* We send the message in TX buffer. */ sk_send(sk, s); - snmp_log("gets send %t", current_time()); - // TODO think through the error state - /* number of bytes parsed from RX-buffer */ + /* number of bytes parsed from RX buffer */ return pkt - pkt_start; } @@ -1246,7 +1216,7 @@ snmp_stop_subagent(struct snmp_proto *p) } /* - * snmp_rx - handle received PDUs in RX-buffer in normal operation + * snmp_rx - handle received PDUs in RX buffer in normal operation * @sk: communication socket * @size: number of bytes received */ @@ -1268,9 +1238,9 @@ snmp_rx(sock *sk, uint size) size -= parsed_len; } - /* We flush the RX-buffer on errors */ + /* We flush the RX buffer on errors */ if (!snmp_is_active(p) || pkt_start == end) - return 1; /* The whole RX-buffer was consumed */ + return 1; /* The whole RX buffer was consumed */ /* Incomplete packet parsing */ memmove(sk->rbuf, pkt_start, size); @@ -1279,21 +1249,20 @@ snmp_rx(sock *sk, uint size) } /* - * snmp_tx - handle TX-buffer + * snmp_tx - handle TX buffer * @sk: communication socket owned by SNMP protocol instance * * The snmp_tx hook is used only to delay the processing in cases we don't have - * enough space in TX-buffer. Therefore we simply call the snmp_rx hook. + * enough space in TX buffer. Therefore we simply call the snmp_rx hook. */ void snmp_tx(sock *sk) { - snmp_log("snmp_tx()"); /* We still not have enough space */ if (!space_for_response(sk)) return; - /* There is nothing to process, no bytes in RX-buffer */ + /* There is nothing to process, no bytes in RX buffer */ if (sk_tx_buffer_empty(sk)) return; @@ -1326,7 +1295,6 @@ snmp_ping(struct snmp_proto *p) ADVANCE(c.buffer, c.size, AGENTX_HEADER_SIZE); snmp_blank_header(h, AGENTX_PING_PDU); p->packet_id++; - snmp_log("incrementing packet_id to %u (ping)", p->packet_id); snmp_session(p, h); /* sending only header */ @@ -1335,27 +1303,12 @@ snmp_ping(struct snmp_proto *p) sk_send(sk, s); } -/** - * snmp_search_check_end_oid - 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 - */ -int -snmp_search_check_end_oid(const struct oid *found, const struct oid *bound) -{ - if (snmp_is_oid_empty(bound)) - return 1; - - return (snmp_oid_compare(found, bound) < 0); -} - /* - * snmp_tbuf_reserve - TODO + * snmp_tbuf_reserve - conditionally grow the TX buffer + * @c: transmit PDU context + * @size: size to make available * + * Return non-zero if the buffer was relocated. */ int snmp_tbuf_reserve(struct snmp_pdu *c, size_t size) @@ -1365,16 +1318,15 @@ snmp_tbuf_reserve(struct snmp_pdu *c, size_t size) struct snmp_proto *p = c->p; sock *sk = p->sock; - int diff; + int start_diff; if (c->sr_vb_start != NULL) - diff = (char *) c->sr_vb_start - (char *) sk->tbuf; + start_diff = (char *) c->sr_vb_start - (char *) sk->tbuf; - snmp_log("snmp_tbuf_reserve()"); sk_set_tbsize(sk, sk->tbsize + 2048); c->size += 2048; if (c->sr_vb_start != NULL) - c->sr_vb_start = (struct agentx_varbind *) (sk->tbuf + diff); + c->sr_vb_start = (struct agentx_varbind *) (sk->tbuf + start_diff); return 1; } @@ -1387,7 +1339,7 @@ snmp_tbuf_reserve(struct snmp_pdu *c, size_t size) * @p: SNMP protocol instance * @c: transmit PDU context to use * - * Prepare known parts of AgentX packet header into the TX-buffer held by @c. + * Prepare known parts of AgentX packet header into the TX buffer held by @c. */ static struct agentx_response * prepare_response(struct snmp_proto *p, struct snmp_pdu *c) diff --git a/proto/snmp/subagent.h b/proto/snmp/subagent.h index 109da6b7..3c90da14 100644 --- a/proto/snmp/subagent.h +++ b/proto/snmp/subagent.h @@ -357,10 +357,10 @@ struct snmp_packet_info { }; int snmp_rx(sock *sk, uint size); +void snmp_tx(sock *sk); 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, u8 is_instance, uint contid); -void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len, uint contid); +void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8 is_instance); +void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len); void snmp_notify_pdu(struct snmp_proto *p, struct oid *oid, void *data, uint size, int include_uptime); int snmp_tbuf_reserve(struct snmp_pdu *c, size_t bytes); @@ -378,12 +378,4 @@ u8 snmp_get_mib_class(const struct oid *oid); void snmp_register_mibs(struct snmp_proto *p); -/* MIB modules */ - -#if 1 -#define snmp_log(...) log(L_INFO "SNMP " __VA_ARGS__) -#else -#define snmp_log(...) do { } while(0) -#endif - #endif