]>
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 | ||
d7c0a89a | 71 | static int 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 | ||
80 | printf("attr_parse s->getp %zd, len %d, lim %d\n", s->getp, len, lim); | |
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); | |
111 | printf("NEXTHOP: %s\n", inet_ntoa(nexthop)); | |
112 | } break; | |
113 | default: | |
114 | stream_getw_from(s, length); | |
115 | break; | |
116 | } | |
718e3744 | 117 | } |
718e3744 | 118 | |
d62a17ae | 119 | return 0; |
718e3744 | 120 | } |
121 | ||
d62a17ae | 122 | int main(int argc, char **argv) |
718e3744 | 123 | { |
d62a17ae | 124 | int ret; |
f96f6899 | 125 | int fd; |
d62a17ae | 126 | struct stream *s; |
127 | time_t now; | |
128 | int type; | |
129 | int subtype; | |
130 | size_t len; | |
131 | int source_as; | |
132 | int dest_as; | |
133 | ifindex_t ifindex; | |
134 | int family; | |
135 | struct in_addr sip; | |
136 | struct in_addr dip; | |
d7c0a89a | 137 | uint16_t viewno, seq_num; |
d62a17ae | 138 | struct prefix_ipv4 p; |
139 | ||
140 | s = stream_new(10000); | |
141 | ||
142 | if (argc != 2) { | |
143 | fprintf(stderr, "Usage: %s FILENAME\n", argv[0]); | |
144 | exit(1); | |
718e3744 | 145 | } |
f96f6899 | 146 | fd = open(argv[1], O_RDONLY); |
147 | if (fd < 0) { | |
d62a17ae | 148 | fprintf(stdout, |
149 | "%% Can't open configuration file %s due to '%s'.\n", | |
150 | argv[1], safe_strerror(errno)); | |
151 | exit(1); | |
718e3744 | 152 | } |
153 | ||
d62a17ae | 154 | while (1) { |
155 | stream_reset(s); | |
156 | ||
f96f6899 | 157 | ret = stream_read(s, fd, 12); |
158 | if (ret != 12) { | |
159 | if (!ret) | |
160 | printf("END OF FILE\n"); | |
161 | else if (ret < 0) | |
162 | printf("ERROR OF READ\n"); | |
163 | else | |
164 | printf("UNDERFLOW\n"); | |
d62a17ae | 165 | break; |
166 | } | |
167 | ||
168 | /* Extract header. */ | |
169 | now = stream_getl(s); | |
170 | type = stream_getw(s); | |
171 | subtype = stream_getw(s); | |
172 | len = stream_getl(s); | |
173 | ||
174 | printf("TIME: %s", ctime(&now)); | |
175 | ||
176 | /* printf ("TYPE: %d/%d\n", type, subtype); */ | |
177 | ||
178 | if (type == MSG_PROTOCOL_BGP4MP) | |
179 | printf("TYPE: BGP4MP"); | |
180 | else if (type == MSG_PROTOCOL_BGP4MP_ET) | |
181 | printf("TYPE: BGP4MP_ET"); | |
182 | else if (type == MSG_TABLE_DUMP) | |
183 | printf("TYPE: MSG_TABLE_DUMP"); | |
184 | else | |
185 | printf("TYPE: Unknown %d", type); | |
186 | ||
187 | if (type == MSG_TABLE_DUMP) | |
188 | switch (subtype) { | |
189 | case AFI_IP: | |
190 | printf("/AFI_IP\n"); | |
191 | break; | |
192 | case AFI_IP6: | |
193 | printf("/AFI_IP6\n"); | |
194 | break; | |
195 | default: | |
196 | printf("/UNKNOWN %d", subtype); | |
197 | break; | |
198 | } | |
199 | else { | |
200 | switch (subtype) { | |
201 | case BGP4MP_STATE_CHANGE: | |
202 | printf("/CHANGE\n"); | |
203 | break; | |
204 | case BGP4MP_MESSAGE: | |
205 | printf("/MESSAGE\n"); | |
206 | break; | |
207 | case BGP4MP_ENTRY: | |
208 | printf("/ENTRY\n"); | |
209 | break; | |
210 | case BGP4MP_SNAPSHOT: | |
211 | printf("/SNAPSHOT\n"); | |
212 | break; | |
213 | default: | |
214 | printf("/UNKNOWN %d", subtype); | |
215 | break; | |
216 | } | |
217 | } | |
218 | ||
219 | printf("len: %zd\n", len); | |
220 | ||
f96f6899 | 221 | ret = stream_read(s, fd, len); |
222 | if (ret != (int)len) { | |
223 | if (!ret) | |
224 | printf("END OF FILE 2\n"); | |
225 | else if (ret < 0) | |
226 | printf("ERROR OF READ 2\n"); | |
227 | else | |
228 | printf("UNDERFLOW 2\n"); | |
d62a17ae | 229 | break; |
230 | } | |
231 | ||
232 | /* printf ("now read %d\n", len); */ | |
233 | ||
234 | if (type == MSG_TABLE_DUMP) { | |
d7c0a89a | 235 | uint8_t status; |
d62a17ae | 236 | time_t originated; |
237 | struct in_addr peer; | |
d7c0a89a | 238 | uint16_t attrlen; |
d62a17ae | 239 | |
240 | viewno = stream_getw(s); | |
241 | seq_num = stream_getw(s); | |
242 | printf("VIEW: %d\n", viewno); | |
243 | printf("SEQUENCE: %d\n", seq_num); | |
244 | ||
245 | /* start */ | |
246 | while (s->getp < len - 16) { | |
247 | p.prefix.s_addr = stream_get_ipv4(s); | |
248 | p.prefixlen = stream_getc(s); | |
249 | printf("PREFIX: %s/%d\n", inet_ntoa(p.prefix), | |
250 | p.prefixlen); | |
251 | ||
252 | status = stream_getc(s); | |
253 | originated = stream_getl(s); | |
254 | peer.s_addr = stream_get_ipv4(s); | |
255 | source_as = stream_getw(s); | |
256 | ||
257 | printf("FROM: %s AS%d\n", inet_ntoa(peer), | |
258 | source_as); | |
259 | printf("ORIGINATED: %s", ctime(&originated)); | |
260 | ||
261 | attrlen = stream_getw(s); | |
262 | printf("ATTRLEN: %d\n", attrlen); | |
263 | ||
264 | attr_parse(s, attrlen); | |
265 | ||
266 | printf("STATUS: 0x%x\n", status); | |
267 | } | |
268 | } else { | |
269 | source_as = stream_getw(s); | |
270 | dest_as = stream_getw(s); | |
271 | printf("source_as: %d\n", source_as); | |
272 | printf("dest_as: %d\n", dest_as); | |
273 | ||
274 | ifindex = stream_getw(s); | |
275 | family = stream_getw(s); | |
276 | ||
277 | printf("ifindex: %d\n", ifindex); | |
278 | printf("family: %d\n", family); | |
279 | ||
280 | sip.s_addr = stream_get_ipv4(s); | |
281 | dip.s_addr = stream_get_ipv4(s); | |
282 | ||
283 | printf("saddr: %s\n", inet_ntoa(sip)); | |
284 | printf("daddr: %s\n", inet_ntoa(dip)); | |
285 | ||
286 | printf("\n"); | |
287 | } | |
718e3744 | 288 | } |
f96f6899 | 289 | close(fd); |
d62a17ae | 290 | return 0; |
718e3744 | 291 | } |