📄 bgp_dump.c
字号:
/* BGP-4 dump routine Copyright (C) 1999 Kunihiro IshiguroThis file is part of GNU Zebra.GNU Zebra is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 2, or (at your option) anylater version.GNU Zebra is distributed in the hope that it will be useful, butWITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNUGeneral Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU Zebra; see the file COPYING. If not, write to the FreeSoftware Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA02111-1307, USA. */#include <zebra.h>#include "log.h"#include "stream.h"#include "sockunion.h"#include "command.h"#include "prefix.h"#include "thread.h"#include "bgpd/bgp_table.h"#include "bgpd/bgpd.h"#include "bgpd/bgp_route.h"#include "bgpd/bgp_attr.h"#include "bgpd/bgp_dump.h"enum bgp_dump_type{ BGP_DUMP_ALL, BGP_DUMP_UPDATES, BGP_DUMP_ROUTES};enum MRT_MSG_TYPES { MSG_NULL, MSG_START, /* sender is starting up */ MSG_DIE, /* receiver should shut down */ MSG_I_AM_DEAD, /* sender is shutting down */ MSG_PEER_DOWN, /* sender's peer is down */ MSG_PROTOCOL_BGP, /* msg is a BGP packet */ MSG_PROTOCOL_RIP, /* msg is a RIP packet */ MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */ MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */ MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */ MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */ MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */ MSG_TABLE_DUMP /* routing table dump */};struct bgp_dump{ enum bgp_dump_type type; char *filename; FILE *fp; unsigned int interval; char *interval_str; struct thread *t_interval;};/* BGP packet dump output buffer. */struct stream *bgp_dump_obuf;/* BGP dump strucuture for 'dump bgp all' */struct bgp_dump bgp_dump_all;/* BGP dump structure for 'dump bgp updates' */struct bgp_dump bgp_dump_updates;/* BGP dump structure for 'dump bgp routes' */struct bgp_dump bgp_dump_routes;/* Dump whole BGP table is very heavy process. */struct thread *t_bgp_dump_routes;/* Some define for BGP packet dump. */FILE *bgp_dump_open_file (struct bgp_dump *bgp_dump){ int ret; time_t clock; struct tm *tm; char fullpath[MAXPATHLEN]; char realpath[MAXPATHLEN]; time (&clock); tm = localtime (&clock); if (bgp_dump->filename[0] != DIRECTORY_SEP) { sprintf (fullpath, "%s/%s", vty_get_cwd (), bgp_dump->filename); ret = strftime (realpath, MAXPATHLEN, fullpath, tm); } else ret = strftime (realpath, MAXPATHLEN, bgp_dump->filename, tm); if (ret == 0) { zlog_warn ("bgp_dump_open_file: strftime error"); return NULL; } if (bgp_dump->fp) fclose (bgp_dump->fp); bgp_dump->fp = fopen (realpath, "w"); if (bgp_dump->fp == NULL) return NULL; return bgp_dump->fp;}intbgp_dump_interval_add (struct bgp_dump *bgp_dump, int interval){ int bgp_dump_interval_func (struct thread *); bgp_dump->t_interval = thread_add_timer (master, bgp_dump_interval_func, bgp_dump, interval); return 0;}/* Dump common header. */voidbgp_dump_header (struct stream *obuf, int type, int subtype){ time_t now; /* Set header. */ time (&now); /* Put dump packet header. */ stream_putl (obuf, now); stream_putw (obuf, type); stream_putw (obuf, subtype); stream_putl (obuf, 0); /* len */}voidbgp_dump_set_size (struct stream *s, int type){ stream_putl_at (s, 8, stream_get_putp (s) - BGP_DUMP_HEADER_SIZE);}voidbgp_dump_routes_entry (struct prefix *p, struct bgp_info *info, int afi, int type, unsigned int seq){ struct stream *obuf; struct attr *attr; struct peer *peer; int plen; int safi = 0; /* Make dump stream. */ obuf = bgp_dump_obuf; stream_reset (obuf); attr = info->attr; peer = info->peer; /* We support MRT's old format. */ if (type == MSG_TABLE_DUMP) { bgp_dump_header (obuf, MSG_TABLE_DUMP, afi); stream_putw (obuf, 0); /* View # */ stream_putw (obuf, seq); /* Sequence number. */ } else { bgp_dump_header (obuf, MSG_PROTOCOL_BGP4MP, BGP4MP_ENTRY); stream_putl (obuf, info->uptime); /* Time Last Change */ stream_putw (obuf, afi); /* Address Family */ stream_putc (obuf, safi); /* SAFI */ } if (afi == AFI_IP) { if (type == MSG_TABLE_DUMP) { /* Prefix */ stream_put_in_addr (obuf, &p->u.prefix4); stream_putc (obuf, p->prefixlen); /* Status */ stream_putc (obuf, 1); /* Originated */ stream_putl (obuf, info->uptime); /* Peer's IP address */ stream_put_in_addr (obuf, &peer->su.sin.sin_addr); /* Peer's AS number. */ stream_putw (obuf, peer->as); /* Dump attribute. */ bgp_dump_routes_attr (obuf, attr); } else { /* Next-Hop-Len */ stream_putc (obuf, IPV4_MAX_BYTELEN); stream_put_in_addr (obuf, &attr->nexthop); stream_putc (obuf, p->prefixlen); plen = PSIZE (p->prefixlen); stream_put (obuf, &p->u.prefix4, plen); bgp_dump_routes_attr (obuf, attr); } }#ifdef HAVE_IPV6 else if (afi == AFI_IP6) { if (type == MSG_TABLE_DUMP) { /* Prefix */ stream_write (obuf, (u_char *)&p->u.prefix6, IPV6_MAX_BYTELEN); stream_putc (obuf, p->prefixlen); /* Status */ stream_putc (obuf, 1); /* Originated */ stream_putl (obuf, info->uptime); /* Peer's IP address */ stream_write (obuf, (u_char *)&peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN); /* Peer's AS number. */ stream_putw (obuf, peer->as); /* Dump attribute. */ bgp_dump_routes_attr (obuf, attr); } else { ; } }#endif /* HAVE_IPV6 */ /* Set length. */ bgp_dump_set_size (obuf, type); fwrite (STREAM_DATA (obuf), stream_get_putp (obuf), 1, bgp_dump_routes.fp); fflush (bgp_dump_routes.fp);}/* Runs under child process. */voidbgp_dump_routes_func (int afi){ struct stream *obuf; struct bgp_node *rn; struct bgp_info *info; struct bgp *bgp; struct bgp_table *table; unsigned int seq = 0; obuf = bgp_dump_obuf; bgp = bgp_get_default (); if (!bgp) return; if (bgp_dump_routes.fp == NULL) return; /* Walk down each BGP route. */ table = bgp->rib[afi][SAFI_UNICAST]; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) for (info = rn->info; info; info = info->next) bgp_dump_routes_entry (&rn->p, info, afi, MSG_TABLE_DUMP, seq++);}intbgp_dump_interval_func (struct thread *t){ struct bgp_dump *bgp_dump; bgp_dump = THREAD_ARG (t); bgp_dump->t_interval = NULL; if (bgp_dump_open_file (bgp_dump) == NULL) return 0; /* In case of bgp_dump_routes, we need special route dump function. */ if (bgp_dump->type == BGP_DUMP_ROUTES) { bgp_dump_routes_func (AFI_IP); bgp_dump_routes_func (AFI_IP6); } bgp_dump_interval_add (bgp_dump, bgp_dump->interval); return 0;}/* Dump common information. */voidbgp_dump_common (struct stream *obuf, struct peer *peer){ char empty[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; /* Source AS number and Destination AS number. */ stream_putw (obuf, peer->as); stream_putw (obuf, peer->local_as); if (peer->afc[AFI_IP][SAFI_UNICAST]) { stream_putw (obuf, peer->ifindex); stream_putw (obuf, AFI_IP); stream_put (obuf, &peer->su.sin.sin_addr, IPV4_MAX_BYTELEN); if (peer->su_local) stream_put (obuf, &peer->su_local->sin.sin_addr, IPV4_MAX_BYTELEN); else stream_put (obuf, empty, IPV4_MAX_BYTELEN); }#ifdef HAVE_IPV6 else if (peer->afc[AFI_IP6][SAFI_UNICAST]) { /* Interface Index and Address family. */ stream_putw (obuf, peer->ifindex); stream_putw (obuf, AFI_IP6); /* Source IP Address and Destination IP Address. */ stream_put (obuf, &peer->su.sin6.sin6_addr, IPV6_MAX_BYTELEN); if (peer->su_local) stream_put (obuf, &peer->su_local->sin6.sin6_addr, IPV6_MAX_BYTELEN); else stream_put (obuf, empty, IPV6_MAX_BYTELEN); }#endif /* HAVE_IPV6 */}/* Dump BGP status change. */voidbgp_dump_state (struct peer *peer, int status_old, int status_new){ struct stream *obuf; /* If dump file pointer is disabled return immediately. */ if (bgp_dump_all.fp == NULL) return; /* Make dump stream. */ obuf = bgp_dump_obuf; stream_reset (obuf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -