New upstream release and new maintainer
[quagga-debian.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 #include "filter.h"
31
32 #include "bgpd/bgpd.h"
33 #include "bgpd/bgp_dump.h"
34 #include "bgpd/bgp_attr.h"
35 #include "bgpd/bgp_aspath.h"
36
37 /* privileges */
38 static zebra_capabilities_t _caps_p [] =
39 {
40     ZCAP_BIND,
41     ZCAP_NET_RAW,
42     ZCAP_NET_ADMIN,
43 };
44
45 struct 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
59 enum 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
75 static int
76 attr_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
85   printf ("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim);
86
87   while (s->getp < lim)
88     {
89       flag = stream_getc (s);
90       type = stream_getc (s);
91
92       if (flag & BGP_ATTR_FLAG_EXTLEN)
93         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           {
112             struct aspath *aspath;
113
114             aspath = aspath_parse (s, length, 1);
115             printf ("ASPATH: %s\n", aspath->str);
116             aspath_free(aspath);
117           }
118           break;
119         case BGP_ATTR_NEXT_HOP:
120           {
121             struct in_addr nexthop;
122             nexthop.s_addr = stream_get_ipv4 (s);
123             printf ("NEXTHOP: %s\n", inet_ntoa (nexthop));
124           }
125           break;
126         default:
127           stream_getw_from (s, length);
128           break;
129         }
130     }
131
132   return 0;
133 }
134
135 int
136 main (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;
144   size_t len;
145   int source_as;
146   int dest_as;
147   ifindex_t ifindex;
148   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);
173       if (!ret || feof (fp))
174         {
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");
196       else if (type == MSG_PROTOCOL_BGP4MP_ET)
197         printf ("TYPE: BGP4MP_ET");
198       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
238       printf ("len: %zd\n", len);
239
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 }