]> git.proxmox.com Git - mirror_frr.git/blob - bgpd/bgp_btoa.c
Merge pull request #12780 from opensourcerouting/spdx-license-id
[mirror_frr.git] / bgpd / bgp_btoa.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* BGP dump to ascii converter
3 * Copyright (C) 1999 Kunihiro Ishiguro
4 */
5
6 #include <zebra.h>
7
8 #include "zebra.h"
9 #include "stream.h"
10 #include "log.h"
11 #include "prefix.h"
12 #include "command.h"
13 #include "memory.h"
14 #include "privs.h"
15 #include "filter.h"
16
17 #include "bgpd/bgpd.h"
18 #include "bgpd/bgp_dump.h"
19 #include "bgpd/bgp_attr.h"
20 #include "bgpd/bgp_aspath.h"
21
22 /* privileges */
23 static zebra_capabilities_t _caps_p[] = {
24 ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN,
25 };
26
27 struct zebra_privs_t bgpd_privs = {
28 #if defined(FRR_USER) && defined(FRR_GROUP)
29 .user = FRR_USER,
30 .group = FRR_GROUP,
31 #endif
32 #ifdef VTY_GROUP
33 .vty_group = VTY_GROUP,
34 #endif
35 .caps_p = _caps_p,
36 .cap_num_p = array_size(_caps_p),
37 .cap_num_i = 0,
38 };
39
40 enum MRT_MSG_TYPES {
41 MSG_NULL,
42 MSG_START, /* sender is starting up */
43 MSG_DIE, /* receiver should shut down */
44 MSG_I_AM_DEAD, /* sender is shutting down */
45 MSG_PEER_DOWN, /* sender's peer is down */
46 MSG_PROTOCOL_BGP, /* msg is a BGP packet */
47 MSG_PROTOCOL_RIP, /* msg is a RIP packet */
48 MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */
49 MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */
50 MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */
51 MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */
52 MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */
53 MSG_TABLE_DUMP /* routing table dump */
54 };
55
56 static void attr_parse(struct stream *s, uint16_t len)
57 {
58 unsigned int flag;
59 unsigned int type;
60 uint16_t length;
61 uint16_t lim;
62
63 lim = s->getp + len;
64
65 printf("%s s->getp %zd, len %d, lim %d\n", __func__, s->getp, len, lim);
66
67 while (s->getp < lim) {
68 flag = stream_getc(s);
69 type = stream_getc(s);
70
71 if (flag & BGP_ATTR_FLAG_EXTLEN)
72 length = stream_getw(s);
73 else
74 length = stream_getc(s);
75
76 printf("FLAG: %d\n", flag);
77 printf("TYPE: %d\n", type);
78 printf("Len: %d\n", length);
79
80 switch (type) {
81 case BGP_ATTR_ORIGIN: {
82 uint8_t origin;
83 origin = stream_getc(s);
84 printf("ORIGIN: %d\n", origin);
85 } break;
86 case BGP_ATTR_AS_PATH: {
87 struct aspath *aspath;
88
89 aspath = aspath_parse(s, length, 1);
90 printf("ASPATH: %s\n", aspath->str);
91 aspath_free(aspath);
92 } break;
93 case BGP_ATTR_NEXT_HOP: {
94 struct in_addr nexthop;
95 nexthop.s_addr = stream_get_ipv4(s);
96 printf("NEXTHOP: %pI4\n", &nexthop);
97 } break;
98 default:
99 stream_getw_from(s, length);
100 break;
101 }
102 }
103 }
104
105 int main(int argc, char **argv)
106 {
107 int ret;
108 int fd;
109 struct stream *s;
110 time_t now;
111 int type;
112 int subtype;
113 size_t len;
114 int source_as;
115 int dest_as;
116 ifindex_t ifindex;
117 int family;
118 struct in_addr sip;
119 struct in_addr dip;
120 uint16_t viewno, seq_num;
121 struct prefix_ipv4 p;
122
123 s = stream_new(10000);
124
125 if (argc != 2) {
126 fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
127 exit(1);
128 }
129 fd = open(argv[1], O_RDONLY);
130 if (fd < 0) {
131 fprintf(stdout,
132 "%% Can't open configuration file %s due to '%s'.\n",
133 argv[1], safe_strerror(errno));
134 exit(1);
135 }
136
137 while (1) {
138 stream_reset(s);
139
140 ret = stream_read(s, fd, 12);
141 if (ret != 12) {
142 if (!ret)
143 printf("END OF FILE\n");
144 else if (ret < 0)
145 printf("ERROR OF READ\n");
146 else
147 printf("UNDERFLOW\n");
148 break;
149 }
150
151 /* Extract header. */
152 now = stream_getl(s);
153 type = stream_getw(s);
154 subtype = stream_getw(s);
155 len = stream_getl(s);
156
157 printf("TIME: %s", ctime(&now));
158
159 /* printf ("TYPE: %d/%d\n", type, subtype); */
160
161 if (type == MSG_PROTOCOL_BGP4MP)
162 printf("TYPE: BGP4MP");
163 else if (type == MSG_PROTOCOL_BGP4MP_ET)
164 printf("TYPE: BGP4MP_ET");
165 else if (type == MSG_TABLE_DUMP)
166 printf("TYPE: MSG_TABLE_DUMP");
167 else
168 printf("TYPE: Unknown %d", type);
169
170 if (type == MSG_TABLE_DUMP)
171 switch (subtype) {
172 case AFI_IP:
173 printf("/AFI_IP\n");
174 break;
175 case AFI_IP6:
176 printf("/AFI_IP6\n");
177 break;
178 default:
179 printf("/UNKNOWN %d", subtype);
180 break;
181 }
182 else {
183 switch (subtype) {
184 case BGP4MP_STATE_CHANGE:
185 printf("/CHANGE\n");
186 break;
187 case BGP4MP_MESSAGE:
188 printf("/MESSAGE\n");
189 break;
190 case BGP4MP_ENTRY:
191 printf("/ENTRY\n");
192 break;
193 case BGP4MP_SNAPSHOT:
194 printf("/SNAPSHOT\n");
195 break;
196 default:
197 printf("/UNKNOWN %d", subtype);
198 break;
199 }
200 }
201
202 printf("len: %zd\n", len);
203
204 ret = stream_read(s, fd, len);
205 if (ret != (int)len) {
206 if (!ret)
207 printf("END OF FILE 2\n");
208 else if (ret < 0)
209 printf("ERROR OF READ 2\n");
210 else
211 printf("UNDERFLOW 2\n");
212 break;
213 }
214
215 /* printf ("now read %d\n", len); */
216
217 if (type == MSG_TABLE_DUMP) {
218 uint8_t status;
219 time_t originated;
220 struct in_addr peer;
221 uint16_t attrlen;
222
223 viewno = stream_getw(s);
224 seq_num = stream_getw(s);
225 printf("VIEW: %d\n", viewno);
226 printf("SEQUENCE: %d\n", seq_num);
227
228 /* start */
229 while (s->getp < len - 16) {
230 p.prefix.s_addr = stream_get_ipv4(s);
231 p.prefixlen = stream_getc(s);
232 printf("PREFIX: %pI4/%d\n", &p.prefix,
233 p.prefixlen);
234
235 status = stream_getc(s);
236 originated = stream_getl(s);
237 peer.s_addr = stream_get_ipv4(s);
238 source_as = stream_getw(s);
239
240 printf("FROM: %pI4 AS%d\n", &peer, source_as);
241 printf("ORIGINATED: %s", ctime(&originated));
242
243 attrlen = stream_getw(s);
244 printf("ATTRLEN: %d\n", attrlen);
245
246 attr_parse(s, attrlen);
247
248 printf("STATUS: 0x%x\n", status);
249 }
250 } else {
251 source_as = stream_getw(s);
252 dest_as = stream_getw(s);
253 printf("source_as: %d\n", source_as);
254 printf("dest_as: %d\n", dest_as);
255
256 ifindex = stream_getw(s);
257 family = stream_getw(s);
258
259 printf("ifindex: %d\n", ifindex);
260 printf("family: %d\n", family);
261
262 sip.s_addr = stream_get_ipv4(s);
263 dip.s_addr = stream_get_ipv4(s);
264
265 printf("saddr: %pI4\n", &sip);
266 printf("daddr: %pI4\n", &dip);
267
268 printf("\n");
269 }
270 }
271 close(fd);
272 return 0;
273 }