Import Upstream version 1.2.2
[quagga-debian.git] / tests / aspath_test.c
1 /* 
2  * Copyright (C) 2005 Sun Microsystems, Inc.
3  *
4  * This file is part of Quagga.
5  *
6  * Quagga is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 2, or (at your option) any
9  * later version.
10  *
11  * Quagga is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Quagga; see the file COPYING.  If not, write to the Free
18  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.  
20  */
21
22 #include <zebra.h>
23
24 #include "vty.h"
25 #include "stream.h"
26 #include "privs.h"
27 #include "filter.h"
28
29 #include "bgpd/bgpd.h"
30 #include "bgpd/bgp_aspath.h"
31 #include "bgpd/bgp_attr.h"
32
33 #define VT100_RESET "\x1b[0m"
34 #define VT100_RED "\x1b[31m"
35 #define VT100_GREEN "\x1b[32m"
36 #define VT100_YELLOW "\x1b[33m"
37 #define OK VT100_GREEN "OK" VT100_RESET
38 #define FAILED VT100_RED "failed" VT100_RESET
39
40 /* need these to link in libbgp */
41 struct zebra_privs_t *bgpd_privs = NULL;
42 struct thread_master *master = NULL;
43
44 static int failed = 0;
45
46 /* specification for a test - what the results should be */
47 struct test_spec 
48 {
49   const char *shouldbe; /* the string the path should parse to */
50   const char *shouldbe_delete_confed; /* ditto, but once confeds are deleted */
51   const unsigned int hops; /* aspath_count_hops result */
52   const unsigned int confeds; /* aspath_count_confeds */
53   const int private_as; /* whether the private_as check should pass or fail */
54 #define NOT_ALL_PRIVATE 0
55 #define ALL_PRIVATE 1
56   const as_t does_loop; /* an ASN which should trigger loop-check */
57   const as_t doesnt_loop; /* one which should not */
58   const as_t first; /* the first ASN, if there is one */
59 #define NULL_ASN 0
60 };
61
62
63 /* test segments to parse and validate, and use for other tests */
64 static struct test_segment {
65   const char *name;
66   const char *desc;
67   const u_char asdata[1024];
68   int len;
69   struct test_spec sp;
70 } test_segments [] = 
71 {
72   { /* 0 */ 
73     "seq1",
74     "seq(8466,3,52737,4096)",
75     { 0x2,0x4, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00 },
76     10,
77     { "8466 3 52737 4096",
78       "8466 3 52737 4096",
79       4, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
80   },
81   { /* 1 */
82     "seq2",
83     "seq(8722) seq(4)",
84     { 0x2,0x1, 0x22,0x12,
85       0x2,0x1, 0x00,0x04 },
86     8,
87     { "8722 4",
88       "8722 4",
89       2, 0, NOT_ALL_PRIVATE, 4, 5, 8722, },
90   },
91   { /* 2 */
92     "seq3",
93     "seq(8466,3,52737,4096,8722,4)",
94     { 0x2,0x6, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 
95                0x22,0x12, 0x00,0x04},
96     14,
97     { "8466 3 52737 4096 8722 4",
98       "8466 3 52737 4096 8722 4",
99        6, 0, NOT_ALL_PRIVATE, 3, 5, 8466 },
100   },
101   { /* 3 */
102     "seqset",
103     "seq(8482,51457) set(5204)",
104     { 0x2,0x2, 0x21,0x22, 0xc9,0x01,
105       0x1,0x1, 0x14,0x54 },
106     10,
107     { "8482 51457 {5204}",
108       "8482 51457 {5204}",
109       3, 0, NOT_ALL_PRIVATE, 5204, 51456, 8482},
110   },
111   { /* 4 */
112     "seqset2",
113     "seq(8467, 59649) set(4196,48658) set(17322,30745)",
114     { 0x2,0x2, 0x21,0x13, 0xe9,0x01,
115       0x1,0x2, 0x10,0x64, 0xbe,0x12,
116       0x1,0x2, 0x43,0xaa, 0x78,0x19 },    
117     18,
118     { "8467 59649 {4196,48658} {17322,30745}",
119       "8467 59649 {4196,48658} {17322,30745}",
120       4, 0, NOT_ALL_PRIVATE, 48658, 1, 8467},
121   },
122   { /* 5 */
123     "multi",
124     "seq(6435,59408,21665) set(2457,61697,4369), seq(1842,41590,51793)",
125     { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
126       0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
127       0x2,0x3, 0x07,0x32, 0xa2,0x76, 0xca,0x51 },
128     24,
129     { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
130       "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
131       7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
132   },
133   { /* 6 */
134     "confed",
135     "confseq(123,456,789)",
136     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15 },
137     8,
138     { "(123 456 789)",
139       "",
140       0, 3, NOT_ALL_PRIVATE, 789, 1, NULL_ASN },
141   },
142   { /* 7 */
143     "confed2",
144     "confseq(123,456,789) confseq(111,222)",
145     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
146       0x3,0x2, 0x00,0x6f, 0x00,0xde },
147     14,
148     { "(123 456 789) (111 222)",
149       "",
150       0, 5, NOT_ALL_PRIVATE, 111, 1, NULL_ASN },
151   },
152   { /* 8 */
153     "confset",
154     "confset(456,123,789)",
155     { 0x4,0x3, 0x01,0xc8, 0x00,0x7b, 0x03,0x15 },
156     8,
157     { "[123,456,789]",
158       "[123,456,789]",
159       0, 1, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
160   },
161   { /* 9 */
162     "confmulti",
163     "confseq(123,456,789) confset(222,111) seq(8722) set(4196,48658)",
164     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
165       0x4,0x2, 0x00,0xde, 0x00,0x6f,
166       0x2,0x1, 0x22,0x12,
167       0x1,0x2, 0x10,0x64, 0xbe,0x12 },
168     24,
169     { "(123 456 789) [111,222] 8722 {4196,48658}",
170       "8722 {4196,48658}",
171       2, 4, NOT_ALL_PRIVATE, 123, 1, NULL_ASN },
172   },
173   { /* 10 */
174     "seq4",
175     "seq(8466,2,52737,4096,8722,4)",
176     { 0x2,0x6, 0x21,0x12, 0x00,0x02, 0xce,0x01, 0x10,0x00, 
177                0x22,0x12, 0x00,0x04},
178     14,
179     { "8466 2 52737 4096 8722 4",
180       "8466 2 52737 4096 8722 4",
181       6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
182   },
183   { /* 11 */
184     "tripleseq1",
185     "seq(8466,2,52737) seq(4096,8722,4) seq(8722)",
186     { 0x2,0x3, 0x21,0x12, 0x00,0x02, 0xce,0x01, 
187       0x2,0x3, 0x10,0x00, 0x22,0x12, 0x00,0x04,
188       0x2,0x1, 0x22,0x12},
189     20,
190     { "8466 2 52737 4096 8722 4 8722",
191       "8466 2 52737 4096 8722 4 8722",
192       7, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
193   },
194   { /* 12 */ 
195     "someprivate",
196     "seq(8466,64512,52737,65535)",
197     { 0x2,0x4, 0x21,0x12, 0xfc,0x00, 0xce,0x01, 0xff,0xff },
198     10,
199     { "8466 64512 52737 65535",
200       "8466 64512 52737 65535",
201       4, 0, NOT_ALL_PRIVATE, 65535, 4, 8466 },
202   },
203   { /* 13 */ 
204     "allprivate",
205     "seq(65534,64512,64513,65535)",
206     { 0x2,0x4, 0xff,0xfe, 0xfc,0x00, 0xfc,0x01, 0xff,0xff },
207     10,
208     { "65534 64512 64513 65535",
209       "65534 64512 64513 65535",
210       4, 0, ALL_PRIVATE, 65534, 4, 65534 },
211   },
212   { /* 14 */ 
213     "long",
214     "seq(8466,3,52737,4096,34285,<repeated 49 more times>)",
215     { 0x2,0xfa, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
216                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
217                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
218                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
219                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
220                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
221                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
222                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
223                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
224                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
225                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
226                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
227                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
228                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
229                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
230                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
231                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
232                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
233                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
234                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
235                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
236                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
237                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
238                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
239                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
240                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
241                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
242                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
243                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
244                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
245                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
246                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
247                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
248                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
249                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
250                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
251                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
252                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
253                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
254                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
255                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
256                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
257                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
258                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
259                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
260                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
261                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
262                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
263                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed,
264                 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x85,0xed, },
265     502,
266     { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
267       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
268       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
269       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
270       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
271       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
272       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
273       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
274       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
275       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
276       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
277       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
278       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
279       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
280       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
281       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
282       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
283       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
284       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
285       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
286       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
287       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
288       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
289       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
290       "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
291       
292       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
293       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
294       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
295       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
296       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
297       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
298       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
299       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
300       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
301       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
302       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
303       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
304       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
305       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
306       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
307       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
308       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
309       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
310       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
311       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
312       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
313       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
314       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
315       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
316       "8466 3 52737 4096 34285 8466 3 52737 4096 34285",
317       250, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
318   },
319   { /* 15 */ 
320     "seq1extra",
321     "seq(8466,3,52737,4096,3456)",
322     { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
323     12,
324     { "8466 3 52737 4096 3456",
325       "8466 3 52737 4096 3456",
326       5, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
327   },
328   { /* 16 */
329     "empty",
330     "<empty>",
331     {},
332     0,
333     { "", "", 0, 0, 0, 0, 0, 0 },
334   },
335   { /* 17 */ 
336     "redundantset",
337     "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153)",
338     { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
339       0x1,0x4, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9 },
340     22,
341     {
342      /* We shouldn't ever /generate/ such paths. However, we should
343       * cope with them fine.
344       */
345      "8466 3 52737 4096 3456 {7099,8153}",
346       "8466 3 52737 4096 3456 {7099,8153}",
347       6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
348   },
349   { /* 18 */
350     "reconcile_lead_asp",
351     "seq(6435,59408,21665) set(23456,23456,23456), seq(23456,23456,23456)",
352     { 0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
353       0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
354       0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 },
355     24,
356     { "6435 59408 21665 {23456} 23456 23456 23456",
357       "6435 59408 21665 {23456} 23456 23456 23456",
358       7, 0, NOT_ALL_PRIVATE, 23456, 1, 6435 },
359   },
360   { /* 19 */
361     "reconcile_new_asp",
362     "set(2457,61697,4369), seq(1842,41591,51793)",
363     { 
364       0x1,0x3, 0x09,0x99, 0xf1,0x01, 0x11,0x11,
365       0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51 },
366     16,
367     { "{2457,4369,61697} 1842 41591 51793",
368       "{2457,4369,61697} 1842 41591 51793",
369       4, 0, NOT_ALL_PRIVATE, 51793, 1, 2457 },
370   },
371   { /* 20 */
372     "reconcile_confed",
373     "confseq(123,456,789) confset(456,124,788) seq(6435,59408,21665)"
374     " set(23456,23456,23456), seq(23456,23456,23456)",
375     { 0x3,0x3, 0x00,0x7b, 0x01,0xc8, 0x03,0x15,
376       0x4,0x3, 0x01,0xc8, 0x00,0x7c, 0x03,0x14,
377       0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1,
378       0x1,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
379       0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0 },
380     40,
381     { "(123 456 789) [124,456,788] 6435 59408 21665"
382       " {23456} 23456 23456 23456",
383       "6435 59408 21665 {23456} 23456 23456 23456",
384       7, 4, NOT_ALL_PRIVATE, 23456, 1, 6435 },
385   },
386   { /* 21 */
387     "reconcile_start_trans",
388     "seq(23456,23456,23456) seq(6435,59408,21665)",
389     { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
390       0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, },
391     16,
392     { "23456 23456 23456 6435 59408 21665",
393       "23456 23456 23456 6435 59408 21665",
394       6, 0, NOT_ALL_PRIVATE, 21665, 1, 23456 },
395   },
396   { /* 22 */
397     "reconcile_start_trans4",
398     "seq(1842,41591,51793) seq(6435,59408,21665)",
399     { 0x2,0x3, 0x07,0x32, 0xa2,0x77, 0xca,0x51,
400       0x2,0x3, 0x19,0x23, 0xe8,0x10, 0x54,0xa1, },
401     16,
402     { "1842 41591 51793 6435 59408 21665",
403       "1842 41591 51793 6435 59408 21665",
404       6, 0, NOT_ALL_PRIVATE, 41591, 1, 1842 },
405   },
406   { /* 23 */
407     "reconcile_start_trans_error",
408     "seq(23456,23456,23456) seq(6435,59408)",
409     { 0x2,0x3, 0x5b,0xa0, 0x5b,0xa0, 0x5b,0xa0,
410       0x2,0x2, 0x19,0x23, 0xe8,0x10, },
411     14,
412     { "23456 23456 23456 6435 59408",
413       "23456 23456 23456 6435 59408",
414       5, 0, NOT_ALL_PRIVATE, 59408, 1, 23456 },
415   },
416   { /* 24 */ 
417     "redundantset2",
418     "seq(8466,3,52737,4096,3456) set(7099,8153,8153,8153,7099)",
419     { 0x2,0x5, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80,
420       0x1,0x5, 0x1b,0xbb, 0x1f,0xd9, 0x1f,0xd9, 0x1f,0xd9, 0x1b,0xbb,},
421     24,
422     {
423      /* We should weed out duplicate set members. */
424      "8466 3 52737 4096 3456 {7099,8153}",
425       "8466 3 52737 4096 3456 {7099,8153}",
426       6, 0, NOT_ALL_PRIVATE, 4096, 4, 8466 },
427   },
428   { /* 25 */ 
429     "zero-size overflow",
430     "#ASNs = 0, data = seq(8466 3 52737 4096 3456)",
431     { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 0x10,0x00, 0x0d,0x80 },
432     12,
433     { NULL, NULL,
434       0, 0, 0, 0, 0, 0 },
435   },
436   { /* 26  */ 
437     "zero-size overflow + valid segment",
438     "seq(#AS=0:8466 3 52737),seq(4096 3456)",
439     { 0x2,0x0, 0x21,0x12, 0x00,0x03, 0xce,0x01, 
440       0x2,0x2, 0x10,0x00, 0x0d,0x80 },
441     14
442     ,
443     { NULL, NULL,
444       0, 0, 0, 0, 0, 0 },
445   },
446   { /* 27  */ 
447     "invalid segment type",
448     "type=8(4096 3456)",
449     { 0x8,0x2, 0x10,0x00, 0x0d,0x80 },
450     14
451     ,
452     { NULL, NULL,
453       0, 0, 0, 0, 0, 0 },
454   },  { NULL, NULL, {0}, 0, { NULL, 0, 0 } }
455 };
456
457 #define COMMON_ATTRS \
458       BGP_ATTR_FLAG_TRANS, \
459       BGP_ATTR_ORIGIN, \
460       1, \
461       BGP_ORIGIN_EGP, \
462       BGP_ATTR_FLAG_TRANS, \
463       BGP_ATTR_NEXT_HOP, \
464       4, 192, 0, 2, 0
465 #define COMMON_ATTR_SIZE 11
466
467 /* */
468 static struct aspath_tests {
469   const char *desc;
470   const struct test_segment *segment;
471   const char *shouldbe;  /* String it should evaluate to */
472   const enum as4 { AS4_DATA, AS2_DATA }
473           as4;  /* whether data should be as4 or not (ie as2) */
474   const int result;     /* expected result for bgp_attr_parse */
475   const int cap;        /* capabilities to set for peer */
476   const char attrheader [1024];
477   size_t len;
478   const struct test_segment *old_segment;
479 } aspath_tests [] =
480 {
481   /* 0 */
482   {
483     "basic test",
484     &test_segments[0],
485     "8466 3 52737 4096",
486     AS2_DATA, 0,
487     0,
488     { COMMON_ATTRS,
489       BGP_ATTR_FLAG_TRANS,
490       BGP_ATTR_AS_PATH,
491       10,
492     },
493     COMMON_ATTR_SIZE + 3,
494   },
495   /* 1 */
496   {
497     "length too short",
498     &test_segments[0],
499     "8466 3 52737 4096",
500     AS2_DATA, -1,
501     0,
502     { COMMON_ATTRS,
503       BGP_ATTR_FLAG_TRANS,
504       BGP_ATTR_AS_PATH, 
505       8,
506     },
507     COMMON_ATTR_SIZE + 3,
508   },
509   /* 2 */
510   {
511     "length too long",
512     &test_segments[0],
513     "8466 3 52737 4096",
514     AS2_DATA, -1,
515     0,
516     { COMMON_ATTRS,
517       BGP_ATTR_FLAG_TRANS,
518       BGP_ATTR_AS_PATH, 
519       12,
520     },
521     COMMON_ATTR_SIZE + 3,
522   },
523   /* 3 */
524   {
525     "incorrect flag",
526     &test_segments[0],
527     "8466 3 52737 4096",
528     AS2_DATA, -1,
529     0,
530     { COMMON_ATTRS,
531       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
532       BGP_ATTR_AS_PATH, 
533       10,
534     },
535     COMMON_ATTR_SIZE + 3,
536   },
537   /* 4 */
538   {
539     "as4_path, with as2 format data",
540     &test_segments[0],
541     "8466 3 52737 4096",
542     AS2_DATA, -1,
543     0,
544     { COMMON_ATTRS,
545       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
546       BGP_ATTR_AS4_PATH, 
547       10,
548     },
549     COMMON_ATTR_SIZE + 3,
550   },
551   /* 5 */
552   {
553     "as4, with incorrect attr length",
554     &test_segments[0],
555     "8466 3 52737 4096",
556     AS4_DATA, -1,
557     PEER_CAP_AS4_RCV,
558     { COMMON_ATTRS,
559       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
560       BGP_ATTR_AS4_PATH, 
561       10,
562     },
563     COMMON_ATTR_SIZE + 3,
564   },
565   /* 6 */
566   {
567     "basic 4-byte as-path",
568     &test_segments[0],
569     "8466 3 52737 4096",
570     AS4_DATA, 0,
571     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
572     { COMMON_ATTRS,
573       BGP_ATTR_FLAG_TRANS,
574       BGP_ATTR_AS_PATH, 
575       18,
576     },
577     COMMON_ATTR_SIZE + 3,
578   },
579   /* 7 */
580   {
581     "4b AS_PATH: too short",
582     &test_segments[0],
583     "8466 3 52737 4096",
584     AS4_DATA, -1,
585     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
586     { COMMON_ATTRS,
587       BGP_ATTR_FLAG_TRANS,
588       BGP_ATTR_AS_PATH, 
589       16,
590     },
591     COMMON_ATTR_SIZE + 3,
592   },
593   /* 8 */
594   {
595     "4b AS_PATH: too long",
596     &test_segments[0],
597     "8466 3 52737 4096",
598     AS4_DATA, -1,
599     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
600     { COMMON_ATTRS,
601       BGP_ATTR_FLAG_TRANS,
602       BGP_ATTR_AS_PATH, 
603       20,
604     },
605     COMMON_ATTR_SIZE + 3,
606   },
607   /* 9 */
608   {
609     "4b AS_PATH: too long2",
610     &test_segments[0],
611     "8466 3 52737 4096",
612     AS4_DATA, -1,
613     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
614     { COMMON_ATTRS,
615       BGP_ATTR_FLAG_TRANS,
616       BGP_ATTR_AS_PATH, 
617       22,
618     },
619     COMMON_ATTR_SIZE + 3,
620   },
621   /* 10 */
622   {
623     "4b AS_PATH: bad flags",
624     &test_segments[0],
625     "8466 3 52737 4096",
626     AS4_DATA, -1,
627     PEER_CAP_AS4_RCV|PEER_CAP_AS4_ADV,
628     { COMMON_ATTRS,
629       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
630       BGP_ATTR_AS_PATH, 
631       18,
632     },
633     COMMON_ATTR_SIZE + 3,
634   },
635   /* 11 */
636   {
637     "4b AS4_PATH w/o AS_PATH",
638     &test_segments[6],
639     NULL,
640     AS4_DATA, -1,
641     PEER_CAP_AS4_ADV,
642     { COMMON_ATTRS,
643       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
644       BGP_ATTR_AS4_PATH, 
645       14,
646     },
647     COMMON_ATTR_SIZE + 3,
648   },
649   /* 12 */
650   {
651     "4b AS4_PATH: confed",
652     &test_segments[6],
653     "8466 3 52737 4096 (123 456 789)",
654     AS4_DATA, 0,
655     PEER_CAP_AS4_ADV,
656     { COMMON_ATTRS,
657       BGP_ATTR_FLAG_TRANS|BGP_ATTR_FLAG_OPTIONAL,
658       BGP_ATTR_AS4_PATH, 
659       14,
660     },
661     COMMON_ATTR_SIZE + 3,
662     &test_segments[0],
663   },
664   { NULL, NULL, NULL, 0, 0, 0, { 0 }, 0 },
665 };
666
667 /* prepending tests */
668 static struct tests {
669   const struct test_segment *test1;
670   const struct test_segment *test2;
671   struct test_spec sp;
672 } prepend_tests[] = 
673 {
674   /* 0 */
675   { &test_segments[0], &test_segments[1],
676     { "8466 3 52737 4096 8722 4",
677       "8466 3 52737 4096 8722 4",
678       6, 0, NOT_ALL_PRIVATE, 4096, 1, 8466 },
679   },
680   /* 1 */
681   { &test_segments[1], &test_segments[3],
682     { "8722 4 8482 51457 {5204}",
683       "8722 4 8482 51457 {5204}",
684       5, 0, NOT_ALL_PRIVATE, 5204, 1, 8722 }
685   },
686   /* 2 */
687   { &test_segments[3], &test_segments[4],
688     { "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
689       "8482 51457 {5204} 8467 59649 {4196,48658} {17322,30745}",
690       7, 0, NOT_ALL_PRIVATE, 5204, 1, 8482 },
691   },
692   /* 3 */
693   { &test_segments[4], &test_segments[5],
694     { "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
695       " {2457,4369,61697} 1842 41590 51793",
696       "8467 59649 {4196,48658} {17322,30745} 6435 59408 21665"
697       " {2457,4369,61697} 1842 41590 51793",
698       11, 0, NOT_ALL_PRIVATE, 61697, 1, 8467 }
699   },
700   /* 4 */
701   { &test_segments[5], &test_segments[6],
702     { "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
703       "6435 59408 21665 {2457,4369,61697} 1842 41590 51793",
704       7, 0, NOT_ALL_PRIVATE, 1842, 1, 6435 },
705   },
706   /* 5 */
707   { &test_segments[6], &test_segments[7],
708     { "(123 456 789) (123 456 789) (111 222)",
709       "",
710       0, 8, NOT_ALL_PRIVATE, 111, 1, 0 }
711   },
712   { &test_segments[7], &test_segments[8],
713     { "(123 456 789) (111 222) [123,456,789]",
714       "",
715       0, 6, NOT_ALL_PRIVATE, 111, 1, 0 }
716   },
717   { &test_segments[8], &test_segments[9],
718     { "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
719       "[123,456,789] (123 456 789) [111,222] 8722 {4196,48658}",
720       2, 5, NOT_ALL_PRIVATE, 456, 1, NULL_ASN },
721   },
722   { &test_segments[9], &test_segments[8],
723     { "(123 456 789) [111,222] 8722 {4196,48658} [123,456,789]",
724       "8722 {4196,48658} [123,456,789]",
725       2, 5, NOT_ALL_PRIVATE, 48658, 1, NULL_ASN },
726   },
727   { &test_segments[14], &test_segments[11],
728     { "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
729       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
730       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
731       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
732       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
733       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
734       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
735       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
736       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
737       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
738       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
739       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
740       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
741       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
742       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
743       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
744       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
745       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
746       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
747       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
748       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
749       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
750       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
751       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
752       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
753       "8466 2 52737 4096 8722 4 8722",
754       
755       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
756       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
757       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
758       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
759       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
760       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
761       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
762       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
763       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
764       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
765       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
766       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
767       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
768       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
769       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
770       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
771       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
772       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
773       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
774       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
775       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
776       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
777       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
778       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
779       "8466 3 52737 4096 34285 8466 3 52737 4096 34285 "
780       "8466 2 52737 4096 8722 4 8722",
781       257, 0, NOT_ALL_PRIVATE, 4096, 1000, 8466 },
782   },
783   { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
784 };
785
786 struct tests reconcile_tests[] =
787 {
788   { &test_segments[18], &test_segments[19],
789     { "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
790       "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
791       7, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
792   },
793   { &test_segments[19], &test_segments[18],
794     /* AS_PATH (19) has more hops than NEW_AS_PATH,
795      * so just AS_PATH should be used (though, this practice
796      * is bad imho).
797      */
798     { "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
799       "{2457,4369,61697} 1842 41591 51793 6435 59408 21665 {23456} 23456 23456 23456",
800       11, 0, NOT_ALL_PRIVATE, 51793, 1, 6435 },
801   },
802   { &test_segments[20], &test_segments[19],
803     { "(123 456 789) [124,456,788] 6435 59408 21665"
804       " {2457,4369,61697} 1842 41591 51793",
805       "6435 59408 21665 {2457,4369,61697} 1842 41591 51793",
806       7, 4, NOT_ALL_PRIVATE, 51793, 1, 6435 },
807   },
808   { &test_segments[21], &test_segments[22],
809     { "1842 41591 51793 6435 59408 21665",
810       "1842 41591 51793 6435 59408 21665",
811       6, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },
812   },
813   { &test_segments[23], &test_segments[22],
814     { "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
815       "23456 23456 23456 6435 59408 1842 41591 51793 6435 59408 21665",
816       11, 0, NOT_ALL_PRIVATE, 51793, 1, 1842 },
817   },
818   { NULL, NULL, { NULL, 0, 0, 0, 0, 0, 0, } },
819 };
820   
821 struct tests aggregate_tests[] =
822 {
823   { &test_segments[0], &test_segments[2],
824     { "8466 3 52737 4096 {4,8722}",
825       "8466 3 52737 4096 {4,8722}",
826       5, 0, NOT_ALL_PRIVATE, 4, 1, 8466 },
827   },
828   { &test_segments[2], &test_segments[0],
829     { "8466 3 52737 4096 {4,8722}",
830       "8466 3 52737 4096 {4,8722}",
831       5, 0, NOT_ALL_PRIVATE, 8722, 1, 8466 },
832   },
833   { &test_segments[2], &test_segments[10],
834     { "8466 {2,3,4,4096,8722,52737}",
835       "8466 {2,3,4,4096,8722,52737}",
836       2, 0, NOT_ALL_PRIVATE, 8722, 5, 8466 },
837   },
838   { &test_segments[10], &test_segments[2],
839     { "8466 {2,3,4,4096,8722,52737}",
840       "8466 {2,3,4,4096,8722,52737}",
841       2, 0, NOT_ALL_PRIVATE, 2, 20000, 8466 },
842   },
843
844   { &test_segments[5], &test_segments[18],
845     { "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
846       "6435 59408 21665 {1842,2457,4369,23456,41590,51793,61697}",
847       4, 0, NOT_ALL_PRIVATE, 41590, 1, 6435 },
848   },
849
850   { NULL, NULL, { NULL, 0, 0}  },
851 };
852
853 struct compare_tests 
854 {
855   int test_index1;
856   int test_index2;
857 #define CMP_RES_YES 1
858 #define CMP_RES_NO 0
859   char shouldbe_cmp;
860   char shouldbe_confed;
861 } left_compare [] =
862 {
863   { 0, 1, CMP_RES_NO, CMP_RES_NO },
864   { 0, 2, CMP_RES_YES, CMP_RES_NO },
865   { 0, 11, CMP_RES_YES, CMP_RES_NO },
866   { 0, 15, CMP_RES_YES, CMP_RES_NO },
867   { 0, 16, CMP_RES_NO, CMP_RES_NO },
868   { 1, 11, CMP_RES_NO, CMP_RES_NO },
869   { 6, 7, CMP_RES_NO, CMP_RES_YES },
870   { 6, 8, CMP_RES_NO, CMP_RES_NO },
871   { 7, 8, CMP_RES_NO, CMP_RES_NO },
872   { 1, 9, CMP_RES_YES, CMP_RES_NO },
873   { 0, 9, CMP_RES_NO, CMP_RES_NO },
874   { 3, 9, CMP_RES_NO, CMP_RES_NO },
875   { 0, 6, CMP_RES_NO, CMP_RES_NO },
876   { 1, 6, CMP_RES_NO, CMP_RES_NO },
877   { 0, 8, CMP_RES_NO, CMP_RES_NO },
878   { 1, 8, CMP_RES_NO, CMP_RES_NO },
879   { 11, 6, CMP_RES_NO, CMP_RES_NO },
880   { 11, 7, CMP_RES_NO, CMP_RES_NO },
881   { 11, 8, CMP_RES_NO, CMP_RES_NO },
882   { 9, 6, CMP_RES_NO, CMP_RES_YES },
883   { 9, 7, CMP_RES_NO, CMP_RES_YES },
884   { 9, 8, CMP_RES_NO, CMP_RES_NO },
885 };
886
887 /* make an aspath from a data stream */
888 static struct aspath *
889 make_aspath (const u_char *data, size_t len, int use32bit)
890 {
891   struct stream *s = NULL;
892   struct aspath *as;
893   
894   if (len)
895     {
896       s = stream_new (len);
897       stream_put (s, data, len);
898     }
899   as = aspath_parse (s, len, use32bit);
900   
901   if (s)
902     stream_free (s);
903   
904   return as;
905 }
906
907 static void
908 printbytes (const u_char *bytes, int len)
909 {
910   int i = 0;
911   while (i < len)
912     {
913       if (i % 2)
914         printf ("%02hhx%s", bytes[i], " ");
915       else
916         printf ("0x%02hhx", bytes[i]);
917       i++;
918     }
919   printf ("\n");
920 }  
921
922 /* validate the given aspath */
923 static int
924 validate (struct aspath *as, const struct test_spec *sp)
925 {
926   size_t bytes, bytes4;
927   int fails = 0;
928   const u_char *out;
929   static struct stream *s;
930   struct aspath *asinout, *asconfeddel, *asstr, *as4;
931   
932   if (as == NULL && sp->shouldbe == NULL)
933     {
934       printf ("Correctly failed to parse\n");
935       return fails;
936     }
937   
938   out = aspath_snmp_pathseg (as, &bytes);
939   asinout = make_aspath (out, bytes, 0);
940   
941   /* Excercise AS4 parsing a bit, with a dogfood test */
942   if (!s)
943     s = stream_new (4096);
944   bytes4 = aspath_put (s, as, 1);
945   as4 = make_aspath (STREAM_DATA(s), bytes4, 1);
946   
947   asstr = aspath_str2aspath (sp->shouldbe);
948   
949   asconfeddel = aspath_delete_confed_seq (aspath_dup (asinout));
950   
951   printf ("got: %s\n", aspath_print(as));
952   
953   /* the parsed path should match the specified 'shouldbe' string.
954    * We should pass the "eat our own dog food" test, be able to output
955    * this path and then input it again. Ie the path resulting from:
956    *
957    *   aspath_parse(aspath_put(as)) 
958    *
959    * should:
960    *
961    * - also match the specified 'shouldbe' value
962    * - hash to same value as original path
963    * - have same hops and confed counts as original, and as the
964    *   the specified counts
965    *
966    * aspath_str2aspath() and shouldbe should match
967    *
968    * We do the same for:
969    *
970    *   aspath_parse(aspath_put(as,USE32BIT))
971    *
972    * Confederation related tests: 
973    * - aspath_delete_confed_seq(aspath) should match shouldbe_confed
974    * - aspath_delete_confed_seq should be idempotent.
975    */
976   if (strcmp(aspath_print (as), sp->shouldbe)
977          /* hash validation */
978       || (aspath_key_make (as) != aspath_key_make (asinout))
979          /* by string */
980       || strcmp(aspath_print (asinout), sp->shouldbe)
981          /* By 4-byte parsing */
982       || strcmp(aspath_print (as4), sp->shouldbe)
983          /* by various path counts */
984       || (aspath_count_hops (as) != sp->hops)
985       || (aspath_count_confeds (as) != sp->confeds)
986       || (aspath_count_hops (asinout) != sp->hops)
987       || (aspath_count_confeds (asinout) != sp->confeds))
988     {
989       failed++;
990       fails++;
991       printf ("shouldbe:\n%s\n", sp->shouldbe);
992       printf ("as4:\n%s\n", aspath_print (as4));
993       printf ("hash keys: in: %d out->in: %d\n", 
994               aspath_key_make (as), aspath_key_make (asinout));
995       printf ("hops: %d, counted %d %d\n", sp->hops, 
996               aspath_count_hops (as),
997               aspath_count_hops (asinout) );
998       printf ("confeds: %d, counted %d %d\n", sp->confeds,
999               aspath_count_confeds (as),
1000               aspath_count_confeds (asinout));
1001       printf ("out->in:\n%s\nbytes: ", aspath_print(asinout));
1002       printbytes (out, bytes);
1003     }
1004          /* basic confed related tests */
1005   if ((aspath_print (asconfeddel) == NULL 
1006           && sp->shouldbe_delete_confed != NULL)
1007       || (aspath_print (asconfeddel) != NULL 
1008           && sp->shouldbe_delete_confed == NULL)
1009       || strcmp(aspath_print (asconfeddel), sp->shouldbe_delete_confed)
1010          /* delete_confed_seq should be idempotent */
1011       || (aspath_key_make (asconfeddel) 
1012           != aspath_key_make (aspath_delete_confed_seq (asconfeddel))))
1013     {
1014       failed++;
1015       fails++;
1016       printf ("confed_del: %s\n", aspath_print (asconfeddel));
1017       printf ("should be: %s\n", sp->shouldbe_delete_confed);
1018     }
1019       /* aspath_str2aspath test */
1020   if ((aspath_print (asstr) == NULL && sp->shouldbe != NULL)
1021       || (aspath_print (asstr) != NULL && sp->shouldbe == NULL)
1022       || strcmp(aspath_print (asstr), sp->shouldbe))
1023     {
1024       failed++;
1025       fails++;
1026       printf ("asstr: %s\n", aspath_print (asstr));
1027     }
1028   
1029     /* loop, private and first as checks */
1030   if ((sp->does_loop && aspath_loop_check (as, sp->does_loop) == 0)
1031       || (sp->doesnt_loop && aspath_loop_check (as, sp->doesnt_loop) != 0)
1032       || (aspath_private_as_check (as) != sp->private_as)
1033       || (aspath_firstas_check (as,sp->first)
1034           && sp->first == 0))
1035     {
1036       failed++;
1037       fails++;
1038       printf ("firstas: %d,  got %d\n", sp->first,
1039               aspath_firstas_check (as,sp->first));
1040       printf ("loop does: %d %d, doesnt: %d %d\n",
1041               sp->does_loop, aspath_loop_check (as, sp->does_loop),
1042               sp->doesnt_loop, aspath_loop_check (as, sp->doesnt_loop));
1043       printf ("private check: %d %d\n", sp->private_as,
1044               aspath_private_as_check (as));
1045     }
1046   aspath_unintern (&asinout);
1047   aspath_unintern (&as4);
1048   
1049   aspath_free (asconfeddel);
1050   aspath_free (asstr);
1051   stream_reset (s);
1052   
1053   return fails;
1054 }
1055
1056 static void
1057 empty_get_test ()
1058 {
1059   struct aspath *as = aspath_empty_get ();
1060   struct test_spec sp = { "", "", 0, 0, 0, 0, 0, 0 };
1061
1062   printf ("empty_get_test, as: %s\n",aspath_print (as));
1063   if (!validate (as, &sp))
1064     printf ("%s\n", OK);
1065   else
1066     printf ("%s!\n", FAILED);
1067   
1068   printf ("\n");
1069   
1070   aspath_free (as);
1071 }
1072
1073 /* basic parsing test */
1074 static void
1075 parse_test (struct test_segment *t)
1076 {
1077   struct aspath *asp;
1078   
1079   printf ("%s: %s\n", t->name, t->desc);
1080
1081   asp = make_aspath (t->asdata, t->len, 0);
1082   
1083   printf ("aspath: %s\nvalidating...:\n", aspath_print (asp));
1084
1085   if (!validate (asp, &t->sp))
1086     printf (OK "\n");
1087   else
1088     printf (FAILED "\n");
1089   
1090   printf ("\n");
1091   
1092   if (asp)
1093     aspath_unintern (&asp);
1094 }
1095
1096 /* prepend testing */
1097 static void
1098 prepend_test (struct tests *t)
1099 {
1100   struct aspath *asp1, *asp2, *ascratch;
1101   
1102   printf ("prepend %s: %s\n", t->test1->name, t->test1->desc);
1103   printf ("to %s: %s\n", t->test2->name, t->test2->desc);
1104   
1105   asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
1106   asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
1107   
1108   ascratch = aspath_dup (asp2);
1109   aspath_unintern (&asp2);
1110   
1111   asp2 = aspath_prepend (asp1, ascratch);
1112   
1113   printf ("aspath: %s\n", aspath_print (asp2));
1114   
1115   if (!validate (asp2, &t->sp))
1116     printf ("%s\n", OK);
1117   else
1118     printf ("%s!\n", FAILED);
1119   
1120   printf ("\n");
1121   aspath_unintern (&asp1);
1122   aspath_free (asp2);
1123 }
1124
1125 /* empty-prepend testing */
1126 static void
1127 empty_prepend_test (struct test_segment *t)
1128 {
1129   struct aspath *asp1, *asp2, *ascratch;
1130   
1131   printf ("empty prepend %s: %s\n", t->name, t->desc);
1132   
1133   asp1 = make_aspath (t->asdata, t->len, 0);
1134   asp2 = aspath_empty ();
1135   
1136   ascratch = aspath_dup (asp2);
1137   aspath_unintern (&asp2);
1138   
1139   asp2 = aspath_prepend (asp1, ascratch);
1140   
1141   printf ("aspath: %s\n", aspath_print (asp2));
1142   
1143   if (!validate (asp2, &t->sp))
1144     printf (OK "\n");
1145   else
1146     printf (FAILED "!\n");
1147   
1148   printf ("\n");
1149   if (asp1)
1150     aspath_unintern (&asp1);
1151   aspath_free (asp2);
1152 }
1153
1154 /* as2+as4 reconciliation testing */
1155 static void
1156 as4_reconcile_test (struct tests *t)
1157 {
1158   struct aspath *asp1, *asp2, *ascratch;
1159   
1160   printf ("reconciling %s:\n  %s\n", t->test1->name, t->test1->desc);
1161   printf ("with %s:\n  %s\n", t->test2->name, t->test2->desc);
1162   
1163   asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
1164   asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
1165   
1166   ascratch = aspath_reconcile_as4 (asp1, asp2);
1167   
1168   if (!validate (ascratch, &t->sp))
1169     printf (OK "\n");
1170   else
1171     printf (FAILED "!\n");
1172   
1173   printf ("\n");
1174   aspath_unintern (&asp1);
1175   aspath_unintern (&asp2);
1176   aspath_free (ascratch);
1177 }
1178
1179
1180 /* aggregation testing */
1181 static void
1182 aggregate_test (struct tests *t)
1183 {
1184   struct aspath *asp1, *asp2, *ascratch;
1185   
1186   printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc);
1187   printf ("with %s: %s\n", t->test2->name, t->test2->desc);
1188   
1189   asp1 = make_aspath (t->test1->asdata, t->test1->len, 0);
1190   asp2 = make_aspath (t->test2->asdata, t->test2->len, 0);
1191   
1192   ascratch = aspath_aggregate (asp1, asp2);
1193   
1194   if (!validate (ascratch, &t->sp))
1195     printf (OK "\n");
1196   else
1197     printf (FAILED "!\n");
1198   
1199   printf ("\n");
1200   aspath_unintern (&asp1);
1201   aspath_unintern (&asp2);
1202   aspath_free (ascratch);
1203 /*  aspath_unintern (ascratch);*/
1204 }
1205
1206 /* cmp_left tests  */
1207 static void
1208 cmp_test ()
1209 {
1210   unsigned int i;
1211 #define CMP_TESTS_MAX \
1212   (sizeof(left_compare) / sizeof (struct compare_tests))
1213
1214   for (i = 0; i < CMP_TESTS_MAX; i++)
1215     {
1216       struct test_segment *t1 = &test_segments[left_compare[i].test_index1];
1217       struct test_segment *t2 = &test_segments[left_compare[i].test_index2];
1218       struct aspath *asp1, *asp2;
1219       
1220       printf ("left cmp %s: %s\n", t1->name, t1->desc);
1221       printf ("and %s: %s\n", t2->name, t2->desc);
1222       
1223       asp1 = make_aspath (t1->asdata, t1->len, 0);
1224       asp2 = make_aspath (t2->asdata, t2->len, 0);
1225       
1226       if (aspath_cmp_left (asp1, asp2) != left_compare[i].shouldbe_cmp
1227           || aspath_cmp_left (asp2, asp1) != left_compare[i].shouldbe_cmp
1228           || aspath_cmp_left_confed (asp1, asp2) 
1229                != left_compare[i].shouldbe_confed
1230           || aspath_cmp_left_confed (asp2, asp1) 
1231                != left_compare[i].shouldbe_confed)
1232         {
1233           failed++;
1234           printf (FAILED "\n");
1235           printf ("result should be: cmp: %d, confed: %d\n", 
1236                   left_compare[i].shouldbe_cmp,
1237                   left_compare[i].shouldbe_confed);
1238           printf ("got: cmp %d, cmp_confed: %d\n",
1239                   aspath_cmp_left (asp1, asp2),
1240                   aspath_cmp_left_confed (asp1, asp2));
1241           printf("path1: %s\npath2: %s\n", aspath_print (asp1),
1242                  aspath_print (asp2));
1243         }
1244       else
1245         printf (OK "\n");
1246       
1247       printf ("\n");
1248       aspath_unintern (&asp1);
1249       aspath_unintern (&asp2);
1250     }
1251 }
1252
1253 static int
1254 handle_attr_test (struct aspath_tests *t)
1255 {
1256   struct bgp bgp = { 0 }; 
1257   struct peer peer = { 0 };
1258   struct attr attr = { 0 };  
1259   int ret;
1260   int initfail = failed;
1261   struct aspath *asp;
1262   size_t datalen;
1263   
1264   asp = make_aspath (t->segment->asdata, t->segment->len, 0);
1265     
1266   peer.ibuf = stream_new (BGP_MAX_PACKET_SIZE);
1267   peer.obuf = stream_fifo_new ();
1268   peer.bgp = &bgp;
1269   peer.host = (char *)"none";
1270   peer.fd = -1;
1271   peer.cap = t->cap;
1272   
1273   stream_write (peer.ibuf, t->attrheader, t->len);
1274   datalen = aspath_put (peer.ibuf, asp, t->as4 == AS4_DATA);
1275   if (t->old_segment)
1276     {
1277       char dummyaspath[] = { BGP_ATTR_FLAG_TRANS, BGP_ATTR_AS_PATH,
1278                              t->old_segment->len };
1279       stream_write (peer.ibuf, dummyaspath, sizeof (dummyaspath));
1280       stream_write (peer.ibuf, t->old_segment->asdata, t->old_segment->len);
1281       datalen += sizeof (dummyaspath) + t->old_segment->len;
1282     }
1283   
1284   ret = bgp_attr_parse (&peer, &attr, t->len + datalen, NULL, NULL);
1285   
1286   if (ret != t->result)
1287     {
1288       printf ("bgp_attr_parse returned %d, expected %d\n", ret, t->result);
1289       printf ("datalen %zd\n", datalen);
1290       failed++;
1291     }
1292   if (ret != 0)
1293     goto out;
1294   
1295   if (t->shouldbe && attr.aspath == NULL)
1296     {
1297       printf ("aspath is NULL, but should be: %s\n", t->shouldbe);
1298       failed++;
1299     }
1300   if (t->shouldbe && attr.aspath && strcmp (attr.aspath->str, t->shouldbe))
1301     {
1302       printf ("attr str and 'shouldbe' mismatched!\n"
1303               "attr str:  %s\n"
1304               "shouldbe:  %s\n",
1305               attr.aspath->str, t->shouldbe);
1306       failed++;
1307     }
1308   if (!t->shouldbe && attr.aspath)
1309     {
1310       printf ("aspath should be NULL, but is: %s\n", attr.aspath->str);
1311       failed++;
1312     }
1313
1314 out:
1315   if (attr.aspath)
1316     aspath_unintern (&attr.aspath);
1317   if (asp)
1318     aspath_unintern (&asp);
1319   return failed - initfail;
1320 }
1321
1322 static void
1323 attr_test (struct aspath_tests *t)
1324 {
1325     printf ("%s\n", t->desc);
1326     printf ("%s\n\n", handle_attr_test (t) ? FAILED : OK);  
1327 }
1328
1329 int
1330 main (void)
1331 {
1332   int i = 0;
1333   bgp_master_init ();
1334   master = bm->master;
1335   bgp_option_set (BGP_OPT_NO_LISTEN);
1336   bgp_attr_init ();
1337   
1338   while (test_segments[i].name)
1339     {
1340       printf ("test %u\n", i);
1341       parse_test (&test_segments[i]);
1342       empty_prepend_test (&test_segments[i++]);
1343     }
1344   
1345   i = 0;
1346   while (prepend_tests[i].test1)
1347     {
1348       printf ("prepend test %u\n", i);
1349       prepend_test (&prepend_tests[i++]);
1350     }
1351   
1352   i = 0;
1353   while (aggregate_tests[i].test1)
1354     {
1355       printf ("aggregate test %u\n", i);
1356       aggregate_test (&aggregate_tests[i++]);
1357     }
1358   
1359   i = 0;
1360   
1361   while (reconcile_tests[i].test1)
1362     {
1363       printf ("reconcile test %u\n", i);
1364       as4_reconcile_test (&reconcile_tests[i++]);
1365     }
1366   
1367   i = 0;
1368   
1369   cmp_test();
1370   
1371   i = 0;
1372   
1373   empty_get_test();
1374   
1375   i = 0;
1376   
1377   while (aspath_tests[i].desc)
1378     {
1379       printf ("aspath_attr test %d\n", i);
1380       attr_test (&aspath_tests[i++]);
1381     }
1382   
1383   printf ("failures: %d\n", failed);
1384   printf ("aspath count: %ld\n", aspath_count());
1385   
1386   return (failed + aspath_count());
1387 }