]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lwip.git/commitdiff
Improved TRAP interfacing. Varbinds maybe allocated at (external) trap source as...
authorchristiaans <christiaans>
Thu, 7 Sep 2006 14:17:03 +0000 (14:17 +0000)
committerchristiaans <christiaans>
Thu, 7 Sep 2006 14:17:03 +0000 (14:17 +0000)
src/core/snmp/mib2.c
src/core/snmp/msg_in.c
src/core/snmp/msg_out.c
src/include/lwip/opt.h
src/include/lwip/snmp.h
src/include/lwip/snmp_msg.h

index ba0474314e589e6a96d64f5d497b6aa36cb8e832..bed77df2d73bb1e26182bf325b7e5b600ae7d21a 100644 (file)
@@ -1919,6 +1919,11 @@ void snmp_set_snmpenableauthentraps(u8_t *value)
   }
 }
 
+void snmp_get_snmpenableauthentraps(u8_t *value)
+{
+  *value = *snmpenableauthentraps_ptr;
+}
+
 void
 noleafs_get_object_def(u8_t ident_len, s32_t *ident, struct obj_def *od)
 {
index c80b24e6939518864d461c4a9db8da0d65317ccf..3f70d6f68afe784413793d678be5d01a4c3407c0 100644 (file)
@@ -66,12 +66,6 @@ struct udp_pcb *snmp1_pcb = NULL;
 static void snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, struct ip_addr *addr, u16_t port);
 static err_t snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
 static err_t snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_msg_pstat *m_stat);
-static struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len);
-static void snmp_varbind_free(struct snmp_varbind *vb);
-static void snmp_varbind_list_free(struct snmp_varbind_root *root);
-static void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb);
-static struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root);
-
 
 
 /**
@@ -99,6 +93,9 @@ snmp_init(void)
     msg_ps++;
   }
   trap_msg.pcb = snmp1_pcb;
+  /* The coldstart trap will only be output
+     if our outgoing interface is up & configured  */
+  snmp_coldstart_trap();
 }
 
 #if 0
@@ -501,12 +498,11 @@ snmp_pdu_header_check(struct pbuf *p, u16_t ofs, u16_t pdu_len, u16_t *ofs_ret,
   len = ((len < (SNMP_COMMUNITY_STR_LEN))?(len):(SNMP_COMMUNITY_STR_LEN));
   m_stat->community[len] = 0;
   m_stat->com_strlen = len;
-  if (strncmp(snmp_publiccommunity, m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
+  if (strncmp(snmp_publiccommunity, (const char*)m_stat->community, SNMP_COMMUNITY_STR_LEN) != 0)
   {
     /** @todo: move this if we need to check more names */
     snmp_inc_snmpinbadcommunitynames();
-
-    /** @todo: send authentication failure trap, if we have a trap destination */
+    snmp_authfail_trap();
     return ERR_ARG;
   }
   ofs += (1 + len_octets + len);
@@ -826,7 +822,7 @@ snmp_pdu_dec_varbindlist(struct pbuf *p, u16_t ofs, u16_t *ofs_ret, struct snmp_
   return ERR_OK;
 }
 
-static struct snmp_varbind*
+struct snmp_varbind*
 snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
 {
   struct snmp_varbind *vb;
@@ -885,7 +881,7 @@ snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len)
   return vb;
 }
 
-static void
+void
 snmp_varbind_free(struct snmp_varbind *vb)
 {
   if (vb->value != NULL )
@@ -899,7 +895,7 @@ snmp_varbind_free(struct snmp_varbind *vb)
   mem_free(vb);
 }
 
-static void
+void
 snmp_varbind_list_free(struct snmp_varbind_root *root)
 {
   struct snmp_varbind *vb, *prev;
@@ -916,7 +912,7 @@ snmp_varbind_list_free(struct snmp_varbind_root *root)
   root->tail = NULL;
 }
 
-static void
+void
 snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb)
 {
   if (root->count == 0)
@@ -935,7 +931,7 @@ snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb)
   root->count += 1;
 }
 
-static struct snmp_varbind*
+struct snmp_varbind*
 snmp_varbind_tail_remove(struct snmp_varbind_root *root)
 {
   struct snmp_varbind* vb;
index e3cabde2d2467582e5e3874d7fa20e42535b0e04..22abf082b51791625d2ccf34a0e38efc5941446b 100644 (file)
 #include "lwip/snmp_asn1.h"
 #include "lwip/snmp_msg.h"
 
-/**
- * TRAP message structure
- * @todo turn this into an arg to snmp_create_trap ?
- */
+struct snmp_trap_dst
+{
+  /* destination IP address in network order */
+  struct ip_addr dip;
+  /* set to 0 when disabled, >0 when enabled */
+  u8_t enable;
+};
+#if (SNMP_TRAP_DESTINATIONS == 0)
+#error "need at least one trap destination"
+#endif
+struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS];
+
+/** TRAP message structure */
 struct snmp_msg_trap trap_msg;
 
 static u16_t snmp_resp_header_sum(struct snmp_msg_pstat *m_stat, u16_t vb_len);
@@ -67,7 +76,33 @@ static u16_t snmp_resp_header_enc(struct snmp_msg_pstat *m_stat, struct pbuf *p)
 static u16_t snmp_trap_header_enc(struct snmp_msg_trap *m_trap, struct pbuf *p);
 static u16_t snmp_varbind_list_enc(struct snmp_varbind_root *root, struct pbuf *p, u16_t ofs);
 
+/**
+ * Sets enable switch for this trap destination.
+ * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
+ * @param enable switch if 0 destination is disabled >0 enabled.
+ */
+void
+snmp_trap_dst_enable(u8_t dst_idx, u8_t enable)
+{
+  if (dst_idx < SNMP_TRAP_DESTINATIONS)
+  {
+    trap_dst[dst_idx].enable = enable;
+  }
+}
 
+/**
+ * Sets IPv4 address for this trap destination.
+ * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1
+ * @param dst IPv4 address in host order.
+ */
+void
+snmp_trap_dst_ip_set(u8_t dst_idx, struct ip_addr *dst)
+{
+  if (dst_idx < SNMP_TRAP_DESTINATIONS)
+  {
+    trap_dst[dst_idx].dip.addr = htonl(dst->addr);
+  }
+}
 
 /**
  * Sends a 'getresponse' message to the request originator.
@@ -172,7 +207,6 @@ snmp_send_response(struct snmp_msg_pstat *m_stat)
 /**
  * Sends an generic or enterprise specific trap message.
  *
- * @param dst points to the trap destination IPv4 address
  * @param generic_trap is the trap code
  * @param specific_trap used for enterprise traps when generic_trap == 6
  * @return ERR_OK when success, ERR_MEM if we're out of memory
@@ -185,63 +219,96 @@ snmp_send_response(struct snmp_msg_pstat *m_stat)
  * (sysObjectID) for specific traps.
  */
 err_t
-snmp_send_trap(struct ip_addr *dst, s8_t generic_trap, s32_t specific_trap)
+snmp_send_trap(s8_t generic_trap, s32_t specific_trap)
 {
+  struct snmp_trap_dst *td;
   struct netif *dst_if;
+  struct ip_addr dst_ip;
   struct pbuf *p;
-  u16_t tot_len;
+  u16_t i,tot_len;
 
-  /* network order trap destination */
-  trap_msg.dip.addr = htonl(dst->addr);
-  /* lookup current source address for this dst */
-  dst_if = ip_route(dst);
-  trap_msg.sip_raw[0] = dst_if->ip_addr.addr >> 24;
-  trap_msg.sip_raw[1] = dst_if->ip_addr.addr >> 16;
-  trap_msg.sip_raw[2] = dst_if->ip_addr.addr >> 8;
-  trap_msg.sip_raw[3] = dst_if->ip_addr.addr;
-  trap_msg.gen_trap = generic_trap;
-  trap_msg.spc_trap = specific_trap;
-  if (generic_trap == 6)
+  for (i=0, td = &trap_dst[0]; i<SNMP_TRAP_DESTINATIONS; i++, td++)
   {
-    /* enterprise-Specific trap */
-    snmp_get_sysobjid_ptr(&trap_msg.enterprise);
-  }
-  else
-  {
-    /* generic (MIB-II) trap */    
-    snmp_get_snmpgrpid_ptr(&trap_msg.enterprise);
-  }
-  snmp_get_sysuptime(&trap_msg.ts);
-
-  /* pass 0, calculate length fields */
-  tot_len = snmp_varbind_list_sum(&trap_msg.outvb);
-  tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
-
-  /* allocate pbuf(s) */
-  p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
-  if (p != NULL)
-  {
-    u16_t ofs;
+    if ((td->enable != 0) && (td->dip.addr != 0))
+    {
+      /* network order trap destination */
+      trap_msg.dip.addr = td->dip.addr;
+      /* lookup current source address for this dst */
+      dst_if = ip_route(&td->dip);
+      dst_ip.addr = ntohl(dst_if->ip_addr.addr);
+      trap_msg.sip_raw[0] = dst_ip.addr >> 24;
+      trap_msg.sip_raw[1] = dst_ip.addr >> 16;
+      trap_msg.sip_raw[2] = dst_ip.addr >> 8;
+      trap_msg.sip_raw[3] = dst_ip.addr;
+      trap_msg.gen_trap = generic_trap;
+      trap_msg.spc_trap = specific_trap;
+      if (generic_trap == SNMP_GENTRAP_ENTERPRISESPC)
+      {
+        /* enterprise-Specific trap */
+        snmp_get_sysobjid_ptr(&trap_msg.enterprise);
+      }
+      else
+      {
+        /* generic (MIB-II) trap */    
+        snmp_get_snmpgrpid_ptr(&trap_msg.enterprise);
+      }
+      snmp_get_sysuptime(&trap_msg.ts);
+
+      /* pass 0, calculate length fields */
+      tot_len = snmp_varbind_list_sum(&trap_msg.outvb);
+      tot_len = snmp_trap_header_sum(&trap_msg, tot_len);
+
+      /* allocate pbuf(s) */
+      p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_POOL);
+      if (p != NULL)
+      {
+        u16_t ofs;
     
-    /* pass 1, encode packet ino the pbuf(s) */
-    ofs = snmp_trap_header_enc(&trap_msg, p);
-    snmp_varbind_list_enc(&trap_msg.outvb, p, ofs);
-
-    snmp_inc_snmpouttraps();
-    snmp_inc_snmpoutpkts();
+        /* pass 1, encode packet ino the pbuf(s) */
+        ofs = snmp_trap_header_enc(&trap_msg, p);
+        snmp_varbind_list_enc(&trap_msg.outvb, p, ofs);
+
+        snmp_inc_snmpouttraps();
+        snmp_inc_snmpoutpkts();
+
+        /** connect to the TRAP destination */
+        udp_connect(trap_msg.pcb, &trap_msg.dip, SNMP_TRAP_PORT);
+        udp_send(trap_msg.pcb, p);
+        /** disassociate remote address and port with this pcb */
+        udp_disconnect(trap_msg.pcb);
+
+        pbuf_free(p);
+      }
+      else
+      {
+        return ERR_MEM;
+      }
+    }
+    td++;
+  }
+  return ERR_OK;
+}
 
-    /** connect to the TRAP destination */
-    udp_connect(trap_msg.pcb, &trap_msg.dip, SNMP_TRAP_PORT);
-    udp_send(trap_msg.pcb, p);
-    /** disassociate remote address and port with this pcb */
-    udp_disconnect(trap_msg.pcb);
+void
+snmp_coldstart_trap(void)
+{  
+  trap_msg.outvb.head = NULL;
+  trap_msg.outvb.tail = NULL;
+  trap_msg.outvb.count = 0;
+  snmp_send_trap(SNMP_GENTRAP_COLDSTART, 0);
+}
 
-    pbuf_free(p);
-    return ERR_OK;
-  }
-  else
+void
+snmp_authfail_trap(void)
+{  
+  u8_t enable;
+  snmp_get_snmpenableauthentraps(&enable);
+  if (enable == 1)
   {
-    return ERR_MEM;
+    trap_msg.outvb.head = NULL;
+    trap_msg.outvb.tail = NULL;
+    trap_msg.outvb.count = 0;
+    snmp_send_trap(SNMP_GENTRAP_AUTHFAIL, 0);
   }
 }
 
index eeb3a57eb2184e7ef10cce31b74aff2071494170..c5e21f76efa11d6a14c69f514fae17a6be62cc47 100644 (file)
@@ -250,11 +250,14 @@ a lot of data that needs to be copied, this should be set high. */
 #endif
 
 /* ---------- SNMP options ---------- */
-/** @todo SNMP isn't functional yet. 
-    @note UDP must be available for SNMP transport */
+/** @note UDP must be available for SNMP transport */
 #ifndef LWIP_SNMP
 #define LWIP_SNMP                       0
 #endif
+/** @note At least one trap destination is required */
+#ifndef SNMP_TRAP_DESTINATIONS
+#define SNMP_TRAP_DESTINATIONS          1
+#endif
 
 #ifndef SNMP_PRIVATE_MIB
 #define SNMP_PRIVATE_MIB                0
index 12ae7b49a9a04751c20227f5f29072c8e12677c5..95145ce0c2b5ac3bb5c282084133e67629cb33e2 100644 (file)
@@ -175,6 +175,7 @@ void snmp_inc_snmpoutgetresponses(void);
 void snmp_inc_snmpouttraps(void);
 void snmp_get_snmpgrpid_ptr(struct snmp_obj_id **oid);
 void snmp_set_snmpenableauthentraps(u8_t *value);
+void snmp_get_snmpenableauthentraps(u8_t *value);
 
 /* LWIP_SNMP support not available */
 /* define everything to be empty */
@@ -301,6 +302,7 @@ void snmp_set_snmpenableauthentraps(u8_t *value);
 #define snmp_inc_snmpouttraps()
 #define snmp_get_snmpgrpid_ptr(oid)
 #define snmp_set_snmpenableauthentraps(value)
+#define snmp_get_snmpenableauthentraps(value)
 
 #endif
 
index de51e10d23fcebc079f32f7852cd0c5850e3f1b0..af7035906b7e01a84f762c4617197964af333721 100644 (file)
 #define SNMP_ES_READONLY 4
 #define SNMP_ES_GENERROR 5
 
+#define SNMP_GENTRAP_COLDSTART 0
+#define SNMP_GENTRAP_WARMSTART 1
+#define SNMP_GENTRAP_AUTHFAIL 4
+#define SNMP_GENTRAP_ENTERPRISESPC 6
+
 struct snmp_varbind
 {
   /* next pointer, NULL for last in list */
@@ -264,9 +269,21 @@ extern struct snmp_msg_trap trap_msg;
 
 /** Agent setup, start listening to port 161. */
 void snmp_init(void);
+void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable);
+void snmp_trap_dst_ip_set(u8_t dst_idx, struct ip_addr *dst);
+
+/** Varbind-list functions. */
+struct snmp_varbind* snmp_varbind_alloc(struct snmp_obj_id *oid, u8_t type, u8_t len);
+void snmp_varbind_free(struct snmp_varbind *vb);
+void snmp_varbind_list_free(struct snmp_varbind_root *root);
+void snmp_varbind_tail_add(struct snmp_varbind_root *root, struct snmp_varbind *vb);
+struct snmp_varbind* snmp_varbind_tail_remove(struct snmp_varbind_root *root);
+
 /** Handles internal/external events. */
 void snmp_msg_event(struct snmp_msg_pstat *msg_ps);
 err_t snmp_send_response(struct snmp_msg_pstat *m_stat);
-err_t snmp_send_trap(struct ip_addr *dst, s8_t generic_trap, s32_t specific_trap);
+err_t snmp_send_trap(s8_t generic_trap, s32_t specific_trap);
+void snmp_coldstart_trap(void);
+void snmp_authfail_trap(void);
 
 #endif