From: Vojtech Vilimek Date: Tue, 20 Sep 2022 12:28:57 +0000 (+0200) Subject: TMP: work on Get-PDU and GetNext-PDU X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ea2e991fac291331687cdc8a8b976d517c73c23;p=thirdparty%2Fbird.git TMP: work on Get-PDU and GetNext-PDU --- diff --git a/proto/snmp/bgp_mib.c b/proto/snmp/bgp_mib.c index 6f80acdc0..f3d2de5b3 100644 --- a/proto/snmp/bgp_mib.c +++ b/proto/snmp/bgp_mib.c @@ -11,11 +11,12 @@ * using mib2c.create-dataset.conf */ - +/* #include #include #include #include +*/ // fix conflicts #undef PACKAGE_BUGREPORT @@ -27,108 +28,38 @@ #include "bgp_mib.h" #include "snmp.h" -static int -bgpPeerTable_handler( - netsnmp_mib_handler *handler, // contains void * for internal use - netsnmp_handler_registration *reginfo, - netsnmp_agent_request_info *reqinfo, - netsnmp_request_info *requests) -{ - - /* perform anything here that you need to do. The requests have - already been processed by the master table_dataset handler, but - this gives you chance to act on the request in some other way - if need be. */ - - log(L_INFO " bgpPeerTable_handler()"); - // walk list of netsnmp_data_list - for (netsnmp_data_list *l = reqinfo->agent_data; - l; l->next) - { - log(L_INFO " name: %s, poniter %p", l->name, l->data); - } - - char buff[64]; - // walk list of netsnmp_variable_list VB - for (netsnmp_variable_list *var = requests->requestvb; - var; var->next_variable) - { - snprint_value(buff, 64, var->name, var->name_length, var); - log(L_INFO "variable %s", buff); - memset((void *) buff, 0, 64); - } - - return SNMP_ERR_NOERROR; -} - void -snmp_init_bgp_table(void) -{ - const oid bgpPeerTable_oid[] = {1,3,6,1,2,1,15,3}; - netsnmp_table_data_set *table_set; - - /* create the table structure itself */ - table_set = netsnmp_create_table_data_set("bgpPeerTable"); - - log(L_INFO "adding indexes to SNMP table bgpPeerTable"); - - netsnmp_table_set_add_indexes( - table_set, - ASN_IPADDRESS, /* index: bgpPeerRemoteAddr */ - 0 - ); - - log(L_INFO "adding column types to SNMP table bgpPeerTable"); - netsnmp_table_set_multi_add_default_row( - table_set, - SNMP_BGP_IDENTIFIER, ASN_IPADDRESS, 0, NULL, 0, - SNMP_BGP_STATE, ASN_INTEGER, 0, NULL, 0, - /* change to ASN_INTEGER, 1, NULL, 0, below to allow write */ - SNMP_BGP_ADMIN_STATUS, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_VERSION, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_LOCAL_ADDR, ASN_IPADDRESS, 0, NULL, 0, - SNMP_BGP_LOCAL_PORT, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_REMOTE_ADDR, ASN_IPADDRESS, 0, NULL, 0, - SNMP_BGP_REMOTE_PORT, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_REMOTE_AS, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_RX_UPDATES, ASN_COUNTER, 0, NULL, 0, - SNMP_BGP_TX_UPDATES, ASN_COUNTER, 0, NULL, 0, - SNMP_BGP_RX_MESSAGES, ASN_COUNTER, 0, NULL, 0, - SNMP_BGP_TX_MESSAGES, ASN_COUNTER, 0, NULL, 0, - SNMP_BGP_LAST_ERROR, ASN_OCTET_STR, 0, NULL, 0, - SNMP_BGP_FSM_TRANSITIONS, ASN_COUNTER, 0, NULL, 0, - SNMP_BGP_FSM_ESTABLISHED_TIME, ASN_GAUGE, 0, NULL, 0, - SNMP_BGP_RETRY_INTERVAL, ASN_INTEGER, 1, NULL, 0, - SNMP_BGP_HOLD_TIME, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_KEEPALIVE, ASN_INTEGER, 0, NULL, 0, - SNMP_BGP_HOLD_TIME_CONFIGURED, ASN_INTEGER, 1, NULL, 0, - SNMP_BGP_KEEPALIVE_CONFIGURED, ASN_INTEGER, 1, NULL, 0, - SNMP_BGP_ORIGINATION_INTERVAL, ASN_INTEGER, 1, NULL, 0, - SNMP_BGP_MIN_ROUTE_ADVERTISEMENT, ASN_INTEGER, 1, NULL, 0, - SNMP_BGP_MIN_UPDATE_ELAPSED_TIME, ASN_GAUGE, 0, NULL, 0, - 0 - ); +snmp_bgp_register() +{} - /* registering the table with the master agent */ - /* note: if you don't need a subhandler to deal with any aspects - of the request, change bgpPeerTable_handler to "NULL" */ - netsnmp_register_table_data_set( - netsnmp_create_handler_registration( - "bgpPeerTable", bgpPeerTable_handler, - bgpPeerTable_oid, - OID_LENGTH(bgpPeerTable_oid), - HANDLER_CAN_RONLY - // HANDLER_CAN_RWRITE - ), - table_set, NULL - ); +static inline int +is_bgp_peer_entry(struct oid *o) +{ + if (o->ids[2] == BGP4_PEER_ENTRY && + o->ids[3] > 0 && + /* do not include bgpPeerInUpdatesElapsedTime + and bgpPeerFsmEstablishedTime */ + o->ids[3] < SNMP_BGP_IN_UPDATE_ELAPSED_TIME && + o->ids[3] != SNMP_BGP_FSM_ESTABLISHED_TIME) + return 1; + else + return 0; } -void -snmp_del_bgp_table(void) +int +snmp_bgp_is_supported(struct oid *o) { - // XXX really needed ? - const oid bgpPeerTable_oid[] = {1,3,6,1,2,1,15,3}; - - remove_tree_entry(bgpPeerTable_oid, OID_LENGTH(bgpPeerTable_oid)); + if (o->prefix == 2 && o->ids[0] == 1) + { + if (o->ids[1] == BGP4_MIB_VERSION || + o->ids == BGP4_MIB_LOCAL_AS) + return 1; + else if (o->ids[1] == BGP4_PEER_TABLE) + return is_bgp_peer_entry(o) + else + return 0; + } + else + return 0; } + diff --git a/proto/snmp/bgp_mib.h b/proto/snmp/bgp_mib.h index dd34fa186..6c538b639 100644 --- a/proto/snmp/bgp_mib.h +++ b/proto/snmp/bgp_mib.h @@ -3,33 +3,41 @@ /* peers attributes */ enum BGP4_MIB { - SNMP_BGP_IDENTIFIER = 1; - SNMP_BGP_STATE = 2; - SNMP_BGP_ADMIN_STATUS = 3; /* in read-only mode */ - SNMP_BGP_VERSION = 4; - SNMP_BGP_LOCAL_ADDR = 5; - SNMP_BGP_LOCAL_PORT = 6; - SNMP_BGP_REMOTE_ADDR = 7; - SNMP_BGP_REMOTE_PORT = 8; - SNMP_BGP_REMOTE_AS = 9; - SNMP_BGP_RX_UPDATES = 10; /* in updates */ - SNMP_BGP_TX_UPDATES = 11; /* out updates */ - SNMP_BGP_RX_MESSAGES = 12; /* in total messages */ - SNMP_BGP_TX_MESSAGES = 13; /* out total messages */ - SNMP_BGP_LAST_ERROR = 14; - SNMP_BGP_FSM_TRANSITIONS = 15; /* FSM established transitions */ - SNMP_BGP_FSM_ESTABLISHED_TIME = 16; /* UNSUPPORTED FSM established time */ - SNMP_BGP_RETRY_INTERVAL = 17; - SNMP_BGP_HOLD_TIME = 18; - SNMP_BGP_KEEPALIVE = 19; - SNMP_BGP_HOLD_TIME_CONFIGURED = 20; - SNMP_BGP_KEEPALIVE_CONFIGURED = 21; - SNMP_BGP_ORIGINATION_INTERVAL = 22; /* UNSUPPORTED 0 */ - SNMP_BGP_MIN_ROUTE_ADVERTISEMENT = 23; /* UNSUPPORTED 0*/ - SNMP_BGP_MIN_UPDATE_ELAPSED_TIME = 24; /* UNSUPPORTED */ + SNMP_BGP_IDENTIFIER = 1, + SNMP_BGP_STATE = 2, + SNMP_BGP_ADMIN_STATUS = 3, /* in read-only mode */ + SNMP_BGP_VERSION = 4, + SNMP_BGP_LOCAL_ADDR = 5, + SNMP_BGP_LOCAL_PORT = 6, + SNMP_BGP_REMOTE_ADDR = 7, + SNMP_BGP_REMOTE_PORT = 8, + SNMP_BGP_REMOTE_AS = 9, + SNMP_BGP_RX_UPDATES = 10, /* in updates */ + SNMP_BGP_TX_UPDATES = 11, /* out updates */ + SNMP_BGP_RX_MESSAGES = 12, /* in total messages */ + SNMP_BGP_TX_MESSAGES = 13, /* out total messages */ + SNMP_BGP_LAST_ERROR = 14, + SNMP_BGP_FSM_TRANSITIONS = 15, /* FSM established transitions */ + SNMP_BGP_FSM_ESTABLISHED_TIME = 16, /* UNSUPPORTED FSM established time */ + SNMP_BGP_RETRY_INTERVAL = 17, + SNMP_BGP_HOLD_TIME = 18, + SNMP_BGP_KEEPALIVE = 19, + SNMP_BGP_HOLD_TIME_CONFIGURED = 20, + SNMP_BGP_KEEPALIVE_CONFIGURED = 21, + SNMP_BGP_ORIGINATION_INTERVAL = 22, /* UNSUPPORTED - 0 */ + SNMP_BGP_MIN_ROUTE_ADVERTISEMENT = 23, /* UNSUPPORTED - 0 */ + SNMP_BGP_IN_UPDATE_ELAPSED_TIME = 24, /* UNSUPPORTED */ } PACKED; -void snmp_init_bgp_table(void); -void snmp_del_bgp_table(void); +//void snmp_init_bgp_table(void); +//void snmp_del_bgp_table(void); + +void snmp_bgp_register(void); +int snmp_bgp_is_supported(struct oid *o); + +#define BGP4_MIB_VERSION 1 +#define BGP4_MIB_LOCAL_AS 2 +#define BGP4_PEER_TABLE 3 +#define BGP4_PEER_ENTRY 1 #endif diff --git a/proto/snmp/config.Y b/proto/snmp/config.Y index d85dbf15c..33f653427 100644 --- a/proto/snmp/config.Y +++ b/proto/snmp/config.Y @@ -14,11 +14,10 @@ CF_HDR CF_DEFINES #define SNMP_CFG ((struct snmp_config *) this_proto) -#define SNMP_CC ((struct snmp_channel_config *) this_channel) CF_DECLS -CF_KEYWORDS(SNMP, TABLE, PROTOCOL, BPG) +CF_KEYWORDS(SNMP, PROTOCOL, BPG, LOCAL, AS, REMOTE, PORT) CF_GRAMMAR @@ -33,19 +32,23 @@ snmp_proto: | snmp_proto REMOTE PORT expr ';' { SNMP_CFG->remote_port = $4; if (($4<1) || ($4>65545)) cf_error("Invalid port number"); } | snmp_proto LOCAL ipa ';' { SNMP_CFG->local_ip = $3; } - | snmp_proto REMOTE ipa ';' { SNMP_CFG->remote_ip = $3; if(!ipa_nonzero($3)) + | snmp_proto REMOTE ipa ';' { SNMP_CFG->remote_ip = $3; if(ipa_zero($3)) cf_error("Invalid remote ip address"); } + | snmp_proto LOCAL AS expr ';' { if ($4<1 || $4>65535) cf_error("invalid local as"); + SNMP_CFG->local_as = $4; } ; snmp_proto_start: proto_start SNMP { this_proto = proto_config_new(&proto_snmp, $1); + init_list(&SNMP_CFG->bgp_entries); SNMP_CFG->local_ip = IPA_NONE; SNMP_CFG->remote_ip = ipa_build4(127,0,0,1); SNMP_CFG->local_port = 0; SNMP_CFG->remote_port = 705; + SNMP_CFG->local_as = 0; SNMP_CFG->timeout = 15; } @@ -53,7 +56,6 @@ snmp_proto_start: proto_start SNMP proto_name ; - snmp_bgp_bond: BGP symbol { struct snmp_bond *this_bond = cfg_alloc(sizeof(struct snmp_bond)); diff --git a/proto/snmp/snmp.c b/proto/snmp/snmp.c index c00dd94fe..587921a84 100644 --- a/proto/snmp/snmp.c +++ b/proto/snmp/snmp.c @@ -14,6 +14,7 @@ #include "nest/cli.h" #include "nest/locks.h" #include "lib/socket.h" +#include "lib/lists.h" #include "snmp.h" #include "subagent.h" @@ -21,6 +22,7 @@ static void snmp_connected(sock *sk); static void snmp_sock_err(sock *sk, int err); static void snmp_ping_timer(struct timer *tm); +static void snmp_retry_timer(struct timer *tm); static struct proto * snmp_init(struct proto_config *CF) @@ -98,7 +100,14 @@ static void snmp_sock_err(sock *sk UNUSED, int err UNUSED) { log(L_INFO "snmp_sock_err() %s - err no: %d", strerror(err), err); - die("socket error"); + + struct snmp_proto *p = sk->data; + + p->state = SNMP_ERR; + if (p->p.proto_state == PS_UP) + proto_notify_state(&p->p, PS_START); + + tm_set(p->retry_timer, current_time() + 5 S); } static int @@ -106,15 +115,17 @@ snmp_start(struct proto *P) { log(L_INFO "snmp_start() - starting timer (almost)"); struct snmp_proto *p = (void *) P; - struct snmp_config *cf = P->cf; + struct snmp_config *cf = (struct snmp_config *) P->cf; p->ping_timer = tm_new_init(p->p.pool, snmp_ping_timer, p, 0, 0); - tm_set(p->ping_timer, current_time() + (2 S_)); + tm_set(p->ping_timer, current_time() + 2 S); + + p->retry_timer = tm_new_init(p->p.pool, snmp_retry_timer, p, 0, 0); /* starting agentX communicaiton channel */ log(L_INFO "preparing lock"); struct object_lock *lock; - lock = p->lock = olock_new(P->pool); + lock = p->lock = olock_new(p->p.pool); lock->type = OBJLOCK_TCP; lock->hook = snmp_start_locked; @@ -126,26 +137,29 @@ snmp_start(struct proto *P) log(L_INFO "local ip: %I:%u, remote ip: %I:%u", p->local_ip, p->local_port, p->remote_ip, p->remote_port); - init_list(p->bgp_entries); + init_list(&p->bgp_entries); /* create copy of bonds to bgp */ - HASH_INIT(p->peer_hash, p->p.pool, 10); + HASH_INIT(p->bgp_hash, p->p.pool, 10); - struct snmp_bond *b; + struct snmp_bond *b, *b2; WALK_LIST(b, cf->bgp_entries) { - struct bgp_config *bc = b->proto; + struct bgp_config *bc = (struct bgp_config *) b->proto; if (bc && !ipa_zero(bc->remote_ip)) { - struct snmp_bgp_peer_entry pe = { - .bond = b; - .peer_ip = bc->remote_ip; - .next = NULL; - }; + struct snmp_bgp_peer *peer = + mb_allocz(p->p.pool, sizeof(struct snmp_bgp_peer)); + peer->bond = b; + peer->peer_ip = bc->remote_ip; - HASH_INSERT(p->peer_hash, SNMP_HASH, pe) + HASH_INSERT(p->bgp_hash, SNMP_HASH, peer); - add_tail(&p->bgp_entries, b); + b2 = mb_allocz(p->p.pool, sizeof(struct snmp_bond)); + b2->proto = b->proto; + b2->type = b->type; + add_tail(&p->bgp_entries, NODE b2); + mb_free(peer); } } @@ -162,6 +176,7 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF) p->remote_ip = cf->remote_ip; p->local_port = cf->local_port; p->remote_port = cf->remote_port; + p->local_as = cf->local_as; p->timeout = 15; /* TODO walk all bind protocols and find their (new) IP @@ -192,7 +207,7 @@ static void snmp_show_proto_info(struct proto *P) cli_msg(-1006, " admin status: %s", (p->disabled) ? "start" : "stop"); // version ? - cli_msg(-1006, " version: ??, likely 4"); + cli_msg(-1006, " version: 4"); cli_msg(-1006, " local ip: %u", bcf->local_ip); cli_msg(-1006, " remote ip: %u", bcf->remote_ip); cli_msg(-1006, " local port: %u", bcf->local_port); @@ -237,21 +252,59 @@ bp->stats.fsm_established_transitions); } } +static void +snmp_postconfig(struct proto_config *CF) +{ + if (((struct snmp_config *) CF)->local_as == 0) + cf_error("local as not specified"); +} + static void snmp_ping_timer(struct timer *tm) { log(L_INFO "snmp_ping_timer() "); struct snmp_proto *p = tm->data; - snmp_ping(p); + if (p->state == SNMP_CONN) + { + snmp_ping(p); + } //tm_set(tm, current_time() + (7 S_)); } +static void +snmp_retry_timer(struct timer *tm) +{ + log(L_INFO "snmp_retry_timer()"); + + struct snmp_proto *p = tm->data; + + /* starting agentX communicaiton channel */ + log(L_INFO "preparing lock"); + struct object_lock *lock; + lock = p->lock = olock_new(p->p.pool); + + lock->type = OBJLOCK_TCP; + lock->hook = snmp_start_locked; + lock->data = p; + + olock_acquire(lock); + log(L_INFO "lock acquired"); + + log(L_INFO "local ip: %I:%u, remote ip: %I:%u", + p->local_ip, p->local_port, p->remote_ip, p->remote_port); +} + static int snmp_shutdown(struct proto *P) { struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P); + p->state = SNMP_INIT; + + tm_stop(p->ping_timer); + tm_stop(p->retry_timer); + snmp_stop_subagent(p); return PS_DOWN; } @@ -262,6 +315,7 @@ struct protocol proto_snmp = { .channel_mask = NB_ANY, .proto_size = sizeof(struct snmp_proto), .config_size = sizeof(struct snmp_config), + .postconfig = snmp_postconfig, .init = snmp_init, .start = snmp_start, .reconfigure = snmp_reconfigure, diff --git a/proto/snmp/snmp.h b/proto/snmp/snmp.h index bb38002cd..baf643c30 100644 --- a/proto/snmp/snmp.h +++ b/proto/snmp/snmp.h @@ -37,8 +37,8 @@ /* hash table macros */ -#define SNMP_HASH_KEY(n) n->peer_ip; -#define SNMP_HASH_NEXT(n) n->next; +#define SNMP_HASH_KEY(n) n->peer_ip +#define SNMP_HASH_NEXT(n) n->next #define SNMP_HASH_EQ(ip1, ip2) ipa_equal(ip1, ip2) #define SNMP_HASH_FN(ip) ipa_hash(ip) @@ -54,16 +54,17 @@ struct snmp_config { ip_addr remote_ip; u16 local_port; u16 remote_port; + u32 local_as; u8 timeout; //struct iface *iface; list bgp_entries; }; -struct snmp_bgp_peer_entry { +struct snmp_bgp_peer { struct snmp_bond *bond; ip_addr peer_ip; - struct snmp_bgp_peer_entry *next; -} + struct snmp_bgp_peer *next; +}; struct snmp_proto { struct proto p; @@ -73,6 +74,7 @@ struct snmp_proto { ip_addr remote_ip; u16 local_port; u16 remote_port; + u32 local_as; sock *sock; u8 timeout; @@ -83,10 +85,11 @@ struct snmp_proto { //struct iface *iface; // map goes here - HASH(struct snmp_bgp_peer_entry) bgp_hash; + HASH(struct snmp_bgp_peer) bgp_hash; struct tbf rl_gen; timer *ping_timer; + timer *retry_timer; u8 state; list bgp_entries; diff --git a/proto/snmp/subagent.c b/proto/snmp/subagent.c index 02638848b..ca84e3f83 100644 --- a/proto/snmp/subagent.c +++ b/proto/snmp/subagent.c @@ -10,6 +10,7 @@ #include "lib/unaligned.h" #include "subagent.h" +#include "bgp_mib.h" /* ============================================================= * Problems @@ -18,6 +19,7 @@ * change of remote ip -> no notification, no update * same ip, different ports * distinct VRF (two interfaces with overlapping private addrs) + * posible link-local addresses in LOCAL_IP * */ @@ -28,8 +30,13 @@ static inline uint vb_size(struct agentx_varbind *vb); static int snmp_stop_ack(sock *sk, uint size); static void do_response(struct snmp_proto *p, byte *buf, uint size); static int parse_get_pdu(struct snmp_proto *p, byte *buf, uint size); -static void response_fail(struct snmp_proto *p, u16 err_no, u16 index); -static byte *prepare_response(struct snmp_proto *p, byte *buf, uint size, u16 err_no, u16 index); +static int parse_gets_pdu(struct snmp_proto *p, byte *buf, uint size); +//static void response_fail(struct snmp_proto *p, u16 err_no, u16 index); +static byte *prepare_response(struct snmp_proto *p, byte *buf, uint size); +static void response_err_ind(byte *buf, uint err, uint ind); +static struct oid *bgp_search(struct oid *o_start, struct oid *o_end, struct oid *o_curr); +static struct oid *prefixize(struct snmp_proto *p, struct oid *o, int byte_ord); +static inline byte *find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord); static const char * const snmp_errs[] = { #define SNMP_ERR_SHIFT 256 @@ -341,9 +348,16 @@ parse_pkt(struct snmp_proto *p, byte *buf, uint size) case AGENTX_RESPONSE_PDU: return parse_response(p, buf, size); + /* case AGENTX_GET_PDU: refresh_ids(p, h); return parse_get_pdu(p, buf, size); + */ + + case AGENTX_GET_PDU: + case AGENTX_GET_NEXT_PDU: + refresh_ids(p, h); + return parse_gets_pdu(p, buf, size); /* should not happen */ default: @@ -378,7 +392,7 @@ SNMP_ERR_SHIFT]); } static void -do_response(struct snmp_proto *p, byte *buf, uint size) +do_response(struct snmp_proto *p, byte *buf, uint size UNUSED) { struct agentx_response *r = (void *) buf; struct agentx_header *h = &r->h; @@ -401,34 +415,47 @@ do_response(struct snmp_proto *p, byte *buf, uint size) p->transaction_id++; log(L_INFO "sending register-pdu"); + + // register whole BGP4-MIB + u32 arr_bgp[] = {1, 15, 1}; + struct oid *o = mb_allocz(p->p.pool, 4 * 4); + put_u8(&o->n_subid, 2); + put_u8(&o->prefix, 2); + + memcpy(o->ids, arr_bgp, 2 * 4); + + snmp_register(p, o, 0, 1); + + put_u8(&o->n_subid, 3); + STORE(o->ids[2], arr_bgp[2]); + snmp_register(p, o, 0, 1); + + + STORE(o->ids[2], 2); + snmp_register(p, o, 0, 1); + + mb_free(o); + u32 arr_with_prefix[] = {1, 15, 3, 1, 1}; struct oid *o2 = mb_allocz(p->p.pool, 10 * 4); - put_u8(&o2->n_subid, 9); - put_u8(&o2->prefix, 2); + put_u8(&o2->n_subid, 9); memcpy(o2->ids, arr_with_prefix, 5 * 4); u32 remote_addr[] = {10, 0, 0, 0}; memcpy(o2->ids + 5, remote_addr, 4 * 4); + STORE(o2->prefix, 2); // register first line in BGP4-MIB bgpPeerTable // TODO register all bind bgp connections snmp_register(p, o2, 9, 24); - - // register whole BGP4 mib-tree section - u32 arr_bgp[] = {1, 15, 1}; - struct oid *o3 = mb_allocz(p->p.pool, 4 * 4); - put_u8(&o3->n_subid, 3); - put_u8(&o3->prefix, 2); - - memcpy(o3->ids, arr_bgp, 3 * 4); - - snmp_register(p, o3, 0, 1); + mb_free(o2); p->state = SNMP_REGISTR; //proto_notify_state(&p->p, PS_UP); break; case SNMP_REGISTR: + p->state = SNMP_CONN; break; case SNMP_CONN: @@ -452,68 +479,80 @@ parse_get_pdu(struct snmp_proto *p, byte *buf, uint size) return 0; log(L_INFO "Get-PDU enough room %p", buf); + struct agentx_header *h = (void *) buf; - int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER; ADVANCE(buf, size, AGENTX_HEADER_SIZE); log(L_INFO "advancing %p cause %u", buf, AGENTX_HEADER_SIZE); + + int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER; + byte *pkt = buf; uint pkt_size = LOAD(h->payload, byte_ord); - log(L_INFO "packet size is %u", pkt_size); + log(L_INFO "RX packet size is %u", pkt_size); - uint clen; + uint clen; /* context len */ char *context = NULL; SNMP_LOAD_CONTEXT(p, h, pkt, context, clen) log(L_INFO "after context load %p, pkt == buf %d", pkt, pkt == buf); - /* parsing one search range */ - struct oid *o_start, *o_end; - o_start = (struct oid *) pkt; - pkt += oid_size(o_start); - o_end = (struct oid *) pkt; // for Get-PDU always null - pkt += oid_size(o_end); - - log(L_INFO "sizes o_start %lu o_end %lu", oid_size(o_start), - oid_size(o_end)); - - log(L_INFO " creating response header rpkt %p %u", res_pkt, res_pkt - res); - log(L_INFO "o_subid: %u o_prefix %u o_include %u ---", - o_start->n_subid, o_start->prefix, o_start->include); - // TODO read a oid - // TODO allow multiple values - - res_pkt = prepare_response(p, res, rsize, AGENTX_RES_NO_ERROR, 0); + res_pkt = prepare_response(p, res, rsize); log(L_INFO "response header created: %p (%u)", res_pkt, res_pkt - res); + /* parsing one search range */ + uint ind = 1; + int err = 0; + /* parsed */ + while (!err && pkt - buf < pkt_size) + { + struct oid *o_start, *o_end; + o_start = (struct oid *) pkt; + pkt += oid_size(o_start); + o_end = (struct oid *) pkt; // for Get-PDU always null + pkt += oid_size(o_end); - res_pkt = request(res_pkt, o_start); - struct agentx_varbind *vb_start; - vb_start = (void *) res_pkt; - log(L_INFO " SNMP_CREATEish rpkt %p %u", res_pkt, res_pkt - res); + log(L_INFO "sizes o_start %lu o_end %lu", oid_size(o_start), + oid_size(o_end)); - memcpy(&vb_start->name, o_start, oid_size(o_start)); - STORE_16(vb_start->type, AGENTX_INTEGER); - STORE_16(vb_start->pad, 0); // padding zeroing - res_pkt += vb_size(vb_start); + log(L_INFO "o_subid: %u o_prefix %u o_include %u ---", + o_start->n_subid, o_start->prefix, o_start->include); - log(L_INFO " vb_size() rpkt %p %u", res_pkt, res_pkt - res); - - STORE_PTR(res_pkt, 0x1234ABCD); - - log(L_INFO " STORE_PTR int-value rpkt %p %u", res_pkt, res_pkt - res); - res_pkt += 4; - log(L_INFO " shift rpkt %p %u", res_pkt, res_pkt - res); - log(L_INFO "after integer write"); + /* currently unsupported non-default context */ + res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord); + + /* + struct agentx_varbind *vb_start; + vb_start = (void *) res_pkt; + + memcpy(&vb_start->name, o_start, oid_size(o_start)); + STORE_16(vb_start->type, AGENTX_INTEGER); + STORE_16(vb_start->pad, 0); // padding zeroing + res_pkt += vb_size(vb_start); + + log(L_INFO " vb_size() rpkt %p %u", res_pkt, res_pkt - res); + + STORE_PTR(res_pkt, 0x1234ABCD); + + log(L_INFO " STORE_PTR int-value rpkt %p %u", res_pkt, res_pkt - res); + res_pkt += 4; + log(L_INFO " shift rpkt %p %u", res_pkt, res_pkt - res); + */ + ind++; + } struct agentx_header *rh = (void *) res; SNMP_UPDATE(rh, pkt_len(res, res_pkt)); + + if (err) + response_err_ind(res, err, ind); + log(L_INFO "res->payload %u (loaded) %u, trying to send: %u", rh->payload, LOAD(rh->payload, rh->flags & AGENTX_NETWORK_BYTE_ORDER), - res_pkt - res); + res_pkt - res + 4); int ret = sk_send(sk, res_pkt - res); log(L_INFO "message sent"); - if (res == 0) + if (ret == 0) log(L_INFO "sleep"); else if (ret < 0) log(L_INFO "err no: %d", ret); @@ -523,6 +562,126 @@ parse_get_pdu(struct snmp_proto *p, byte *buf, uint size) return 1; } + +/* req is request */ +static int +parse_gets_pdu(struct snmp_proto *p, byte *req, uint size) +{ + log(L_INFO "parse_gets_pdu"); + + sock *sk = p->sock; + byte *res_pkt, *res = sk->tbuf; + uint rsize = sk->tbsize; + + if (size < AGENTX_HEADER_SIZE) + return 0; + + struct agentx_header *h = (void *) req; + ADVANCE(req, size, AGENTX_HEADER_SIZE); + log(L_INFO "advancing %p cause header", req); + + byte *pkt = req; + + int byte_ord = h->flags & AGENTX_NETWORK_BYTE_ORDER; + uint pkt_size = LOAD(h->payload, byte_ord); + + uint clen; + char *context; + SNMP_LOAD_CONTEXT(p, h, req, context, clen); + + res_pkt = prepare_response(p, res, rsize); + uint ind = 1; + int err = 0; + while (!err && pkt - req < pkt_size) + { + struct oid *o_start, *o_end; + o_start = (struct oid *) pkt; + pkt += oid_size(o_start); + o_end = (struct oid *) pkt; + pkt += oid_size(o_end); + + // TODO normalize OID to prefix form + + /* advertised size of oid is greater then size of message */ + if (oid_size(o_start) > size || oid_size(o_end) > size) + { + err = -1; /* parse error too big n_subid */ + continue; + } + + switch (h->type) + { + case AGENTX_GET_PDU: + res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord); + break; + + case AGENTX_GET_NEXT_PDU: + o_start = bgp_search(o_start, o_end, NULL); + if (o_start) + res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord); + else + { + err = -2; + continue; + } + break; + + case AGENTX_GET_BULK_PDU: + { + struct oid *o_curr = NULL; + /* TODO add res packet size limiting logic */ + while ((o_curr = bgp_search(o_start, o_end, o_curr)) != NULL) + { + res_pkt = find_n_fill(p, o_start, res_pkt, rsize, 0, byte_ord); + } + + /* no item found */ + if (res_pkt == res + sizeof(struct agentx_response)) + { + err = -2; + continue; + } + + break; + } + } + + ind++; + } + + switch (err) + { + case 0: + response_err_ind(req, AGENTX_RES_NO_ERROR, 0); + err = 1; + break; + case -1: + response_err_ind(req, AGENTX_RES_PARSE_ERROR, ind); + break; + + /* no item found - could it happen? */ + case -2: + response_err_ind(req, AGENTX_RES_GEN_ERROR, ind); + break; + } + + struct agentx_header *rh = (void *) res; + SNMP_UPDATE(rh, pkt_len(res, res_pkt)); + + int ret = sk_send(sk, res_pkt - res); + log(L_INFO "message sent"); + + if (ret == 0) + log(L_INFO "sleep"); + else if (ret < 0) + log(L_INFO "err no: %d", ret); + else + log("OK ! !!"); + + return err; +} + + static void header_update_len(byte *buf, u32 len) { @@ -552,9 +711,12 @@ snmp_stop_subagent(struct snmp_proto *p) log(L_INFO "snmp_stop_subagent()"); sock *sk = p->sock; - close_pdu(p, AGENTX_CLOSE_SHUTDOWN); + if (p->state == SNMP_CONN) + { + close_pdu(p, AGENTX_CLOSE_SHUTDOWN); - sk->rx_hook = snmp_stop_ack; + sk->rx_hook = snmp_stop_ack; + } } static inline uint @@ -652,12 +814,53 @@ snmp_agent_reconfigure(void) } */ +static int +compare(struct oid *left, struct oid *right) +{ + if (left->prefix < right->prefix) + return -1; + + else if (left->prefix > right->prefix) + return 1; + + for (int i = 0; i < MIN(left->n_subid, right->n_subid); i++) + { + if (left->ids[i] < right->ids[i]) + return -1; + else if (left->ids[i] > right->ids[i]) + return 1; + } + return 0; +} + +static inline int +is_bgp4_mib_prefix(struct oid *o) +{ + if (o->prefix == 2 && o->ids[0] == 15) + return 1; + else + return 0; +} + +static struct oid * +bgp_search(struct oid *o_start, struct oid *e_end, struct oid *o_curr) +{ + if (o_start->include); + // if valid o_start + + // search o_start.0 (resp. o_start.1) + return o_start; +} + static byte * -find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *buf, uint size, uint contid) +find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *pkt, uint size, uint contid) { struct bgp_conn *b_conn = bp->conn; - struct bgp_conn *b_in = bp->incomming_conn; - struct bgp_conn *b_out = bp->outgoing_conn; + struct bgp_conn *b_in = &bp->incoming_conn; + struct bgp_conn *b_out = &bp->outgoing_conn; + + struct bgp_stats *b_stats = &bp->stats; + const struct bgp_config *b_conf = bp->cf; uint b_state; @@ -672,122 +875,216 @@ find_bgp_one(struct bgp_proto *bp, struct oid *o, byte *buf, uint size, uint co else b_state = MAX(b_in->state, b_out->state); - struct agentx_varbind *vb = (void *) buf; - + struct agentx_varbind *vb = (void *) pkt; + pkt += vb_size(vb); switch (o->ids[4]) { case SNMP_BGP_IDENTIFIER: - if (b_state == BS_ESTABLISHED) - STORE_PTR(pkt, ip_to_u32(b_conn->remote_ip)); - BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt); - else if (b_state == BS_OPENCONFIRM) - STORE_PTR(pkt, ip4_to_u32( (b_state == b_in->state) ? b_in->state : b_out->state)); + if (b_state == BS_OPENCONFIRM || b_state == BS_ESTABLISHED) + { + STORE_PTR(pkt, ipa_to_u32(bp->remote_ip)); BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt); + } else - STORE_PTR(pkt, ip4_to_u32(IPA_NONE)); + { + STORE_PTR(pkt, ipa_to_u32(IPA_NONE)); BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt); + } + break; case SNMP_BGP_STATE: STORE_PTR(pkt, b_state); BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; case SNMP_BGP_ADMIN_STATUS: - STORE_PTR(pkt, (bp->disabled) ? AGENTX_ADMIN_STOP : AGENTX_ADMIN_START); + if (((struct proto *) bp)->disabled) + STORE_PTR(pkt, AGENTX_ADMIN_STOP); + else + STORE_PTR(pkt, AGENTX_ADMIN_START); BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; case SNMP_BGP_VERSION: - STORE(pkt, BGP4_VERSIONS); - STORE + if (b_state == BS_OPENCONFIRM || b_state == BS_ESTABLISHED) + STORE_PTR(pkt, 4); + else + STORE_PTR(pkt, 0); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + case SNMP_BGP_LOCAL_ADDR: + // TODO XXX bp->link_addr & zero local_ip + STORE_PTR(pkt, ipa_to_u32(bp->local_ip)); + BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt); + break; + case SNMP_BGP_LOCAL_PORT: + STORE_PTR(pkt, b_conf->local_port); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + case SNMP_BGP_REMOTE_ADDR: + STORE_PTR(pkt, ipa_to_u32(bp->remote_ip)); + BGP_DATA(vb, AGENTX_IP_ADDRESS, pkt); + break; + case SNMP_BGP_REMOTE_PORT: + STORE_PTR(pkt, b_conf->remote_port); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + case SNMP_BGP_REMOTE_AS: + STORE_PTR(pkt, bp->remote_as); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + + /* IN UPDATES */ case SNMP_BGP_RX_UPDATES: + STORE_PTR(pkt, b_stats->rx_updates); + BGP_DATA(vb, AGENTX_COUNTER_32, pkt); + break; + + /* OUT UPDATES */ case SNMP_BGP_TX_UPDATES: + STORE_PTR(pkt, b_stats->tx_updates); + BGP_DATA(vb, AGENTX_COUNTER_32, pkt); + break; + + /* IN MESSAGES */ case SNMP_BGP_RX_MESSAGES: + STORE_PTR(pkt, b_stats->rx_messages); + BGP_DATA(vb, AGENTX_COUNTER_32, pkt); + break; + + /* OUT MESSAGES */ case SNMP_BGP_TX_MESSAGES: + STORE_PTR(pkt, b_stats->tx_messages); + BGP_DATA(vb, AGENTX_COUNTER_32, pkt); + break; + + case SNMP_BGP_LAST_ERROR: + STORE_PTR(pkt, 2); + pkt += 4; + /* force network order */ + put_u32(pkt, + (bp->last_error_code << 8 | bp->last_error_code << 48) & 0xFFFF0000); + /* real size is 8 but we already shifted the pkt by 4 */ + BGP_DATA(vb, AGENTX_OCTET_STRING, pkt); + break; case SNMP_BGP_FSM_TRANSITIONS: + STORE_PTR(pkt, b_stats->fsm_established_transitions); + BGP_DATA(vb, AGENTX_COUNTER_32, pkt); + break; case SNMP_BGP_RETRY_INTERVAL: + STORE_PTR(pkt, b_conf->connect_retry_time); + BGP_DATA(vb, AGENTX_COUNTER_32, pkt); + break; + case SNMP_BGP_HOLD_TIME: + if (b_conn && b_conf->hold_time) + STORE_PTR(pkt, b_conn->hold_time); + else + STORE_PTR(pkt, 0); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + case SNMP_BGP_KEEPALIVE: + if (b_conn && b_conf->keepalive_time) + STORE_PTR(pkt, b_conn->keepalive_time); + else + STORE_PTR(pkt, 0); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + case SNMP_BGP_HOLD_TIME_CONFIGURED: + STORE_PTR(pkt, b_conf->hold_time); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + case SNMP_BGP_KEEPALIVE_CONFIGURED: + STORE_PTR(pkt, b_conf->keepalive_time); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; /* UNSUPPORTED */ - case SNMP_BGP_LAST_ERROR: - - case SNMP_BGP_FSM_ESTABLISHED_TIME: - + /* TODO XXX forbiden value 0 */ case SNMP_BGP_ORIGINATION_INTERVAL: case SNMP_BGP_MIN_ROUTE_ADVERTISEMENT: - case SNMP_BGP_MIN_UPDATE_ELAPSED_TIME: - defualt: + STORE_PTR(pkt, 0); + BGP_DATA(vb, AGENTX_INTEGER, pkt); + break; + + case SNMP_BGP_FSM_ESTABLISHED_TIME: + case SNMP_BGP_IN_UPDATE_ELAPSED_TIME: vb->type = AGENTX_NO_SUCH_OBJECT; /* pkt += 0; no data */ break; + + /* no default */ } + + return pkt; } /* contid - context identification number */ static byte * -find_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid) +snmp_bgp_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid) { struct agentx_varbind *vb = (void *) buf; - - if (o->n_subid < 3) - { - vb->type = AGENTX_NO_SUCH_OBJECT; - return buff + vb_size(vb); - } - byte *pkt = buf + vb_size(vb); + switch (o->ids[2]) { case BGP4_MIB_VERSION: - vb->type = AGENTX_OCTET_STRING; - STORE(pkt, BGP4_VERSIONS); - pkt += 4; + STORE_PTR(pkt, 1); // string len + pkt += 4; + STORE_PTR(pkt, BGP4_VERSIONS); + /* real size is 8 but we already shifted the pkt by 4 */ + BGP_DATA(vb, AGENTX_OCTET_STRING, pkt); break; case BGP4_MIB_LOCAL_AS: - vb->type = AGENTX_INTEGER; // XXX local as to use - STORE(pkt, p->local_as); - pkt += 4; + STORE_PTR(pkt, p->local_as); + BGP_DATA(vb, AGENTX_INTEGER, pkt); break; case BGP4_PEER_TABLE: /* end part of .1.3.6.1.2.1.15.3.1.x.a.b.c.d */ - if (o->n_subid < 9 || o->ids[3] != 1 + if (o->n_subid < 9 || o->ids[3] != BGP4_PEER_ENTRY || o->ids[4] == 0 || o->ids[4] > 24) { vb->type = AGENTX_NO_SUCH_OBJECT; - return buff + vb_size(vb); + return buf + vb_size(vb); } // TODO enumerate range requests ip_addr addr = ipa_build4(o->ids[5], o->ids[6], o->ids[7], o->ids[8]); - struct snmp_bgp_peer_entry *pe = - HASH_FIND(p->bgp_entries, SNMP_HASH, addr); + struct snmp_bgp_peer *pe = + HASH_FIND(p->bgp_hash, SNMP_HASH, addr); struct bgp_proto *bp = NULL; if (pe && pe->bond->proto->proto && - ipa_equal(pe->bond->proto->proto->remote_ip, addr)) + ipa_equal(addr, + ((struct bgp_proto *) pe->bond->proto->proto)->remote_ip)) { - bp = pe->bond->proto->proto; + bp = (void *) pe->bond->proto->proto; } + + /* IF WE CONSIDER CHANGES OF REMOTE IP else { struct snmp_bond *b; WALK_LIST(b, p->bgp_entries) if (b->proto->proto && - ipa_equal(b->proto->proto->remote_ip, addr)) - bp = b->proto->proto; + ipa_equal(((struct bgp_proto *) b->proto->proto)->remote_ip, addr)) + bp = (struct bgp_proto *) b->proto->proto; } + */ if (!bp) { @@ -815,15 +1112,23 @@ find_ospf_record(struct snmp_proto *p, struct oid *o, byte *buf, uint size) return NULL; } +static byte * +unsupported_oid(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid) +{ + struct agentx_varbind *vb = (void *) buf; + vb->type = AGENTX_NO_SUCH_OBJECT; + return buf + vb_size(vb); +} + static inline byte * -find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size) +find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid) { - struct agetnx_varbind *vb = (void *) buf; + struct agentx_varbind *vb = (void *) buf; memcpy(&vb->name, o, oid_size(o)); - /* SNMPv2 mgmt mib-2 */ - if (o->n_subid < 2 || (o->prefix != 2 && o->ides[0] != 1)) + /* SNMPv2 mgmt mib-2 */ + if (o->n_subid < 2 || (o->prefix != 2 && o->ids[0] != 1)) { vb->type = AGENTX_NO_SUCH_OBJECT; return buf + vb_size(vb); @@ -832,29 +1137,26 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size) switch (o->ids[1]) { case SNMP_BGP4_MIB: - return find_bgp_record(p, o, buf, size); + if (snmp_bgp_is_supported(o)) + return snmp_bgp_record(p, o, buf, size, contid); + else + return unsupported_oid(p, o, buf, size, contid); case SNMP_OSPFv3_MIB: - return find_ospf_record(p, o, buf, size); - - /* the old OSPF */ - case SNMP_OSPF_MIB: - log("too old OSPF oid request"); - break; + return unsupported_oid(p, o, buf, size, contid); + //return find_ospf_record(p, o, buf, size); default: + return unsupported_oid(p, o, buf, size, contid); log(L_INFO "unsupported oid"); break; } - - vb->type = AGENTX_NO_SUCH_OBJECT; - return buf + vb_size(vb); } /* tests if there is present canonical "internet" prefix .1.3.6.1 and if so it shortens the oid to the ``prefix'' form */ static int -prefixize(struct oid *o, int byte_ord) +prefixize_in_place(struct oid *o, int byte_ord) { const u32 prefix[] = {1, 3, 6, 1}; @@ -876,25 +1178,51 @@ prefixize(struct oid *o, int byte_ord) return 1; } +static struct oid * +prefixize(struct snmp_proto *p, struct oid *o, int byte_ord) +{ + const u32 prefix[] = {1, 3, 6, 1}; + + if (o->n_subid < 5) + return NULL; + + for (int i = 0; i < 4; i++) + if (LOAD(o->ids[i], byte_ord) != prefix[i]) + return NULL; + + struct oid *new = mb_alloc(p->p.pool, sizeof(struct oid) + MAX((o->n_subid - 5) * 4, 0)); + + memcpy(new, o, sizeof(struct oid)); + new->n_subid = o->n_subid - 5; + + if (o->ids[4] < 256) + new->prefix = o->ids[4]; + else return NULL; + + memcpy(&new->ids, &o->ids[5], new->n_subid * 4); + return new; +} + static inline byte * -find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, int byte_ord) +find_n_fill(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint contid, int byte_ord) { - if (!o->prefix && prefixize(o, byte_ord)) - find_prefixed(p, o, buf, size); + struct oid *new; + if (!o->prefix && (new = prefixize(p, o, byte_ord)) != NULL) + find_prefixed(p, new, buf, size, contid); else if (o->prefix) - find_prefixed(p, o, buf, size); + find_prefixed(p, o, buf, size, contid); else + // TODO handle unprefixable oids return NULL; } static byte * -prepare_response(struct snmp_proto *p, byte *buf, uint size, u16 err_no, u16 index) +prepare_response(struct snmp_proto *p, byte *buf, uint size) { log(L_INFO "prepare_response()"); if (size < sizeof(struct agentx_response)) return NULL; - struct agentx_response *r = (void *) buf; struct agentx_header *h = &r->h; @@ -903,11 +1231,21 @@ prepare_response(struct snmp_proto *p, byte *buf, uint size, u16 err_no, u16 ind /* protocol doesn't care about subagent upTime */ STORE(r->uptime, 0); - STORE_16(r->err, err_no); - STORE_16(r->index, index); + STORE_16(r->err, AGENTX_RES_NO_ERROR); + STORE_16(r->index, 0); buf += sizeof(struct agentx_response); return buf; } +static void +response_err_ind(byte *buf, uint err, uint ind) +{ + log(L_INFO "reponse_err_ind()"); + struct agentx_response *res = (void *) buf; + + res->err = err; + res->index = ind; +} + #undef SNMP_ERR_SHIFT diff --git a/proto/snmp/subagent.h b/proto/snmp/subagent.h index c34dfa4be..16da447ba 100644 --- a/proto/snmp/subagent.h +++ b/proto/snmp/subagent.h @@ -14,20 +14,22 @@ void snmp_ping(struct snmp_proto *p); #define SNMP_BGP4_MIB 15 /* part of oid .1.3.6.1.2.1.15 */ #define SNMP_OSPFv3_MIB 192 /* part of oid .1.3.6.1.2.1.192 */ +#define BGP4_VERSIONS 0x10 + enum agentx_type { - AGENTX_INTEGER = 2; - AGENTX_OCTET_STRING = 4; - AGENTX_NULL = 5; - AGENTX_OBJECT_ID = 6; - AGENTX_IP_ADDRESS = 64; - AGENTX_COUNTER_32 = 65; - AGENTX_GAUGE_32 = 66; - AGENTX_TIME_TICKS = 67; - AGENTX_OPAQUE = 68; - AGENTX_COUNTER_64 = 70; - AGENTX_NO_SUCH_OBJECT = 128; - AGENTX_NO_SUCH_INSTANCE = 129; - AGENTX_END_OF_MIB_VIEW = 130; + AGENTX_INTEGER = 2, + AGENTX_OCTET_STRING = 4, + AGENTX_NULL = 5, + AGENTX_OBJECT_ID = 6, + AGENTX_IP_ADDRESS = 64, + AGENTX_COUNTER_32 = 65, + AGENTX_GAUGE_32 = 66, + AGENTX_TIME_TICKS = 67, + AGENTX_OPAQUE = 68, + AGENTX_COUNTER_64 = 70, + AGENTX_NO_SUCH_OBJECT = 128, + AGENTX_NO_SUCH_INSTANCE = 129, + AGENTX_END_OF_MIB_VIEW = 130, } PACKED; #define AGENTX_ADMIN_STOP 1 @@ -110,7 +112,7 @@ enum agentx_type { (v)->type = d; \ p += o; -#define BGP_DATA(v, d, p) BGP_DATA(v, d, p, 4) +#define BGP_DATA(v, d, p) BGP_DATA_(v, d, p, 4) struct agentx_header { u8 version; @@ -211,20 +213,33 @@ enum agentx_close_reasons { /* RESPONSE_PDU - result error */ enum agentx_response_err { - AGENTX_RES_NO_ERROR = 0, - AGENTX_RES_OPEN_FAILED = 256, - AGENTX_RES_NOT_OPEN = 257, - AGENTX_RES_INDEX_WRONG_TYPE = 258, - AGENTX_RES_INDEX_ALREADY_ALLOC = 259, - AGENTX_RES_INDEX_NONE_AVAIL = 260, - AGENTX_RES_NOT_ALLOCATED = 261, - AGENTX_RES_UNSUPPORTED_CONTEXT = 262, - AGENTX_RES_DUPLICATE_REGISTR = 263, - AGENTX_RES_UNKNOWN_REGISTR = 264, - AGENTX_RES_UNKNOWN_AGENT_CAPS = 265, - AGENTX_RES_PARSE_ERROR = 266, - AGENTX_RES_REQUEST_DENIED = 267, - AGENTX_RES_PROCESSING_ERR = 268, + AGENTX_RES_NO_ERROR = 0, + /* TEST_SET_PDU response errors */ + AGENTX_RES_GEN_ERROR = 5, + AGENTX_RES_NO_ACCESS = 6, + AGENTX_RES_WRONG_TYPE = 7, + AGENTX_RES_WRONG_LENGTH = 8, + AGENTX_RES_WRONG_ENCODING = 9, + AGENTX_RES_WRONG_VALUE = 10, + AGENTX_RES_NO_CREATION = 11, + AGENTX_RES_INCONSISTENT_VALUE = 12, + AGENTX_RES_RESOURCE_UNAVAILABLE = 13, + AGENTX_RES_NOT_WRITEABLE = 17, + AGENTX_RES_INCONSISTENT_NAME = 18, + /* end of TEST_SET_PDU resonse errs */ + AGENTX_RES_OPEN_FAILED = 256, + AGENTX_RES_NOT_OPEN = 257, + AGENTX_RES_INDEX_WRONG_TYPE = 258, + AGENTX_RES_INDEX_ALREADY_ALLOC = 259, + AGENTX_RES_INDEX_NONE_AVAIL = 260, + AGENTX_RES_NOT_ALLOCATED = 261, + AGENTX_RES_UNSUPPORTED_CONTEXT = 262, + AGENTX_RES_DUPLICATE_REGISTR = 263, + AGENTX_RES_UNKNOWN_REGISTR = 264, + AGENTX_RES_UNKNOWN_AGENT_CAPS = 265, + AGENTX_RES_PARSE_ERROR = 266, + AGENTX_RES_REQUEST_DENIED = 267, + AGENTX_RES_PROCESSING_ERR = 268, } PACKED; int snmp_rx(sock *sk, uint size);