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
attr_parse(struct stream * s,u_int16_t len)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
main(int argc,char ** argv)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 }
314