blob: b408efdd15c077647b304418a9ee42be168933a8 [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* BGP dump to ascii converter
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4This file is part of GNU Zebra.
5
6GNU Zebra is free software; you can redistribute it and/or modify it
7under the terms of the GNU General Public License as published by the
8Free Software Foundation; either version 2, or (at your option) any
9later version.
10
11GNU Zebra is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Zebra; see the file COPYING. If not, write to the Free
18Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
20
21#include <zebra.h>
22
23#include "zebra.h"
24#include "stream.h"
25#include "log.h"
26#include "prefix.h"
27#include "command.h"
Donald Sharpbf99b422015-10-21 10:00:47 -040028#include "memory.h"
29#include "privs.h"
Donald Sharp04907292016-01-07 10:03:01 -050030#include "filter.h"
paul718e3742002-12-13 20:15:29 +000031
32#include "bgpd/bgpd.h"
33#include "bgpd/bgp_dump.h"
34#include "bgpd/bgp_attr.h"
35#include "bgpd/bgp_aspath.h"
36
Donald Sharpbf99b422015-10-21 10:00:47 -040037/* privileges */
38static zebra_capabilities_t _caps_p [] =
39{
40 ZCAP_BIND,
41 ZCAP_NET_RAW,
42 ZCAP_NET_ADMIN,
43};
44
45struct zebra_privs_t bgpd_privs =
46{
47#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
48 .user = QUAGGA_USER,
49 .group = QUAGGA_GROUP,
50#endif
51#ifdef VTY_GROUP
52 .vty_group = VTY_GROUP,
53#endif
54 .caps_p = _caps_p,
55 .cap_num_p = array_size(_caps_p),
56 .cap_num_i = 0,
57};
58
paul718e3742002-12-13 20:15:29 +000059enum MRT_MSG_TYPES {
60 MSG_NULL,
61 MSG_START, /* sender is starting up */
62 MSG_DIE, /* receiver should shut down */
63 MSG_I_AM_DEAD, /* sender is shutting down */
64 MSG_PEER_DOWN, /* sender's peer is down */
65 MSG_PROTOCOL_BGP, /* msg is a BGP packet */
66 MSG_PROTOCOL_RIP, /* msg is a RIP packet */
67 MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
68 MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
69 MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
70 MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
71 MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
72 MSG_TABLE_DUMP /* routing table dump */
73};
74
Donald Sharpbf99b422015-10-21 10:00:47 -040075static int
paul718e3742002-12-13 20:15:29 +000076attr_parse (struct stream *s, u_int16_t len)
77{
78 u_int flag;
79 u_int type;
80 u_int16_t length;
81 u_int16_t lim;
82
83 lim = s->getp + len;
84
Donald Sharpbf99b422015-10-21 10:00:47 -040085 printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);
paul718e3742002-12-13 20:15:29 +000086
87 while (s->getp < lim)
88 {
89 flag = stream_getc (s);
90 type = stream_getc (s);
91
Donald Sharpbf99b422015-10-21 10:00:47 -040092 if (flag & BGP_ATTR_FLAG_EXTLEN)
paul718e3742002-12-13 20:15:29 +000093 length = stream_getw (s);
94 else
95 length = stream_getc (s);
96
97 printf ("FLAG: %d\n", flag);
98 printf ("TYPE: %d\n", type);
99 printf ("Len: %d\n", length);
100
101 switch (type)
102 {
103 case BGP_ATTR_ORIGIN:
104 {
105 u_char origin;
106 origin = stream_getc (s);
107 printf ("ORIGIN: %d\n", origin);
108 }
109 break;
110 case BGP_ATTR_AS_PATH:
111 {
Donald Sharpbf99b422015-10-21 10:00:47 -0400112 struct aspath *aspath;
paul718e3742002-12-13 20:15:29 +0000113
Donald Sharpbf99b422015-10-21 10:00:47 -0400114 aspath = aspath_parse (s, length, 1);
115 printf ("ASPATH: %s\n", aspath->str);
116 aspath_free(aspath);
paul718e3742002-12-13 20:15:29 +0000117 }
118 break;
Donald Sharpbf99b422015-10-21 10:00:47 -0400119 case BGP_ATTR_NEXT_HOP:
paul718e3742002-12-13 20:15:29 +0000120 {
121 struct in_addr nexthop;
122 nexthop.s_addr = stream_get_ipv4 (s);
123 printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
paul718e3742002-12-13 20:15:29 +0000124 }
125 break;
126 default:
Donald Sharpbf99b422015-10-21 10:00:47 -0400127 stream_getw_from (s, length);
paul718e3742002-12-13 20:15:29 +0000128 break;
129 }
130 }
131
132 return 0;
133}
134
135int
136main (int argc, char **argv)
137{
138 int ret;
139 FILE *fp;
140 struct stream *s;
141 time_t now;
142 int type;
143 int subtype;
Donald Sharpbf99b422015-10-21 10:00:47 -0400144 size_t len;
paul718e3742002-12-13 20:15:29 +0000145 int source_as;
146 int dest_as;
Paul Jakma9099f9b2016-01-18 10:12:10 +0000147 ifindex_t ifindex;
paul718e3742002-12-13 20:15:29 +0000148 int family;
149 struct in_addr sip;
150 struct in_addr dip;
151 u_int16_t viewno, seq_num;
152 struct prefix_ipv4 p;
153
154 s = stream_new (10000);
155
156 if (argc != 2)
157 {
158 fprintf (stderr, "Usage: %s FILENAME\n", argv[0]);
159 exit (1);
160 }
161 fp = fopen (argv[1], "r");
162 if (!fp)
163 {
164 perror ("fopen");
165 exit (1);
166 }
167
168 while (1)
169 {
170 stream_reset (s);
171
172 ret = fread (s->data, 12, 1, fp);
Donald Sharpbf99b422015-10-21 10:00:47 -0400173 if (!ret || feof (fp))
paul718e3742002-12-13 20:15:29 +0000174 {
175 printf ("END OF FILE\n");
176 break;
177 }
178 if (ferror (fp))
179 {
180 printf ("ERROR OF FREAD\n");
181 break;
182 }
183
184 /* Extract header. */
185 now = stream_getl (s);
186 type = stream_getw (s);
187 subtype = stream_getw (s);
188 len = stream_getl (s);
189
190 printf ("TIME: %s", ctime (&now));
191
192 /* printf ("TYPE: %d/%d\n", type, subtype); */
193
194 if (type == MSG_PROTOCOL_BGP4MP)
195 printf ("TYPE: BGP4MP");
Alexis Fasqueldbe99e02015-11-16 13:55:16 -0500196 else if (type == MSG_PROTOCOL_BGP4MP_ET)
197 printf ("TYPE: BGP4MP_ET");
paul718e3742002-12-13 20:15:29 +0000198 else if (type == MSG_TABLE_DUMP)
199 printf ("TYPE: MSG_TABLE_DUMP");
200 else
201 printf ("TYPE: Unknown %d", type);
202
203 if (type == MSG_TABLE_DUMP)
204 switch (subtype)
205 {
206 case AFI_IP:
207 printf ("/AFI_IP\n");
208 break;
209 case AFI_IP6:
210 printf ("/AFI_IP6\n");
211 break;
212 default:
213 printf ("/UNKNOWN %d", subtype);
214 break;
215 }
216 else
217 {
218 switch (subtype)
219 {
220 case BGP4MP_STATE_CHANGE:
221 printf ("/CHANGE\n");
222 break;
223 case BGP4MP_MESSAGE:
224 printf ("/MESSAGE\n");
225 break;
226 case BGP4MP_ENTRY:
227 printf ("/ENTRY\n");
228 break;
229 case BGP4MP_SNAPSHOT:
230 printf ("/SNAPSHOT\n");
231 break;
232 default:
233 printf ("/UNKNOWN %d", subtype);
234 break;
235 }
236 }
237
Donald Sharpbf99b422015-10-21 10:00:47 -0400238 printf ("len: %zd\n", len);
paul718e3742002-12-13 20:15:29 +0000239
240 ret = fread (s->data + 12, len, 1, fp);
241 if (feof (fp))
242 {
243 printf ("ENDOF FILE 2\n");
244 break;
245 }
246 if (ferror (fp))
247 {
248 printf ("ERROR OF FREAD 2\n");
249 break;
250 }
251
252 /* printf ("now read %d\n", len); */
253
254 if (type == MSG_TABLE_DUMP)
255 {
256 u_char status;
257 time_t originated;
258 struct in_addr peer;
259 u_int16_t attrlen;
260
261 viewno = stream_getw (s);
262 seq_num = stream_getw (s);
263 printf ("VIEW: %d\n", viewno);
264 printf ("SEQUENCE: %d\n", seq_num);
265
266 /* start */
267 while (s->getp < len - 16)
268 {
269 p.prefix.s_addr = stream_get_ipv4 (s);
270 p.prefixlen = stream_getc (s);
271 printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen);
272
273 status = stream_getc (s);
274 originated = stream_getl (s);
275 peer.s_addr = stream_get_ipv4 (s);
276 source_as = stream_getw(s);
277
278 printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as);
279 printf ("ORIGINATED: %s", ctime (&originated));
280
281 attrlen = stream_getw (s);
282 printf ("ATTRLEN: %d\n", attrlen);
283
284 attr_parse (s, attrlen);
285
286 printf ("STATUS: 0x%x\n", status);
287 }
288 }
289 else
290 {
291 source_as = stream_getw (s);
292 dest_as = stream_getw (s);
293 printf ("source_as: %d\n", source_as);
294 printf ("dest_as: %d\n", dest_as);
295
296 ifindex = stream_getw (s);
297 family = stream_getw (s);
298
299 printf ("ifindex: %d\n", ifindex);
300 printf ("family: %d\n", family);
301
302 sip.s_addr = stream_get_ipv4 (s);
303 dip.s_addr = stream_get_ipv4 (s);
304
305 printf ("saddr: %s\n", inet_ntoa (sip));
306 printf ("daddr: %s\n", inet_ntoa (dip));
307
308 printf ("\n");
309 }
310 }
311 fclose (fp);
312 return 0;
313}