Since we have several places where we loop over a TLV stream, define a
helper macro to deal with framing checks and looping.

Signed-off-by: Toke Høiland-Jørgensen <t...@toke.dk>
---
 proto/babel/packets.c |   64 ++++++++++++++++++++++++++-----------------------
 1 file changed, 34 insertions(+), 30 deletions(-)

diff --git a/proto/babel/packets.c b/proto/babel/packets.c
index d4ecf649..9c767874 100644
--- a/proto/babel/packets.c
+++ b/proto/babel/packets.c
@@ -167,6 +167,30 @@ struct babel_write_state {
 
 #define NET_SIZE(n) BYTES(net_pxlen(n))
 
+
+/* Helper macros to loop over a series of TLVs.
+ * @start pointer to first TLV
+ * @end   byte * pointer to TLV stream end
+ * @tlv   struct babel_tlv pointer used as iterator
+ */
+#define LOOP_TLVS(start, end, tlv)                                     \
+  for (tlv = (void *)start;                                            \
+       (byte *)tlv < end;                                              \
+       tlv = NEXT_TLV(tlv))                                            \
+  {                                                                    \
+    byte *loop_pos;                                                    \
+    /* Ugly special case */                                            \
+    if (tlv->type == BABEL_TLV_PAD1)                                   \
+      continue;                                                                
\
+                                                                       \
+    /* The end of the common TLV header */                             \
+    loop_pos = (byte *)tlv + sizeof(struct babel_tlv);                 \
+    if ((loop_pos > end) || (loop_pos + tlv->length > end))            \
+      goto frame_err;                                                  \
+
+#define LOOP_TLVS_END }
+
+
 static inline uint
 bytes_equal(u8 *b1, u8 *b2, uint maxlen)
 {
@@ -1090,22 +1114,11 @@ babel_read_subtlvs(struct babel_tlv *hdr,
                   struct babel_parse_state *state)
 {
   struct babel_tlv *tlv;
-  byte *pos, *end = (byte *) hdr + TLV_LENGTH(hdr);
+  byte *end = (byte *) hdr + TLV_LENGTH(hdr);
   int res;
 
-  for (tlv = (void *) hdr + state->current_tlv_endpos;
-       (byte *) tlv < end;
-       tlv = NEXT_TLV(tlv))
+  LOOP_TLVS(hdr + state->current_tlv_endpos, end, tlv)
   {
-    /* Ugly special case */
-    if (tlv->type == BABEL_TLV_PAD1)
-      continue;
-
-    /* The end of the common TLV header */
-    pos = (byte *)tlv + sizeof(struct babel_tlv);
-    if ((pos > end) || (pos + tlv->length > end))
-      return PARSE_ERROR;
-
     /*
      * The subtlv type space is non-contiguous (due to the mandatory bit), so
      * use a switch for dispatch instead of the mapping array we use for TLVs
@@ -1126,8 +1139,12 @@ babel_read_subtlvs(struct babel_tlv *hdr,
       break;
     }
   }
+  LOOP_TLVS_END;
 
   return PARSE_SUCCESS;
+
+frame_err:
+  return PARSE_ERROR;
 }
 
 static inline int
@@ -1337,7 +1354,6 @@ babel_process_packet(struct babel_pkt_header *pkt, int 
len,
   int res;
 
   int plen = sizeof(struct babel_pkt_header) + get_u16(&pkt->length);
-  byte *pos;
   byte *end = (byte *)pkt + plen;
 
   struct babel_parse_state state = {
@@ -1369,23 +1385,8 @@ babel_process_packet(struct babel_pkt_header *pkt, int 
len,
 
   /* First pass through the packet TLV by TLV, parsing each into internal data
      structures. */
-  for (tlv = FIRST_TLV(pkt);
-       (byte *)tlv < end;
-       tlv = NEXT_TLV(tlv))
+  LOOP_TLVS(FIRST_TLV(pkt), end, tlv)
   {
-    /* Ugly special case */
-    if (tlv->type == BABEL_TLV_PAD1)
-      continue;
-
-    /* The end of the common TLV header */
-    pos = (byte *)tlv + sizeof(struct babel_tlv);
-    if ((pos > end) || (pos + tlv->length > end))
-    {
-      LOG_PKT("Bad TLV from %I via %s type %d pos %d - framing error",
-             saddr, ifa->iface->name, tlv->type, (byte *)tlv - (byte *)pkt);
-      break;
-    }
-
     msg = sl_alloc(p->msg_slab);
     res = babel_read_tlv(tlv, &msg->msg, &state);
     if (res == PARSE_SUCCESS)
@@ -1405,6 +1406,9 @@ babel_process_packet(struct babel_pkt_header *pkt, int 
len,
       break;
     }
   }
+  LOOP_TLVS_END;
+
+frame_err:
 
   /* Parsing done, handle all parsed TLVs */
   WALK_LIST_FIRST(msg, msgs)

Reply via email to