]>
Commit | Line | Data |
---|---|---|
718e3744 | 1 | /* BGP dump to ascii converter |
896014f4 DL |
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 along | |
17 | * with this program; see the file COPYING; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
19 | */ | |
718e3744 | 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" | |
7625a0de DS |
28 | #include "memory.h" |
29 | #include "privs.h" | |
039f3a34 | 30 | #include "filter.h" |
718e3744 | 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 | ||
7625a0de | 37 | /* privileges */ |
d62a17ae | 38 | static zebra_capabilities_t _caps_p[] = { |
9d303b37 | 39 | ZCAP_BIND, ZCAP_NET_RAW, ZCAP_NET_ADMIN, |
7625a0de DS |
40 | }; |
41 | ||
d62a17ae | 42 | struct zebra_privs_t bgpd_privs = { |
b2f36157 | 43 | #if defined(FRR_USER) && defined(FRR_GROUP) |
d62a17ae | 44 | .user = FRR_USER, |
45 | .group = FRR_GROUP, | |
7625a0de DS |
46 | #endif |
47 | #ifdef VTY_GROUP | |
d62a17ae | 48 | .vty_group = VTY_GROUP, |
7625a0de | 49 | #endif |
d62a17ae | 50 | .caps_p = _caps_p, |
51 | .cap_num_p = array_size(_caps_p), | |
52 | .cap_num_i = 0, | |
7625a0de DS |
53 | }; |
54 | ||
718e3744 | 55 | enum MRT_MSG_TYPES { |
d62a17ae | 56 | MSG_NULL, |
57 | MSG_START, /* sender is starting up */ | |
58 | MSG_DIE, /* receiver should shut down */ | |
59 | MSG_I_AM_DEAD, /* sender is shutting down */ | |
60 | MSG_PEER_DOWN, /* sender's peer is down */ | |
61 | MSG_PROTOCOL_BGP, /* msg is a BGP packet */ | |
62 | MSG_PROTOCOL_RIP, /* msg is a RIP packet */ | |
63 | MSG_PROTOCOL_IDRP, /* msg is an IDRP packet */ | |
64 | MSG_PROTOCOL_RIPNG, /* msg is a RIPNG packet */ | |
65 | MSG_PROTOCOL_BGP4PLUS, /* msg is a BGP4+ packet */ | |
66 | MSG_PROTOCOL_BGP4PLUS_01, /* msg is a BGP4+ (draft 01) packet */ | |
67 | MSG_PROTOCOL_OSPF, /* msg is an OSPF packet */ | |
68 | MSG_TABLE_DUMP /* routing table dump */ | |
718e3744 | 69 | }; |
70 | ||
3dc339cd | 71 | static void attr_parse(struct stream *s, uint16_t len) |
718e3744 | 72 | { |
d7c0a89a QY |
73 | unsigned int flag; |
74 | unsigned int type; | |
75 | uint16_t length; | |
76 | uint16_t lim; | |
d62a17ae | 77 | |
78 | lim = s->getp + len; | |
79 | ||
a10c2872 | 80 | printf("%s s->getp %zd, len %d, lim %d\n", __func__, s->getp, len, lim); |
d62a17ae | 81 | |
82 | while (s->getp < lim) { | |
83 | flag = stream_getc(s); | |
84 | type = stream_getc(s); | |
85 | ||
86 | if (flag & BGP_ATTR_FLAG_EXTLEN) | |
87 | length = stream_getw(s); | |
88 | else | |
89 | length = stream_getc(s); | |
90 | ||
91 | printf("FLAG: %d\n", flag); | |
92 | printf("TYPE: %d\n", type); | |
93 | printf("Len: %d\n", length); | |
94 | ||
95 | switch (type) { | |
96 | case BGP_ATTR_ORIGIN: { | |
d7c0a89a | 97 | uint8_t origin; |
d62a17ae | 98 | origin = stream_getc(s); |
99 | printf("ORIGIN: %d\n", origin); | |
100 | } break; | |
101 | case BGP_ATTR_AS_PATH: { | |
102 | struct aspath *aspath; | |
103 | ||
104 | aspath = aspath_parse(s, length, 1); | |
105 | printf("ASPATH: %s\n", aspath->str); | |
106 | aspath_free(aspath); | |
107 | } break; | |
108 | case BGP_ATTR_NEXT_HOP: { | |
109 | struct in_addr nexthop; | |
110 | nexthop.s_addr = stream_get_ipv4(s); | |
23d0a753 | 111 | printf("NEXTHOP: %pI4\n", &nexthop); |
d62a17ae | 112 | } break; |
113 | default: | |
114 | stream_getw_from(s, length); | |
115 | break; | |
116 | } | |
718e3744 | 117 | } |
718e3744 | 118 | } |
119 | ||
d62a17ae | 120 | int main(int argc, char **argv) |
718e3744 | 121 | { |
d62a17ae | 122 | int ret; |
f96f6899 | 123 | int fd; |
d62a17ae | 124 | struct stream *s; |
125 | time_t now; | |
126 | int type; | |
127 | int subtype; | |
128 | size_t len; | |
129 | int source_as; | |
130 | int dest_as; | |
131 | ifindex_t ifindex; | |
132 | int family; | |
133 | struct in_addr sip; | |
134 | struct in_addr dip; | |
d7c0a89a | 135 | uint16_t viewno, seq_num; |
d62a17ae | 136 | struct prefix_ipv4 p; |
137 | ||
138 | s = stream_new(10000); | |
139 | ||
140 | if (argc != 2) { | |
141 | fprintf(stderr, "Usage: %s FILENAME\n", argv[0]); | |
142 | exit(1); | |
718e3744 | 143 | } |
f96f6899 | 144 | fd = open(argv[1], O_RDONLY); |
145 | if (fd < 0) { | |
d62a17ae | 146 | fprintf(stdout, |
147 | "%% Can't open configuration file %s due to '%s'.\n", | |
148 | argv[1], safe_strerror(errno)); | |
149 | exit(1); | |
718e3744 | 150 | } |
151 | ||
d62a17ae | 152 | while (1) { |
153 | stream_reset(s); | |
154 | ||
f96f6899 | 155 | ret = stream_read(s, fd, 12); |
156 | if (ret != 12) { | |
157 | if (!ret) | |
158 | printf("END OF FILE\n"); | |
159 | else if (ret < 0) | |
160 | printf("ERROR OF READ\n"); | |
161 | else | |
162 | printf("UNDERFLOW\n"); | |
d62a17ae | 163 | break; |
164 | } | |
165 | ||
166 | /* Extract header. */ | |
167 | now = stream_getl(s); | |
168 | type = stream_getw(s); | |
169 | subtype = stream_getw(s); | |
170 | len = stream_getl(s); | |
171 | ||
172 | printf("TIME: %s", ctime(&now)); | |
173 | ||
174 | /* printf ("TYPE: %d/%d\n", type, subtype); */ | |
175 | ||
176 | if (type == MSG_PROTOCOL_BGP4MP) | |
177 | printf("TYPE: BGP4MP"); | |
178 | else if (type == MSG_PROTOCOL_BGP4MP_ET) | |
179 | printf("TYPE: BGP4MP_ET"); | |
180 | else if (type == MSG_TABLE_DUMP) | |
181 | printf("TYPE: MSG_TABLE_DUMP"); | |
182 | else | |
183 | printf("TYPE: Unknown %d", type); | |
184 | ||
185 | if (type == MSG_TABLE_DUMP) | |
186 | switch (subtype) { | |
187 | case AFI_IP: | |
188 | printf("/AFI_IP\n"); | |
189 | break; | |
190 | case AFI_IP6: | |
191 | printf("/AFI_IP6\n"); | |
192 | break; | |
193 | default: | |
194 | printf("/UNKNOWN %d", subtype); | |
195 | break; | |
196 | } | |
197 | else { | |
198 | switch (subtype) { | |
199 | case BGP4MP_STATE_CHANGE: | |
200 | printf("/CHANGE\n"); | |
201 | break; | |
202 | case BGP4MP_MESSAGE: | |
203 | printf("/MESSAGE\n"); | |
204 | break; | |
205 | case BGP4MP_ENTRY: | |
206 | printf("/ENTRY\n"); | |
207 | break; | |
208 | case BGP4MP_SNAPSHOT: | |
209 | printf("/SNAPSHOT\n"); | |
210 | break; | |
211 | default: | |
212 | printf("/UNKNOWN %d", subtype); | |
213 | break; | |
214 | } | |
215 | } | |
216 | ||
217 | printf("len: %zd\n", len); | |
218 | ||
f96f6899 | 219 | ret = stream_read(s, fd, len); |
220 | if (ret != (int)len) { | |
221 | if (!ret) | |
222 | printf("END OF FILE 2\n"); | |
223 | else if (ret < 0) | |
224 | printf("ERROR OF READ 2\n"); | |
225 | else | |
226 | printf("UNDERFLOW 2\n"); | |
d62a17ae | 227 | break; |
228 | } | |
229 | ||
230 | /* printf ("now read %d\n", len); */ | |
231 | ||
232 | if (type == MSG_TABLE_DUMP) { | |
d7c0a89a | 233 | uint8_t status; |
d62a17ae | 234 | time_t originated; |
235 | struct in_addr peer; | |
d7c0a89a | 236 | uint16_t attrlen; |
d62a17ae | 237 | |
238 | viewno = stream_getw(s); | |
239 | seq_num = stream_getw(s); | |
240 | printf("VIEW: %d\n", viewno); | |
241 | printf("SEQUENCE: %d\n", seq_num); | |
242 | ||
243 | /* start */ | |
244 | while (s->getp < len - 16) { | |
245 | p.prefix.s_addr = stream_get_ipv4(s); | |
246 | p.prefixlen = stream_getc(s); | |
23d0a753 | 247 | printf("PREFIX: %pI4/%d\n", &p.prefix, |
d62a17ae | 248 | p.prefixlen); |
249 | ||
250 | status = stream_getc(s); | |
251 | originated = stream_getl(s); | |
252 | peer.s_addr = stream_get_ipv4(s); | |
253 | source_as = stream_getw(s); | |
254 | ||
23d0a753 | 255 | printf("FROM: %pI4 AS%d\n", &peer, source_as); |
d62a17ae | 256 | printf("ORIGINATED: %s", ctime(&originated)); |
257 | ||
258 | attrlen = stream_getw(s); | |
259 | printf("ATTRLEN: %d\n", attrlen); | |
260 | ||
261 | attr_parse(s, attrlen); | |
262 | ||
263 | printf("STATUS: 0x%x\n", status); | |
264 | } | |
265 | } else { | |
266 | source_as = stream_getw(s); | |
267 | dest_as = stream_getw(s); | |
268 | printf("source_as: %d\n", source_as); | |
269 | printf("dest_as: %d\n", dest_as); | |
270 | ||
271 | ifindex = stream_getw(s); | |
272 | family = stream_getw(s); | |
273 | ||
274 | printf("ifindex: %d\n", ifindex); | |
275 | printf("family: %d\n", family); | |
276 | ||
277 | sip.s_addr = stream_get_ipv4(s); | |
278 | dip.s_addr = stream_get_ipv4(s); | |
279 | ||
23d0a753 DA |
280 | printf("saddr: %pI4\n", &sip); |
281 | printf("daddr: %pI4\n", &dip); | |
d62a17ae | 282 | |
283 | printf("\n"); | |
284 | } | |
718e3744 | 285 | } |
f96f6899 | 286 | close(fd); |
d62a17ae | 287 | return 0; |
718e3744 | 288 | } |