]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
tmp: compiles and runs
authorVojtech Vilimek <vojtech.vilimek@nic.cz>
Sat, 10 Dec 2022 17:08:00 +0000 (18:08 +0100)
committerVojtech Vilimek <vojtech.vilimek@nic.cz>
Sat, 10 Dec 2022 17:08:00 +0000 (18:08 +0100)
proto/snmp/bgp_mib.c
proto/snmp/bgp_mib.h
proto/snmp/snmp.c
proto/snmp/snmp.h
proto/snmp/snmp_utils.c
proto/snmp/snmp_utils.h
proto/snmp/subagent.c
proto/snmp/subagent.h

index 3018809de131e881f6a9b2b604f4c118d0c85a71..07026a05933b295a24c90d014614dbbd0c240c27 100644 (file)
@@ -25,24 +25,24 @@ static const char * const debug_bgp_states[] = {
   [BGP_INTERNAL_IDENTIFIER] = "BGP_INTERNAL_IDENTIFIER",
   [BGP_INTERNAL_STATE] = "BGP_INTERNAL_STATE",
   [BGP_INTERNAL_ADMIN_STATUS] = "BGP_INTERNAL_ADMIN_STATUS",
-  [BGP_INTERNAL_NEGOTIATED_VERSION] = "BGP_INTERNAL_NEGOTIATED_VERSION", 
+  [BGP_INTERNAL_NEGOTIATED_VERSION] = "BGP_INTERNAL_NEGOTIATED_VERSION",
   [BGP_INTERNAL_LOCAL_ADDR] = "BGP_INTERNAL_LOCAL_ADDR",
-  [BGP_INTERNAL_LOCAL_PORT] = "BGP_INTERNAL_LOCAL_PORT", 
+  [BGP_INTERNAL_LOCAL_PORT] = "BGP_INTERNAL_LOCAL_PORT",
   [BGP_INTERNAL_REMOTE_ADDR] = "BGP_INTERNAL_REMOTE_ADDR",
-  [BGP_INTERNAL_REMOTE_PORT] = "BGP_INTERNAL_REMOTE_PORT", 
+  [BGP_INTERNAL_REMOTE_PORT] = "BGP_INTERNAL_REMOTE_PORT",
   [BGP_INTERNAL_REMOTE_AS] = "BGP_INTERNAL_REMOTE_AS",
   [BGP_INTERNAL_RX_UPDATES] = "BGP_INTERNAL_RX_UPDATES",
   [BGP_INTERNAL_TX_UPDATES] = "BGP_INTERNAL_TX_UPDATES",
   [BGP_INTERNAL_RX_MESSAGES] = "BGP_INTERNAL_RX_MESSAGES",
   [BGP_INTERNAL_TX_MESSAGES] = "BGP_INTERNAL_TX_MESSAGES",
-  [BGP_INTERNAL_LAST_ERROR] = "BGP_INTERNAL_LAST_ERROR", 
+  [BGP_INTERNAL_LAST_ERROR] = "BGP_INTERNAL_LAST_ERROR",
   [BGP_INTERNAL_FSM_TRANSITIONS] = "BGP_INTERNAL_FSM_TRANSITIONS",
   [BGP_INTERNAL_FSM_ESTABLISHED_TIME] = "BGP_INTERNAL_FSM_ESTABLISHED_TIME",
   [BGP_INTERNAL_RETRY_INTERVAL] = "BGP_INTERNAL_RETRY_INTERVAL",
   [BGP_INTERNAL_HOLD_TIME] = "BGP_INTERNAL_HOLD_TIME",
   [BGP_INTERNAL_KEEPALIVE] = "BGP_INTERNAL_KEEPALIVE",
   [BGP_INTERNAL_HOLD_TIME_CONFIGURED] = "BGP_INTERNAL_HOLD_TIME_CONFIGURED",
-  [BGP_INTERNAL_KEEPALIVE_CONFIGURED] = "BGP_INTERNAL_KEEPALIVE_CONFIGURED",  
+  [BGP_INTERNAL_KEEPALIVE_CONFIGURED] = "BGP_INTERNAL_KEEPALIVE_CONFIGURED",
   [BGP_INTERNAL_ORIGINATION_INTERVAL] = "BGP_INTERNAL_ORIGINATION_INTERVAL",
   [BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT] = "BGP_INTERNAL_MIN_ROUTE_ADVERTISEMENT",
   [BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME] = "BGP_INTERNAL_IN_UPDATE_ELAPSED_TIME",
@@ -51,8 +51,106 @@ static const char * const debug_bgp_states[] = {
 };
 
 void
-snmp_bgp_register()
-{}
+snmp_bgp_register(struct snmp_proto *p)
+{
+  snmp_log("snmp_bgp_register()");
+
+  u32 arr_bgp[] = {1, 15, 1};
+
+  { /* registering whole BGP4-MIB subtree */
+    snmp_log("snmp_proto %p (%p)", p, p->p.pool);
+    struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
+
+    struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(2));
+    put_u8(&oid->n_subid, 2);
+    put_u8(&oid->prefix, 2);
+
+    memcpy(oid->ids, arr_bgp, 2 * sizeof(u32));
+
+    registering->oid = oid;
+    add_tail(&p->register_queue, &registering->n);
+    p->register_to_ack++;
+
+    snmp_register(p, oid, 0, 1);
+  }
+
+  // TODO squash bgpVersion and bgpLocalAs to one PDU
+  { /* registering BGP4-MIB::bgpVersion */
+    snmp_log("snmp_proto %p (%p)", p, p->p.pool);
+    struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
+
+    struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(3));
+    put_u8(&oid->n_subid, 3);
+    put_u8(&oid->prefix, 2);
+
+    memcpy(oid->ids, arr_bgp, 3 * sizeof(u32));
+
+    registering->oid = oid;
+    add_tail(&p->register_queue, &registering->n);
+    p->register_to_ack++;
+
+    snmp_register(p, oid, 0, 1);
+  }
+
+  { /* registering BGP4-MIB::bgpLocalAs */
+    struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
+
+    struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(3));
+    put_u8(&oid->n_subid, 3);
+    put_u8(&oid->prefix, 2);
+
+    memcpy(oid->ids, arr_bgp, 2 * sizeof(u32));
+    STORE(oid->ids[2], 2);
+
+    registering->oid = oid;
+    add_tail(&p->register_queue, &registering->n);
+    p->register_to_ack++;
+
+    snmp_register(p, oid, 0, 1);
+  }
+
+  { /* registering BGP4-MIB::bgpPeerTable */
+    struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
+
+    struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(3));
+    put_u8(&oid->n_subid, 3);
+    put_u8(&oid->prefix, 2);
+
+    memcpy(oid->ids, arr_bgp, 2 * sizeof(u32));
+    STORE(oid->ids[2], 3);
+
+    registering->oid = oid;
+    add_tail(&p->register_queue, &registering->n);
+    p->register_to_ack++;
+
+    snmp_register(p, oid, 0, 1);
+  }
+
+  /* register dynamic BGP4-MIB::bgpPeerEntry.* */
+
+  u32 arr_with_prefix[] = { 1, 15, 3, 1, 1};
+  snmp_log("before hash walk - registering dynamic parts");
+  HASH_WALK(p->bgp_hash, next, peer)
+  {
+    struct snmp_register *registering = snmp_register_create(p, SNMP_BGP4_MIB);
+
+    struct oid *oid = mb_alloc(p->p.pool, snmp_oid_sizeof(10));
+
+    put_u8(&oid->n_subid, 9);
+    put_u8(&oid->prefix, 2);
+
+    memcpy(oid->ids, arr_with_prefix, 5 * sizeof(u32));
+
+    snmp_oid_ip4_index(oid, 5, ipa_to_ip4(peer->peer_ip));
+
+    registering->oid = oid;
+    add_tail(&p->register_queue, &registering->n);
+
+    snmp_register(p, oid, 0, 1);
+  }
+  HASH_WALK_END;
+  snmp_log("after hash walk");
+}
 
 int
 snmp_bgp_valid_ip4(struct oid *o)
@@ -110,7 +208,7 @@ static void
 print_bgp_record(struct bgp_config *config)
 {
   struct proto_config *cf = (struct proto_config *) config;
-  struct proto *P = cf->proto;
+  // struct proto *P = cf->proto;
   struct bgp_proto *bgp_proto = (struct bgp_proto *) cf->proto;
   struct bgp_conn *conn = bgp_proto->conn;
 
@@ -381,14 +479,14 @@ update_bgp_oid(struct oid *oid, u8 state)
   {
     case BGP_INTERNAL_BGP:
       /* could destroy same old data */
-      oid = mb_realloc(oid, sizeof(struct oid) + 2 * sizeof(u32));
+      oid = mb_realloc(oid, snmp_oid_sizeof(2));
       oid->n_subid = 2;
       oid->ids[0] = 1;
       oid->ids[1] = SNMP_BGP4_MIB;
       break;
 
     case BGP_INTERNAL_VERSION:
-      oid = mb_realloc(oid, sizeof(struct oid) + 3 * sizeof(u32));
+      oid = mb_realloc(oid, snmp_oid_sizeof(3));
       oid->n_subid = 3;
       oid->ids[2] = SNMP_BGP_VERSION;
       break;
@@ -398,7 +496,7 @@ update_bgp_oid(struct oid *oid, u8 state)
       break;
 
     case BGP_INTERNAL_IDENTIFIER:
-      oid = mb_realloc(oid, sizeof(struct oid) + 9 * sizeof(u32));
+      oid = mb_realloc(oid, snmp_oid_sizeof(9));
       oid->n_subid = 9;
       oid->ids[2] = SNMP_BGP_PEER_TABLE;
       oid->ids[3] = SNMP_BGP_PEER_ENTRY;
@@ -484,7 +582,7 @@ bgp_find_dynamic_oid(struct snmp_proto *p, struct oid *o_start, struct oid *o_en
 
   if (trie_walk_next(ws, net) && ip4_less(net4_prefix(net), dest))
   {
-    struct oid *o = mb_allocz(p->p.pool, sizeof(struct oid) + 9 * sizeof(u32));
+    struct oid *o = mb_allocz(p->p.pool, snmp_oid_sizeof(9));
     o->n_subid = 9;
 
     memcpy(o, o_start, snmp_oid_size(o_start));
index 56080010c2d857b7377e6e51236e7bb0a3d51d94..7cce97226540d89a8d3662351a9820b996f1fd33 100644 (file)
@@ -37,7 +37,7 @@ enum BGP4_MIB {
 
 struct oid;
 
-void snmp_bgp_register(void);
+void snmp_bgp_register(struct snmp_proto *p);
 // - int snmp_bgp_is_supported(struct oid *o);
 
 int snmp_bgp_valid_ip4(struct oid *o);
index 13071c3a27df59de96e0e8d24521442074256e27..e383f85d60387f8c361902286a0e63173713d809 100644 (file)
@@ -94,7 +94,6 @@ snmp_startup(struct snmp_proto *p)
 
   snmp_log("preparing lock");
   struct object_lock *lock;
-  snmp_log("snmp_startup() object lock state %p", p->lock);
 
   /* we could have the lock already acquired but be in ERROR state */
   lock = p->lock = olock_new(p->p.pool);
@@ -209,6 +208,9 @@ snmp_start(struct proto *P)
   p->pool = lp_new(p->p.pool);
   p->bgp_trie = f_new_trie(p->pool, cf->bonds);
 
+  init_list(&p->register_queue);
+  init_list(&p->bgp_registered);
+
   p->ping_timer = tm_new_init(p->p.pool, snmp_ping_timer, p, 0, 0);
   // tm_set(p->ping_timer, current_time() + 2 S);
 
@@ -271,6 +273,9 @@ snmp_reconfigure(struct proto *P, struct proto_config *CF)
   p->local_as = cf->local_as;
   p->timeout = 15;
 
+  /* workaround to make the registration happen */
+  p->register_to_ack = 1;
+
   /* TODO walk all bind protocols and find their (new) IP
     to update HASH table */
   snmp_log("snmp_reconfigure() lip: %I:%u rip: %I:%u",
@@ -359,7 +364,7 @@ snmp_postconfig(struct proto_config *CF)
 static void
 snmp_ping_timer(struct timer *tm)
 {
-  snmp_log("snmp_ping_timer() ");
+  // snmp_log("snmp_ping_timer() ");
   struct snmp_proto *p = tm->data;
 
   if (p->state == SNMP_CONN)
@@ -374,6 +379,7 @@ snmp_ping_timer(struct timer *tm)
 static int
 snmp_shutdown(struct proto *P)
 {
+  snmp_log("snmp_shutdown()");
   struct snmp_proto *p = SKIP_BACK(struct snmp_proto, p, P);
   p->state = SNMP_INIT;
 
index 5960d3d713a5f77f7b8fc02e3a486fe622928cfb..8f4eede894651eb18a897f8a57b16ef0db2eeb45 100644 (file)
@@ -72,6 +72,20 @@ struct snmp_bgp_peer {
   struct snmp_bgp_peer *next;
 };
 
+struct snmp_register {
+  node n;
+  u8 mib_class;
+  u32 session_id;
+  u32 transaction_id;
+  u32 packet_id;
+  struct oid *oid;
+};
+
+struct snmp_registered_oid {
+  node n;
+  struct oid *oid;
+};
+
 struct snmp_proto {
   struct proto p;
   struct object_lock *lock;
@@ -84,12 +98,17 @@ struct snmp_proto {
   u32 local_as;
 
   sock *sock;
+  // timeout for what ??
   u8 timeout;
 
   u32 session_id;
   u32 transaction_id;
   u32 packet_id;
 
+  uint register_to_ack;                    /* counter of pending responses to register-pdu */
+  list register_queue;             /* list containing snmp_register records */
+  list bgp_registered;             /* list of currently registered bgp oids
+                                     (struct snmp_registered_oid) */
   //struct iface *iface;
 
   // map
@@ -107,4 +126,14 @@ struct snmp_proto {
   uint errs;
 };
 
+/*
+struct snmp_pdu {
+  node n;
+
+  //u32 session_id;
+  u32 transaction_id;
+  u32 packet_id; // in future need support for ranges of packet_id-s
+};
+*/
+
 #endif
index ba3510530da219df0cf54f737d8048716a3ed2da..225efd4c54f5e4f2f138865579f30979f177f648 100644 (file)
@@ -36,6 +36,16 @@ snmp_pkt_len(byte *buf, byte *pkt)
   return (pkt - buf) - AGENTX_HEADER_SIZE;
 }
 
+/**
+ * create new null oid (blank)
+ * @p: pool hodling snmp_proto structure
+ */
+struct oid *
+snmp_oid_blank(struct snmp_proto *p)
+{
+  return mb_allocz(p->p.pool, sizeof(struct oid));
+}
+
 /**
  * snmp_str_size - return in packet size of supplied string
  * @str: measured string
@@ -60,6 +70,16 @@ snmp_oid_size(struct oid *o)
   return 4 + (o->n_subid << 2);
 }
 
+/**
+ * snmp_get_size - calculate size for allocation
+ * @n_subid: number of ids in oid
+ */
+inline size_t
+snmp_oid_sizeof(uint n_subid)
+{
+  return sizeof(struct oid) + n_subid * sizeof(u32);
+}
+
 /**
  * snmp_vb_size - measure size of varbind in bytes
  * @vb: variable binding to use
@@ -191,13 +211,12 @@ snmp_put_oid(byte *buf, struct oid *oid)
 byte *
 snmp_put_fbyte(byte *buf, u8 data)
 {
-  log(L_INFO "paste_fbyte()");
+  // log(L_INFO "paste_fbyte()");
   put_u8(buf, data);
   put_u24(++buf, 0);  // PADDING
   return buf + 3;
 }
 
-
 void
 snmp_oid_ip4_index(struct oid *o, uint start, ip4_addr addr)
 {
@@ -298,3 +317,55 @@ all_same:
   else
     return 0;
 }
+
+struct snmp_register *
+snmp_register_create(struct snmp_proto *p, u8 mib_class)
+{
+  struct snmp_register *r = mb_alloc(p->p.pool, sizeof(struct snmp_register));
+
+  r->n.prev = r->n.next = NULL;
+
+  r->session_id = p->session_id;
+  r->transaction_id = p->transaction_id;
+  r->packet_id = p->packet_id;
+
+  r->mib_class = mib_class;
+
+  return r;
+}
+
+int
+snmp_register_same(struct snmp_register *r, struct agentx_header *h, u8 class)
+{
+  return
+    (r->mib_class == class) &&
+    (r->session_id == h->session_id) &&
+    (r->transaction_id == h->transaction_id) &&
+    (r->packet_id == h->packet_id);
+}
+
+void
+snmp_register_ack(struct snmp_proto *p, struct agentx_header *h)
+{
+  struct snmp_register *reg;
+  WALK_LIST(reg, p->register_queue)
+  {
+    // TODO add support for more mib trees (other than BGP)
+    if (snmp_register_same(reg, h, SNMP_BGP4_MIB))
+    {
+      struct snmp_registered_oid *ro = \
+        mb_alloc(p->p.pool, sizeof(struct snmp_registered_oid));
+
+      ro->n.prev = ro->n.next = NULL;
+
+      ro->oid = reg->oid;
+
+      rem_node(&reg->n);
+      p->register_to_ack--;
+
+      add_tail(&p->bgp_registered, &ro->n);
+
+      return;
+    }
+  }
+}
index a1bd6df338db86cbdc438f3782ce68b956b053ee..f624fbd0f4e7e2a877767c8b510a852230cdfb29 100644 (file)
@@ -9,8 +9,11 @@ int snmp_is_oid_empty(struct oid *oid);
 int snmp_valid_ip4_index(struct oid *o, uint start);
 int snmp_valid_ip4_index_unsafe(struct oid *o, uint start);
 uint snmp_oid_size(struct oid *o);
+size_t snmp_oid_sizeof(uint n_subid);
 uint snmp_varbind_size(struct agentx_varbind *vb);
 
+struct oid *snmp_oid_blank(struct snmp_proto *p);
+
 struct agentx_varbind *snmp_create_varbind(byte* buf, struct oid *oid);
 byte *snmp_fix_varbind(struct agentx_varbind *vb, struct oid *new);
 
@@ -32,4 +35,8 @@ void snmp_oid_dump(struct oid *oid);
 int snmp_oid_compare(struct oid *left, struct oid *right);
 
 struct oid *snmp_prefixize(struct snmp_proto *p, struct oid *o, int byte_ord);
+
+struct snmp_register *snmp_register_create(struct snmp_proto *p, u8 mib_class);
+
+void snmp_register_ack(struct snmp_proto *p, struct agentx_header *h);
 #endif
index a91da7e471fdf075067c0d62829f19895c55beac..44040a61f6e95d5ddd71a0a1617ed4a3b6c3cb24 100644 (file)
@@ -55,6 +55,27 @@ static const char * const snmp_errs[] = {
   [AGENTX_RES_PROCESSING_ERR - SNMP_ERR_SHIFT] = "Processing error",
 };
 
+static const char * const snmp_pkt_type[] = {
+  [AGENTX_OPEN_PDU]              =  "Open-PDU",
+  [AGENTX_CLOSE_PDU]             =  "Close-PDU",
+  [AGENTX_REGISTER_PDU]                  =  "Register-PDU",
+  [AGENTX_UNREGISTER_PDU]        =  "Unregister-PDU",
+  [AGENTX_GET_PDU]               =  "Get-PDU",
+  [AGENTX_GET_NEXT_PDU]                  =  "GetNext-PDU",
+  [AGENTX_GET_BULK_PDU]                  =  "GetBulk-PDU",
+  [AGENTX_TEST_SET_PDU]                  =  "TestSet-PDU",
+  [AGENTX_COMMIT_SET_PDU]        =  "CommitSet-PDU",
+  [AGENTX_UNDO_SET_PDU]                  =  "UndoSet-PDU",
+  [AGENTX_CLEANUP_SET_PDU]       =  "CleanupSet-PDU",
+  [AGENTX_NOTIFY_PDU]            =  "Notify-PDU",
+  [AGENTX_PING_PDU]              =  "Ping-PDU",
+  [AGENTX_INDEX_ALLOCATE_PDU]     =  "IndexAllocate-PDU",
+  [AGENTX_INDEX_DEALLOCATE_PDU]   =  "IndexDeallocate-PDU",
+  [AGENTX_ADD_AGENT_CAPS_PDU]    =  "AddAgentCaps-PDU",
+  [AGENTX_REMOVE_AGENT_CAPS_PDU]  =  "RemoveAgentCaps-PDU",
+  [AGENTX_RESPONSE_PDU]                  =  "Response-PDU",
+};
+
 static void
 open_pdu(struct snmp_proto *p, struct oid *oid)
 {
@@ -157,7 +178,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
     STORE(ur->range_subid, (len > 1) ? index : 0);
 
     pkt = snmp_put_oid(pkt, oid);
-    snmp_log("pkt - buf : %lu sizeof %u", pkt -buf, AGENTX_HEADER_SIZE);
+    // snmp_log("pkt - buf : %lu sizeof %u", pkt -buf, AGENTX_HEADER_SIZE);
 
     /* place upper-bound if needed */
     if (len > 1)
@@ -166,13 +187,15 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
       pkt += 4;
     }
 
-    log("size of pkt: %u", snmp_pkt_len(buf,pkt));
+    // log("size of pkt: %u", snmp_pkt_len(buf,pkt));
     SNMP_UPDATE(h, snmp_pkt_len(buf, pkt));
 
+    /*
     for (uint i = 0; i < pkt - buf; i++)
       snmp_log("%p:  %02X", buf+i, *(buf + i));
+    */
 
-    snmp_log("sending (un)register %d", type);
+    snmp_log("sending (un)register %s", snmp_pkt_type[type]);
     int ret = sk_send(sk, pkt - buf);
 
     if (ret == 0)
@@ -188,7 +211,7 @@ un_register_pdu(struct snmp_proto *p, struct oid *oid, uint index, uint len, u8
 }
 
 /* register pdu */
-static void
+void
 snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len)
 {
   un_register_pdu(p, oid, index, len, AGENTX_REGISTER_PDU);
@@ -196,7 +219,7 @@ snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len)
 
 
 /* unregister pdu */
-static void UNUSED
+void UNUSED
 snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len)
 {
   un_register_pdu(p, oid, index, len, AGENTX_UNREGISTER_PDU);
@@ -253,7 +276,9 @@ parse_pkt(struct snmp_proto *p, byte *buf, uint size)
 
   uint len = 0;
   struct agentx_header *h = (void *) buf;
-  snmp_log("parse_pkt got type %u", h->type);
+
+  snmp_log("parse_pkt got type %s", snmp_pkt_type[h->type]);
+
   switch (h->type)
   {
     case AGENTX_RESPONSE_PDU:
@@ -305,13 +330,13 @@ parse_response(struct snmp_proto *p, byte *buf, uint size)
   struct agentx_response *r = (void *) buf;
   struct agentx_header *h = &r->h;
 
-  snmp_log("endianity: %s, session %u, transaction: %u", (h->flags & AGENTX_NETWORK_BYTE_ORDER) ? "big end":
+  snmp_log("  endianity: %s, session %u, transaction: %u", (h->flags & AGENTX_NETWORK_BYTE_ORDER) ? "big end":
 "little end", h->session_id, h->transaction_id);
-  snmp_log("sid: %3u\ttid: %3u\tpid: %3u\t", p->session_id, p->transaction_id,
+  snmp_log("  sid: %3u\ttid: %3u\tpid: %3u\t", p->session_id, p->transaction_id,
 p->packet_id);
 
-  snmp_log("size %u", h->payload);
-  snmp_log("uptime: %u s", r->uptime);
+  snmp_log("  pkt size %u", h->payload);
+  // snmp_log("uptime: %u s", r->uptime);
 
   if (r->err == AGENTX_RES_NO_ERROR)
     do_response(p, buf, size);
@@ -322,9 +347,27 @@ SNMP_ERR_SHIFT]);
   return 1;
 }
 
+static inline int
+snmp_registered_all(struct snmp_proto *p)
+{
+  return p->register_to_ack == 0;
+}
+
+static void
+snmp_register_mibs(struct snmp_proto *p) {
+  snmp_log("snmp_register_mibs()");
+
+  snmp_bgp_register(p);
+
+  snmp_log("registering all done");
+}
+
+
+
 static void
 do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
 {
+  snmp_log("do_response()");
   struct agentx_response *r = (void *) buf;
   struct agentx_header *h = &r->h;
 
@@ -332,6 +375,7 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
   switch (p->state)
   {
     case SNMP_INIT:
+      /* parse open_pdu response */
       if (h->flags & AGENTX_NETWORK_BYTE_ORDER)
       {
        p->session_id = get_u32(&h->session_id);
@@ -343,73 +387,23 @@ do_response(struct snmp_proto *p, byte *buf, uint size UNUSED)
        memcpy(&p->session_id, &h->session_id, 12);
       }
 
-      p->transaction_id++;
-
-      snmp_log("sending register-pdu");
-
-      // register whole BGP4-MIB
-      u32 arr_bgp[] = {1, 15, 1};
-      struct oid *o = mb_allocz(p->p.pool, 4 * sizeof(u32));
-      put_u8(&o->n_subid, 2);
-      put_u8(&o->prefix, 2);
-
-      memcpy(o->ids, arr_bgp, 2 * sizeof(u32));
-
-      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 * sizeof(u32));
-
-      put_u8(&o2->n_subid, 9);
-      memcpy(o2->ids, arr_with_prefix, 5 * sizeof(u32));
-      u32 remote_addr[] = {10, 0, 0, 0};
-      memcpy(o2->ids + 5, remote_addr, 4 * sizeof(u32));
-      STORE(o2->prefix, 2);
-
-      // register first line in BGP4-MIB bgpPeerTable
-      // TODO register all bind bgp connections
-      snmp_register(p, o2, 9, 24);
-
-      snmp_log("before hash walk");
-      HASH_WALK(p->bgp_hash, next, peer)
-      {
-       snmp_oid_ip4_index(o2, 5, ipa_to_ip4(peer->peer_ip));
-
-       snmp_log("");
-       snmp_log("o2 n_subid %u prefix %u include %u", o2->n_subid,
-         o2->prefix, o2->include);
-       for (int i = 0; i < o2->n_subid; i++)
-         snmp_log("%d: %u", i, o2->ids[i]);
-       snmp_log("");
-
-       snmp_register(p, o2, 9, 24);
-      }
-      HASH_WALK_END;
-      snmp_log("after hash walk");
-
-      mb_free(o2);
-
-      snmp_log("changing proto_snmp state to REGISTER");
+      snmp_register_mibs(p);
+      snmp_log("changing state to REGISTER");
       p->state = SNMP_REGISTR;
-      //proto_notify_state(&p->p, PS_UP);
+
       break;
 
     case SNMP_REGISTR:
-      snmp_log("chaning proto_snmp state to CONNECTED");
-      p->state = SNMP_CONN;
+      snmp_register_ack(p, h);
+
+      if (snmp_registered_all(p)) {
+       snmp_log("changing proto_snmp state to CONNECTED");
+       p->state = SNMP_CONN;
+      }
       break;
 
     case SNMP_CONN:
+      // proto_notify_state(&p->p, PS_UP);
       break;
 
     default:
@@ -526,7 +520,7 @@ get_mib_class(struct oid *oid)
 
     default:
       return SNMP_CLASS_END;
-  } 
+  }
 }
 
 static byte *
@@ -800,15 +794,15 @@ snmp_start_subagent(struct snmp_proto *p)
   snmp_log("snmp_start_subagent() starting subagent");
 
   /* blank oid means unsupported */
-  struct oid *o = mb_allocz(p->p.pool, sizeof(struct oid));
-  open_pdu(p, o);
-  mb_free(o);
+  struct oid *blank = snmp_oid_blank(p);
+  open_pdu(p, blank);
+  mb_free(blank);
 }
 
 void
 snmp_stop_subagent(struct snmp_proto *p)
 {
-  snmp_log("snmp_stop_subagent()");
+  snmp_log("snmp_stop_subagent() state %s", p->state);
   sock *sk = p->sock;
 
   if (p->state == SNMP_CONN)
@@ -860,7 +854,6 @@ snmp_ping(struct snmp_proto *p)
   {
     snmp_log("ping_pdu()");
     struct agentx_header *h;
-    log("before dead %p", pkt );
     SNMP_CREATE(pkt, struct agentx_header, h);
     SNMP_B_HEADER(h, AGENTX_PING_PDU);
     SNMP_SESSION(h, p);
@@ -873,7 +866,7 @@ snmp_ping(struct snmp_proto *p)
     else if (ret < 0)
       snmp_log("sk_send err %d", ret);
     else
-      log("sk_send ok ! !");
+      snmp_log("sk_send ok ! !");
   }
 
   else
@@ -895,8 +888,8 @@ snmp_stop_ack(sock *sk, uint size)
     p->p.disabled = 1;
     proto_notify_state(&p->p, PS_DOWN);
 
-    sk->tx_hook = NULL;
-    sk->rx_hook = NULL;
+    //sk->tx_hook = NULL;
+    //sk->rx_hook = NULL;
   }
 
   /* all done */
@@ -1326,7 +1319,7 @@ find_prefixed(struct snmp_proto *p, struct oid *o, byte *buf, uint size, uint co
  * @byte_ord: byte order of @oid 
  *
  * Returns prefixed (meaning with nonzero prefix field) oid copy of @oid if
- * possible. NULL otherwise. Returned pointer is always allocated from @proto's
+ * possible, NULL otherwise. Returned pointer is always allocated from @proto's
  * pool not a pointer to recieve buffer (from which is most likely @oid).
  */
 struct oid *
@@ -1340,8 +1333,7 @@ snmp_prefixize(struct snmp_proto *proto, struct oid *oid, int byte_ord)
   if (snmp_is_oid_empty(oid))
   {
     /* allocate new zeroed oid */
-    struct oid *new = mb_allocz(proto->p.pool, sizeof(struct oid));
-    return new;
+    return snmp_oid_blank(proto);
   }
   else if (LOAD(oid->n_subid, byte_ord) != 0)
   {
@@ -1357,6 +1349,7 @@ snmp_prefixize(struct snmp_proto *proto, struct oid *oid, int byte_ord)
     if (LOAD(oid->ids[i], byte_ord) != prefix[i])
       return NULL;
 
+  /* validity chech here */
   if (oid->ids[4] >= 256)
     return NULL;
 
@@ -1400,7 +1393,7 @@ byte *buf, uint size, struct snmp_error *error, uint contid, int byte_ord)
   struct agentx_varbind *vb = snmp_create_varbind(buf, oid);
   buf += snmp_varbind_size(vb);
 
-                       /* SNMPv2   mgmt                     mib-2 */
+                       /* SNMPv2      mgmt               mib-2 */
   if (oid->n_subid < 2 || (oid->prefix != 2 && oid->ids[0] != 1))
   {
     vb->type = AGENTX_NO_SUCH_OBJECT; 
index 889cab6557874248dd0474177445af20d5c756b7..27c878f742296a0ffea4af2f6f403d7a6c4f2ba6 100644 (file)
@@ -273,6 +273,8 @@ enum agentx_response_err {
 } PACKED;
 
 int snmp_rx(sock *sk, uint size);
+void snmp_register(struct snmp_proto *p, struct oid *oid, uint index, uint len);
+void snmp_unregister(struct snmp_proto *p, struct oid *oid, uint index, uint len);
 
 // debug wrapper
 #define snmp_log(...) log(L_INFO "snmp " __VA_ARGS__)