bgp_capability_test.c 18 KB

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