1*de1e4e89SAndroid Build Coastguard Worker /*
2*de1e4e89SAndroid Build Coastguard Worker * brmonitor.c "bridge monitor"
3*de1e4e89SAndroid Build Coastguard Worker *
4*de1e4e89SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or
5*de1e4e89SAndroid Build Coastguard Worker * modify it under the terms of the GNU General Public License
6*de1e4e89SAndroid Build Coastguard Worker * as published by the Free Software Foundation; either version
7*de1e4e89SAndroid Build Coastguard Worker * 2 of the License, or (at your option) any later version.
8*de1e4e89SAndroid Build Coastguard Worker *
9*de1e4e89SAndroid Build Coastguard Worker * Authors: Stephen Hemminger <[email protected]>
10*de1e4e89SAndroid Build Coastguard Worker *
11*de1e4e89SAndroid Build Coastguard Worker */
12*de1e4e89SAndroid Build Coastguard Worker
13*de1e4e89SAndroid Build Coastguard Worker #include <stdio.h>
14*de1e4e89SAndroid Build Coastguard Worker #include <stdlib.h>
15*de1e4e89SAndroid Build Coastguard Worker #include <unistd.h>
16*de1e4e89SAndroid Build Coastguard Worker #include <time.h>
17*de1e4e89SAndroid Build Coastguard Worker #include <sys/socket.h>
18*de1e4e89SAndroid Build Coastguard Worker #include <sys/time.h>
19*de1e4e89SAndroid Build Coastguard Worker #include <net/if.h>
20*de1e4e89SAndroid Build Coastguard Worker #include <netinet/in.h>
21*de1e4e89SAndroid Build Coastguard Worker #include <linux/if_bridge.h>
22*de1e4e89SAndroid Build Coastguard Worker #include <linux/neighbour.h>
23*de1e4e89SAndroid Build Coastguard Worker #include <string.h>
24*de1e4e89SAndroid Build Coastguard Worker
25*de1e4e89SAndroid Build Coastguard Worker #include "utils.h"
26*de1e4e89SAndroid Build Coastguard Worker #include "br_common.h"
27*de1e4e89SAndroid Build Coastguard Worker
28*de1e4e89SAndroid Build Coastguard Worker
29*de1e4e89SAndroid Build Coastguard Worker static void usage(void) __attribute__((noreturn));
30*de1e4e89SAndroid Build Coastguard Worker int prefix_banner;
31*de1e4e89SAndroid Build Coastguard Worker
usage(void)32*de1e4e89SAndroid Build Coastguard Worker static void usage(void)
33*de1e4e89SAndroid Build Coastguard Worker {
34*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Usage: bridge monitor [file | link | fdb | mdb | all]\n");
35*de1e4e89SAndroid Build Coastguard Worker exit(-1);
36*de1e4e89SAndroid Build Coastguard Worker }
37*de1e4e89SAndroid Build Coastguard Worker
accept_msg(const struct sockaddr_nl * who,struct rtnl_ctrl_data * ctrl,struct nlmsghdr * n,void * arg)38*de1e4e89SAndroid Build Coastguard Worker static int accept_msg(const struct sockaddr_nl *who,
39*de1e4e89SAndroid Build Coastguard Worker struct rtnl_ctrl_data *ctrl,
40*de1e4e89SAndroid Build Coastguard Worker struct nlmsghdr *n, void *arg)
41*de1e4e89SAndroid Build Coastguard Worker {
42*de1e4e89SAndroid Build Coastguard Worker FILE *fp = arg;
43*de1e4e89SAndroid Build Coastguard Worker
44*de1e4e89SAndroid Build Coastguard Worker if (timestamp)
45*de1e4e89SAndroid Build Coastguard Worker print_timestamp(fp);
46*de1e4e89SAndroid Build Coastguard Worker
47*de1e4e89SAndroid Build Coastguard Worker switch (n->nlmsg_type) {
48*de1e4e89SAndroid Build Coastguard Worker case RTM_NEWLINK:
49*de1e4e89SAndroid Build Coastguard Worker case RTM_DELLINK:
50*de1e4e89SAndroid Build Coastguard Worker if (prefix_banner)
51*de1e4e89SAndroid Build Coastguard Worker fprintf(fp, "[LINK]");
52*de1e4e89SAndroid Build Coastguard Worker
53*de1e4e89SAndroid Build Coastguard Worker return print_linkinfo(who, n, arg);
54*de1e4e89SAndroid Build Coastguard Worker
55*de1e4e89SAndroid Build Coastguard Worker case RTM_NEWNEIGH:
56*de1e4e89SAndroid Build Coastguard Worker case RTM_DELNEIGH:
57*de1e4e89SAndroid Build Coastguard Worker if (prefix_banner)
58*de1e4e89SAndroid Build Coastguard Worker fprintf(fp, "[NEIGH]");
59*de1e4e89SAndroid Build Coastguard Worker return print_fdb(who, n, arg);
60*de1e4e89SAndroid Build Coastguard Worker
61*de1e4e89SAndroid Build Coastguard Worker case RTM_NEWMDB:
62*de1e4e89SAndroid Build Coastguard Worker case RTM_DELMDB:
63*de1e4e89SAndroid Build Coastguard Worker if (prefix_banner)
64*de1e4e89SAndroid Build Coastguard Worker fprintf(fp, "[MDB]");
65*de1e4e89SAndroid Build Coastguard Worker return print_mdb(who, n, arg);
66*de1e4e89SAndroid Build Coastguard Worker
67*de1e4e89SAndroid Build Coastguard Worker case NLMSG_TSTAMP:
68*de1e4e89SAndroid Build Coastguard Worker print_nlmsg_timestamp(fp, n);
69*de1e4e89SAndroid Build Coastguard Worker return 0;
70*de1e4e89SAndroid Build Coastguard Worker
71*de1e4e89SAndroid Build Coastguard Worker default:
72*de1e4e89SAndroid Build Coastguard Worker return 0;
73*de1e4e89SAndroid Build Coastguard Worker }
74*de1e4e89SAndroid Build Coastguard Worker }
75*de1e4e89SAndroid Build Coastguard Worker
do_monitor(int argc,char ** argv)76*de1e4e89SAndroid Build Coastguard Worker int do_monitor(int argc, char **argv)
77*de1e4e89SAndroid Build Coastguard Worker {
78*de1e4e89SAndroid Build Coastguard Worker char *file = NULL;
79*de1e4e89SAndroid Build Coastguard Worker unsigned int groups = ~RTMGRP_TC;
80*de1e4e89SAndroid Build Coastguard Worker int llink = 0;
81*de1e4e89SAndroid Build Coastguard Worker int lneigh = 0;
82*de1e4e89SAndroid Build Coastguard Worker int lmdb = 0;
83*de1e4e89SAndroid Build Coastguard Worker
84*de1e4e89SAndroid Build Coastguard Worker rtnl_close(&rth);
85*de1e4e89SAndroid Build Coastguard Worker
86*de1e4e89SAndroid Build Coastguard Worker while (argc > 0) {
87*de1e4e89SAndroid Build Coastguard Worker if (matches(*argv, "file") == 0) {
88*de1e4e89SAndroid Build Coastguard Worker NEXT_ARG();
89*de1e4e89SAndroid Build Coastguard Worker file = *argv;
90*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "link") == 0) {
91*de1e4e89SAndroid Build Coastguard Worker llink = 1;
92*de1e4e89SAndroid Build Coastguard Worker groups = 0;
93*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "fdb") == 0) {
94*de1e4e89SAndroid Build Coastguard Worker lneigh = 1;
95*de1e4e89SAndroid Build Coastguard Worker groups = 0;
96*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "mdb") == 0) {
97*de1e4e89SAndroid Build Coastguard Worker lmdb = 1;
98*de1e4e89SAndroid Build Coastguard Worker groups = 0;
99*de1e4e89SAndroid Build Coastguard Worker } else if (strcmp(*argv, "all") == 0) {
100*de1e4e89SAndroid Build Coastguard Worker groups = ~RTMGRP_TC;
101*de1e4e89SAndroid Build Coastguard Worker prefix_banner = 1;
102*de1e4e89SAndroid Build Coastguard Worker } else if (matches(*argv, "help") == 0) {
103*de1e4e89SAndroid Build Coastguard Worker usage();
104*de1e4e89SAndroid Build Coastguard Worker } else {
105*de1e4e89SAndroid Build Coastguard Worker fprintf(stderr, "Argument \"%s\" is unknown, try \"bridge monitor help\".\n", *argv);
106*de1e4e89SAndroid Build Coastguard Worker exit(-1);
107*de1e4e89SAndroid Build Coastguard Worker }
108*de1e4e89SAndroid Build Coastguard Worker argc--; argv++;
109*de1e4e89SAndroid Build Coastguard Worker }
110*de1e4e89SAndroid Build Coastguard Worker
111*de1e4e89SAndroid Build Coastguard Worker if (llink)
112*de1e4e89SAndroid Build Coastguard Worker groups |= nl_mgrp(RTNLGRP_LINK);
113*de1e4e89SAndroid Build Coastguard Worker
114*de1e4e89SAndroid Build Coastguard Worker if (lneigh) {
115*de1e4e89SAndroid Build Coastguard Worker groups |= nl_mgrp(RTNLGRP_NEIGH);
116*de1e4e89SAndroid Build Coastguard Worker }
117*de1e4e89SAndroid Build Coastguard Worker
118*de1e4e89SAndroid Build Coastguard Worker if (lmdb) {
119*de1e4e89SAndroid Build Coastguard Worker groups |= nl_mgrp(RTNLGRP_MDB);
120*de1e4e89SAndroid Build Coastguard Worker }
121*de1e4e89SAndroid Build Coastguard Worker
122*de1e4e89SAndroid Build Coastguard Worker if (file) {
123*de1e4e89SAndroid Build Coastguard Worker FILE *fp;
124*de1e4e89SAndroid Build Coastguard Worker int err;
125*de1e4e89SAndroid Build Coastguard Worker
126*de1e4e89SAndroid Build Coastguard Worker fp = fopen(file, "r");
127*de1e4e89SAndroid Build Coastguard Worker if (fp == NULL) {
128*de1e4e89SAndroid Build Coastguard Worker perror("Cannot fopen");
129*de1e4e89SAndroid Build Coastguard Worker exit(-1);
130*de1e4e89SAndroid Build Coastguard Worker }
131*de1e4e89SAndroid Build Coastguard Worker err = rtnl_from_file(fp, accept_msg, stdout);
132*de1e4e89SAndroid Build Coastguard Worker fclose(fp);
133*de1e4e89SAndroid Build Coastguard Worker return err;
134*de1e4e89SAndroid Build Coastguard Worker }
135*de1e4e89SAndroid Build Coastguard Worker
136*de1e4e89SAndroid Build Coastguard Worker if (rtnl_open(&rth, groups) < 0)
137*de1e4e89SAndroid Build Coastguard Worker exit(1);
138*de1e4e89SAndroid Build Coastguard Worker ll_init_map(&rth);
139*de1e4e89SAndroid Build Coastguard Worker
140*de1e4e89SAndroid Build Coastguard Worker if (rtnl_listen(&rth, accept_msg, stdout) < 0)
141*de1e4e89SAndroid Build Coastguard Worker exit(2);
142*de1e4e89SAndroid Build Coastguard Worker
143*de1e4e89SAndroid Build Coastguard Worker return 0;
144*de1e4e89SAndroid Build Coastguard Worker }
145