bgp_capability_test.c 18 KB

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