bgp_capability_test.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. #include <zebra.h>
  2. #include "vty.h"
  3. #include "stream.h"
  4. #include "privs.h"
  5. #include "memory.h"
  6. #include "bgpd/bgpd.h"
  7. #include "bgpd/bgp_open.h"
  8. #include "bgpd/bgp_debug.h"
  9. #include "bgpd/bgp_packet.h"
  10. #define VT100_RESET "\x1b[0m"
  11. #define VT100_RED "\x1b[31m"
  12. #define VT100_GREEN "\x1b[32m"
  13. #define VT100_YELLOW "\x1b[33m"
  14. #define CAPABILITY 0
  15. #define DYNCAP 1
  16. #define OPT_PARAM 2
  17. /* need these to link in libbgp */
  18. struct zebra_privs_t *bgpd_privs = NULL;
  19. struct thread_master *master = NULL;
  20. static int failed = 0;
  21. static int tty = 0;
  22. /* test segments to parse and validate, and use for other tests */
  23. static struct test_segment {
  24. const char *name;
  25. const char *desc;
  26. const u_char data[1024];
  27. int len;
  28. #define SHOULD_PARSE 0
  29. #define SHOULD_ERR -1
  30. int parses; /* whether it should parse or not */
  31. as_t peek_for; /* what peek_for_as4_capability should say */
  32. /* AFI/SAFI validation */
  33. int validate_afi;
  34. afi_t afi;
  35. safi_t safi;
  36. #define VALID_AFI 1
  37. #define INVALID_AFI 0
  38. int afi_valid;
  39. } test_segments [] =
  40. {
  41. /* 0 */
  42. { "caphdr",
  43. "capability header, and no more",
  44. { CAPABILITY_CODE_REFRESH, 0x0 },
  45. 2, SHOULD_PARSE,
  46. },
  47. /* 1 */
  48. { "nodata",
  49. "header, no data but length says there is",
  50. { 0x1, 0xa },
  51. 2, SHOULD_ERR,
  52. },
  53. /* 2 */
  54. { "padded",
  55. "valid, with padding",
  56. { CAPABILITY_CODE_REFRESH, 0x2, 0x0, 0x0 },
  57. 4, SHOULD_PARSE,
  58. },
  59. /* 3 */
  60. { "minsize",
  61. "violates minsize requirement",
  62. { CAPABILITY_CODE_ORF, 0x2, 0x0, 0x0 },
  63. 4, SHOULD_ERR,
  64. },
  65. { NULL, NULL, {0}, 0, 0},
  66. };
  67. static struct test_segment mp_segments[] =
  68. {
  69. { "MP4",
  70. "MP IP/Uni",
  71. { 0x1, 0x4, 0x0, 0x1, 0x0, 0x1 },
  72. 6, SHOULD_PARSE, 0,
  73. 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
  74. },
  75. { "MPv6",
  76. "MP IPv6/Uni",
  77. { 0x1, 0x4, 0x0, 0x2, 0x0, 0x1 },
  78. 6, SHOULD_PARSE, 0,
  79. 1, AFI_IP6, SAFI_UNICAST, VALID_AFI,
  80. },
  81. /* 5 */
  82. { "MP2",
  83. "MP IP/Multicast",
  84. { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x2 },
  85. 6, SHOULD_PARSE, 0,
  86. 1, AFI_IP, SAFI_MULTICAST, VALID_AFI,
  87. },
  88. /* 6 */
  89. { "MP3",
  90. "MP IP6/MPLS-labeled VPN",
  91. { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x80 },
  92. 6, SHOULD_PARSE, 0,
  93. 1, AFI_IP6, SAFI_MPLS_LABELED_VPN, VALID_AFI,
  94. },
  95. /* 7 */
  96. { "MP5",
  97. "MP IP6/MPLS-VPN",
  98. { CAPABILITY_CODE_MP, 0x4, 0x0, 0x2, 0x0, 0x4 },
  99. 6, SHOULD_PARSE, 0,
  100. 1, AFI_IP6, SAFI_MPLS_VPN, VALID_AFI,
  101. },
  102. /* 8 */
  103. { "MP6",
  104. "MP IP4/MPLS-laveled VPN",
  105. { CAPABILITY_CODE_MP, 0x4, 0x0, 0x1, 0x0, 0x80 },
  106. 6, SHOULD_PARSE, 0,
  107. 1, AFI_IP, SAFI_MPLS_LABELED_VPN, VALID_AFI,
  108. },
  109. /* 10 */
  110. { "MP8",
  111. "MP unknown AFI/SAFI",
  112. { CAPABILITY_CODE_MP, 0x4, 0x0, 0xa, 0x0, 0x81 },
  113. 6, SHOULD_PARSE, 0,
  114. 1, 0xa, 0x81, INVALID_AFI, /* parses, but unknown */
  115. },
  116. /* 11 */
  117. { "MP-short",
  118. "MP IP4/Unicast, length too short (< minimum)",
  119. { CAPABILITY_CODE_MP, 0x2, 0x0, 0x1, 0x0, 0x1 },
  120. 6, SHOULD_ERR,
  121. },
  122. /* 12 */
  123. { "MP-overflow",
  124. "MP IP4/Unicast, length too long",
  125. { CAPABILITY_CODE_MP, 0x6, 0x0, 0x1, 0x0, 0x1 },
  126. 6, SHOULD_ERR, 0,
  127. 1, AFI_IP, SAFI_UNICAST, VALID_AFI,
  128. },
  129. { NULL, NULL, {0}, 0, 0}
  130. };
  131. static struct test_segment misc_segments[] =
  132. {
  133. /* 13 */
  134. { "ORF",
  135. "ORF, simple, single entry, single tuple",
  136. { /* hdr */ CAPABILITY_CODE_ORF, 0x7,
  137. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  138. /* num */ 0x1,
  139. /* tuples */ 0x40, 0x3
  140. },
  141. 9, SHOULD_PARSE,
  142. },
  143. /* 14 */
  144. { "ORF-many",
  145. "ORF, multi entry/tuple",
  146. { /* hdr */ CAPABILITY_CODE_ORF, 0x21,
  147. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  148. /* num */ 0x3,
  149. /* tuples */ 0x40, ORF_MODE_BOTH,
  150. 0x80, ORF_MODE_RECEIVE,
  151. 0x80, ORF_MODE_SEND,
  152. /* mpc */ 0x0, 0x2, 0x0, 0x1,
  153. /* num */ 0x3,
  154. /* tuples */ 0x40, ORF_MODE_BOTH,
  155. 0x80, ORF_MODE_RECEIVE,
  156. 0x80, ORF_MODE_SEND,
  157. /* mpc */ 0x0, 0x2, 0x0, 0x2,
  158. /* num */ 0x3,
  159. /* tuples */ 0x40, ORF_MODE_RECEIVE,
  160. 0x80, ORF_MODE_SEND,
  161. 0x80, ORF_MODE_BOTH,
  162. },
  163. 35, SHOULD_PARSE,
  164. },
  165. /* 15 */
  166. { "ORFlo",
  167. "ORF, multi entry/tuple, hdr length too short",
  168. { /* hdr */ CAPABILITY_CODE_ORF, 0x15,
  169. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  170. /* num */ 0x3,
  171. /* tuples */ 0x40, 0x3,
  172. 0x80, 0x1,
  173. 0x80, 0x2,
  174. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  175. /* num */ 0x3,
  176. /* tuples */ 0x40, 0x3,
  177. 0x80, 0x1,
  178. 0x80, 0x2,
  179. /* mpc */ 0x0, 0x2, 0x0, 0x2,
  180. /* num */ 0x3,
  181. /* tuples */ 0x40, 0x3,
  182. 0x80, 0x1,
  183. 0x80, 0x2,
  184. },
  185. 35, SHOULD_ERR, /* It should error on invalid Route-Refresh.. */
  186. },
  187. /* 16 */
  188. { "ORFlu",
  189. "ORF, multi entry/tuple, length too long",
  190. { /* hdr */ 0x3, 0x22,
  191. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  192. /* num */ 0x3,
  193. /* tuples */ 0x40, 0x3,
  194. 0x80, 0x1,
  195. 0x80, 0x2,
  196. /* mpc */ 0x0, 0x2, 0x0, 0x1,
  197. /* num */ 0x3,
  198. /* tuples */ 0x40, 0x3,
  199. 0x80, 0x1,
  200. 0x80, 0x2,
  201. /* mpc */ 0x0, 0x2, 0x0, 0x2,
  202. /* num */ 0x3,
  203. /* tuples */ 0x40, 0x3,
  204. 0x80, 0x1,
  205. 0x80, 0x2,
  206. },
  207. 35, SHOULD_ERR
  208. },
  209. /* 17 */
  210. { "ORFnu",
  211. "ORF, multi entry/tuple, entry number too long",
  212. { /* hdr */ 0x3, 0x21,
  213. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  214. /* num */ 0x3,
  215. /* tuples */ 0x40, 0x3,
  216. 0x80, 0x1,
  217. 0x80, 0x2,
  218. /* mpc */ 0x0, 0x2, 0x0, 0x1,
  219. /* num */ 0x4,
  220. /* tuples */ 0x40, 0x3,
  221. 0x80, 0x1,
  222. 0x80, 0x2,
  223. /* mpc */ 0x0, 0x2, 0x0, 0x2,
  224. /* num */ 0x3,
  225. /* tuples */ 0x40, 0x3,
  226. 0x80, 0x1,
  227. 0x80, 0x2,
  228. },
  229. 35, SHOULD_PARSE, /* parses, but last few tuples should be gibberish */
  230. },
  231. /* 18 */
  232. { "ORFno",
  233. "ORF, multi entry/tuple, entry number too short",
  234. { /* hdr */ 0x3, 0x21,
  235. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  236. /* num */ 0x3,
  237. /* tuples */ 0x40, 0x3,
  238. 0x80, 0x1,
  239. 0x80, 0x2,
  240. /* mpc */ 0x0, 0x2, 0x0, 0x1,
  241. /* num */ 0x1,
  242. /* tuples */ 0x40, 0x3,
  243. 0x80, 0x1,
  244. 0x80, 0x2,
  245. /* mpc */ 0x0, 0x2, 0x0, 0x2,
  246. /* num */ 0x3,
  247. /* tuples */ 0x40, 0x3,
  248. 0x80, 0x1,
  249. 0x80, 0x2,
  250. },
  251. 35, SHOULD_PARSE, /* Parses, but should get gibberish afi/safis */
  252. },
  253. /* 17 */
  254. { "ORFpad",
  255. "ORF, multi entry/tuple, padded to align",
  256. { /* hdr */ 0x3, 0x22,
  257. /* mpc */ 0x0, 0x1, 0x0, 0x1,
  258. /* num */ 0x3,
  259. /* tuples */ 0x40, 0x3,
  260. 0x80, 0x1,
  261. 0x80, 0x2,
  262. /* mpc */ 0x0, 0x2, 0x0, 0x1,
  263. /* num */ 0x3,
  264. /* tuples */ 0x40, 0x3,
  265. 0x80, 0x1,
  266. 0x80, 0x2,
  267. /* mpc */ 0x0, 0x2, 0x0, 0x2,
  268. /* num */ 0x3,
  269. /* tuples */ 0x40, 0x3,
  270. 0x80, 0x1,
  271. 0x80, 0x2,
  272. 0x00,
  273. },
  274. 36, SHOULD_PARSE,
  275. },
  276. /* 19 */
  277. { "AS4",
  278. "AS4 capability",
  279. { 0x41, 0x4, 0xab, 0xcd, 0xef, 0x12 }, /* AS: 2882400018 */
  280. 6, SHOULD_PARSE, 2882400018,
  281. },
  282. /* 20 */
  283. { "GR",
  284. "GR capability",
  285. { /* hdr */ CAPABILITY_CODE_RESTART, 0xe,
  286. /* R-bit, time */ 0xf1, 0x12,
  287. /* afi */ 0x0, 0x1,
  288. /* safi */ 0x1,
  289. /* flags */ 0xf,
  290. /* afi */ 0x0, 0x2,
  291. /* safi */ 0x1,
  292. /* flags */ 0x0,
  293. /* afi */ 0x0, 0x2,
  294. /* safi */ 0x2,
  295. /* flags */ 0x1,
  296. },
  297. 16, SHOULD_PARSE,
  298. },
  299. /* 21 */
  300. { "GR-short",
  301. "GR capability, but header length too short",
  302. { /* hdr */ 0x40, 0xa,
  303. /* R-bit, time */ 0xf1, 0x12,
  304. /* afi */ 0x0, 0x1,
  305. /* safi */ 0x1,
  306. /* flags */ 0xf,
  307. /* afi */ 0x0, 0x2,
  308. /* safi */ 0x1,
  309. /* flags */ 0x0,
  310. /* afi */ 0x0, 0x2,
  311. /* safi */ 0x2,
  312. /* flags */ 0x1,
  313. },
  314. 16, SHOULD_PARSE,
  315. },
  316. /* 22 */
  317. { "GR-long",
  318. "GR capability, but header length too long",
  319. { /* hdr */ 0x40, 0xf,
  320. /* R-bit, time */ 0xf1, 0x12,
  321. /* afi */ 0x0, 0x1,
  322. /* safi */ 0x1,
  323. /* flags */ 0xf,
  324. /* afi */ 0x0, 0x2,
  325. /* safi */ 0x1,
  326. /* flags */ 0x0,
  327. /* afi */ 0x0, 0x2,
  328. /* safi */ 0x2,
  329. },
  330. 16, SHOULD_ERR,
  331. },
  332. { "GR-trunc",
  333. "GR capability, but truncated",
  334. { /* hdr */ 0x40, 0xf,
  335. /* R-bit, time */ 0xf1, 0x12,
  336. /* afi */ 0x0, 0x1,
  337. /* safi */ 0x1,
  338. /* flags */ 0xf,
  339. /* afi */ 0x0, 0x2,
  340. /* safi */ 0x1,
  341. /* flags */ 0x0,
  342. /* afi */ 0x0, 0x2,
  343. /* safi */ 0x2,
  344. /* flags */ 0x1,
  345. },
  346. 15, SHOULD_ERR,
  347. },
  348. { "GR-empty",
  349. "GR capability, but empty.",
  350. { /* hdr */ 0x40, 0x0,
  351. },
  352. 2, SHOULD_ERR,
  353. },
  354. { "MP-empty",
  355. "MP capability, but empty.",
  356. { /* hdr */ 0x1, 0x0,
  357. },
  358. 2, SHOULD_ERR,
  359. },
  360. { "ORF-empty",
  361. "ORF capability, but empty.",
  362. { /* hdr */ 0x3, 0x0,
  363. },
  364. 2, SHOULD_ERR,
  365. },
  366. { "AS4-empty",
  367. "AS4 capability, but empty.",
  368. { /* hdr */ 0x41, 0x0,
  369. },
  370. 2, SHOULD_ERR,
  371. },
  372. { "dyn-empty",
  373. "Dynamic capability, but empty.",
  374. { /* hdr */ 0x42, 0x0,
  375. },
  376. 2, SHOULD_PARSE,
  377. },
  378. { "dyn-old",
  379. "Dynamic capability (deprecated version)",
  380. { CAPABILITY_CODE_DYNAMIC, 0x0 },
  381. 2, SHOULD_PARSE,
  382. },
  383. { NULL, NULL, {0}, 0, 0}
  384. };
  385. /* DYNAMIC message */
  386. struct test_segment dynamic_cap_msgs[] =
  387. {
  388. { "DynCap",
  389. "Dynamic Capability Message, IP/Multicast",
  390. { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
  391. 7, SHOULD_PARSE, /* horrible alignment, just as with ORF */
  392. },
  393. { "DynCapLong",
  394. "Dynamic Capability Message, IP/Multicast, truncated",
  395. { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2 },
  396. 5, SHOULD_ERR,
  397. },
  398. { "DynCapPadded",
  399. "Dynamic Capability Message, IP/Multicast, padded",
  400. { 0x0, 0x1, 0x4, 0x0, 0x1, 0x0, 0x2, 0x0 },
  401. 8, SHOULD_ERR, /* No way to tell padding from data.. */
  402. },
  403. { "DynCapMPCpadded",
  404. "Dynamic Capability Message, IP/Multicast, cap data padded",
  405. { 0x0, 0x1, 0x5, 0x0, 0x1, 0x0, 0x2, 0x0 },
  406. 8, SHOULD_PARSE, /* You can though add padding to the capability data */
  407. },
  408. { "DynCapMPCoverflow",
  409. "Dynamic Capability Message, IP/Multicast, cap data != length",
  410. { 0x0, 0x1, 0x3, 0x0, 0x1, 0x0, 0x2, 0x0 },
  411. 8, SHOULD_ERR,
  412. },
  413. { NULL, NULL, {0}, 0, 0}
  414. };
  415. /* Entire Optional-Parameters block */
  416. struct test_segment opt_params[] =
  417. {
  418. { "Cap-singlets",
  419. "One capability per Optional-Param",
  420. { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
  421. 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
  422. 0x02, 0x02, 0x80, 0x00, /* RR (old) */
  423. 0x02, 0x02, 0x02, 0x00, /* RR */
  424. },
  425. 24, SHOULD_PARSE,
  426. },
  427. { "Cap-series",
  428. "Series of capability, one Optional-Param",
  429. { 0x02, 0x10,
  430. 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
  431. 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
  432. 0x80, 0x00, /* RR (old) */
  433. 0x02, 0x00, /* RR */
  434. },
  435. 18, SHOULD_PARSE,
  436. },
  437. { "AS4more",
  438. "AS4 capability after other caps (singlets)",
  439. { 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
  440. 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
  441. 0x02, 0x02, 0x80, 0x00, /* RR (old) */
  442. 0x02, 0x02, 0x02, 0x00, /* RR */
  443. 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
  444. },
  445. 32, SHOULD_PARSE, 196614,
  446. },
  447. { "AS4series",
  448. "AS4 capability, in series of capabilities",
  449. { 0x02, 0x16,
  450. 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/Uni */
  451. 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/Uni */
  452. 0x80, 0x00, /* RR (old) */
  453. 0x02, 0x00, /* RR */
  454. 0x41, 0x04, 0x00, 0x03, 0x00, 0x06 /* AS4: 1996614 */
  455. },
  456. 24, SHOULD_PARSE, 196614,
  457. },
  458. { "AS4real",
  459. "AS4 capability, in series of capabilities",
  460. {
  461. 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01, /* MP IPv4/uni */
  462. 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01, /* MP IPv6/uni */
  463. 0x02, 0x02, 0x80, 0x00, /* RR old */
  464. 0x02, 0x02, 0x02, 0x00, /* RR */
  465. 0x02, 0x06, 0x41, 0x04, 0x00, 0x03, 0x00, 0x06, /* AS4 */
  466. },
  467. 32, SHOULD_PARSE, 196614,
  468. },
  469. { "AS4real2",
  470. "AS4 capability, in series of capabilities",
  471. {
  472. 0x02, 0x06, 0x01, 0x04, 0x00, 0x01, 0x00, 0x01,
  473. 0x02, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x01,
  474. 0x02, 0x02, 0x80, 0x00,
  475. 0x02, 0x02, 0x02, 0x00,
  476. 0x02, 0x06, 0x41, 0x04, 0x00, 0x00, 0xfc, 0x03,
  477. 0x02, 0x09, 0x82, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x80, 0x03,
  478. 0x02, 0x09, 0x03, 0x07, 0x00, 0x01, 0x00, 0x01, 0x01, 0x40, 0x03,
  479. 0x02, 0x02, 0x42, 0x00,
  480. },
  481. 58, SHOULD_PARSE, 64515,
  482. },
  483. { NULL, NULL, {0}, 0, 0}
  484. };
  485. /* basic parsing test */
  486. static void
  487. parse_test (struct peer *peer, struct test_segment *t, int type)
  488. {
  489. int ret;
  490. int capability = 0;
  491. as_t as4 = 0;
  492. int oldfailed = failed;
  493. int len = t->len;
  494. #define RANDOM_FUZZ 35
  495. stream_reset (peer->ibuf);
  496. stream_put (peer->ibuf, NULL, RANDOM_FUZZ);
  497. stream_set_getp (peer->ibuf, RANDOM_FUZZ);
  498. switch (type)
  499. {
  500. case CAPABILITY:
  501. stream_putc (peer->ibuf, BGP_OPEN_OPT_CAP);
  502. stream_putc (peer->ibuf, t->len);
  503. break;
  504. case DYNCAP:
  505. /* for (i = 0; i < BGP_MARKER_SIZE; i++)
  506. stream_putc (peer->, 0xff);
  507. stream_putw (s, 0);
  508. stream_putc (s, BGP_MSG_CAPABILITY);*/
  509. break;
  510. }
  511. stream_write (peer->ibuf, t->data, t->len);
  512. printf ("%s: %s\n", t->name, t->desc);
  513. switch (type)
  514. {
  515. case CAPABILITY:
  516. len += 2; /* to cover the OPT-Param header */
  517. case OPT_PARAM:
  518. printf ("len: %u\n", len);
  519. /* peek_for_as4 wants getp at capibility*/
  520. as4 = peek_for_as4_capability (peer, len);
  521. printf ("peek_for_as4: as4 is %u\n", as4);
  522. /* and it should leave getp as it found it */
  523. assert (stream_get_getp (peer->ibuf) == RANDOM_FUZZ);
  524. ret = bgp_open_option_parse (peer, len, &capability);
  525. break;
  526. case DYNCAP:
  527. ret = bgp_capability_receive (peer, t->len);
  528. break;
  529. default:
  530. printf ("unknown type %u\n", type);
  531. exit(1);
  532. }
  533. if (!ret && t->validate_afi)
  534. {
  535. safi_t safi = t->safi;
  536. if (bgp_afi_safi_valid_indices (t->afi, &safi) != t->afi_valid)
  537. failed++;
  538. printf ("MP: %u/%u (%u): recv %u, nego %u\n",
  539. t->afi, t->safi, safi,
  540. peer->afc_recv[t->afi][safi],
  541. peer->afc_nego[t->afi][safi]);
  542. if (t->afi_valid == VALID_AFI)
  543. {
  544. if (!peer->afc_recv[t->afi][safi])
  545. failed++;
  546. if (!peer->afc_nego[t->afi][safi])
  547. failed++;
  548. }
  549. }
  550. if (as4 != t->peek_for)
  551. {
  552. printf ("as4 %u != %u\n", as4, t->peek_for);
  553. failed++;
  554. }
  555. printf ("parsed?: %s\n", ret ? "no" : "yes");
  556. if (ret != t->parses)
  557. failed++;
  558. if (tty)
  559. printf ("%s", (failed > oldfailed) ? VT100_RED "failed!" VT100_RESET
  560. : VT100_GREEN "OK" VT100_RESET);
  561. else
  562. printf ("%s", (failed > oldfailed) ? "failed!" : "OK" );
  563. if (failed)
  564. printf (" (%u)", failed);
  565. printf ("\n\n");
  566. }
  567. static struct bgp *bgp;
  568. static as_t asn = 100;
  569. int
  570. main (void)
  571. {
  572. struct peer *peer;
  573. int i, j;
  574. conf_bgp_debug_fsm = -1UL;
  575. conf_bgp_debug_events = -1UL;
  576. conf_bgp_debug_packet = -1UL;
  577. conf_bgp_debug_normal = -1UL;
  578. conf_bgp_debug_as4 = -1UL;
  579. term_bgp_debug_fsm = -1UL;
  580. term_bgp_debug_events = -1UL;
  581. term_bgp_debug_packet = -1UL;
  582. term_bgp_debug_normal = -1UL;
  583. term_bgp_debug_as4 = -1UL;
  584. master = thread_master_create ();
  585. bgp_master_init ();
  586. bgp_option_set (BGP_OPT_NO_LISTEN);
  587. if (fileno (stdout) >= 0)
  588. tty = isatty (fileno (stdout));
  589. if (bgp_get (&bgp, &asn, NULL))
  590. return -1;
  591. peer = peer_create_accept (bgp);
  592. peer->host = (char *) "foo";
  593. for (i = AFI_IP; i < AFI_MAX; i++)
  594. for (j = SAFI_UNICAST; j < SAFI_MAX; j++)
  595. {
  596. peer->afc[i][j] = 1;
  597. peer->afc_adv[i][j] = 1;
  598. }
  599. i = 0;
  600. while (mp_segments[i].name)
  601. parse_test (peer, &mp_segments[i++], CAPABILITY);
  602. /* These tests assume mp_segments tests set at least
  603. * one of the afc_nego's
  604. */
  605. i = 0;
  606. while (test_segments[i].name)
  607. parse_test (peer, &test_segments[i++], CAPABILITY);
  608. i = 0;
  609. while (misc_segments[i].name)
  610. parse_test (peer, &misc_segments[i++], CAPABILITY);
  611. i = 0;
  612. while (opt_params[i].name)
  613. parse_test (peer, &opt_params[i++], OPT_PARAM);
  614. SET_FLAG (peer->cap, PEER_CAP_DYNAMIC_ADV);
  615. peer->status = Established;
  616. i = 0;
  617. while (dynamic_cap_msgs[i].name)
  618. parse_test (peer, &dynamic_cap_msgs[i++], DYNCAP);
  619. printf ("failures: %d\n", failed);
  620. return failed;
  621. }