]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
718e3744 | 2 | /* BGP dump to ascii converter |
896014f4 | 3 | * Copyright (C) 1999 Kunihiro Ishiguro |
896014f4 | 4 | */ |
718e3744 | 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" | |
7625a0de DS |
13 | #include "memory.h" |
14 | #include "privs.h" | |
039f3a34 | 15 | #include "filter.h" |
718e3744 | 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 | ||
7625a0de | 22 | /* privileges */ |
d62a17ae | 23 | static zebra_capabilities_t _caps_p[] = { |
9d303b37 | 24 | ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN, |
7625a0de DS |
25 | }; |
26 | ||
d62a17ae | 27 | struct zebra_privs_t bgpd_privs = { |
b2f36157 | 28 | #if defined(FRR_USER) && defined(FRR_GROUP) |
d62a17ae | 29 | .user = FRR_USER, |
30 | .group = FRR_GROUP, | |
7625a0de DS |
31 | #endif |
32 | #ifdef VTY_GROUP | |
d62a17ae | 33 | .vty_group = VTY_GROUP, |
7625a0de | 34 | #endif |
d62a17ae | 35 | .caps_p = _caps_p, |
36 | .cap_num_p = array_size(_caps_p), | |
37 | .cap_num_i = 0, | |
7625a0de DS |
38 | }; |
39 | ||
718e3744 | 40 | enum MRT_MSG_TYPES { |
d62a17ae | 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 */ | |
718e3744 | 54 | }; |
55 | ||
3dc339cd | 56 | static void attr_parse(struct stream *s, uint16_t len) |
718e3744 | 57 | { |
d7c0a89a QY |
58 | unsigned int flag; |
59 | unsigned int type; | |
60 | uint16_t length; | |
61 | uint16_t lim; | |
d62a17ae | 62 | |
63 | lim = s->getp + len; | |
64 | ||
a10c2872 | 65 | printf("%s s->getp %zd, len %d, lim %d\n", __func__, s->getp, len, lim); |
d62a17ae | 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: { | |
d7c0a89a | 82 | uint8_t origin; |
d62a17ae | 83 | origin = stream_getc(s); |
84 | printf("ORIGIN: %d\n", origin); | |
85 | } break; | |
86 | case BGP_ATTR_AS_PATH: { | |
87 | struct aspath *aspath; | |
88 | ||
17571c4a PG |
89 | aspath = aspath_parse(s, length, 1, |
90 | bgp_get_asnotation(NULL)); | |
d62a17ae | 91 | printf("ASPATH: %s\n", aspath->str); |
92 | aspath_free(aspath); | |
93 | } break; | |
94 | case BGP_ATTR_NEXT_HOP: { | |
95 | struct in_addr nexthop; | |
96 | nexthop.s_addr = stream_get_ipv4(s); | |
23d0a753 | 97 | printf("NEXTHOP: %pI4\n", &nexthop); |
d62a17ae | 98 | } break; |
99 | default: | |
100 | stream_getw_from(s, length); | |
101 | break; | |
102 | } | |
718e3744 | 103 | } |
718e3744 | 104 | } |
105 | ||
d62a17ae | 106 | int main(int argc, char **argv) |
718e3744 | 107 | { |
d62a17ae | 108 | int ret; |
f96f6899 | 109 | int fd; |
d62a17ae | 110 | struct stream *s; |
111 | time_t now; | |
112 | int type; | |
113 | int subtype; | |
114 | size_t len; | |
115 | int source_as; | |
116 | int dest_as; | |
117 | ifindex_t ifindex; | |
118 | int family; | |
119 | struct in_addr sip; | |
120 | struct in_addr dip; | |
d7c0a89a | 121 | uint16_t viewno, seq_num; |
d62a17ae | 122 | struct prefix_ipv4 p; |
123 | ||
124 | s = stream_new(10000); | |
125 | ||
126 | if (argc != 2) { | |
127 | fprintf(stderr, "Usage: %s FILENAME\n", argv[0]); | |
128 | exit(1); | |
718e3744 | 129 | } |
f96f6899 | 130 | fd = open(argv[1], O_RDONLY); |
131 | if (fd < 0) { | |
d62a17ae | 132 | fprintf(stdout, |
133 | "%% Can't open configuration file %s due to '%s'.\n", | |
134 | argv[1], safe_strerror(errno)); | |
135 | exit(1); | |
718e3744 | 136 | } |
137 | ||
d62a17ae | 138 | while (1) { |
139 | stream_reset(s); | |
140 | ||
f96f6899 | 141 | ret = stream_read(s, fd, 12); |
142 | if (ret != 12) { | |
143 | if (!ret) | |
144 | printf("END OF FILE\n"); | |
145 | else if (ret < 0) | |
146 | printf("ERROR OF READ\n"); | |
147 | else | |
148 | printf("UNDERFLOW\n"); | |
d62a17ae | 149 | break; |
150 | } | |
151 | ||
152 | /* Extract header. */ | |
153 | now = stream_getl(s); | |
154 | type = stream_getw(s); | |
155 | subtype = stream_getw(s); | |
156 | len = stream_getl(s); | |
157 | ||
158 | printf("TIME: %s", ctime(&now)); | |
159 | ||
160 | /* printf ("TYPE: %d/%d\n", type, subtype); */ | |
161 | ||
162 | if (type == MSG_PROTOCOL_BGP4MP) | |
163 | printf("TYPE: BGP4MP"); | |
164 | else if (type == MSG_PROTOCOL_BGP4MP_ET) | |
165 | printf("TYPE: BGP4MP_ET"); | |
166 | else if (type == MSG_TABLE_DUMP) | |
167 | printf("TYPE: MSG_TABLE_DUMP"); | |
168 | else | |
169 | printf("TYPE: Unknown %d", type); | |
170 | ||
171 | if (type == MSG_TABLE_DUMP) | |
172 | switch (subtype) { | |
173 | case AFI_IP: | |
174 | printf("/AFI_IP\n"); | |
175 | break; | |
176 | case AFI_IP6: | |
177 | printf("/AFI_IP6\n"); | |
178 | break; | |
179 | default: | |
180 | printf("/UNKNOWN %d", subtype); | |
181 | break; | |
182 | } | |
183 | else { | |
184 | switch (subtype) { | |
185 | case BGP4MP_STATE_CHANGE: | |
186 | printf("/CHANGE\n"); | |
187 | break; | |
188 | case BGP4MP_MESSAGE: | |
189 | printf("/MESSAGE\n"); | |
190 | break; | |
191 | case BGP4MP_ENTRY: | |
192 | printf("/ENTRY\n"); | |
193 | break; | |
194 | case BGP4MP_SNAPSHOT: | |
195 | printf("/SNAPSHOT\n"); | |
196 | break; | |
197 | default: | |
198 | printf("/UNKNOWN %d", subtype); | |
199 | break; | |
200 | } | |
201 | } | |
202 | ||
203 | printf("len: %zd\n", len); | |
204 | ||
f96f6899 | 205 | ret = stream_read(s, fd, len); |
206 | if (ret != (int)len) { | |
207 | if (!ret) | |
208 | printf("END OF FILE 2\n"); | |
209 | else if (ret < 0) | |
210 | printf("ERROR OF READ 2\n"); | |
211 | else | |
212 | printf("UNDERFLOW 2\n"); | |
d62a17ae | 213 | break; |
214 | } | |
215 | ||
216 | /* printf ("now read %d\n", len); */ | |
217 | ||
218 | if (type == MSG_TABLE_DUMP) { | |
d7c0a89a | 219 | uint8_t status; |
d62a17ae | 220 | time_t originated; |
221 | struct in_addr peer; | |
d7c0a89a | 222 | uint16_t attrlen; |
d62a17ae | 223 | |
224 | viewno = stream_getw(s); | |
225 | seq_num = stream_getw(s); | |
226 | printf("VIEW: %d\n", viewno); | |
227 | printf("SEQUENCE: %d\n", seq_num); | |
228 | ||
229 | /* start */ | |
230 | while (s->getp < len - 16) { | |
231 | p.prefix.s_addr = stream_get_ipv4(s); | |
232 | p.prefixlen = stream_getc(s); | |
23d0a753 | 233 | printf("PREFIX: %pI4/%d\n", &p.prefix, |
d62a17ae | 234 | p.prefixlen); |
235 | ||
236 | status = stream_getc(s); | |
237 | originated = stream_getl(s); | |
238 | peer.s_addr = stream_get_ipv4(s); | |
239 | source_as = stream_getw(s); | |
240 | ||
23d0a753 | 241 | printf("FROM: %pI4 AS%d\n", &peer, source_as); |
d62a17ae | 242 | printf("ORIGINATED: %s", ctime(&originated)); |
243 | ||
244 | attrlen = stream_getw(s); | |
245 | printf("ATTRLEN: %d\n", attrlen); | |
246 | ||
247 | attr_parse(s, attrlen); | |
248 | ||
249 | printf("STATUS: 0x%x\n", status); | |
250 | } | |
251 | } else { | |
252 | source_as = stream_getw(s); | |
253 | dest_as = stream_getw(s); | |
254 | printf("source_as: %d\n", source_as); | |
255 | printf("dest_as: %d\n", dest_as); | |
256 | ||
257 | ifindex = stream_getw(s); | |
258 | family = stream_getw(s); | |
259 | ||
260 | printf("ifindex: %d\n", ifindex); | |
261 | printf("family: %d\n", family); | |
262 | ||
263 | sip.s_addr = stream_get_ipv4(s); | |
264 | dip.s_addr = stream_get_ipv4(s); | |
265 | ||
23d0a753 DA |
266 | printf("saddr: %pI4\n", &sip); |
267 | printf("daddr: %pI4\n", &dip); | |
d62a17ae | 268 | |
269 | printf("\n"); | |
270 | } | |
718e3744 | 271 | } |
f96f6899 | 272 | close(fd); |
d62a17ae | 273 | return 0; |
718e3744 | 274 | } |