]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_btoa.c
BGP: Update dump to allow Extended Time Format
[mirror_frr.git] / bgpd / bgp_btoa.c
1 /* BGP dump to ascii converter
2 Copyright (C) 1999 Kunihiro Ishiguro
3
4 This file is part of GNU Zebra.
5
6 GNU Zebra 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 GNU Zebra 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 GNU Zebra; 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
23 #include "zebra.h"
24 #include "stream.h"
25 #include "log.h"
26 #include "prefix.h"
27 #include "command.h"
28 #include "memory.h"
29 #include "privs.h"
30
31 #include "bgpd/bgpd.h"
32 #include "bgpd/bgp_dump.h"
33 #include "bgpd/bgp_attr.h"
34 #include "bgpd/bgp_aspath.h"
35
36 /* privileges */
37 static zebra_capabilities_t _caps_p [] =
38 {
39 ZCAP_BIND,
40 ZCAP_NET_RAW,
41 ZCAP_NET_ADMIN,
42 };
43
44 struct zebra_privs_t bgpd_privs =
45 {
46 #if defined(QUAGGA_USER) && defined(QUAGGA_GROUP)
47 .user = QUAGGA_USER,
48 .group = QUAGGA_GROUP,
49 #endif
50 #ifdef VTY_GROUP
51 .vty_group = VTY_GROUP,
52 #endif
53 .caps_p = _caps_p,
54 .cap_num_p = array_size(_caps_p),
55 .cap_num_i = 0,
56 };
57
58 enum MRT_MSG_TYPES {
59 MSG_NULL,
60 MSG_START, /* sender is starting up */
61 MSG_DIE, /* receiver should shut down */
62 MSG_I_AM_DEAD, /* sender is shutting down */
63 MSG_PEER_DOWN, /* sender's peer is down */
64 MSG_PROTOCOL_BGP, /* msg is a BGP packet */
65 MSG_PROTOCOL_RIP, /* msg is a RIP packet */
66 MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
67 MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
68 MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
69 MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
70 MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
71 MSG_TABLE_DUMP /* routing table dump */
72 };
73
74 static int
75 attr_parse (struct stream *s, u_int16_t len)
76 {
77 u_int flag;
78 u_int type;
79 u_int16_t length;
80 u_int16_t lim;
81
82 lim = s->getp + len;
83
84 printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);
85
86 while (s->getp < lim)
87 {
88 flag = stream_getc (s);
89 type = stream_getc (s);
90
91 if (flag & BGP_ATTR_FLAG_EXTLEN)
92 length = stream_getw (s);
93 else
94 length = stream_getc (s);
95
96 printf ("FLAG: %d\n", flag);
97 printf ("TYPE: %d\n", type);
98 printf ("Len: %d\n", length);
99
100 switch (type)
101 {
102 case BGP_ATTR_ORIGIN:
103 {
104 u_char origin;
105 origin = stream_getc (s);
106 printf ("ORIGIN: %d\n", origin);
107 }
108 break;
109 case BGP_ATTR_AS_PATH:
110 {
111 struct aspath *aspath;
112
113 aspath = aspath_parse (s, length, 1);
114 printf ("ASPATH: %s\n", aspath->str);
115 aspath_free(aspath);
116 }
117 break;
118 case BGP_ATTR_NEXT_HOP:
119 {
120 struct in_addr nexthop;
121 nexthop.s_addr = stream_get_ipv4 (s);
122 printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
123 }
124 break;
125 default:
126 stream_getw_from (s, length);
127 break;
128 }
129 }
130
131 return 0;
132 }
133
134 int
135 main (int argc, char **argv)
136 {
137 int ret;
138 FILE *fp;
139 struct stream *s;
140 time_t now;
141 int type;
142 int subtype;
143 size_t len;
144 int source_as;
145 int dest_as;
146 int ifindex;
147 int family;
148 struct in_addr sip;
149 struct in_addr dip;
150 u_int16_t viewno, seq_num;
151 struct prefix_ipv4 p;
152
153 s = stream_new (10000);
154
155 if (argc != 2)
156 {
157 fprintf (stderr, "Usage: %s FILENAME\n", argv[0]);
158 exit (1);
159 }
160 fp = fopen (argv[1], "r");
161 if (!fp)
162 {
163 perror ("fopen");
164 exit (1);
165 }
166
167 while (1)
168 {
169 stream_reset (s);
170
171 ret = fread (s->data, 12, 1, fp);
172 if (!ret || feof (fp))
173 {
174 printf ("END OF FILE\n");
175 break;
176 }
177 if (ferror (fp))
178 {
179 printf ("ERROR OF FREAD\n");
180 break;
181 }
182
183 /* Extract header. */
184 now = stream_getl (s);
185 type = stream_getw (s);
186 subtype = stream_getw (s);
187 len = stream_getl (s);
188
189 printf ("TIME: %s", ctime (&now));
190
191 /* printf ("TYPE: %d/%d\n", type, subtype); */
192
193 if (type == MSG_PROTOCOL_BGP4MP)
194 printf ("TYPE: BGP4MP");
195 else if (type == MSG_PROTOCOL_BGP4MP_ET)
196 printf ("TYPE: BGP4MP_ET");
197 else if (type == MSG_TABLE_DUMP)
198 printf ("TYPE: MSG_TABLE_DUMP");
199 else
200 printf ("TYPE: Unknown %d", type);
201
202 if (type == MSG_TABLE_DUMP)
203 switch (subtype)
204 {
205 case AFI_IP:
206 printf ("/AFI_IP\n");
207 break;
208 case AFI_IP6:
209 printf ("/AFI_IP6\n");
210 break;
211 default:
212 printf ("/UNKNOWN %d", subtype);
213 break;
214 }
215 else
216 {
217 switch (subtype)
218 {
219 case BGP4MP_STATE_CHANGE:
220 printf ("/CHANGE\n");
221 break;
222 case BGP4MP_MESSAGE:
223 printf ("/MESSAGE\n");
224 break;
225 case BGP4MP_ENTRY:
226 printf ("/ENTRY\n");
227 break;
228 case BGP4MP_SNAPSHOT:
229 printf ("/SNAPSHOT\n");
230 break;
231 default:
232 printf ("/UNKNOWN %d", subtype);
233 break;
234 }
235 }
236
237 printf ("len: %zd\n", len);
238
239 ret = fread (s->data + 12, len, 1, fp);
240 if (feof (fp))
241 {
242 printf ("ENDOF FILE 2\n");
243 break;
244 }
245 if (ferror (fp))
246 {
247 printf ("ERROR OF FREAD 2\n");
248 break;
249 }
250
251 /* printf ("now read %d\n", len); */
252
253 if (type == MSG_TABLE_DUMP)
254 {
255 u_char status;
256 time_t originated;
257 struct in_addr peer;
258 u_int16_t attrlen;
259
260 viewno = stream_getw (s);
261 seq_num = stream_getw (s);
262 printf ("VIEW: %d\n", viewno);
263 printf ("SEQUENCE: %d\n", seq_num);
264
265 /* start */
266 while (s->getp < len - 16)
267 {
268 p.prefix.s_addr = stream_get_ipv4 (s);
269 p.prefixlen = stream_getc (s);
270 printf ("PREFIX: %s/%d\n", inet_ntoa (p.prefix), p.prefixlen);
271
272 status = stream_getc (s);
273 originated = stream_getl (s);
274 peer.s_addr = stream_get_ipv4 (s);
275 source_as = stream_getw(s);
276
277 printf ("FROM: %s AS%d\n", inet_ntoa (peer), source_as);
278 printf ("ORIGINATED: %s", ctime (&originated));
279
280 attrlen = stream_getw (s);
281 printf ("ATTRLEN: %d\n", attrlen);
282
283 attr_parse (s, attrlen);
284
285 printf ("STATUS: 0x%x\n", status);
286 }
287 }
288 else
289 {
290 source_as = stream_getw (s);
291 dest_as = stream_getw (s);
292 printf ("source_as: %d\n", source_as);
293 printf ("dest_as: %d\n", dest_as);
294
295 ifindex = stream_getw (s);
296 family = stream_getw (s);
297
298 printf ("ifindex: %d\n", ifindex);
299 printf ("family: %d\n", family);
300
301 sip.s_addr = stream_get_ipv4 (s);
302 dip.s_addr = stream_get_ipv4 (s);
303
304 printf ("saddr: %s\n", inet_ntoa (sip));
305 printf ("daddr: %s\n", inet_ntoa (dip));
306
307 printf ("\n");
308 }
309 }
310 fclose (fp);
311 return 0;
312 }