bgpdump_lib.c 54 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697
  1. /*
  2. Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved
  3. Permission to use, copy, modify, and distribute this software and its
  4. documentation for any purpose and without fee is hereby granted, provided
  5. that the above copyright notice appear in all copies and that both that
  6. copyright notice and this permission notice appear in supporting
  7. documentation, and that the name of the author not be used in advertising or
  8. publicity pertaining to distribution of the software without specific,
  9. written prior permission.
  10. THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  11. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  12. AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  13. DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  14. AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. Parts of this code have been engineered after analiyzing GNU Zebra's
  17. source code and therefore might contain declarations/code from GNU
  18. Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing
  19. software, distributed under the GNU General Public License. A copy of
  20. this license is included with libbgpdump.
  21. */
  22. #include "bgpdump-config.h"
  23. #include "cfile_tools.h"
  24. #include "bgpdump_lib.h"
  25. #include "bgpdump_mstream.h"
  26. #include "util.h"
  27. #include <sys/stat.h>
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <stdbool.h>
  31. #include <netinet/in.h>
  32. #include <sys/socket.h>
  33. #include <arpa/inet.h>
  34. #include <zlib.h>
  35. #include <assert.h>
  36. void bgpdump_free_attr(attributes_t *attr);
  37. static BGPDUMP_ENTRY* bgpdump_entry_create(BGPDUMP *dump);
  38. static int process_mrtd_bgp(struct mstream *s, BGPDUMP_ENTRY *entry);
  39. static int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry);
  40. static int process_mrtd_table_dump_v2(struct mstream *s,BGPDUMP_ENTRY *entry);
  41. static int process_mrtd_table_dump_v2_peer_index_table(struct mstream *s,BGPDUMP_ENTRY *entry);
  42. static int process_mrtd_table_dump_v2_ipv4_unicast(struct mstream *s,BGPDUMP_ENTRY *entry);
  43. static int process_mrtd_table_dump_v2_ipv6_unicast(struct mstream *s,BGPDUMP_ENTRY *entry);
  44. static int process_zebra_bgp(struct mstream *s,BGPDUMP_ENTRY *entry);
  45. static int process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len);
  46. static int process_zebra_bgp_message(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len);
  47. static int process_zebra_bgp_message_update(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len);
  48. static int process_zebra_bgp_message_open(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len);
  49. static int process_zebra_bgp_message_notify(struct mstream *s,BGPDUMP_ENTRY *entry);
  50. static int process_zebra_bgp_entry(struct mstream *s,BGPDUMP_ENTRY *entry);
  51. static int process_zebra_bgp_snapshot(struct mstream *s,BGPDUMP_ENTRY *entry);
  52. static attributes_t *process_attributes(struct mstream *s, u_int8_t asn_len, struct zebra_incomplete *incomplete, int is_addp);
  53. static void process_attr_aspath_string(struct aspath *as);
  54. static char aspath_delimiter_char (u_char type, u_char which);
  55. static void process_attr_community_string(struct community *com);
  56. static void process_mp_announce(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete, int is_addp);
  57. static void process_mp_withdraw(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete, int is_addp);
  58. static int read_prefix_list(struct mstream *s, u_int16_t af, struct prefix *prefixes, struct zebra_incomplete *incomplete, int is_addp);
  59. static as_t read_asn(struct mstream *s, u_int8_t len);
  60. static struct aspath *create_aspath(u_int16_t len, u_int8_t asn_len);
  61. static void aspath_error(struct aspath *as);
  62. static int check_new_aspath(struct aspath *aspath);
  63. static void process_asn32_trans(attributes_t *attr, u_int8_t asn_len);
  64. static struct aspath *asn32_merge_paths(struct aspath *path, struct aspath *newpath);
  65. static void asn32_expand_16_to_32(char *dst, char *src, int len);
  66. #if defined(linux)
  67. static size_t strlcat(char *dst, const char *src, size_t size);
  68. #endif
  69. char *bgpdump_version(void) {
  70. return PACKAGE_VERSION;
  71. }
  72. BGPDUMP *bgpdump_open_dump(const char *filename) {
  73. CFRFILE *f = cfr_open(filename);
  74. if(! f) {
  75. perror("can't open dumpfile");
  76. return NULL;
  77. }
  78. BGPDUMP *this_dump = malloc(sizeof(BGPDUMP));
  79. if (this_dump == NULL) {
  80. perror("malloc");
  81. return NULL;
  82. }
  83. strcpy(this_dump->filename, "[STDIN]");
  84. if(filename && strcmp(filename, "-")) {
  85. if (strlen(filename) >= BGPDUMP_MAX_FILE_LEN - 1) {
  86. fprintf (stderr, "File name %s is too long.\n", filename);
  87. exit(1);
  88. }
  89. strcpy(this_dump->filename, filename);
  90. }
  91. this_dump->f = f;
  92. this_dump->eof=0;
  93. this_dump->parsed = 0;
  94. this_dump->parsed_ok = 0;
  95. // peer index table shared among entries
  96. this_dump->table_dump_v2_peer_index_table = NULL;
  97. return this_dump;
  98. }
  99. void bgpdump_close_dump(BGPDUMP *dump) {
  100. if(dump == NULL) {
  101. return;
  102. }
  103. if(dump->table_dump_v2_peer_index_table){
  104. free(dump->table_dump_v2_peer_index_table->entries);
  105. }
  106. free(dump->table_dump_v2_peer_index_table);
  107. cfr_close(dump->f);
  108. free(dump);
  109. }
  110. BGPDUMP_ENTRY* bgpdump_entry_create(BGPDUMP *dump){
  111. BGPDUMP_ENTRY *this_entry = malloc(sizeof(BGPDUMP_ENTRY));
  112. if(this_entry == NULL) {
  113. err("%s: out of memory", __func__);
  114. return NULL;
  115. }
  116. memset(this_entry, 0, sizeof(BGPDUMP_ENTRY));
  117. this_entry->dump = dump;
  118. return this_entry;
  119. }
  120. BGPDUMP_ENTRY* bgpdump_read_next(BGPDUMP *dump) {
  121. assert(dump);
  122. struct mstream s;
  123. u_char *buffer;
  124. int ok=0;
  125. u_int32_t bytes_read, t;
  126. BGPDUMP_ENTRY *this_entry = bgpdump_entry_create(dump);
  127. if(this_entry == NULL) {
  128. err("%s: out of memmory", __func__);
  129. dump->eof = 1;
  130. return(NULL);
  131. }
  132. bytes_read = cfr_read_n(dump->f, &t, 4);
  133. bytes_read += cfr_read_n(dump->f, &(this_entry->type), 2);
  134. bytes_read += cfr_read_n(dump->f, &(this_entry->subtype), 2);
  135. bytes_read += cfr_read_n(dump->f, &(this_entry->length), 4);
  136. if (bytes_read == 12) {
  137. /* Intel byte ordering stuff ... */
  138. this_entry->type = ntohs(this_entry->type);
  139. this_entry->subtype = ntohs(this_entry->subtype);
  140. this_entry->time = (time_t) ntohl (t);
  141. this_entry->length = ntohl(this_entry->length);
  142. /* If Extended Header format, then reading the miscroseconds attribute */
  143. if (this_entry->type == BGPDUMP_TYPE_ZEBRA_BGP_ET) {
  144. bytes_read += cfr_read_n(dump->f, &(this_entry->ms), 4);
  145. if (bytes_read == 16) {
  146. this_entry->ms = ntohl(this_entry->ms);
  147. /* "The Microsecond Timestamp is included in the computation of
  148. * the Length field value." (RFC6396 2011) */
  149. this_entry->length -= 4;
  150. ok = 1;
  151. }
  152. } else {
  153. this_entry->ms = 0;
  154. ok = 1;
  155. }
  156. }
  157. if (!ok) {
  158. if(bytes_read > 0) {
  159. /* Malformed record */
  160. err("bgpdump_read_next: incomplete MRT header (%d bytes read, expecting 12 or 16)",
  161. bytes_read);
  162. }
  163. /* Nothing more to read, quit */
  164. free(this_entry);
  165. dump->eof = 1;
  166. return(NULL);
  167. }
  168. dump->parsed++;
  169. this_entry->attr=NULL;
  170. if(this_entry->length == 0) {
  171. err("%s: invalid entry length: 0", __func__);
  172. free(this_entry);
  173. dump->eof=1;
  174. return(NULL);
  175. }
  176. if ((buffer = malloc(this_entry->length)) == NULL) {
  177. err("%s: out of memory", __func__);
  178. free(this_entry);
  179. dump->eof=1;
  180. return(NULL);
  181. }
  182. bytes_read = cfr_read_n(dump->f, buffer, this_entry->length);
  183. if(bytes_read != this_entry->length) {
  184. err("bgpdump_read_next: incomplete dump record (%d bytes read, expecting %d)",
  185. bytes_read, this_entry->length);
  186. free(this_entry);
  187. free(buffer);
  188. dump->eof=1;
  189. return(NULL);
  190. }
  191. ok=0;
  192. mstream_init(&s,buffer,this_entry->length);
  193. switch(this_entry->type) {
  194. case BGPDUMP_TYPE_MRTD_BGP:
  195. ok = process_mrtd_bgp(&s,this_entry);
  196. break;
  197. case BGPDUMP_TYPE_MRTD_TABLE_DUMP:
  198. ok = process_mrtd_table_dump(&s,this_entry);
  199. break;
  200. case BGPDUMP_TYPE_ZEBRA_BGP:
  201. case BGPDUMP_TYPE_ZEBRA_BGP_ET:
  202. ok = process_zebra_bgp(&s,this_entry);
  203. break;
  204. case BGPDUMP_TYPE_TABLE_DUMP_V2:
  205. ok = process_mrtd_table_dump_v2(&s,this_entry);
  206. break;
  207. }
  208. free(buffer);
  209. if(ok) {
  210. dump->parsed_ok++;
  211. } else {
  212. bgpdump_free_mem(this_entry);
  213. return NULL;
  214. }
  215. return this_entry;
  216. }
  217. static void bgpdump_free_mp_info(struct mp_info *info) {
  218. u_int16_t afi;
  219. u_int8_t safi;
  220. for(afi = 1; afi <= BGPDUMP_MAX_AFI; afi++) {
  221. for(safi = 1; safi < BGPDUMP_MAX_SAFI; safi++) {
  222. if(info->announce[afi][safi])
  223. free(info->announce[afi][safi]);
  224. info->announce[afi][safi] = NULL;
  225. if(info->withdraw[afi][safi]) {
  226. free(info->withdraw[afi][safi]);
  227. info->withdraw[afi][safi] = NULL;
  228. }
  229. }
  230. }
  231. free(info);
  232. }
  233. void bgpdump_free_mem(BGPDUMP_ENTRY *entry) {
  234. if(entry!=NULL) {
  235. bgpdump_free_attr(entry->attr);
  236. switch(entry->type) {
  237. case BGPDUMP_TYPE_ZEBRA_BGP:
  238. case BGPDUMP_TYPE_ZEBRA_BGP_ET:
  239. switch(entry->subtype) {
  240. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE:
  241. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4:
  242. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL:
  243. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL:
  244. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH:
  245. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH:
  246. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH:
  247. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL_ADDPATH:
  248. switch(entry->body.zebra_message.type) {
  249. case BGP_MSG_NOTIFY:
  250. if(entry->body.zebra_message.notify_data)
  251. free(entry->body.zebra_message.notify_data);
  252. break;
  253. case BGP_MSG_OPEN:
  254. if(entry->body.zebra_message.opt_data)
  255. free(entry->body.zebra_message.opt_data);
  256. break;
  257. }
  258. break;
  259. }
  260. break;
  261. case BGPDUMP_TYPE_TABLE_DUMP_V2:
  262. switch(entry->subtype) {
  263. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV4_UNICAST:
  264. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV6_UNICAST:
  265. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH:
  266. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH:
  267. {
  268. BGPDUMP_TABLE_DUMP_V2_PREFIX *e;
  269. e = &entry->body.mrtd_table_dump_v2_prefix;
  270. int i;
  271. // Conditional as the entries have already been free'd in this case
  272. if(!(e->entry_count && entry->dump->table_dump_v2_peer_index_table == NULL)) {
  273. for(i = 0; i < e->entry_count; i++){
  274. bgpdump_free_attr(e->entries[i].attr);
  275. }
  276. free(e->entries);
  277. }
  278. }
  279. }
  280. break;
  281. }
  282. free(entry);
  283. }
  284. }
  285. void bgpdump_free_attr(attributes_t *attr){
  286. if(attr != NULL) {
  287. u_int16_t i;
  288. struct aspath *path, *pathstofree[3] = { attr->aspath, attr->old_aspath, attr->new_aspath };
  289. for(i = 0; i < sizeof(pathstofree) / sizeof(pathstofree[0]); i++) {
  290. path = pathstofree[i];
  291. if(path) {
  292. if(path->data)
  293. free(path->data);
  294. if(path->str)
  295. free(path->str);
  296. free(path);
  297. }
  298. }
  299. if(attr->community != NULL) {
  300. if(attr->community->val != NULL)
  301. free(attr->community->val);
  302. if(attr->community->str != NULL)
  303. free(attr->community->str);
  304. free(attr->community);
  305. }
  306. if(attr->data != NULL)
  307. free(attr->data);
  308. if(attr->mp_info != NULL)
  309. bgpdump_free_mp_info(attr->mp_info);
  310. if(attr->cluster != NULL) {
  311. free(attr->cluster->list);
  312. free(attr->cluster);
  313. }
  314. if (attr->unknown_num) {
  315. for (i = 0; i < attr->unknown_num; i++)
  316. free(attr->unknown[i].raw);
  317. free(attr->unknown);
  318. }
  319. free(attr);
  320. }
  321. }
  322. /* Helper function to check if this is an Additional Paths enabled subtype (exported) */
  323. int is_addpath(BGPDUMP_ENTRY *entry) {
  324. switch(entry->type) {
  325. case BGPDUMP_TYPE_ZEBRA_BGP:
  326. case BGPDUMP_TYPE_ZEBRA_BGP_ET:
  327. switch(entry->subtype) {
  328. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH:
  329. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH:
  330. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH:
  331. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL_ADDPATH:
  332. return 1;
  333. default:
  334. return 0;
  335. }
  336. case BGPDUMP_TYPE_TABLE_DUMP_V2:
  337. switch(entry->subtype) {
  338. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH:
  339. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV4_MULTICAST_ADDPATH:
  340. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH:
  341. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV6_MULTICAST_ADDPATH:
  342. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_GENERIC_ADDPATH:
  343. return 1;
  344. default:
  345. return 0;
  346. }
  347. default:
  348. return 0;
  349. }
  350. }
  351. int process_mrtd_bgp(struct mstream *s, BGPDUMP_ENTRY *entry) {
  352. switch(entry->subtype) {
  353. case BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE:
  354. case BGPDUMP_SUBTYPE_MRTD_BGP_KEEPALIVE:
  355. entry->body.mrtd_message.source_as = read_asn(s, ASN16_LEN);
  356. entry->body.mrtd_message.source_ip = mstream_get_ipv4(s);
  357. entry->body.mrtd_message.destination_as = read_asn(s, ASN16_LEN);
  358. entry->body.mrtd_message.destination_ip = mstream_get_ipv4(s);
  359. mstream_t withdraw_stream = mstream_copy(s, mstream_getw(s, NULL));
  360. entry->body.mrtd_message.withdraw_count = read_prefix_list(&withdraw_stream, AFI_IP,
  361. entry->body.mrtd_message.withdraw,
  362. &entry->body.mrtd_message.incomplete, 0);
  363. if((entry->attr = process_attributes(s, ASN16_LEN, &entry->body.mrtd_message.incomplete, 0)) == NULL)
  364. return 0;
  365. entry->body.mrtd_message.announce_count = read_prefix_list(s, AFI_IP,
  366. entry->body.mrtd_message.announce,
  367. &entry->body.mrtd_message.incomplete, 0);
  368. break;
  369. case BGPDUMP_SUBTYPE_MRTD_BGP_STATE_CHANGE:
  370. entry->body.mrtd_state_change.destination_as = read_asn(s, ASN16_LEN);
  371. entry->body.mrtd_state_change.destination_ip = mstream_get_ipv4(s);
  372. entry->body.mrtd_state_change.old_state = mstream_getw(s, NULL);
  373. entry->body.mrtd_state_change.new_state = mstream_getw(s, NULL);
  374. break;
  375. }
  376. return 1;
  377. }
  378. int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry) {
  379. int afi = entry->subtype;
  380. u_int8_t asn_len;
  381. u_int32_t temp_time = 0;
  382. mstream_getw(s,&entry->body.mrtd_table_dump.view);
  383. mstream_getw(s,&entry->body.mrtd_table_dump.sequence);
  384. switch(afi) {
  385. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP:
  386. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP_32BIT_AS:
  387. entry->body.mrtd_table_dump.prefix.v4_addr = mstream_get_ipv4(s);
  388. break;
  389. #ifdef BGPDUMP_HAVE_IPV6
  390. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP6:
  391. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP6_32BIT_AS:
  392. mstream_get(s, &entry->body.mrtd_table_dump.prefix.v6_addr.s6_addr, 16);
  393. break;
  394. #endif
  395. default:
  396. warn("process_mrtd_table_dump: unknown AFI %d", afi);
  397. mstream_get(s, NULL, mstream_can_read(s));
  398. return 0;
  399. }
  400. mstream_getc(s,&entry->body.mrtd_table_dump.mask);
  401. mstream_getc(s,&entry->body.mrtd_table_dump.status);
  402. mstream_getl(s,&temp_time);
  403. (entry->body).mrtd_table_dump.uptime = temp_time;
  404. switch(afi) {
  405. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP:
  406. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP_32BIT_AS:
  407. entry->body.mrtd_table_dump.peer_ip.v4_addr = mstream_get_ipv4(s);
  408. break;
  409. #ifdef BGPDUMP_HAVE_IPV6
  410. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP6:
  411. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP6_32BIT_AS:
  412. mstream_get(s, &entry->body.mrtd_table_dump.peer_ip.v6_addr.s6_addr, 16);
  413. break;
  414. #endif
  415. }
  416. switch(afi) {
  417. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP:
  418. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP6:
  419. asn_len = ASN16_LEN;
  420. break;
  421. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP_32BIT_AS:
  422. case BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP6_32BIT_AS:
  423. asn_len = ASN32_LEN;
  424. break;
  425. default:
  426. assert(0); // unreachable
  427. }
  428. entry->body.mrtd_table_dump.peer_as = read_asn(s, asn_len);
  429. if((entry->attr = process_attributes(s, asn_len, NULL, 0)) == NULL)
  430. return 0;
  431. return 1;
  432. }
  433. int process_mrtd_table_dump_v2(struct mstream *s,BGPDUMP_ENTRY *entry) {
  434. switch(entry->subtype){
  435. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_PEER_INDEX_TABLE:
  436. return process_mrtd_table_dump_v2_peer_index_table(s, entry);
  437. break;
  438. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV4_UNICAST:
  439. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV4_UNICAST_ADDPATH:
  440. return process_mrtd_table_dump_v2_ipv4_unicast(s, entry);
  441. break;
  442. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV6_UNICAST:
  443. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_IPV6_UNICAST_ADDPATH:
  444. return process_mrtd_table_dump_v2_ipv6_unicast(s, entry);
  445. break;
  446. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_GENERIC:
  447. case BGPDUMP_SUBTYPE_TABLE_DUMP_V2_RIB_GENERIC_ADDPATH:
  448. //return process_mrtd_table_dump_v2_generic(s, entry);
  449. break;
  450. }
  451. return 0;
  452. }
  453. int process_mrtd_table_dump_v2_peer_index_table(struct mstream *s,BGPDUMP_ENTRY *entry) {
  454. BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE *t;
  455. uint16_t i;
  456. uint8_t peertype;
  457. uint16_t view_name_len;
  458. if(entry->dump->table_dump_v2_peer_index_table) {
  459. free(entry->dump->table_dump_v2_peer_index_table->entries);
  460. }
  461. free(entry->dump->table_dump_v2_peer_index_table);
  462. if((entry->dump->table_dump_v2_peer_index_table = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE))) == NULL) {
  463. err("process_mrtd_table_dump_v2_peer_index_table: failed to allocate memory for index table");
  464. return 0;
  465. }
  466. t = entry->dump->table_dump_v2_peer_index_table;
  467. t->entries = NULL;
  468. t->local_bgp_id = mstream_get_ipv4(s);
  469. mstream_getw(s,&view_name_len);
  470. strcpy(t->view_name, "");
  471. // view_name_len is without trailing \0
  472. if(view_name_len+1 > BGPDUMP_TYPE_TABLE_DUMP_V2_MAX_VIEWNAME_LEN) {
  473. warn("process_mrtd_table_dump_v2_peer_index_table: view name length more than maximum length (%d), ignoring view name", BGPDUMP_TYPE_TABLE_DUMP_V2_MAX_VIEWNAME_LEN);
  474. } else {
  475. mstream_get(s, t->view_name, view_name_len);
  476. t->view_name[view_name_len] = 0;
  477. }
  478. mstream_getw(s,&t->peer_count);
  479. t->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE_ENTRY) * t->peer_count);
  480. if(t->entries == NULL){
  481. err("process_mrtd_table_dump_v2_peer_index_table: failed to allocate memory for index table");
  482. return 0;
  483. }
  484. for(i=0; i < t->peer_count; i++) {
  485. mstream_getc(s,&peertype);
  486. t->entries[i].afi = AFI_IP;
  487. #ifdef BGPDUMP_HAVE_IPV6
  488. if(peertype & BGPDUMP_PEERTYPE_TABLE_DUMP_V2_AFI_IP6)
  489. t->entries[i].afi = AFI_IP6;
  490. #endif
  491. t->entries[i].peer_bgp_id = mstream_get_ipv4(s);
  492. if(t->entries[i].afi == AFI_IP)
  493. t->entries[i].peer_ip.v4_addr = mstream_get_ipv4(s);
  494. #ifdef BGPDUMP_HAVE_IPV6
  495. else
  496. mstream_get(s, &t->entries[i].peer_ip.v6_addr.s6_addr, 16);
  497. #endif
  498. if(peertype & BGPDUMP_PEERTYPE_TABLE_DUMP_V2_AS4)
  499. t->entries[i].peer_as = read_asn(s, ASN32_LEN);
  500. else
  501. t->entries[i].peer_as = read_asn(s, ASN16_LEN);
  502. }
  503. return 0;
  504. }
  505. int process_mrtd_table_dump_v2_ipv4_unicast(struct mstream *s, BGPDUMP_ENTRY *entry){
  506. BGPDUMP_TABLE_DUMP_V2_PREFIX *prefixdata;
  507. prefixdata = &entry->body.mrtd_table_dump_v2_prefix;
  508. int addpath = is_addpath(entry);
  509. uint16_t i;
  510. prefixdata->afi = AFI_IP;
  511. prefixdata->safi = SAFI_UNICAST;
  512. mstream_getl(s, &prefixdata->seq);
  513. mstream_getc(s, &prefixdata->prefix_length);
  514. bzero(&prefixdata->prefix.v4_addr.s_addr, 4);
  515. mstream_get(s, &prefixdata->prefix.v4_addr.s_addr, (prefixdata->prefix_length+7)/8);
  516. mstream_getw(s, &prefixdata->entry_count);
  517. prefixdata->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY) * prefixdata->entry_count);
  518. if(prefixdata->entries == NULL){
  519. err("process_mrtd_table_dump_v2_ipv4_unicast: failed to allocate memory for entry table");
  520. return 0;
  521. }
  522. if(prefixdata->entry_count && entry->dump->table_dump_v2_peer_index_table == NULL) {
  523. free(prefixdata->entries);
  524. err("%s: missing peer index table", __func__);
  525. return 0;
  526. }
  527. for(i=0; i < prefixdata->entry_count; i++){
  528. BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY *e;
  529. e = &prefixdata->entries[i];
  530. mstream_getw(s, &e->peer_index);
  531. assert(e->peer_index <= entry->dump->table_dump_v2_peer_index_table->peer_count);
  532. e->peer = &entry->dump->table_dump_v2_peer_index_table->entries[e->peer_index];
  533. mstream_getl(s, &e->originated_time);
  534. if (addpath)
  535. mstream_getl(s, &e->path_id);
  536. if((e->attr = process_attributes(s, 4, NULL, is_addpath(entry))) == NULL)
  537. return 0;
  538. }
  539. return 1;
  540. }
  541. int process_mrtd_table_dump_v2_ipv6_unicast(struct mstream *s, BGPDUMP_ENTRY *entry){
  542. #ifdef BGPDUMP_HAVE_IPV6
  543. BGPDUMP_TABLE_DUMP_V2_PREFIX *prefixdata;
  544. prefixdata = &entry->body.mrtd_table_dump_v2_prefix;
  545. int addpath = is_addpath(entry);
  546. uint16_t i;
  547. prefixdata->afi = AFI_IP6;
  548. prefixdata->safi = SAFI_UNICAST;
  549. mstream_getl(s, &prefixdata->seq);
  550. mstream_getc(s, &prefixdata->prefix_length);
  551. bzero(&prefixdata->prefix.v6_addr.s6_addr, 16);
  552. mstream_get(s, &prefixdata->prefix.v6_addr.s6_addr, (prefixdata->prefix_length+7)/8);
  553. mstream_getw(s, &prefixdata->entry_count);
  554. prefixdata->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY) * prefixdata->entry_count);
  555. if(prefixdata->entries == NULL){
  556. err("process_mrtd_table_dump_v2_ipv6_unicast: failed to allocate memory for entry table");
  557. return 0;
  558. }
  559. if(prefixdata->entry_count && entry->dump->table_dump_v2_peer_index_table == NULL) {
  560. free(prefixdata->entries);
  561. err("%s: missing peer index table", __func__);
  562. return 0;
  563. }
  564. for(i=0; i < prefixdata->entry_count; i++){
  565. BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY *e;
  566. e = &prefixdata->entries[i];
  567. mstream_getw(s, &e->peer_index);
  568. assert(e->peer_index <= entry->dump->table_dump_v2_peer_index_table->peer_count);
  569. e->peer = &entry->dump->table_dump_v2_peer_index_table->entries[e->peer_index];
  570. mstream_getl(s, &e->originated_time);
  571. if (addpath)
  572. mstream_getl(s, &e->path_id);
  573. if((e->attr = process_attributes(s, 4, NULL, is_addpath(entry))) == NULL)
  574. return 0;
  575. }
  576. #endif
  577. return 1;
  578. }
  579. int process_zebra_bgp(struct mstream *s,BGPDUMP_ENTRY *entry) {
  580. switch(entry->subtype) {
  581. case BGPDUMP_SUBTYPE_ZEBRA_BGP_STATE_CHANGE:
  582. return process_zebra_bgp_state_change(s, entry, ASN16_LEN);
  583. case BGPDUMP_SUBTYPE_ZEBRA_BGP_STATE_CHANGE_AS4:
  584. return process_zebra_bgp_state_change(s, entry, ASN32_LEN);
  585. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE:
  586. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL:
  587. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH:
  588. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH:
  589. return process_zebra_bgp_message(s, entry, ASN16_LEN);
  590. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4:
  591. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL:
  592. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH:
  593. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL_ADDPATH:
  594. return process_zebra_bgp_message(s, entry, ASN32_LEN);
  595. case BGPDUMP_SUBTYPE_ZEBRA_BGP_ENTRY:
  596. return process_zebra_bgp_entry(s,entry);
  597. case BGPDUMP_SUBTYPE_ZEBRA_BGP_SNAPSHOT:
  598. return process_zebra_bgp_snapshot(s, entry);
  599. default:
  600. warn("process_zebra_bgp: unknown subtype %d", entry->subtype);
  601. return 0;
  602. }
  603. }
  604. int process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len) {
  605. entry->body.zebra_state_change.source_as = read_asn(s, asn_len);
  606. entry->body.zebra_state_change.destination_as = read_asn(s, asn_len);
  607. /* Work around Zebra dump corruption.
  608. * N.B. I don't see this in quagga 0.96.4 any more. Is it fixed? */
  609. if (entry->length == 8) {
  610. warn("process_zebra_bgp_state_change: 8-byte state change (zebra bug?)");
  611. mstream_getw(s,&entry->body.zebra_state_change.old_state);
  612. mstream_getw(s,&entry->body.zebra_state_change.new_state);
  613. /* Fill in with dummy values */
  614. entry->body.zebra_state_change.interface_index = 0;
  615. entry->body.zebra_state_change.address_family = AFI_IP;
  616. entry->body.zebra_state_change.source_ip.v4_addr.s_addr = 0;
  617. entry->body.zebra_state_change.destination_ip.v4_addr.s_addr = 0;
  618. return 1;
  619. }
  620. mstream_getw(s,&entry->body.zebra_state_change.interface_index);
  621. mstream_getw(s,&entry->body.zebra_state_change.address_family);
  622. switch(entry->body.zebra_state_change.address_family) {
  623. case AFI_IP:
  624. // length could be 20 or 24 (asn16 vs asn32)
  625. if(entry->length != 20 && entry->length != 24) {
  626. warn("process_zebra_bgp_state_change: bad length %d",
  627. entry->length);
  628. return 0;
  629. }
  630. entry->body.zebra_state_change.source_ip.v4_addr = mstream_get_ipv4(s);
  631. entry->body.zebra_state_change.destination_ip.v4_addr = mstream_get_ipv4(s);
  632. break;
  633. #ifdef BGPDUMP_HAVE_IPV6
  634. case AFI_IP6:
  635. // length could be 44 or 48 (asn16 vs asn32)
  636. if(entry->length != 44 && entry->length != 48) {
  637. warn("process_zebra_bgp_state_change: bad length %d",
  638. entry->length);
  639. return 0;
  640. }
  641. mstream_get(s, &entry->body.zebra_state_change.source_ip.v6_addr.s6_addr, 16);
  642. mstream_get(s, &entry->body.zebra_state_change.destination_ip.v6_addr.s6_addr, 16);
  643. break;
  644. #endif
  645. default:
  646. warn("process_zebra_bgp_state_change: unknown AFI %d",
  647. entry->body.zebra_state_change.address_family);
  648. return 0;
  649. }
  650. mstream_getw(s,&entry->body.zebra_state_change.old_state);
  651. mstream_getw(s,&entry->body.zebra_state_change.new_state);
  652. return 1;
  653. }
  654. int process_zebra_bgp_message(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len) {
  655. u_char marker[16]; /* BGP marker */
  656. switch(entry->subtype) {
  657. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL:
  658. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL:
  659. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH:
  660. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL_ADDPATH:
  661. entry->body.zebra_message.destination_as = read_asn(s, asn_len);
  662. entry->body.zebra_message.source_as = read_asn(s, asn_len);
  663. break;
  664. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE:
  665. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4:
  666. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH:
  667. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH:
  668. default:
  669. entry->body.zebra_message.source_as = read_asn(s, asn_len);
  670. entry->body.zebra_message.destination_as = read_asn(s, asn_len);
  671. break;
  672. }
  673. mstream_getw(s,&entry->body.zebra_message.interface_index);
  674. mstream_getw(s,&entry->body.zebra_message.address_family);
  675. entry->body.zebra_message.opt_len = 0;
  676. entry->body.zebra_message.opt_data = NULL;
  677. entry->body.zebra_message.notify_len = 0;
  678. entry->body.zebra_message.notify_data = NULL;
  679. switch(entry->body.zebra_message.address_family) {
  680. case AFI_IP:
  681. switch(entry->subtype) {
  682. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL:
  683. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL:
  684. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH:
  685. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL_ADDPATH:
  686. entry->body.zebra_message.destination_ip.v4_addr = mstream_get_ipv4(s);
  687. entry->body.zebra_message.source_ip.v4_addr = mstream_get_ipv4(s);
  688. break;
  689. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE:
  690. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4:
  691. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH:
  692. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH:
  693. default:
  694. entry->body.zebra_message.source_ip.v4_addr = mstream_get_ipv4(s);
  695. entry->body.zebra_message.destination_ip.v4_addr = mstream_get_ipv4(s);
  696. break;
  697. }
  698. mstream_get (s, marker, 16);
  699. break;
  700. #ifdef BGPDUMP_HAVE_IPV6
  701. case AFI_IP6:
  702. switch(entry->subtype) {
  703. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL:
  704. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL:
  705. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH:
  706. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL_ADDPATH:
  707. mstream_get(s,&entry->body.zebra_message.destination_ip.v6_addr.s6_addr, 16);
  708. mstream_get(s,&entry->body.zebra_message.source_ip.v6_addr.s6_addr, 16);
  709. break;
  710. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE:
  711. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4:
  712. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH:
  713. case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH:
  714. default:
  715. mstream_get(s,&entry->body.zebra_message.source_ip.v6_addr.s6_addr, 16);
  716. mstream_get(s,&entry->body.zebra_message.destination_ip.v6_addr.s6_addr, 16);
  717. break;
  718. }
  719. mstream_get (s, marker, 16);
  720. break;
  721. #endif
  722. case 0xFFFF:
  723. /* Zebra doesn't dump ifindex or src/dest IPs in OPEN
  724. * messages. Work around it. */
  725. if (entry->body.zebra_message.interface_index == 0xFFFF) {
  726. memset(marker, 0xFF, 4);
  727. mstream_get (s, marker + 4, 12);
  728. entry->body.zebra_message.interface_index = 0;
  729. entry->body.zebra_message.address_family = AFI_IP;
  730. entry->body.zebra_message.source_ip.v4_addr.s_addr = 0;
  731. entry->body.zebra_message.destination_ip.v4_addr.s_addr = 0;
  732. break;
  733. }
  734. /* Note fall through! If we don't recognize this type of data corruption, we say
  735. * the address family is unsupported (since FFFF is not a valid address family) */
  736. default:
  737. /* unsupported address family */
  738. warn("process_zebra_bgp_message: unsupported AFI %d",
  739. entry->body.zebra_message.address_family);
  740. return 0;
  741. }
  742. if(memcmp(marker, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) != 0) {
  743. /* bad marker... ignore packet */
  744. warn(
  745. "bgp_message: bad marker: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x",
  746. marker[0],marker[1],marker[2],marker[3],marker[4],marker[5],marker[6],marker[7],
  747. marker[8],marker[9],marker[10],marker[11],marker[12],marker[13],marker[14],marker[15]);
  748. return 0;
  749. }
  750. mstream_getw(s,&entry->body.zebra_message.size);
  751. int expected = entry->body.zebra_message.size - sizeof(marker) - sizeof(u_int16_t);
  752. mstream_t copy = mstream_copy(s, expected);
  753. entry->body.zebra_message.cut_bytes = expected - mstream_can_read(&copy);
  754. switch(mstream_getc (&copy, &entry->body.zebra_message.type)) {
  755. case BGP_MSG_OPEN:
  756. return process_zebra_bgp_message_open(&copy, entry, asn_len);
  757. case BGP_MSG_UPDATE:
  758. return process_zebra_bgp_message_update(&copy, entry, asn_len);
  759. case BGP_MSG_NOTIFY:
  760. return process_zebra_bgp_message_notify(&copy, entry);
  761. case BGP_MSG_KEEPALIVE:
  762. /* Nothing to do */
  763. return 1;
  764. case BGP_MSG_ROUTE_REFRESH_01:
  765. /* Not implemented yet */
  766. warn("bgp_message: MSG_ROUTE_REFRESH_01 not implemented yet");
  767. return 0;
  768. case BGP_MSG_ROUTE_REFRESH:
  769. /* Not implemented yet */
  770. warn("bgp_message: MSG_ROUTE_REFRESH not implemented yet");
  771. return 0;
  772. default:
  773. warn("bgp_message: unknown BGP message type %d",
  774. entry->body.zebra_message.type);
  775. return 0;
  776. }
  777. }
  778. int process_zebra_bgp_message_notify(struct mstream *s, BGPDUMP_ENTRY *entry) {
  779. mstream_getc(s, &entry->body.zebra_message.error_code);
  780. mstream_getc(s, &entry->body.zebra_message.sub_error_code);
  781. entry->body.zebra_message.notify_len = entry->body.zebra_message.size - 21;
  782. if(entry->body.zebra_message.notify_len > 0) {
  783. if((entry->body.zebra_message.notify_data = malloc(entry->body.zebra_message.notify_len)) == NULL) {
  784. err("%s: out of memory", __func__);
  785. return 0;
  786. }
  787. mstream_get(s, entry->body.zebra_message.notify_data, entry->body.zebra_message.notify_len);
  788. }
  789. return 1;
  790. }
  791. int process_zebra_bgp_message_open(struct mstream *s, BGPDUMP_ENTRY *entry, u_int8_t asn_len) {
  792. mstream_getc(s, &entry->body.zebra_message.version);
  793. entry->body.zebra_message.my_as = read_asn(s, asn_len);
  794. mstream_getw(s, &entry->body.zebra_message.hold_time);
  795. entry->body.zebra_message.bgp_id = mstream_get_ipv4(s);
  796. mstream_getc(s, &entry->body.zebra_message.opt_len);
  797. if(entry->body.zebra_message.opt_len) {
  798. if((entry->body.zebra_message.opt_data = malloc(entry->body.zebra_message.opt_len)) == NULL) {
  799. err("%s: out of memory", __func__);
  800. return 0;
  801. }
  802. mstream_get(s, entry->body.zebra_message.opt_data, entry->body.zebra_message.opt_len);
  803. }
  804. return 1;
  805. }
  806. int process_zebra_bgp_message_update(struct mstream *s, BGPDUMP_ENTRY *entry, u_int8_t asn_len) {
  807. entry->body.zebra_message.incomplete.orig_len = 0;
  808. mstream_t withdraw_stream = mstream_copy(s, mstream_getw(s, NULL));
  809. entry->body.zebra_message.withdraw_count = read_prefix_list(&withdraw_stream, AFI_IP,
  810. entry->body.zebra_message.withdraw,
  811. &entry->body.zebra_message.incomplete,
  812. is_addpath(entry));
  813. if((entry->attr = process_attributes(s, asn_len, &entry->body.zebra_message.incomplete, is_addpath(entry))) == NULL)
  814. return 0;
  815. entry->body.zebra_message.announce_count = read_prefix_list(s, AFI_IP,
  816. entry->body.zebra_message.announce,
  817. &entry->body.zebra_message.incomplete,
  818. is_addpath(entry));
  819. return 1;
  820. }
  821. int process_zebra_bgp_entry(struct mstream *s, BGPDUMP_ENTRY *entry) {
  822. warn("process_zebra_bgp_entry: record type not implemented yet");
  823. return 0;
  824. }
  825. int process_zebra_bgp_snapshot(struct mstream *s, BGPDUMP_ENTRY *entry) {
  826. warn("process_zebra_bgp_snapshot: record type not implemented yet");
  827. return 0;
  828. }
  829. static attributes_t *attr_init(struct mstream *s, int len) {
  830. attributes_t *attr = malloc(sizeof(struct attr));
  831. if(attr == NULL) {
  832. err("%s: out of memory", __func__);
  833. return NULL;
  834. }
  835. if((attr->data=malloc(len)) == NULL) {
  836. free(attr);
  837. err("%s: out of memory", __func__);
  838. return NULL;
  839. }
  840. memcpy(attr->data, &s->start[s->position], len);
  841. attr->len = len;
  842. attr->flag = 0;
  843. attr->origin = -1;
  844. attr->nexthop.s_addr = INADDR_NONE;
  845. attr->med = -1;
  846. attr->local_pref = -1;
  847. attr->aggregator_as = -1;
  848. attr->aggregator_addr.s_addr = INADDR_NONE;
  849. attr->weight = -1;
  850. attr->originator_id.s_addr = -1;
  851. attr->cluster = NULL;
  852. attr->aspath = NULL;
  853. attr->community = NULL;
  854. attr->transit = NULL;
  855. attr->mp_info = calloc(1, sizeof(struct mp_info));
  856. if(attr->mp_info == NULL) {
  857. free(attr->data);
  858. free(attr);
  859. err("%s: out of memory", __func__);
  860. return NULL;
  861. }
  862. attr->unknown_num = 0;
  863. attr->unknown = NULL;
  864. attr->new_aspath = NULL;
  865. attr->old_aspath = NULL;
  866. attr->new_aggregator_as = -1;
  867. attr->new_aggregator_addr.s_addr = INADDR_NONE;
  868. return attr;
  869. }
  870. static void process_unknown_attr(struct mstream *s, attributes_t *attr, int flag, int type, int len) {
  871. /* Unknown attribute. Save as is */
  872. attr->unknown_num++;
  873. if((attr->unknown = realloc(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr))) == NULL) {
  874. err("%s: out of memory", __func__);
  875. exit(1); /* XXX */
  876. }
  877. /* Pointer to the unknown attribute we want to fill in */
  878. struct unknown_attr unknown = {
  879. .flag = flag,
  880. .type = type,
  881. .len = len,
  882. .raw = malloc(len)
  883. };
  884. if(unknown.raw == NULL) {
  885. err("%s: out of memory", __func__);
  886. exit(1); /* XXX */
  887. }
  888. attr->unknown[attr->unknown_num - 1] = unknown;
  889. mstream_get(s, unknown.raw, len);
  890. }
  891. static void process_one_attr(struct mstream *outer_stream, attributes_t *attr, u_int8_t asn_len, struct zebra_incomplete *incomplete, int is_addp) {
  892. int flag = mstream_getc(outer_stream, NULL);
  893. int type = mstream_getc(outer_stream, NULL);
  894. int len;
  895. if(flag & BGP_ATTR_FLAG_EXTLEN)
  896. len = mstream_getw(outer_stream,NULL);
  897. else
  898. len = mstream_getc(outer_stream,NULL);
  899. //info("flag:%-2i type:%-2i length:%i", flag, type, len);
  900. mstream_t ms = mstream_copy(outer_stream, len), *s = &ms;
  901. if(mstream_can_read(s) != len) {
  902. warn("ERROR attribute is truncated: expected=%u remaining=%u\n", len, mstream_can_read(s));
  903. return;
  904. }
  905. /* Take note of all attributes, including unknown ones */
  906. if(type <= sizeof(attr->flag) * 8)
  907. attr->flag |= ATTR_FLAG_BIT(type);
  908. switch(type) {
  909. case BGP_ATTR_MP_REACH_NLRI:
  910. process_mp_announce(s, attr->mp_info, incomplete, is_addp);
  911. break;
  912. case BGP_ATTR_MP_UNREACH_NLRI:
  913. process_mp_withdraw(s, attr->mp_info, incomplete, is_addp);
  914. break;
  915. case BGP_ATTR_ORIGIN:
  916. assert(attr->origin == -1);
  917. attr->origin = mstream_getc(s, NULL);
  918. break;
  919. case BGP_ATTR_AS_PATH:
  920. assert(! attr->aspath);
  921. attr->aspath = create_aspath(len, asn_len);
  922. mstream_get(s, attr->aspath->data, len);
  923. process_attr_aspath_string(attr->aspath);
  924. break;
  925. case BGP_ATTR_NEXT_HOP:
  926. assert(INADDR_NONE == attr->nexthop.s_addr);
  927. attr->nexthop = mstream_get_ipv4(s);
  928. break;
  929. case BGP_ATTR_MULTI_EXIT_DISC:
  930. assert(-1 == attr->med);
  931. mstream_getl(s,&attr->med);
  932. break;
  933. case BGP_ATTR_LOCAL_PREF:
  934. assert(-1 == attr->local_pref);
  935. mstream_getl(s,&attr->local_pref);
  936. break;
  937. case BGP_ATTR_ATOMIC_AGGREGATE:
  938. break;
  939. case BGP_ATTR_AGGREGATOR:
  940. assert(-1 == attr->new_aggregator_as);
  941. attr->aggregator_as = read_asn(s, asn_len);
  942. attr->aggregator_addr = mstream_get_ipv4(s);
  943. break;
  944. case BGP_ATTR_COMMUNITIES:
  945. assert(! attr->community);
  946. if((attr->community = malloc(sizeof(struct community))) == NULL) {
  947. err("%s: out of memory", __func__);
  948. exit(1); /* XXX */
  949. }
  950. attr->community->size = len / 4;
  951. if((attr->community->val = malloc(len)) == NULL) {
  952. err("%s: out of memory", __func__);
  953. exit(1); /* XXX */
  954. }
  955. mstream_get(s,attr->community->val,len);
  956. attr->community->str = NULL;
  957. process_attr_community_string(attr->community);
  958. break;
  959. case BGP_ATTR_NEW_AS_PATH:
  960. assert(! attr->new_aspath);
  961. attr->new_aspath = create_aspath(len, ASN32_LEN);
  962. mstream_get(s,attr->new_aspath->data, len);
  963. process_attr_aspath_string(attr->new_aspath);
  964. /* AS_CONFED_SEQUENCE and AS_CONFED_SET segments invalid in NEW_AS_PATH */
  965. check_new_aspath(attr->new_aspath);
  966. break;
  967. case BGP_ATTR_NEW_AGGREGATOR:
  968. assert(-1 == attr->new_aggregator_as);
  969. attr->new_aggregator_as = read_asn(s, ASN32_LEN);
  970. attr->new_aggregator_addr = mstream_get_ipv4(s);
  971. break;
  972. case BGP_ATTR_ORIGINATOR_ID:
  973. assert(INADDR_NONE == attr->originator_id.s_addr);
  974. attr->originator_id = mstream_get_ipv4(s);
  975. break;
  976. case BGP_ATTR_CLUSTER_LIST:
  977. assert(! attr->cluster);
  978. if((attr->cluster= malloc(sizeof(struct cluster_list))) == NULL) {
  979. err("%s: out of memory", __func__);
  980. exit(1); /* XXX */
  981. }
  982. attr->cluster->length = len/4;
  983. if((attr->cluster->list = calloc((attr->cluster->length), sizeof(struct in_addr))) == NULL) {
  984. err("%s: out of memory", __func__);
  985. exit(1); /* XXX */
  986. }
  987. int i; // cluster index
  988. for (i = 0; i < attr->cluster->length; i++)
  989. attr->cluster->list[i] = mstream_get_ipv4(s);
  990. break;
  991. default:
  992. process_unknown_attr(s, attr, flag, type, len);
  993. }
  994. }
  995. attributes_t *process_attributes(struct mstream *s, u_int8_t asn_len, struct zebra_incomplete *incomplete, int is_addp) {
  996. int total = mstream_getw(s, NULL);
  997. attributes_t *attr = attr_init(s, total);
  998. if(attr == NULL)
  999. return NULL;
  1000. mstream_t copy = mstream_copy(s, total);
  1001. if(mstream_can_read(&copy) != total)
  1002. warn("entry is truncated: expected=%u remaining=%u", total, mstream_can_read(&copy));
  1003. while(mstream_can_read(&copy))
  1004. process_one_attr(&copy, attr, asn_len, incomplete, is_addp);
  1005. // Once all attributes have been read, take care of ASN32 transition
  1006. process_asn32_trans(attr, asn_len);
  1007. return attr;
  1008. }
  1009. struct aspath *create_aspath(u_int16_t len, u_int8_t asn_len) {
  1010. struct aspath *aspath = malloc(sizeof(struct aspath));
  1011. if(aspath) {
  1012. aspath->asn_len = asn_len;
  1013. aspath->length = len;
  1014. aspath->count = 0;
  1015. aspath->str = NULL;
  1016. if(len > 0) {
  1017. if((aspath->data = malloc(len)) == NULL) {
  1018. err("%s: out of memory", __func__);
  1019. free(aspath);
  1020. return NULL;
  1021. }
  1022. } else
  1023. aspath->data = NULL;
  1024. } else
  1025. err("%s: out of memory", __func__);
  1026. return aspath;
  1027. }
  1028. void aspath_error(struct aspath *as) {
  1029. as->count = 0;
  1030. if(as->str) {
  1031. free(as->str);
  1032. as->str = NULL;
  1033. }
  1034. as->str = malloc(strlen(ASPATH_STR_ERROR) + 1);
  1035. if (as->str != NULL)
  1036. strcpy(as->str, ASPATH_STR_ERROR);
  1037. }
  1038. void process_attr_aspath_string(struct aspath *as) {
  1039. const int MAX_ASPATH_LEN = 8000;
  1040. if((as->str = malloc(MAX_ASPATH_LEN)) == NULL) {
  1041. err("%s: out of memory", __func__);
  1042. exit(1); /* XXX */
  1043. }
  1044. /* Set default values */
  1045. int space = 0;
  1046. u_char type = AS_SEQUENCE;
  1047. int pos = 0;
  1048. /* Set initial pointer. */
  1049. caddr_t pnt = as->data;
  1050. caddr_t end = pnt + as->length;
  1051. struct assegment *segment = NULL;
  1052. while (pnt < end) {
  1053. int i;
  1054. /* For fetch value. */
  1055. segment = (struct assegment *) pnt;
  1056. /* Check AS type validity. */
  1057. if ((segment->type != AS_SET) &&
  1058. (segment->type != AS_SEQUENCE) &&
  1059. (segment->type != AS_CONFED_SET) &&
  1060. (segment->type != AS_CONFED_SEQUENCE))
  1061. {
  1062. aspath_error(as);
  1063. return;
  1064. }
  1065. /* Check AS length. */
  1066. if ((pnt + (segment->length * as->asn_len) + AS_HEADER_SIZE) > end)
  1067. {
  1068. aspath_error(as);
  1069. return;
  1070. }
  1071. /* If segment type is changed, print previous type's end
  1072. character. */
  1073. if (type != AS_SEQUENCE)
  1074. as->str[pos++] = aspath_delimiter_char (type, AS_SEG_END);
  1075. if (space)
  1076. as->str[pos++] = ' ';
  1077. if (segment->type != AS_SEQUENCE)
  1078. as->str[pos++] = aspath_delimiter_char (segment->type, AS_SEG_START);
  1079. space = 0;
  1080. /* Increment as->count - NOT ignoring CONFED_SETS/SEQUENCES any more.
  1081. I doubt anybody was relying on this behaviour anyway. */
  1082. switch(segment->type) {
  1083. case AS_SEQUENCE:
  1084. case AS_CONFED_SEQUENCE:
  1085. as->count += segment->length;
  1086. break;
  1087. case AS_SET:
  1088. case AS_CONFED_SET:
  1089. as->count += 1;
  1090. break;
  1091. }
  1092. for (i = 0; i < segment->length; i++)
  1093. {
  1094. as_t asn;
  1095. if (space)
  1096. {
  1097. if (segment->type == AS_SET
  1098. || segment->type == AS_CONFED_SET)
  1099. as->str[pos++] = ',';
  1100. else
  1101. as->str[pos++] = ' ';
  1102. }
  1103. else
  1104. space = 1;
  1105. int asn_pos = i * as->asn_len;
  1106. switch(as->asn_len) {
  1107. case ASN16_LEN:
  1108. asn = ntohs (*(u_int16_t *) (segment->data + asn_pos));
  1109. break;
  1110. case ASN32_LEN:
  1111. asn = ntohl (*(u_int32_t *) (segment->data + asn_pos));
  1112. break;
  1113. default:
  1114. assert("invalid asn_len" && false);
  1115. }
  1116. pos += int2str(asn, as->str + pos);
  1117. if(pos > MAX_ASPATH_LEN - 100) {
  1118. strcpy(as->str + pos, "...");
  1119. return;
  1120. };
  1121. }
  1122. type = segment->type;
  1123. pnt += (segment->length * as->asn_len) + AS_HEADER_SIZE;
  1124. }
  1125. if (segment && segment->type != AS_SEQUENCE)
  1126. as->str[pos++] = aspath_delimiter_char (segment->type, AS_SEG_END);
  1127. as->str[pos] = '\0';
  1128. }
  1129. char aspath_delimiter_char (u_char type, u_char which) {
  1130. int i;
  1131. struct
  1132. {
  1133. int type;
  1134. char start;
  1135. char end;
  1136. } aspath_delim_char [] =
  1137. {
  1138. { AS_SET, '{', '}' },
  1139. { AS_SEQUENCE, ' ', ' ' },
  1140. { AS_CONFED_SET, '[', ']' },
  1141. { AS_CONFED_SEQUENCE, '(', ')' },
  1142. { 0, '\0', '\0' }
  1143. };
  1144. for (i = 0; aspath_delim_char[i].type != 0; i++)
  1145. {
  1146. if (aspath_delim_char[i].type == type)
  1147. {
  1148. if (which == AS_SEG_START)
  1149. return aspath_delim_char[i].start;
  1150. else if (which == AS_SEG_END)
  1151. return aspath_delim_char[i].end;
  1152. }
  1153. }
  1154. return ' ';
  1155. }
  1156. void process_attr_community_string(struct community *com) {
  1157. char buf[BUFSIZ];
  1158. int i;
  1159. u_int32_t comval;
  1160. u_int16_t as;
  1161. u_int16_t val;
  1162. memset (buf, 0, BUFSIZ);
  1163. for (i = 0; i < com->size; i++)
  1164. {
  1165. memcpy (&comval, com_nthval (com, i), sizeof (u_int32_t));
  1166. comval = ntohl (comval);
  1167. switch (comval)
  1168. {
  1169. case COMMUNITY_NO_EXPORT:
  1170. strlcat (buf, " no-export", BUFSIZ);
  1171. break;
  1172. case COMMUNITY_NO_ADVERTISE:
  1173. strlcat (buf, " no-advertise", BUFSIZ);
  1174. break;
  1175. case COMMUNITY_LOCAL_AS:
  1176. strlcat (buf, " local-AS", BUFSIZ);
  1177. break;
  1178. default:
  1179. as = (comval >> 16) & 0xFFFF;
  1180. val = comval & 0xFFFF;
  1181. snprintf (buf + strlen (buf), BUFSIZ - strlen (buf),
  1182. " %d:%d", as, val);
  1183. break;
  1184. }
  1185. }
  1186. if((com->str = malloc(strlen(buf)+1)) != NULL) {
  1187. strcpy(com->str, buf);
  1188. } else {
  1189. err("%s: out of memory", __func__);
  1190. exit(1); /* XXX */
  1191. }
  1192. }
  1193. static struct mp_nlri *get_nexthop(struct mstream *s) {
  1194. struct mp_nlri *nlri = calloc(1, sizeof(struct mp_nlri));
  1195. if(nlri == NULL) {
  1196. err("%s: out of memory", __func__);
  1197. return NULL;
  1198. }
  1199. nlri->nexthop_len = mstream_getc(s, NULL);
  1200. // sometimes nexthop_len is 0 - not sure what this means (see IS-626)
  1201. // if(mp_nlri->nexthop_len == 0)
  1202. // return len;
  1203. // the AFI is irrelevant to the nexthop, since RFC5549
  1204. // so this code now just checks for an expected length:
  1205. // 4 = IPv4
  1206. // 16 = IPv6
  1207. // 32 = IPv6 + link-local
  1208. if(nlri->nexthop_len == 4) {
  1209. nlri->nexthop.v4_addr = mstream_get_ipv4(s);
  1210. } else if(nlri->nexthop_len == 16) {
  1211. mstream_get(s, &nlri->nexthop.v6_addr, 16);
  1212. } else if(nlri->nexthop_len == 32) {
  1213. mstream_get(s, &nlri->nexthop.v6_addr, 16);
  1214. mstream_get(s, &nlri->nexthop_local.v6_addr.s6_addr, 16);
  1215. }
  1216. else {
  1217. warn("process_mp_announce: unknown MP nexthop length %d", nlri->nexthop_len);
  1218. }
  1219. return nlri;
  1220. }
  1221. void process_mp_announce(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete, int is_addp) {
  1222. u_int16_t afi;
  1223. u_int8_t safi;
  1224. // look for MRT abbreviated MP_NLRI packets
  1225. if(s->start[s->position] != 0) {
  1226. assert(info->announce[AFI_IP6][SAFI_UNICAST] == NULL);
  1227. info->announce[AFI_IP6][SAFI_UNICAST] = get_nexthop(s);
  1228. return;
  1229. }
  1230. mstream_getw(s, &afi);
  1231. mstream_getc(s, &safi);
  1232. if(afi > BGPDUMP_MAX_AFI || safi > BGPDUMP_MAX_SAFI) {
  1233. warn("process_mp_announce: unknown protocol(AFI=%d, SAFI=%d)!", afi, safi);
  1234. return;
  1235. }
  1236. if(info->announce[afi][safi] != NULL) {
  1237. warn("process_mp_announce: two MP_NLRI for the same protocol(%d, %d)!", afi, safi);
  1238. return;
  1239. }
  1240. info->announce[afi][safi] = get_nexthop(s);
  1241. // SNPA is defunct and num_snpa should always be 0
  1242. u_int8_t num_snpa;
  1243. if(mstream_getc(s, &num_snpa))
  1244. warn("process_mp_announce: MP_NLRI contains SNPAs, skipping");
  1245. for(; num_snpa > 0; --num_snpa) {
  1246. mstream_get(s, NULL, mstream_getc(s, NULL));
  1247. }
  1248. info->announce[afi][safi]->prefix_count = read_prefix_list(s, afi, info->announce[afi][safi]->nlri, incomplete, is_addp);
  1249. }
  1250. void process_mp_withdraw(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete, int is_addp) {
  1251. u_int16_t afi;
  1252. u_int8_t safi;
  1253. struct mp_nlri *mp_nlri;
  1254. mstream_getw(s, &afi);
  1255. mstream_getc(s, &safi);
  1256. /* Do we know about this address family? */
  1257. if(afi > BGPDUMP_MAX_AFI || safi > BGPDUMP_MAX_SAFI) {
  1258. warn("process_mp_withdraw: unknown AFI,SAFI %d,%d!", afi, safi);
  1259. return;
  1260. }
  1261. /* If there are 2 NLRI's for the same protocol, fail but don't burn and die */
  1262. if(info->withdraw[afi][safi] != NULL) {
  1263. warn("process_mp_withdraw: update contains more than one MP_NLRI with AFI,SAFI %d,%d!", afi, safi);
  1264. return;
  1265. }
  1266. /* Allocate structure */
  1267. if((mp_nlri = malloc(sizeof(struct mp_nlri))) == NULL) {
  1268. err("%s: out of memory", __func__);
  1269. exit(1); /* XXX */
  1270. }
  1271. memset(mp_nlri, 0, sizeof(struct mp_nlri));
  1272. info->withdraw[afi][safi] = mp_nlri;
  1273. mp_nlri->prefix_count = read_prefix_list(s, afi, mp_nlri->nlri, incomplete, is_addp);
  1274. }
  1275. static int read_prefix_list(struct mstream *s, u_int16_t afi, struct prefix *prefixes, struct zebra_incomplete *incomplete, int is_addp) {
  1276. int count = 0;
  1277. while(mstream_can_read(s)) {
  1278. /* If this is an Additional Paths enabled NLRI, then there is a
  1279. * 4 octet identifier preceeding each prefix entry */
  1280. pathid_t path_id = 0;
  1281. if (is_addp)
  1282. path_id = mstream_getl(s, NULL);
  1283. u_int8_t p_len = mstream_getc(s,NULL); // length in bits
  1284. u_int8_t p_bytes = (p_len + 7) / 8;
  1285. /* Truncated prefix list? */
  1286. if(mstream_can_read(s) < p_bytes) {
  1287. if(! incomplete)
  1288. break;
  1289. /* Put prefix in incomplete structure */
  1290. incomplete->afi = afi;
  1291. incomplete->orig_len = p_len;
  1292. incomplete->prefix = (struct prefix) {
  1293. .len = mstream_can_read(s) * 8,
  1294. .path_id = path_id
  1295. };
  1296. mstream_get(s, &incomplete->prefix.address, p_bytes);
  1297. break;
  1298. }
  1299. struct prefix *prefix = prefixes + count;
  1300. if(count++ > MAX_PREFIXES)
  1301. continue;
  1302. *prefix = (struct prefix) { .len = p_len, .path_id = path_id };
  1303. mstream_get(s, &prefix->address, p_bytes);
  1304. }
  1305. if(count > MAX_PREFIXES) {
  1306. err("too many prefixes (%i > %i)", count, MAX_PREFIXES);
  1307. return MAX_PREFIXES;
  1308. }
  1309. return count;
  1310. }
  1311. static as_t read_asn(struct mstream *s, u_int8_t len) {
  1312. assert(len == ASN32_LEN || len == ASN16_LEN);
  1313. switch(len) {
  1314. case ASN32_LEN:
  1315. return mstream_getl(s, NULL);
  1316. case ASN16_LEN:
  1317. return mstream_getw(s, NULL);
  1318. default:
  1319. /* Not reached. Avoid compiler warning */
  1320. return 0;
  1321. }
  1322. }
  1323. int check_new_aspath(struct aspath *aspath) {
  1324. struct assegment *segment;
  1325. for(segment = (struct assegment *) aspath->data;
  1326. segment < (struct assegment *) (aspath->data + aspath->length);
  1327. segment = (struct assegment *) ((char *) segment + sizeof(*segment) + segment->length * ASN32_LEN)) {
  1328. if(segment->type == AS_CONFED_SEQUENCE || segment->type == AS_CONFED_SET) {
  1329. warn("check_new_aspath: invalid segment of type AS_CONFED_%s in NEW_AS_PATH",
  1330. segment->type == AS_CONFED_SET ? "SET" : "SEQUENCE");
  1331. return 0;
  1332. }
  1333. }
  1334. return 1;
  1335. }
  1336. void process_asn32_trans(attributes_t *attr, u_int8_t asn_len) {
  1337. if(asn_len == ASN32_LEN) {
  1338. /* These attributes "SHOULD NOT" be used with ASN32. */
  1339. if(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEW_AS_PATH))
  1340. warn("process_asn32_trans: ASN32 message contains NEW_AS_PATH attribute");
  1341. if(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEW_AGGREGATOR))
  1342. warn("process_asn32_trans: ASN32 message contains NEW_AGGREGATOR attribute");
  1343. /* Don't compute anything, just leave AS_PATH and AGGREGATOR as they are */
  1344. return;
  1345. }
  1346. /* Process NEW_AGGREGATOR */
  1347. if(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR) &&
  1348. attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEW_AGGREGATOR)) {
  1349. /* Both AGGREGATOR and NEW_AGGREGATOR present, merge */
  1350. if(attr->aggregator_as != AS_TRAN) {
  1351. /* Don't do anything */
  1352. return;
  1353. } else {
  1354. attr->old_aggregator_as = attr->aggregator_as;
  1355. attr->old_aggregator_addr = attr->aggregator_addr;
  1356. attr->aggregator_as = attr->new_aggregator_as;
  1357. attr->aggregator_addr = attr->new_aggregator_addr;
  1358. }
  1359. }
  1360. /* Process NEW_AS_PATH */
  1361. if(! (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEW_AS_PATH)))
  1362. return;
  1363. // attr->aspath may be NULL, at least in case of MP_UNREACH_NLRI
  1364. if(attr->aspath == NULL) return;
  1365. if(attr->aspath->count < attr->new_aspath->count) {
  1366. return;
  1367. }
  1368. /* Merge paths */
  1369. attr->old_aspath = attr->aspath;
  1370. attr->aspath = asn32_merge_paths(attr->old_aspath, attr->new_aspath);
  1371. if(attr->aspath) {
  1372. process_attr_aspath_string(attr->aspath);
  1373. }
  1374. }
  1375. struct aspath *asn32_merge_paths(struct aspath *path, struct aspath *newpath) {
  1376. void *tmp;
  1377. struct aspath *mergedpath = create_aspath(0, ASN32_LEN);
  1378. if(mergedpath == NULL)
  1379. return NULL;
  1380. struct assegment *segment, *mergedsegment;
  1381. int newlen;
  1382. /* Keep copying segments from AS_PATH until our path is as long as AS_PATH - NEW_AS_PATH. */
  1383. segment = (struct assegment *) (path->data);
  1384. while(mergedpath->count < path->count - newpath->count) {
  1385. /* Make room */
  1386. newlen = mergedpath->length + sizeof(struct assegment) + segment->length * ASN32_LEN;
  1387. tmp = realloc(mergedpath->data, newlen);
  1388. if(tmp == NULL) {
  1389. free(mergedpath->data);
  1390. free(mergedpath);
  1391. err("%s: out of memory", __func__);
  1392. return NULL;
  1393. }
  1394. mergedpath->data = tmp;
  1395. /* Create a new AS-path segment */
  1396. mergedsegment = (struct assegment *) (mergedpath->data + mergedpath->length);
  1397. /* Copy segment over. AS_PATH contains 16-bit ASes, so expand */
  1398. mergedsegment->type = segment->type;
  1399. mergedsegment->length = segment->length;
  1400. asn32_expand_16_to_32(mergedsegment->data, segment->data, segment->length);
  1401. /* Update length */
  1402. mergedpath->length = newlen;
  1403. if(segment->type == AS_SET || segment->type == AS_CONFED_SET) {
  1404. mergedpath->count += 1;
  1405. } else {
  1406. mergedpath->count += segment->length;
  1407. /* Did we copy too many ASes over? */
  1408. if(mergedpath->count > path->count - newpath->count) {
  1409. mergedsegment->length -= mergedpath->count - (path->count - newpath->count);
  1410. mergedpath->length -= (mergedpath->count - (path->count - newpath->count)) * ASN32_LEN;
  1411. }
  1412. }
  1413. }
  1414. /* Append NEW_AS_PATH to merged path */
  1415. tmp = realloc(mergedpath->data, mergedpath->length + newpath->length);
  1416. if(tmp == NULL) {
  1417. free(mergedpath->data);
  1418. free(mergedpath);
  1419. err("%s: out of memory", __func__);
  1420. return NULL;
  1421. }
  1422. mergedpath->data = tmp;
  1423. memcpy(mergedpath->data + mergedpath->length, newpath->data, newpath->length);
  1424. mergedpath->length += newpath->length;
  1425. return mergedpath;
  1426. }
  1427. void asn32_expand_16_to_32(char *dst, char *src, int len) {
  1428. u_int32_t *dstarray = (u_int32_t *) dst;
  1429. u_int16_t *srcarray = (u_int16_t *) src;
  1430. int i;
  1431. for(i = 0; i < len; i++) {
  1432. dstarray[i] = htonl(ntohs(srcarray[i]));
  1433. }
  1434. }
  1435. #if defined(linux)
  1436. size_t strlcat(char *dst, const char *src, size_t size) {
  1437. if (strlen (dst) + strlen (src) >= size)
  1438. return -1;
  1439. strcat (dst, src);
  1440. return (strlen(dst));
  1441. }
  1442. #endif