"Fossies" - the Fresh Open Source Software Archive 
Member "ospfctl/ospfctl.c" (6 Jun 2009, 30485 Bytes) of package /linux/privat/old/openospfd-4.6.tgz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "ospfctl.c" see the
Fossies "Dox" file reference documentation.
1 /* $OpenBSD: ospfctl.c,v 1.48 2009/06/06 07:31:26 eric Exp $ */
2
3 /*
4 * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
5 * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
6 * Copyright (c) 2003 Henning Brauer <henning@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21 #include <sys/types.h>
22 #include <sys/socket.h>
23 #include <sys/un.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26 #include <net/if_media.h>
27 #include <net/if_types.h>
28
29 #include <err.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34
35 #include "ospf.h"
36 #include "ospfd.h"
37 #include "ospfe.h"
38 #include "parser.h"
39
40 __dead void usage(void);
41 int show_summary_msg(struct imsg *);
42 int get_ifms_type(int);
43 int show_interface_msg(struct imsg *);
44 int show_interface_detail_msg(struct imsg *);
45 const char *print_link(int);
46 const char *fmt_timeframe(time_t t);
47 const char *fmt_timeframe_core(time_t t);
48 const char *log_id(u_int32_t );
49 const char *log_adv_rtr(u_int32_t);
50 void show_database_head(struct in_addr, u_int8_t);
51 int show_database_msg(struct imsg *);
52 char *print_ls_type(u_int8_t);
53 void show_db_hdr_msg_detail(struct lsa_hdr *);
54 char *print_rtr_link_type(u_int8_t);
55 const char *print_ospf_flags(u_int8_t);
56 int show_db_msg_detail(struct imsg *imsg);
57 int show_nbr_msg(struct imsg *);
58 const char *print_ospf_options(u_int8_t);
59 int show_nbr_detail_msg(struct imsg *);
60 int show_rib_msg(struct imsg *);
61 void show_rib_head(struct in_addr, u_int8_t, u_int8_t);
62 const char *print_ospf_rtr_flags(u_int8_t);
63 int show_rib_detail_msg(struct imsg *);
64 void show_fib_head(void);
65 int show_fib_msg(struct imsg *);
66 void show_interface_head(void);
67 const char * get_media_descr(int);
68 const char * get_linkstate(int, int);
69 void print_baudrate(u_int64_t);
70 int show_fib_interface_msg(struct imsg *);
71
72 struct imsgbuf *ibuf;
73
74 __dead void
75 usage(void)
76 {
77 extern char *__progname;
78
79 fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n",
80 __progname);
81 exit(1);
82 }
83
84 int
85 main(int argc, char *argv[])
86 {
87 struct sockaddr_un sun;
88 struct parse_result *res;
89 struct imsg imsg;
90 unsigned int ifidx = 0;
91 int ctl_sock;
92 int done = 0;
93 int n;
94 int ch;
95 char *sockname;
96
97 sockname = OSPFD_SOCKET;
98 while ((ch = getopt(argc, argv, "s:")) != -1) {
99 switch (ch) {
100 case 's':
101 sockname = optarg;
102 break;
103 default:
104 usage();
105 /* NOTREACHED */
106 }
107 }
108 argc -= optind;
109 argv += optind;
110
111 /* parse options */
112 if ((res = parse(argc, argv)) == NULL)
113 exit(1);
114
115 /* connect to ospfd control socket */
116 if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
117 err(1, "socket");
118
119 bzero(&sun, sizeof(sun));
120 sun.sun_family = AF_UNIX;
121
122 strlcpy(sun.sun_path, sockname, sizeof(sun.sun_path));
123 if (connect(ctl_sock, (struct sockaddr *)&sun, sizeof(sun)) == -1)
124 err(1, "connect: %s", sockname);
125
126 if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL)
127 err(1, NULL);
128 imsg_init(ibuf, ctl_sock);
129 done = 0;
130
131 /* process user request */
132 switch (res->action) {
133 case NONE:
134 usage();
135 /* not reached */
136 case SHOW:
137 case SHOW_SUM:
138 imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0);
139 break;
140 case SHOW_IFACE:
141 printf("%-11s %-18s %-6s %-10s %-10s %-8s %3s %3s\n",
142 "Interface", "Address", "State", "HelloTimer", "Linkstate",
143 "Uptime", "nc", "ac");
144 /*FALLTHROUGH*/
145 case SHOW_IFACE_DTAIL:
146 if (*res->ifname) {
147 ifidx = if_nametoindex(res->ifname);
148 if (ifidx == 0)
149 errx(1, "no such interface %s", res->ifname);
150 }
151 imsg_compose(ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1,
152 &ifidx, sizeof(ifidx));
153 break;
154 case SHOW_NBR:
155 printf("%-15s %-3s %-12s %-8s %-15s %-9s %s\n", "ID", "Pri",
156 "State", "DeadTime", "Address", "Iface","Uptime");
157 /*FALLTHROUGH*/
158 case SHOW_NBR_DTAIL:
159 imsg_compose(ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
160 break;
161 case SHOW_DB:
162 imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1, NULL, 0);
163 break;
164 case SHOW_DBBYAREA:
165 imsg_compose(ibuf, IMSG_CTL_SHOW_DATABASE, 0, 0, -1,
166 &res->addr, sizeof(res->addr));
167 break;
168 case SHOW_DBEXT:
169 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_EXT, 0, 0, -1, NULL, 0);
170 break;
171 case SHOW_DBNET:
172 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_NET, 0, 0, -1, NULL, 0);
173 break;
174 case SHOW_DBRTR:
175 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_RTR, 0, 0, -1, NULL, 0);
176 break;
177 case SHOW_DBSELF:
178 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SELF, 0, 0, -1, NULL, 0);
179 break;
180 case SHOW_DBSUM:
181 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_SUM, 0, 0, -1, NULL, 0);
182 break;
183 case SHOW_DBASBR:
184 imsg_compose(ibuf, IMSG_CTL_SHOW_DB_ASBR, 0, 0, -1, NULL, 0);
185 break;
186 case SHOW_RIB:
187 printf("%-20s %-17s %-12s %-9s %-7s %-8s\n", "Destination",
188 "Nexthop", "Path Type", "Type", "Cost", "Uptime");
189 /*FALLTHROUGH*/
190 case SHOW_RIB_DTAIL:
191 imsg_compose(ibuf, IMSG_CTL_SHOW_RIB, 0, 0, -1, NULL, 0);
192 break;
193 case SHOW_FIB:
194 if (!res->addr.s_addr)
195 imsg_compose(ibuf, IMSG_CTL_KROUTE, 0, 0, -1,
196 &res->flags, sizeof(res->flags));
197 else
198 imsg_compose(ibuf, IMSG_CTL_KROUTE_ADDR, 0, 0, -1,
199 &res->addr, sizeof(res->addr));
200 show_fib_head();
201 break;
202 case SHOW_FIB_IFACE:
203 if (*res->ifname)
204 imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1,
205 res->ifname, sizeof(res->ifname));
206 else
207 imsg_compose(ibuf, IMSG_CTL_IFINFO, 0, 0, -1, NULL, 0);
208 show_interface_head();
209 break;
210 case FIB:
211 errx(1, "fib couple|decouple");
212 break;
213 case FIB_COUPLE:
214 imsg_compose(ibuf, IMSG_CTL_FIB_COUPLE, 0, 0, -1, NULL, 0);
215 printf("couple request sent.\n");
216 done = 1;
217 break;
218 case FIB_DECOUPLE:
219 imsg_compose(ibuf, IMSG_CTL_FIB_DECOUPLE, 0, 0, -1, NULL, 0);
220 printf("decouple request sent.\n");
221 done = 1;
222 break;
223 case RELOAD:
224 imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
225 printf("reload request sent.\n");
226 done = 1;
227 break;
228 }
229
230 while (ibuf->w.queued)
231 if (msgbuf_write(&ibuf->w) < 0)
232 err(1, "write error");
233
234 while (!done) {
235 if ((n = imsg_read(ibuf)) == -1)
236 errx(1, "imsg_read error");
237 if (n == 0)
238 errx(1, "pipe closed");
239
240 while (!done) {
241 if ((n = imsg_get(ibuf, &imsg)) == -1)
242 errx(1, "imsg_get error");
243 if (n == 0)
244 break;
245 switch (res->action) {
246 case SHOW:
247 case SHOW_SUM:
248 done = show_summary_msg(&imsg);
249 break;
250 case SHOW_IFACE:
251 done = show_interface_msg(&imsg);
252 break;
253 case SHOW_IFACE_DTAIL:
254 done = show_interface_detail_msg(&imsg);
255 break;
256 case SHOW_NBR:
257 done = show_nbr_msg(&imsg);
258 break;
259 case SHOW_NBR_DTAIL:
260 done = show_nbr_detail_msg(&imsg);
261 break;
262 case SHOW_DB:
263 case SHOW_DBBYAREA:
264 case SHOW_DBSELF:
265 done = show_database_msg(&imsg);
266 break;
267 case SHOW_DBEXT:
268 case SHOW_DBNET:
269 case SHOW_DBRTR:
270 case SHOW_DBSUM:
271 case SHOW_DBASBR:
272 done = show_db_msg_detail(&imsg);
273 break;
274 case SHOW_RIB:
275 done = show_rib_msg(&imsg);
276 break;
277 case SHOW_RIB_DTAIL:
278 done = show_rib_detail_msg(&imsg);
279 break;
280 case SHOW_FIB:
281 done = show_fib_msg(&imsg);
282 break;
283 case SHOW_FIB_IFACE:
284 done = show_fib_interface_msg(&imsg);
285 break;
286 case NONE:
287 case FIB:
288 case FIB_COUPLE:
289 case FIB_DECOUPLE:
290 case RELOAD:
291 break;
292 }
293 imsg_free(&imsg);
294 }
295 }
296 close(ctl_sock);
297 free(ibuf);
298
299 return (0);
300 }
301
302 int
303 show_summary_msg(struct imsg *imsg)
304 {
305 struct ctl_sum *sum;
306 struct ctl_sum_area *sumarea;
307
308 switch (imsg->hdr.type) {
309 case IMSG_CTL_SHOW_SUM:
310 sum = imsg->data;
311 printf("Router ID: %s\n", inet_ntoa(sum->rtr_id));
312 printf("Uptime: %s\n", fmt_timeframe_core(sum->uptime));
313 printf("RFC1583 compatibility flag is ");
314 if (sum->rfc1583compat)
315 printf("enabled\n");
316 else
317 printf("disabled\n");
318
319 printf("SPF delay is %d sec(s), hold time between two SPFs "
320 "is %d sec(s)\n", sum->spf_delay, sum->spf_hold_time);
321 printf("Number of external LSA(s) %d\n", sum->num_ext_lsa);
322 printf("Number of areas attached to this router: %d\n",
323 sum->num_area);
324 break;
325 case IMSG_CTL_SHOW_SUM_AREA:
326 sumarea = imsg->data;
327 printf("\nArea ID: %s\n", inet_ntoa(sumarea->area));
328 printf(" Number of interfaces in this area: %d\n",
329 sumarea->num_iface);
330 printf(" Number of fully adjacent neighbors in this "
331 "area: %d\n", sumarea->num_adj_nbr);
332 printf(" SPF algorithm executed %d time(s)\n",
333 sumarea->num_spf_calc);
334 printf(" Number LSA(s) %d\n", sumarea->num_lsa);
335 break;
336 case IMSG_CTL_END:
337 printf("\n");
338 return (1);
339 default:
340 break;
341 }
342
343 return (0);
344 }
345
346 int
347 get_ifms_type(int mediatype)
348 {
349 switch (mediatype) {
350 case IFT_ETHER:
351 return (IFM_ETHER);
352 case IFT_FDDI:
353 return (IFM_FDDI);
354 case IFT_CARP:
355 return (IFM_CARP);
356 case IFT_PPP:
357 return (IFM_TDM);
358 default:
359 return (0);
360 }
361 }
362
363 int
364 show_interface_msg(struct imsg *imsg)
365 {
366 struct ctl_iface *iface;
367 char *netid;
368
369 switch (imsg->hdr.type) {
370 case IMSG_CTL_SHOW_INTERFACE:
371 iface = imsg->data;
372
373 if (asprintf(&netid, "%s/%d", inet_ntoa(iface->addr),
374 mask2prefixlen(iface->mask.s_addr)) == -1)
375 err(1, NULL);
376 printf("%-11s %-18s %-6s %-10s %-10s %s %3d %3d\n",
377 iface->name, netid, if_state_name(iface->state),
378 iface->hello_timer < 0 ? "-" :
379 fmt_timeframe_core(iface->hello_timer),
380 get_linkstate(get_ifms_type(iface->mediatype),
381 iface->linkstate), fmt_timeframe_core(iface->uptime),
382 iface->nbr_cnt, iface->adj_cnt);
383 free(netid);
384 break;
385 case IMSG_CTL_END:
386 printf("\n");
387 return (1);
388 default:
389 break;
390 }
391
392 return (0);
393 }
394
395 int
396 show_interface_detail_msg(struct imsg *imsg)
397 {
398 struct ctl_iface *iface;
399
400 switch (imsg->hdr.type) {
401 case IMSG_CTL_SHOW_INTERFACE:
402 iface = imsg->data;
403 printf("\n");
404 printf("Interface %s, line protocol is %s\n",
405 iface->name, print_link(iface->flags));
406 printf(" Internet address %s/%d, ",
407 inet_ntoa(iface->addr),
408 mask2prefixlen(iface->mask.s_addr));
409 printf("Area %s\n", inet_ntoa(iface->area));
410 printf(" Linkstate %s\n",
411 get_linkstate(get_ifms_type(iface->mediatype),
412 iface->linkstate));
413 printf(" Router ID %s, network type %s, cost: %d\n",
414 inet_ntoa(iface->rtr_id),
415 if_type_name(iface->type), iface->metric);
416 printf(" Transmit delay is %d sec(s), state %s, priority %d\n",
417 iface->transmit_delay, if_state_name(iface->state),
418 iface->priority);
419 printf(" Designated Router (ID) %s, ",
420 inet_ntoa(iface->dr_id));
421 printf("interface address %s\n", inet_ntoa(iface->dr_addr));
422 printf(" Backup Designated Router (ID) %s, ",
423 inet_ntoa(iface->bdr_id));
424 printf("interface address %s\n", inet_ntoa(iface->bdr_addr));
425 printf(" Timer intervals configured, "
426 "hello %d, dead %d, wait %d, retransmit %d\n",
427 iface->hello_interval, iface->dead_interval,
428 iface->dead_interval, iface->rxmt_interval);
429 if (iface->passive)
430 printf(" Passive interface (No Hellos)\n");
431 else if (iface->hello_timer < 0)
432 printf(" Hello timer not running\n");
433 else
434 printf(" Hello timer due in %s\n",
435 fmt_timeframe_core(iface->hello_timer));
436 printf(" Uptime %s\n", fmt_timeframe_core(iface->uptime));
437 printf(" Neighbor count is %d, adjacent neighbor count is "
438 "%d\n", iface->nbr_cnt, iface->adj_cnt);
439 if (iface->auth_type > 0) {
440 switch (iface->auth_type) {
441 case AUTH_SIMPLE:
442 printf(" Simple password authentication "
443 "enabled\n");
444 break;
445 case AUTH_CRYPT:
446 printf(" Message digest authentication "
447 "enabled\n");
448 printf(" Primary key id is %d\n",
449 iface->auth_keyid);
450 break;
451 default:
452 break;
453 }
454 }
455 break;
456 case IMSG_CTL_END:
457 printf("\n");
458 return (1);
459 default:
460 break;
461 }
462
463 return (0);
464 }
465
466 const char *
467 print_link(int state)
468 {
469 if (state & IFF_UP)
470 return ("UP");
471 else
472 return ("DOWN");
473 }
474
475 #define TF_BUFS 8
476 #define TF_LEN 9
477
478 const char *
479 fmt_timeframe(time_t t)
480 {
481 if (t == 0)
482 return ("Never");
483 else
484 return (fmt_timeframe_core(time(NULL) - t));
485 }
486
487 const char *
488 fmt_timeframe_core(time_t t)
489 {
490 char *buf;
491 static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
492 static int idx = 0;
493 unsigned int sec, min, hrs, day, week;
494
495 if (t == 0)
496 return ("00:00:00");
497
498 buf = tfbuf[idx++];
499 if (idx == TF_BUFS)
500 idx = 0;
501
502 week = t;
503
504 sec = week % 60;
505 week /= 60;
506 min = week % 60;
507 week /= 60;
508 hrs = week % 24;
509 week /= 24;
510 day = week % 7;
511 week /= 7;
512
513 if (week > 0)
514 snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
515 else if (day > 0)
516 snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
517 else
518 snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
519
520 return (buf);
521 }
522
523 const char *
524 log_id(u_int32_t id)
525 {
526 static char buf[48];
527 struct in_addr addr;
528
529 addr.s_addr = id;
530
531 if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL)
532 return ("?");
533 else
534 return (buf);
535 }
536
537 const char *
538 log_adv_rtr(u_int32_t adv_rtr)
539 {
540 static char buf[48];
541 struct in_addr addr;
542
543 addr.s_addr = adv_rtr;
544
545 if (inet_ntop(AF_INET, &addr, buf, sizeof(buf)) == NULL)
546 return ("?");
547 else
548 return (buf);
549 }
550
551 /* prototype defined in ospfd.h and shared with the kroute.c version */
552 u_int8_t
553 mask2prefixlen(in_addr_t ina)
554 {
555 if (ina == 0)
556 return (0);
557 else
558 return (33 - ffs(ntohl(ina)));
559 }
560
561 void
562 show_database_head(struct in_addr aid, u_int8_t type)
563 {
564 char *header, *format;
565
566 switch (type) {
567 case LSA_TYPE_ROUTER:
568 format = "Router Link States";
569 break;
570 case LSA_TYPE_NETWORK:
571 format = "Net Link States";
572 break;
573 case LSA_TYPE_SUM_NETWORK:
574 format = "Summary Net Link States";
575 break;
576 case LSA_TYPE_SUM_ROUTER:
577 format = "Summary Router Link States";
578 break;
579 case LSA_TYPE_EXTERNAL:
580 format = NULL;
581 if ((header = strdup("Type-5 AS External Link States")) == NULL)
582 err(1, NULL);
583 break;
584 default:
585 errx(1, "unknown LSA type");
586 }
587 if (type != LSA_TYPE_EXTERNAL)
588 if (asprintf(&header, "%s (Area %s)", format,
589 inet_ntoa(aid)) == -1)
590 err(1, NULL);
591
592 printf("\n%-15s %s\n\n", "", header);
593 free(header);
594 }
595
596 int
597 show_database_msg(struct imsg *imsg)
598 {
599 static struct in_addr area_id;
600 static u_int8_t lasttype;
601 struct area *area;
602 struct lsa_hdr *lsa;
603
604 switch (imsg->hdr.type) {
605 case IMSG_CTL_SHOW_DATABASE:
606 case IMSG_CTL_SHOW_DB_SELF:
607 lsa = imsg->data;
608 if (lsa->type != lasttype) {
609 show_database_head(area_id, lsa->type);
610 printf("%-15s %-15s %-4s %-10s %-8s\n", "Link ID",
611 "Adv Router", "Age", "Seq#", "Checksum");
612 }
613 printf("%-15s %-15s %-4d 0x%08x 0x%04x\n",
614 log_id(lsa->ls_id), log_adv_rtr(lsa->adv_rtr),
615 ntohs(lsa->age), ntohl(lsa->seq_num),
616 ntohs(lsa->ls_chksum));
617 lasttype = lsa->type;
618 break;
619 case IMSG_CTL_AREA:
620 area = imsg->data;
621 area_id = area->id;
622 lasttype = 0;
623 break;
624 case IMSG_CTL_END:
625 printf("\n");
626 return (1);
627 default:
628 break;
629 }
630
631 return (0);
632 }
633
634 char *
635 print_ls_type(u_int8_t type)
636 {
637 switch (type) {
638 case LSA_TYPE_ROUTER:
639 return ("Router");
640 case LSA_TYPE_NETWORK:
641 return ("Network");
642 case LSA_TYPE_SUM_NETWORK:
643 return ("Summary (Network)");
644 case LSA_TYPE_SUM_ROUTER:
645 return ("Summary (Router)");
646 case LSA_TYPE_EXTERNAL:
647 return ("AS External");
648 default:
649 return ("Unknown");
650 }
651 }
652
653 void
654 show_db_hdr_msg_detail(struct lsa_hdr *lsa)
655 {
656 printf("LS age: %d\n", ntohs(lsa->age));
657 printf("Options: %s\n", print_ospf_options(lsa->opts));
658 printf("LS Type: %s\n", print_ls_type(lsa->type));
659
660 switch (lsa->type) {
661 case LSA_TYPE_ROUTER:
662 printf("Link State ID: %s\n", log_id(lsa->ls_id));
663 break;
664 case LSA_TYPE_NETWORK:
665 printf("Link State ID: %s (address of Designated Router)\n",
666 log_id(lsa->ls_id));
667 break;
668 case LSA_TYPE_SUM_NETWORK:
669 printf("Link State ID: %s (Network ID)\n", log_id(lsa->ls_id));
670 break;
671 case LSA_TYPE_SUM_ROUTER:
672 printf("Link State ID: %s (ASBR Router ID)\n",
673 log_id(lsa->ls_id));
674 break;
675 case LSA_TYPE_EXTERNAL:
676 printf("Link State ID: %s (External Network Number)\n",
677 log_id(lsa->ls_id));
678 break;
679 }
680
681 printf("Advertising Router: %s\n", log_adv_rtr(lsa->adv_rtr));
682 printf("LS Seq Number: 0x%08x\n", ntohl(lsa->seq_num));
683 printf("Checksum: 0x%04x\n", ntohs(lsa->ls_chksum));
684 printf("Length: %d\n", ntohs(lsa->len));
685 }
686
687 char *
688 print_rtr_link_type(u_int8_t type)
689 {
690 switch (type) {
691 case LINK_TYPE_POINTTOPOINT:
692 return ("Point-to-Point");
693 case LINK_TYPE_TRANSIT_NET:
694 return ("Transit Network");
695 case LINK_TYPE_STUB_NET:
696 return ("Stub Network");
697 case LINK_TYPE_VIRTUAL:
698 return ("Virtual Link");
699 default:
700 return ("Unknown");
701 }
702 }
703
704 const char *
705 print_ospf_flags(u_int8_t opts)
706 {
707 static char optbuf[32];
708
709 snprintf(optbuf, sizeof(optbuf), "*|*|*|*|*|%s|%s|%s",
710 opts & OSPF_RTR_V ? "V" : "-",
711 opts & OSPF_RTR_E ? "E" : "-",
712 opts & OSPF_RTR_B ? "B" : "-");
713 return (optbuf);
714 }
715
716 int
717 show_db_msg_detail(struct imsg *imsg)
718 {
719 static struct in_addr area_id;
720 static u_int8_t lasttype;
721 struct in_addr addr, data;
722 struct area *area;
723 struct lsa *lsa;
724 struct lsa_rtr_link *rtr_link;
725 struct lsa_asext *asext;
726 u_int16_t i, nlinks, off;
727
728 /* XXX sanity checks! */
729
730 switch (imsg->hdr.type) {
731 case IMSG_CTL_SHOW_DB_EXT:
732 lsa = imsg->data;
733 if (lsa->hdr.type != lasttype)
734 show_database_head(area_id, lsa->hdr.type);
735 show_db_hdr_msg_detail(&lsa->hdr);
736 addr.s_addr = lsa->data.asext.mask;
737 printf("Network Mask: %s\n", inet_ntoa(addr));
738
739 asext = (struct lsa_asext *)((char *)lsa + sizeof(lsa->hdr));
740
741 printf(" Metric type: ");
742 if (ntohl(lsa->data.asext.metric) & LSA_ASEXT_E_FLAG)
743 printf("2\n");
744 else
745 printf("1\n");
746 printf(" Metric: %d\n", ntohl(asext->metric)
747 & LSA_METRIC_MASK);
748 addr.s_addr = asext->fw_addr;
749 printf(" Forwarding Address: %s\n", inet_ntoa(addr));
750 printf(" External Route Tag: %d\n\n", ntohl(asext->ext_tag));
751
752 lasttype = lsa->hdr.type;
753 break;
754 case IMSG_CTL_SHOW_DB_NET:
755 lsa = imsg->data;
756 if (lsa->hdr.type != lasttype)
757 show_database_head(area_id, lsa->hdr.type);
758 show_db_hdr_msg_detail(&lsa->hdr);
759 addr.s_addr = lsa->data.net.mask;
760 printf("Network Mask: %s\n", inet_ntoa(addr));
761
762 nlinks = (ntohs(lsa->hdr.len) - sizeof(struct lsa_hdr)
763 - sizeof(u_int32_t)) / sizeof(struct lsa_net_link);
764 off = sizeof(lsa->hdr) + sizeof(u_int32_t);
765
766 for (i = 0; i < nlinks; i++) {
767 addr.s_addr = lsa->data.net.att_rtr[i];
768 printf(" Attached Router: %s\n", inet_ntoa(addr));
769 }
770
771 printf("\n");
772 lasttype = lsa->hdr.type;
773 break;
774 case IMSG_CTL_SHOW_DB_RTR:
775 lsa = imsg->data;
776 if (lsa->hdr.type != lasttype)
777 show_database_head(area_id, lsa->hdr.type);
778 show_db_hdr_msg_detail(&lsa->hdr);
779 printf("Flags: %s\n", print_ospf_flags(lsa->data.rtr.flags));
780 nlinks = ntohs(lsa->data.rtr.nlinks);
781 printf("Number of Links: %d\n\n", nlinks);
782
783 off = sizeof(lsa->hdr) + sizeof(struct lsa_rtr);
784
785 for (i = 0; i < nlinks; i++) {
786 rtr_link = (struct lsa_rtr_link *)((char *)lsa + off);
787
788 printf(" Link connected to: %s\n",
789 print_rtr_link_type(rtr_link->type));
790
791 addr.s_addr = rtr_link->id;
792 data.s_addr = rtr_link->data;
793
794 switch (rtr_link->type) {
795 case LINK_TYPE_POINTTOPOINT:
796 case LINK_TYPE_VIRTUAL:
797 printf(" Link ID (Neighbors Router ID):"
798 " %s\n", inet_ntoa(addr));
799 printf(" Link Data (Router Interface "
800 "address): %s\n", inet_ntoa(data));
801 break;
802 case LINK_TYPE_TRANSIT_NET:
803 printf(" Link ID (Designated Router "
804 "address): %s\n", inet_ntoa(addr));
805 printf(" Link Data (Router Interface "
806 "address): %s\n", inet_ntoa(data));
807 break;
808 case LINK_TYPE_STUB_NET:
809 printf(" Link ID (Network ID): %s\n",
810 inet_ntoa(addr));
811 printf(" Link Data (Network Mask): %s\n",
812 inet_ntoa(data));
813 break;
814 default:
815 printf(" Link ID (Unknown): %s\n",
816 inet_ntoa(addr));
817 printf(" Link Data (Unknown): %s\n",
818 inet_ntoa(data));
819 break;
820 }
821
822 printf(" Metric: %d\n\n", ntohs(rtr_link->metric));
823
824 off += sizeof(struct lsa_rtr_link) +
825 rtr_link->num_tos * sizeof(u_int32_t);
826 }
827
828 lasttype = lsa->hdr.type;
829 break;
830 case IMSG_CTL_SHOW_DB_SUM:
831 case IMSG_CTL_SHOW_DB_ASBR:
832 lsa = imsg->data;
833 if (lsa->hdr.type != lasttype)
834 show_database_head(area_id, lsa->hdr.type);
835 show_db_hdr_msg_detail(&lsa->hdr);
836 addr.s_addr = lsa->data.sum.mask;
837 printf("Network Mask: %s\n", inet_ntoa(addr));
838 printf("Metric: %d\n\n", ntohl(lsa->data.sum.metric) &
839 LSA_METRIC_MASK);
840 lasttype = lsa->hdr.type;
841 break;
842 case IMSG_CTL_AREA:
843 area = imsg->data;
844 area_id = area->id;
845 lasttype = 0;
846 break;
847 case IMSG_CTL_END:
848 return (1);
849 default:
850 break;
851 }
852
853 return (0);
854 }
855
856 int
857 show_nbr_msg(struct imsg *imsg)
858 {
859 struct ctl_nbr *nbr;
860 char *state;
861
862 switch (imsg->hdr.type) {
863 case IMSG_CTL_SHOW_NBR:
864 nbr = imsg->data;
865 if (asprintf(&state, "%s/%s", nbr_state_name(nbr->nbr_state),
866 if_state_name(nbr->iface_state)) == -1)
867 err(1, NULL);
868 printf("%-15s %-3d %-12s %-9s", inet_ntoa(nbr->id),
869 nbr->priority, state, fmt_timeframe_core(nbr->dead_timer));
870 printf("%-15s %-9s %s\n", inet_ntoa(nbr->addr), nbr->name,
871 nbr->uptime == 0 ? "-" : fmt_timeframe_core(nbr->uptime));
872 free(state);
873 break;
874 case IMSG_CTL_END:
875 printf("\n");
876 return (1);
877 default:
878 break;
879 }
880
881 return (0);
882 }
883
884 const char *
885 print_ospf_options(u_int8_t opts)
886 {
887 static char optbuf[32];
888
889 snprintf(optbuf, sizeof(optbuf), "*|*|%s|%s|%s|%s|%s|*",
890 opts & OSPF_OPTION_DC ? "DC" : "-",
891 opts & OSPF_OPTION_EA ? "EA" : "-",
892 opts & OSPF_OPTION_NP ? "N/P" : "-",
893 opts & OSPF_OPTION_MC ? "MC" : "-",
894 opts & OSPF_OPTION_E ? "E" : "-");
895 return (optbuf);
896 }
897
898 int
899 show_nbr_detail_msg(struct imsg *imsg)
900 {
901 struct ctl_nbr *nbr;
902
903 switch (imsg->hdr.type) {
904 case IMSG_CTL_SHOW_NBR:
905 nbr = imsg->data;
906 printf("\nNeighbor %s, ", inet_ntoa(nbr->id));
907 printf("interface address %s\n", inet_ntoa(nbr->addr));
908 printf(" Area %s, interface %s\n", inet_ntoa(nbr->area),
909 nbr->name);
910 printf(" Neighbor priority is %d, "
911 "State is %s, %d state changes\n",
912 nbr->priority, nbr_state_name(nbr->nbr_state),
913 nbr->state_chng_cnt);
914 printf(" DR is %s, ", inet_ntoa(nbr->dr));
915 printf("BDR is %s\n", inet_ntoa(nbr->bdr));
916 printf(" Options %s\n", print_ospf_options(nbr->options));
917 printf(" Dead timer due in %s\n",
918 fmt_timeframe_core(nbr->dead_timer));
919 printf(" Uptime %s\n", fmt_timeframe_core(nbr->uptime));
920 printf(" Database Summary List %d\n", nbr->db_sum_lst_cnt);
921 printf(" Link State Request List %d\n", nbr->ls_req_lst_cnt);
922 printf(" Link State Retransmission List %d\n",
923 nbr->ls_retrans_lst_cnt);
924 break;
925 case IMSG_CTL_END:
926 printf("\n");
927 return (1);
928 default:
929 break;
930 }
931
932 return (0);
933 }
934
935 int
936 show_rib_msg(struct imsg *imsg)
937 {
938 struct ctl_rt *rt;
939 char *dstnet;
940
941 switch (imsg->hdr.type) {
942 case IMSG_CTL_SHOW_RIB:
943 rt = imsg->data;
944 switch (rt->d_type) {
945 case DT_NET:
946 if (asprintf(&dstnet, "%s/%d", inet_ntoa(rt->prefix),
947 rt->prefixlen) == -1)
948 err(1, NULL);
949 break;
950 case DT_RTR:
951 if (asprintf(&dstnet, "%s",
952 inet_ntoa(rt->prefix)) == -1)
953 err(1, NULL);
954 break;
955 default:
956 errx(1, "Invalid route type");
957 }
958
959 printf("%-20s %-17s %-12s %-9s %-7d %s\n", dstnet,
960 inet_ntoa(rt->nexthop), path_type_name(rt->p_type),
961 dst_type_name(rt->d_type), rt->cost,
962 rt->uptime == 0 ? "-" : fmt_timeframe_core(rt->uptime));
963 free(dstnet);
964 break;
965 case IMSG_CTL_END:
966 printf("\n");
967 return (1);
968 default:
969 break;
970 }
971
972 return (0);
973 }
974
975 void
976 show_rib_head(struct in_addr aid, u_int8_t d_type, u_int8_t p_type)
977 {
978 char *header, *format, *format2;
979
980 switch (p_type) {
981 case PT_INTRA_AREA:
982 case PT_INTER_AREA:
983 switch (d_type) {
984 case DT_NET:
985 format = "Network Routing Table";
986 format2 = "";
987 break;
988 case DT_RTR:
989 format = "Router Routing Table";
990 format2 = "Type";
991 break;
992 default:
993 errx(1, "unknown route type");
994 }
995 break;
996 case PT_TYPE1_EXT:
997 case PT_TYPE2_EXT:
998 format = NULL;
999 format2 = "Cost 2";
1000 if ((header = strdup("External Routing Table")) == NULL)
1001 err(1, NULL);
1002 break;
1003 default:
1004 errx(1, "unknown route type");
1005 }
1006
1007 if (p_type != PT_TYPE1_EXT && p_type != PT_TYPE2_EXT)
1008 if (asprintf(&header, "%s (Area %s)", format,
1009 inet_ntoa(aid)) == -1)
1010 err(1, NULL);
1011
1012 printf("\n%-18s %s\n", "", header);
1013 free(header);
1014
1015 printf("\n%-18s %-15s %-15s %-12s %-7s %-7s\n", "Destination",
1016 "Nexthop", "Adv Router", "Path type", "Cost", format2);
1017 }
1018
1019 const char *
1020 print_ospf_rtr_flags(u_int8_t opts)
1021 {
1022 static char optbuf[32];
1023
1024 snprintf(optbuf, sizeof(optbuf), "%s%s%s",
1025 opts & OSPF_RTR_E ? "AS" : "",
1026 opts & OSPF_RTR_E && opts & OSPF_RTR_B ? "+" : "",
1027 opts & OSPF_RTR_B ? "ABR" : "");
1028 return (optbuf);
1029 }
1030
1031 int
1032 show_rib_detail_msg(struct imsg *imsg)
1033 {
1034 static struct in_addr area_id;
1035 struct ctl_rt *rt;
1036 struct area *area;
1037 char *dstnet;
1038 static u_int8_t lasttype;
1039
1040 switch (imsg->hdr.type) {
1041 case IMSG_CTL_SHOW_RIB:
1042 rt = imsg->data;
1043
1044 switch (rt->p_type) {
1045 case PT_INTRA_AREA:
1046 case PT_INTER_AREA:
1047 switch (rt->d_type) {
1048 case DT_NET:
1049 if (lasttype != RIB_NET)
1050 show_rib_head(rt->area, rt->d_type,
1051 rt->p_type);
1052 if (asprintf(&dstnet, "%s/%d",
1053 inet_ntoa(rt->prefix), rt->prefixlen) == -1)
1054 err(1, NULL);
1055 lasttype = RIB_NET;
1056 break;
1057 case DT_RTR:
1058 if (lasttype != RIB_RTR)
1059 show_rib_head(rt->area, rt->d_type,
1060 rt->p_type);
1061 if (asprintf(&dstnet, "%s",
1062 inet_ntoa(rt->prefix)) == -1)
1063 err(1, NULL);
1064 lasttype = RIB_RTR;
1065 break;
1066 default:
1067 errx(1, "unknown route type");
1068 }
1069 printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop));
1070 printf("%-15s %-12s %-7d", inet_ntoa(rt->adv_rtr),
1071 path_type_name(rt->p_type), rt->cost);
1072 free(dstnet);
1073
1074 if (rt->d_type == DT_RTR)
1075 printf(" %-7s",
1076 print_ospf_rtr_flags(rt->flags));
1077
1078 printf("\n");
1079 break;
1080 case PT_TYPE1_EXT:
1081 case PT_TYPE2_EXT:
1082 if (lasttype != RIB_EXT)
1083 show_rib_head(rt->area, rt->d_type, rt->p_type);
1084
1085 if (asprintf(&dstnet, "%s/%d",
1086 inet_ntoa(rt->prefix), rt->prefixlen) == -1)
1087 err(1, NULL);
1088
1089 printf("%-18s %-15s ", dstnet, inet_ntoa(rt->nexthop));
1090 printf("%-15s %-12s %-7d %-7d\n",
1091 inet_ntoa(rt->adv_rtr), path_type_name(rt->p_type),
1092 rt->cost, rt->cost2);
1093 free(dstnet);
1094
1095 lasttype = RIB_EXT;
1096 break;
1097 default:
1098 errx(1, "unknown route type");
1099 }
1100 break;
1101 case IMSG_CTL_AREA:
1102 area = imsg->data;
1103 area_id = area->id;
1104 break;
1105 case IMSG_CTL_END:
1106 printf("\n");
1107 return (1);
1108 default:
1109 break;
1110 }
1111
1112 return (0);
1113 }
1114
1115 void
1116 show_fib_head(void)
1117 {
1118 printf("flags: * = valid, O = OSPF, C = Connected, S = Static\n");
1119 printf("%-6s %-4s %-20s %-17s\n", "Flags", "Prio", "Destination", "Nexthop");
1120 }
1121
1122 int
1123 show_fib_msg(struct imsg *imsg)
1124 {
1125 struct kroute *k;
1126 char *p;
1127
1128 switch (imsg->hdr.type) {
1129 case IMSG_CTL_KROUTE:
1130 if (imsg->hdr.len < IMSG_HEADER_SIZE + sizeof(struct kroute))
1131 errx(1, "wrong imsg len");
1132 k = imsg->data;
1133
1134 if (k->flags & F_DOWN)
1135 printf(" ");
1136 else
1137 printf("*");
1138
1139 if (!(k->flags & F_KERNEL))
1140 printf("O");
1141 else if (k->flags & F_CONNECTED)
1142 printf("C");
1143 else if (k->flags & F_STATIC)
1144 printf("S");
1145 else
1146 printf(" ");
1147
1148 printf(" ");
1149 printf("%4d ", k->priority);
1150 if (asprintf(&p, "%s/%u", inet_ntoa(k->prefix), k->prefixlen) ==
1151 -1)
1152 err(1, NULL);
1153 printf("%-20s ", p);
1154 free(p);
1155
1156 if (k->nexthop.s_addr)
1157 printf("%s", inet_ntoa(k->nexthop));
1158 else if (k->flags & F_CONNECTED)
1159 printf("link#%u", k->ifindex);
1160 printf("\n");
1161
1162 break;
1163 case IMSG_CTL_END:
1164 printf("\n");
1165 return (1);
1166 default:
1167 break;
1168 }
1169
1170 return (0);
1171 }
1172
1173 void
1174 show_interface_head(void)
1175 {
1176 printf("%-15s%-15s%s\n", "Interface", "Flags",
1177 "Link state");
1178 }
1179
1180 const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST;
1181 const struct ifmedia_status_description
1182 ifm_status_descriptions[] = IFM_STATUS_DESCRIPTIONS;
1183 const struct ifmedia_description
1184 ifm_type_descriptions[] = IFM_TYPE_DESCRIPTIONS;
1185
1186 const char *
1187 get_media_descr(int media_type)
1188 {
1189 const struct ifmedia_description *p;
1190
1191 for (p = ifm_type_descriptions; p->ifmt_string != NULL; p++)
1192 if (media_type == p->ifmt_word)
1193 return (p->ifmt_string);
1194
1195 return ("unknown");
1196 }
1197
1198 const char *
1199 get_linkstate(int media_type, int link_state)
1200 {
1201 const struct ifmedia_status_description *p;
1202 int i;
1203
1204 if (link_state == LINK_STATE_UNKNOWN)
1205 return ("unknown");
1206
1207 for (i = 0; ifm_status_valid_list[i] != 0; i++)
1208 for (p = ifm_status_descriptions; p->ifms_valid != 0; p++) {
1209 if (p->ifms_type != media_type ||
1210 p->ifms_valid != ifm_status_valid_list[i])
1211 continue;
1212 if (LINK_STATE_IS_UP(link_state))
1213 return (p->ifms_string[1]);
1214 return (p->ifms_string[0]);
1215 }
1216
1217 return ("unknown");
1218 }
1219
1220 void
1221 print_baudrate(u_int64_t baudrate)
1222 {
1223 if (baudrate > IF_Gbps(1))
1224 printf("%llu GBit/s", baudrate / IF_Gbps(1));
1225 else if (baudrate > IF_Mbps(1))
1226 printf("%llu MBit/s", baudrate / IF_Mbps(1));
1227 else if (baudrate > IF_Kbps(1))
1228 printf("%llu KBit/s", baudrate / IF_Kbps(1));
1229 else
1230 printf("%llu Bit/s", baudrate);
1231 }
1232
1233 int
1234 show_fib_interface_msg(struct imsg *imsg)
1235 {
1236 struct kif *k;
1237 int ifms_type;
1238
1239 switch (imsg->hdr.type) {
1240 case IMSG_CTL_IFINFO:
1241 k = imsg->data;
1242 printf("%-15s", k->ifname);
1243 printf("%-15s", k->flags & IFF_UP ? "UP" : "");
1244 switch (k->media_type) {
1245 case IFT_ETHER:
1246 ifms_type = IFM_ETHER;
1247 break;
1248 case IFT_FDDI:
1249 ifms_type = IFM_FDDI;
1250 break;
1251 case IFT_CARP:
1252 ifms_type = IFM_CARP;
1253 break;
1254 default:
1255 ifms_type = 0;
1256 break;
1257 }
1258
1259 if (ifms_type)
1260 printf("%s, %s", get_media_descr(ifms_type),
1261 get_linkstate(ifms_type, k->link_state));
1262 else if (k->link_state == LINK_STATE_UNKNOWN)
1263 printf("unknown");
1264 else
1265 printf("link state %u", k->link_state);
1266
1267 if (k->link_state != LINK_STATE_DOWN && k->baudrate > 0) {
1268 printf(", ");
1269 print_baudrate(k->baudrate);
1270 }
1271 printf("\n");
1272 break;
1273 case IMSG_CTL_END:
1274 printf("\n");
1275 return (1);
1276 default:
1277 break;
1278 }
1279
1280 return (0);
1281 }