summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_aspath.c143
-rw-r--r--bgpd/bgp_aspath.h2
-rw-r--r--bgpd/bgp_attr.c116
-rw-r--r--bgpd/bgp_damp.c8
-rwxr-xr-xconfigure.ac2
-rw-r--r--tests/aspath_test.c178
6 files changed, 245 insertions, 204 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index 1053f1e8..5a6ad91f 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -671,57 +671,82 @@ aspath_hash_alloc (void *arg)
return aspath;
}
-/* parse as-segment byte stream in struct assegment */
+/* parse *not-empty* as-segment byte stream in struct assegment
+ *
+ * Requires stream to be positioned immediately after the length field of the
+ * atttribute red-tape, and for the length != 0.
+ *
+ * Returns NULL if the AS_PATH or AS4_PATH is not valid.
+ */
static struct assegment *
-assegments_parse (struct stream *s, size_t length, int use32bit)
+assegments_parse (struct stream *s, size_t length, int use32bit, int as4_path)
{
struct assegment_header segh;
struct assegment *seg, *prev = NULL, *head = NULL;
- size_t bytes = 0;
- /* empty aspath (ie iBGP or somesuch) */
- if (length == 0)
- return NULL;
+ assert (length > 0); /* does not expect empty AS_PATH or AS4_PATH */
if (BGP_DEBUG (as4, AS4_SEGMENT))
zlog_debug ("[AS4SEG] Parse aspath segment: got total byte length %lu",
(unsigned long) length);
- /* basic checks */
- if ( (STREAM_READABLE(s) < length)
- || (STREAM_READABLE(s) < AS_HEADER_SIZE)
- || (length % AS16_VALUE_SIZE ))
+
+ /* double check that length does not exceed stream */
+ if (STREAM_READABLE(s) < length)
return NULL;
- while ( (STREAM_READABLE(s) > AS_HEADER_SIZE)
- && (bytes < length))
+ /* deal with each segment in turn */
+ while (length > 0)
{
int i;
- int seg_size;
+ size_t seg_size;
/* softly softly, get the header first on its own */
- segh.type = stream_getc (s);
- segh.length = stream_getc (s);
+ if (length >= AS_HEADER_SIZE)
+ {
+ segh.type = stream_getc (s);
+ segh.length = stream_getc (s);
- seg_size = ASSEGMENT_SIZE(segh.length, use32bit);
+ seg_size = ASSEGMENT_SIZE(segh.length, use32bit);
+ /* includes the segment type and length red tape */
- if (BGP_DEBUG (as4, AS4_SEGMENT))
- zlog_debug ("[AS4SEG] Parse aspath segment: got type %d, length %d",
- segh.type, segh.length);
-
- /* check it.. */
- if ( ((bytes + seg_size) > length)
- /* 1771bis 4.3b: seg length contains one or more */
- || (segh.length == 0)
- /* Paranoia in case someone changes type of segment length.
- * Shift both values by 0x10 to make the comparison operate
- * on more, than 8 bits (otherwise it's a warning, bug #564).
- */
- || ((sizeof segh.length > 1) && (0x10 + segh.length > 0x10 + AS_SEGMENT_MAX)) )
+ if (BGP_DEBUG (as4, AS4_SEGMENT))
+ zlog_debug ("[AS4SEG] Parse aspath segment: got type %d, length %d",
+ segh.type, segh.length);
+
+ /* Check that the segment type is valid */
+ switch (segh.type)
+ {
+ case AS_SEQUENCE:
+ case AS_SET:
+ break ;
+
+ case AS_CONFED_SEQUENCE:
+ case AS_CONFED_SET:
+ if (!as4_path)
+ break ;
+ /* RFC4893 3: "invalid for the AS4_PATH attribute" */
+ /* fall through */
+
+ default: /* reject unknown or invalid AS_PATH segment types */
+ seg_size = 0 ;
+ } ;
+ }
+ else
+ seg_size = 0 ;
+
+ /* Stop now if segment is not valid (discarding anything collected to date)
+ *
+ * RFC4271 4.3, Path Attributes, b) AS_PATH:
+ *
+ * "path segment value field contains one or more AS numbers"
+ */
+ if ((seg_size == 0) || (seg_size > length) || (segh.length == 0))
{
- if (head)
- assegment_free_all (head);
+ assegment_free_all (head);
return NULL;
- }
+ } ;
+
+ length -= seg_size ;
/* now its safe to trust lengths */
seg = assegment_new (segh.type, segh.length);
@@ -734,11 +759,9 @@ assegments_parse (struct stream *s, size_t length, int use32bit)
for (i = 0; i < segh.length; i++)
seg->as[i] = (use32bit) ? stream_getl (s) : stream_getw (s);
- bytes += seg_size;
-
if (BGP_DEBUG (as4, AS4_SEGMENT))
- zlog_debug ("[AS4SEG] Parse aspath segment: Bytes now: %lu",
- (unsigned long) bytes);
+ zlog_debug ("[AS4SEG] Parse aspath segment: length left: %lu",
+ (unsigned long) length);
prev = seg;
}
@@ -746,30 +769,42 @@ assegments_parse (struct stream *s, size_t length, int use32bit)
return assegment_normalise (head);
}
-/* AS path parse function. pnt is a pointer to byte stream and length
- is length of byte stream. If there is same AS path in the the AS
- path hash then return it else make new AS path structure. */
+/* AS path parse function -- parses AS_PATH and AS4_PATH attributes
+ *
+ * Requires: s -- stream, currently positioned before first segment
+ * of AS_PATH or AS4_PATH (ie after attribute header)
+ * length -- length of the value of the AS_PATH or AS4_PATH
+ * use32bit -- true <=> 4Byte ASN, otherwise 2Byte ASN
+ * as4_path -- true <=> AS4_PATH, otherwise AS_PATH
+ *
+ * Returns: if valid: address of struct aspath in the hash of known aspaths,
+ * with reference count incremented.
+ * else: NULL
+ *
+ * NB: empty AS path (length == 0) is valid. The returned struct aspath will
+ * have segments == NULL and str == zero length string (unique).
+ */
struct aspath *
-aspath_parse (struct stream *s, size_t length, int use32bit)
+aspath_parse (struct stream *s, size_t length, int use32bit, int as4_path)
{
struct aspath as;
struct aspath *find;
- /* If length is odd it's malformed AS path. */
- /* Nit-picking: if (use32bit == 0) it is malformed if odd,
- * otherwise its malformed when length is larger than 2 and (length-2)
- * is not dividable by 4.
- * But... this time we're lazy
- */
- if (length % AS16_VALUE_SIZE )
- return NULL;
-
+ /* Parse each segment and construct normalised list of struct assegment */
memset (&as, 0, sizeof (struct aspath));
- as.segments = assegments_parse (s, length, use32bit);
+ if (length != 0)
+ {
+ as.segments = assegments_parse (s, length, use32bit, as4_path);
- /* If already same aspath exist then return it. */
+ if (as.segments == NULL)
+ return NULL ; /* Invalid AS_PATH or AS4_PATH */
+ } ;
+
+ /* If already same aspath exist then return it. */
find = hash_get (ashash, &as, aspath_hash_alloc);
+ assert(find) ; /* valid aspath, so must find or create */
+
/* aspath_hash_alloc dupes segments too. that probably could be
* optimised out.
*/
@@ -777,12 +812,10 @@ aspath_parse (struct stream *s, size_t length, int use32bit)
if (as.str)
XFREE (MTYPE_AS_STR, as.str);
- if (! find)
- return NULL;
find->refcnt++;
return find;
-}
+} ;
static inline void
assegment_data_put (struct stream *s, as_t *as, int num, int use32bit)
@@ -1605,7 +1638,7 @@ aspath_segment_add (struct aspath *as, int type)
struct aspath *
aspath_empty (void)
{
- return aspath_parse (NULL, 0, 1); /* 32Bit ;-) */
+ return aspath_parse (NULL, 0, 1, 0); /* 32Bit ;-) not AS4_PATH */
}
struct aspath *
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index 4556c503..895379aa 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -70,7 +70,7 @@ struct aspath
/* Prototypes. */
extern void aspath_init (void);
extern void aspath_finish (void);
-extern struct aspath *aspath_parse (struct stream *, size_t, int);
+extern struct aspath *aspath_parse (struct stream *, size_t, int, int);
extern struct aspath *aspath_dup (struct aspath *);
extern struct aspath *aspath_aggregate (struct aspath *, struct aspath *);
extern struct aspath *aspath_prepend (struct aspath *, struct aspath *);
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index e3ef01d7..688cc015 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -869,52 +869,77 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length,
return 0;
}
-/* Parse AS path information. This function is wrapper of
- aspath_parse. */
-static int
+/* Parse AS path information. This function is wrapper of aspath_parse.
+ *
+ * Parses AS_PATH or AS4_PATH.
+ *
+ * Returns: if valid: address of struct aspath in the hash of known aspaths,
+ * with reference count incremented.
+ * else: NULL
+ *
+ * NB: empty AS path (length == 0) is valid. The returned struct aspath will
+ * have segments == NULL and str == zero length string (unique).
+ */
+static struct aspath *
bgp_attr_aspath (struct peer *peer, bgp_size_t length,
- struct attr *attr, u_char flag, u_char *startp)
+ struct attr *attr, u_char flag, u_char *startp, int as4_path)
{
- bgp_size_t total;
+ u_char require ;
+ struct aspath *asp ;
- total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+ /* Check the attribute flags */
+ require = as4_path ? BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
+ : BGP_ATTR_FLAG_TRANS ;
- /* Flag check. */
- if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL)
- || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS))
+ if ((flag & (BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS)) != require)
{
+ const char* path_type ;
+ bgp_size_t total;
+
+ path_type = as4_path ? "AS4_PATH" : "AS_PATH" ;
+
+ if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS))
zlog (peer->log, LOG_ERR,
- "As-Path attribute flag isn't transitive %d", flag);
- bgp_peer_down_error_with_data (peer,
- BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
- startp, total);
- return -1;
- }
+ "%s attribute flag isn't transitive %d", path_type, flag) ;
- /*
- * peer with AS4 => will get 4Byte ASnums provided AS4 was advertised
- * otherwise, will get 16 Bit
+ if ((flag & BGP_ATTR_FLAG_OPTIONAL) != (require & BGP_ATTR_FLAG_OPTIONAL))
+ zlog (peer->log, LOG_ERR,
+ "%s attribute flag must %sbe optional %d", path_type,
+ (flag & BGP_ATTR_FLAG_OPTIONAL) ? "not " : "", flag) ;
+
+ total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+
+ bgp_peer_down_error_with_data (peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
+ startp, total) ;
+
+ return NULL ;
+ } ;
+
+ /* Parse the AS_PATH/AS4_PATH body.
+ *
+ * For AS_PATH peer with AS4 => 4Byte ASN otherwise 2Byte ASN
+ * AS4_PATH 4Byte ASN
*/
- attr->aspath = aspath_parse (peer->ibuf, length, PEER_CAP_AS4_USE(peer)) ;
+ asp = aspath_parse (peer->ibuf, length,
+ as4_path || PEER_CAP_AS4_USE(peer), as4_path) ;
- /* In case of IBGP, length will be zero. */
- if (! attr->aspath)
+ if (asp != NULL)
{
- zlog (peer->log, LOG_ERR, "Malformed AS path length is %d", length);
- bgp_peer_down_error (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_MAL_AS_PATH);
- return -1;
+ attr->flag |= ATTR_FLAG_BIT (as4_path ? BGP_ATTR_AS4_PATH
+ : BGP_ATTR_AS_PATH) ;
}
+ else
+ {
+ zlog (peer->log, LOG_ERR, "Malformed AS path length is %d", length);
- /* Forward pointer. */
-/* stream_forward_getp (peer->ibuf, length);*/
+ /* TODO: should BGP_NOTIFY_UPDATE_MAL_AS_PATH be sent for AS4_PATH ?? */
+ bgp_peer_down_error (peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_MAL_AS_PATH) ;
+ } ;
- /* Set aspath attribute flag. */
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH);
-
- return 0;
-}
+ return asp ;
+} ;
static int bgp_attr_aspath_check( struct peer *peer,
struct attr *attr)
@@ -969,21 +994,6 @@ static int bgp_attr_aspath_check( struct peer *peer,
}
-/* Parse AS4 path information. This function is another wrapper of
- aspath_parse. */
-static int
-bgp_attr_as4_path (struct peer *peer, bgp_size_t length,
- struct attr *attr, struct aspath **as4_path)
-{
- *as4_path = aspath_parse (peer->ibuf, length, 1);
-
- /* Set aspath attribute flag. */
- if (as4_path)
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH);
-
- return 0;
-}
-
/* Nexthop attribute. */
static int
bgp_attr_nexthop (struct peer *peer, bgp_size_t length,
@@ -1723,11 +1733,13 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size,
ret = bgp_attr_origin (peer, length, attr, flag, startp);
break;
case BGP_ATTR_AS_PATH:
- ret = bgp_attr_aspath (peer, length, attr, flag, startp);
- break;
+ attr->aspath = bgp_attr_aspath (peer, length, attr, flag, startp, 0);
+ ret = attr->aspath ? 0 : -1 ;
+ break;
case BGP_ATTR_AS4_PATH:
- ret = bgp_attr_as4_path (peer, length, attr, &as4_path );
- break;
+ as4_path = bgp_attr_aspath (peer, length, attr, flag, startp, 1);
+ ret = as4_path ? 0 : -1 ;
+ break;
case BGP_ATTR_NEXT_HOP:
ret = bgp_attr_nexthop (peer, length, attr, flag, startp);
break;
diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c
index 52a93eb7..a474b606 100644
--- a/bgpd/bgp_damp.c
+++ b/bgpd/bgp_damp.c
@@ -405,7 +405,7 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
/* Decay-array computations */
damp->decay_array_size = ceil ((double) damp->max_suppress_time / DELTA_T);
- damp->decay_array = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
+ damp->decay_array = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
sizeof(double) * (damp->decay_array_size));
damp->decay_array[0] = 1.0;
damp->decay_array[1] = exp ((1.0/((double)damp->half_life/DELTA_T)) * log(0.5));
@@ -423,14 +423,10 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup)
damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
damp->reuse_list_size
* sizeof (struct bgp_reuse_node *));
- memset (damp->reuse_list, 0x00,
- damp->reuse_list_size * sizeof (struct bgp_reuse_node *));
/* Reuse-array computations */
- damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY,
+ damp->reuse_index = XCALLOC (MTYPE_BGP_DAMP_ARRAY,
sizeof(int) * damp->reuse_index_size);
- memset (damp->reuse_index, 0x00,
- damp->reuse_list_size * sizeof (int));
reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit;
j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0));
diff --git a/configure.ac b/configure.ac
index a4c411bb..983ebae9 100755
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@
## $Id$
AC_PREREQ(2.53)
-AC_INIT(Quagga, 0.99.15ex05, [http://bugzilla.quagga.net])
+AC_INIT(Quagga, 0.99.15ex06, [http://bugzilla.quagga.net])
AC_CONFIG_SRCDIR(lib/zebra.h)
AC_CONFIG_MACRO_DIR([m4])
diff --git a/tests/aspath_test.c b/tests/aspath_test.c
index fb504f31..ff9d4d5e 100644
--- a/tests/aspath_test.c
+++ b/tests/aspath_test.c
@@ -21,7 +21,7 @@ struct thread_master *master = NULL;
static int failed = 0;
/* specification for a test - what the results should be */
-struct test_spec
+struct test_spec
{
const char *shouldbe; /* the string the path should parse to */
const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
@@ -44,9 +44,9 @@ static struct test_segment {
const u_char asdata[1024];
int len;
struct test_spec sp;
-} test_segments [] =
+} test_segments [] =
{
- { /* 0 */
+ { /* 0 */
"seq1",
"seq(8466,3,52737,4096)",
{ 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
@@ -68,7 +68,7 @@ static struct test_segment {
{ /* 2 */
"seq3",
"seq(8466,3,52737,4096,8722,4)",
- { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00,
+ { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00,
0x22,0x12, 0x00,0x04},
14,
{ "8466 3 52737 4096 8722 4",
@@ -90,7 +90,7 @@ static struct test_segment {
"seq(8467, 59649) set(4196,48658) set(17322,30745)",
{ 0x2,0x2, 0x21,0x13, 0xe9,0x01,
0x1,0x2, 0x10,0x64, 0xbe,0x12,
- 0x1,0x2, 0x43,0xaa, 0x78,0x19 },
+ 0x1,0x2, 0x43,0xaa, 0x78,0x19 },
18,
{ "8467 59649 {4196,48658} {17322,30745}",
"8467 59649 {4196,48658} {17322,30745}",
@@ -150,7 +150,7 @@ static struct test_segment {
{ /* 10 */
"seq4",
"seq(8466,2,52737,4096,8722,4)",
- { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00,
+ { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00,
0x22,0x12, 0x00,0x04},
14,
{ "8466 2 52737 4096 8722 4",
@@ -160,7 +160,7 @@ static struct test_segment {
{ /* 11 */
"tripleseq1",
"seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
- { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01,
+ { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01,
0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
0x2,0x1, 0x22,0x12},
20,
@@ -168,7 +168,7 @@ static struct test_segment {
"8466 2 52737 4096 8722 4 8722",
7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
},
- { /* 12 */
+ { /* 12 */
"someprivate",
"seq(8466,64512,52737,65535)",
{ 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
@@ -177,7 +177,7 @@ static struct test_segment {
"8466 64512 52737 65535",
4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
},
- { /* 13 */
+ { /* 13 */
"allprivate",
"seq(65534,64512,64513,65535)",
{ 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
@@ -186,7 +186,7 @@ static struct test_segment {
"65534 64512 64513 65535",
4, 0, ALL_PRIVATE, 65534, 4, 65534 },
},
- { /* 14 */
+ { /* 14 */
"long",
"seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
{ 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
@@ -265,7 +265,7 @@ static struct test_segment {
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285",
-
+
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
@@ -293,7 +293,7 @@ static struct test_segment {
"8466 3 52737 4096 34285 8466 3 52737 4096 34285",
250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
},
- { /* 15 */
+ { /* 15 */
"seq1extra",
"seq(8466,3,52737,4096,3456)",
{ 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
@@ -309,7 +309,7 @@ static struct test_segment {
0,
{ "", "", 0, 0, 0, 0, 0, 0 },
},
- { /* 17 */
+ { /* 17 */
"redundantset",
"seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
{ 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
@@ -337,7 +337,7 @@ static struct test_segment {
{ /* 19 */
"reconcile_new_asp",
"set(2457,61697,4369), seq(1842,41591,51793)",
- {
+ {
0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51 },
16,
@@ -390,7 +390,7 @@ static struct test_segment {
"23456 23456 23456 6435 59408",
5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456 },
},
- { /* 24 */
+ { /* 24 */
"redundantset2",
"seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)",
{ 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
@@ -402,7 +402,7 @@ static struct test_segment {
"8466 3 52737 4096 3456 {7099,8153}",
6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
},
- { /* 25 */
+ { /* 25 */
"zero-size overflow",
"#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
{ 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
@@ -410,10 +410,10 @@ static struct test_segment {
{ "", "",
0, 0, 0, 0, 0, 0 },
},
- { /* 26 */
+ { /* 26 */
"zero-size overflow + valid segment",
"seq(#AS=0:8466 3 52737),seq(4096 3456)",
- { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01,
+ { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01,
0x2,0x2, 0x10,0x00, 0x0d,0x80 },
14
,
@@ -428,7 +428,7 @@ static struct tests {
const struct test_segment *test1;
const struct test_segment *test2;
struct test_spec sp;
-} prepend_tests[] =
+} prepend_tests[] =
{
{ &test_segments[0], &test_segments[1],
{ "8466 3 52737 4096 8722 4",
@@ -504,7 +504,7 @@ static struct tests {
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 2 52737 4096 8722 4 8722",
-
+
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
"8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
@@ -570,7 +570,7 @@ struct tests reconcile_tests[] =
},
{ NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
};
-
+
struct tests aggregate_tests[] =
{
{ &test_segments[0], &test_segments[2],
@@ -603,7 +603,7 @@ struct tests aggregate_tests[] =
{ NULL, NULL, { NULL, 0, 0} },
};
-struct compare_tests
+struct compare_tests
{
int test_index1;
int test_index2;
@@ -643,17 +643,17 @@ make_aspath (const u_char *data, size_t len, int use32bit)
{
struct stream *s = NULL;
struct aspath *as;
-
+
if (len)
{
s = stream_new (len);
stream_put (s, data, len);
}
- as = aspath_parse (s, len, use32bit);
-
+ as = aspath_parse (s, len, use32bit, 0);
+
if (s)
stream_free (s);
-
+
return as;
}
@@ -670,7 +670,7 @@ printbytes (const u_char *bytes, int len)
i++;
}
printf ("\n");
-}
+}
/* validate the given aspath */
static int
@@ -681,27 +681,27 @@ validate (struct aspath *as, const struct test_spec *sp)
const u_char *out;
static struct stream *s;
struct aspath *asinout, *asconfeddel, *asstr, *as4;
-
+
out = aspath_snmp_pathseg (as, &bytes);
asinout = make_aspath (out, bytes, 0);
-
+
/* Excercise AS4 parsing a bit, with a dogfood test */
if (!s)
s = stream_new (4096);
bytes4 = aspath_put (s, as, 1);
as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
-
+
asstr = aspath_str2aspath (sp->shouldbe);
-
+
asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
-
+
printf ("got: %s\n", aspath_print(as));
-
+
/* the parsed path should match the specified 'shouldbe' string.
* We should pass the "eat our own dog food" test, be able to output
* this path and then input it again. Ie the path resulting from:
*
- * aspath_parse(aspath_put(as))
+ * aspath_parse(aspath_put(as))
*
* should:
*
@@ -716,7 +716,7 @@ validate (struct aspath *as, const struct test_spec *sp)
*
* aspath_parse(aspath_put(as,USE32BIT))
*
- * Confederation related tests:
+ * Confederation related tests:
* - aspath_delete_confed_seq(aspath) should match shouldbe_confed
* - aspath_delete_confed_seq should be idempotent.
*/
@@ -737,9 +737,9 @@ validate (struct aspath *as, const struct test_spec *sp)
fails++;
printf ("shouldbe:\n%s\n", sp->shouldbe);
printf ("as4:\n%s\n", aspath_print (as4));
- printf ("hash keys: in: %d out->in: %d\n",
+ printf ("hash keys: in: %d out->in: %d\n",
aspath_key_make (as), aspath_key_make (asinout));
- printf ("hops: %d, counted %d %d\n", sp->hops,
+ printf ("hops: %d, counted %d %d\n", sp->hops,
aspath_count_hops (as),
aspath_count_hops (asinout) );
printf ("confeds: %d, counted %d %d\n", sp->confeds,
@@ -749,13 +749,13 @@ validate (struct aspath *as, const struct test_spec *sp)
printbytes (out, bytes);
}
/* basic confed related tests */
- if ((aspath_print (asconfeddel) == NULL
+ if ((aspath_print (asconfeddel) == NULL
&& sp->shouldbe_delete_confed != NULL)
- || (aspath_print (asconfeddel) != NULL
+ || (aspath_print (asconfeddel) != NULL
&& sp->shouldbe_delete_confed == NULL)
|| strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
/* delete_confed_seq should be idempotent */
- || (aspath_key_make (asconfeddel)
+ || (aspath_key_make (asconfeddel)
!= aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
{
failed++;
@@ -772,7 +772,7 @@ validate (struct aspath *as, const struct test_spec *sp)
fails++;
printf ("asstr: %s\n", aspath_print (asstr));
}
-
+
/* loop, private and first as checks */
if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
|| (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
@@ -792,11 +792,11 @@ validate (struct aspath *as, const struct test_spec *sp)
}
aspath_unintern (asinout);
aspath_unintern (as4);
-
+
aspath_free (asconfeddel);
aspath_free (asstr);
stream_reset (s);
-
+
return fails;
}
@@ -811,9 +811,9 @@ empty_get_test ()
printf ("%s\n", OK);
else
printf ("%s!\n", FAILED);
-
+
printf ("\n");
-
+
aspath_free (as);
}
@@ -822,7 +822,7 @@ static void
parse_test (struct test_segment *t)
{
struct aspath *asp;
-
+
printf ("%s: %s\n", t->name, t->desc);
asp = make_aspath (t->asdata, t->len, 0);
@@ -833,7 +833,7 @@ parse_test (struct test_segment *t)
printf (OK "\n");
else
printf (FAILED "\n");
-
+
printf ("\n");
aspath_unintern (asp);
}
@@ -843,25 +843,25 @@ static void
prepend_test (struct tests *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);
printf ("to %s: %s\n", t->test2->name, t->test2->desc);
-
+
asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-
+
ascratch = aspath_dup (asp2);
aspath_unintern (asp2);
-
+
asp2 = aspath_prepend (asp1, ascratch);
-
+
printf ("aspath: %s\n", aspath_print (asp2));
-
+
if (!validate (asp2, &t->sp))
printf ("%s\n", OK);
else
printf ("%s!\n", FAILED);
-
+
printf ("\n");
aspath_unintern (asp1);
aspath_free (asp2);
@@ -872,24 +872,24 @@ static void
empty_prepend_test (struct test_segment *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("empty prepend %s: %s\n", t->name, t->desc);
-
+
asp1 = make_aspath (t->asdata, t->len, 0);
asp2 = aspath_empty ();
-
+
ascratch = aspath_dup (asp2);
aspath_unintern (asp2);
-
+
asp2 = aspath_prepend (asp1, ascratch);
-
+
printf ("aspath: %s\n", aspath_print (asp2));
-
+
if (!validate (asp2, &t->sp))
printf (OK "\n");
else
printf (FAILED "!\n");
-
+
printf ("\n");
aspath_unintern (asp1);
aspath_free (asp2);
@@ -900,20 +900,20 @@ static void
as4_reconcile_test (struct tests *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("reconciling %s:\n %s\n", t->test1->name, t->test1->desc);
printf ("with %s:\n %s\n", t->test2->name, t->test2->desc);
-
+
asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-
+
ascratch = aspath_reconcile_as4 (asp1, asp2);
-
+
if (!validate (ascratch, &t->sp))
printf (OK "\n");
else
printf (FAILED "!\n");
-
+
printf ("\n");
aspath_unintern (asp1);
aspath_unintern (asp2);
@@ -926,20 +926,20 @@ static void
aggregate_test (struct tests *t)
{
struct aspath *asp1, *asp2, *ascratch;
-
+
printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);
printf ("with %s: %s\n", t->test2->name, t->test2->desc);
-
+
asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
-
+
ascratch = aspath_aggregate (asp1, asp2);
-
+
if (!validate (ascratch, &t->sp))
printf (OK "\n");
else
printf (FAILED "!\n");
-
+
printf ("\n");
aspath_unintern (asp1);
aspath_unintern (asp2);
@@ -960,23 +960,23 @@ cmp_test ()
struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
struct aspath *asp1, *asp2;
-
+
printf ("left cmp %s: %s\n", t1->name, t1->desc);
printf ("and %s: %s\n", t2->name, t2->desc);
-
+
asp1 = make_aspath (t1->asdata, t1->len, 0);
asp2 = make_aspath (t2->asdata, t2->len, 0);
-
+
if (aspath_cmp_left (asp1, asp2) != left_compare[i].shouldbe_cmp
|| aspath_cmp_left (asp2, asp1) != left_compare[i].shouldbe_cmp
- || aspath_cmp_left_confed (asp1, asp2)
+ || aspath_cmp_left_confed (asp1, asp2)
!= left_compare[i].shouldbe_confed
- || aspath_cmp_left_confed (asp2, asp1)
+ || aspath_cmp_left_confed (asp2, asp1)
!= left_compare[i].shouldbe_confed)
{
failed++;
printf (FAILED "\n");
- printf ("result should be: cmp: %d, confed: %d\n",
+ printf ("result should be: cmp: %d, confed: %d\n",
left_compare[i].shouldbe_cmp,
left_compare[i].shouldbe_confed);
printf ("got: cmp %d, cmp_confed: %d\n",
@@ -987,13 +987,13 @@ cmp_test ()
}
else
printf (OK "\n");
-
+
printf ("\n");
aspath_unintern (asp1);
aspath_unintern (asp2);
}
}
-
+
int
main (void)
{
@@ -1004,30 +1004,30 @@ main (void)
parse_test (&test_segments[i]);
empty_prepend_test (&test_segments[i++]);
}
-
+
i = 0;
while (prepend_tests[i].test1)
prepend_test (&prepend_tests[i++]);
-
+
i = 0;
while (aggregate_tests[i].test1)
aggregate_test (&aggregate_tests[i++]);
-
+
i = 0;
-
+
while (reconcile_tests[i].test1)
as4_reconcile_test (&reconcile_tests[i++]);
-
+
i = 0;
-
+
cmp_test();
-
+
i = 0;
-
+
empty_get_test();
-
+
printf ("failures: %d\n", failed);
printf ("aspath count: %ld\n", aspath_count());
-
+
return (failed + aspath_count());
}