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