mirror_iproute2/ip/rtmon.c
Matteo Croce 8589eb4efd treewide: refactor help messages
Every tool in the iproute2 package have one or more function to show
an help message to the user. Some of these functions print the help
line by line with a series of printf call, e.g. ip/xfrm_state.c does
60 fprintf calls.
If we group all the calls to a single one and just concatenate strings,
we save a lot of libc calls and thus object size. The size difference
of the compiled binaries calculated with bloat-o-meter is:

        ip/ip:
        add/remove: 0/0 grow/shrink: 5/15 up/down: 103/-4796 (-4693)
        Total: Before=672591, After=667898, chg -0.70%
        ip/rtmon:
        add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-54 (-54)
        Total: Before=48879, After=48825, chg -0.11%
        tc/tc:
        add/remove: 0/2 grow/shrink: 31/10 up/down: 882/-6133 (-5251)
        Total: Before=351912, After=346661, chg -1.49%
        bridge/bridge:
        add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-459 (-459)
        Total: Before=70502, After=70043, chg -0.65%
        misc/lnstat:
        add/remove: 0/1 grow/shrink: 1/0 up/down: 48/-486 (-438)
        Total: Before=9960, After=9522, chg -4.40%
        tipc/tipc:
        add/remove: 0/0 grow/shrink: 1/1 up/down: 18/-62 (-44)
        Total: Before=79182, After=79138, chg -0.06%

While at it, indent some strings which were starting at column 0,
and use tabs where possible, to have a consistent style across helps.

Signed-off-by: Matteo Croce <mcroce@redhat.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
2019-05-20 14:35:07 -07:00

185 lines
4.1 KiB
C

/*
* rtmon.c RTnetlink listener.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <string.h>
#include "SNAPSHOT.h"
#include "utils.h"
#include "libnetlink.h"
static int init_phase = 1;
static void write_stamp(FILE *fp)
{
char buf[128];
struct nlmsghdr *n1 = (void *)buf;
struct timeval tv;
n1->nlmsg_type = NLMSG_TSTAMP;
n1->nlmsg_flags = 0;
n1->nlmsg_seq = 0;
n1->nlmsg_pid = 0;
n1->nlmsg_len = NLMSG_LENGTH(4*2);
gettimeofday(&tv, NULL);
((__u32 *)NLMSG_DATA(n1))[0] = tv.tv_sec;
((__u32 *)NLMSG_DATA(n1))[1] = tv.tv_usec;
fwrite((void *)n1, 1, NLMSG_ALIGN(n1->nlmsg_len), fp);
}
static int dump_msg(struct rtnl_ctrl_data *ctrl,
struct nlmsghdr *n, void *arg)
{
FILE *fp = (FILE *)arg;
if (!init_phase)
write_stamp(fp);
fwrite((void *)n, 1, NLMSG_ALIGN(n->nlmsg_len), fp);
fflush(fp);
return 0;
}
static int dump_msg2(struct nlmsghdr *n, void *arg)
{
return dump_msg(NULL, n, arg);
}
static void usage(void)
{
fprintf(stderr,
"Usage: rtmon [ OPTIONS ] file FILE [ all | LISTofOBJECTS ]\n"
"OPTIONS := { -f[amily] { inet | inet6 | link | help } |\n"
" -4 | -6 | -0 | -V[ersion] }\n"
"LISTofOBJECTS := [ link ] [ address ] [ route ]\n");
exit(-1);
}
int
main(int argc, char **argv)
{
FILE *fp;
struct rtnl_handle rth;
int family = AF_UNSPEC;
unsigned int groups = ~0U;
int llink = 0;
int laddr = 0;
int lroute = 0;
char *file = NULL;
while (argc > 1) {
if (matches(argv[1], "-family") == 0) {
argc--;
argv++;
if (argc <= 1)
usage();
if (strcmp(argv[1], "inet") == 0)
family = AF_INET;
else if (strcmp(argv[1], "inet6") == 0)
family = AF_INET6;
else if (strcmp(argv[1], "link") == 0)
family = AF_INET6;
else if (strcmp(argv[1], "help") == 0)
usage();
else {
fprintf(stderr, "Protocol ID \"%s\" is unknown, try \"rtmon help\".\n", argv[1]);
exit(-1);
}
} else if (strcmp(argv[1], "-4") == 0) {
family = AF_INET;
} else if (strcmp(argv[1], "-6") == 0) {
family = AF_INET6;
} else if (strcmp(argv[1], "-0") == 0) {
family = AF_PACKET;
} else if (matches(argv[1], "-Version") == 0) {
printf("rtmon utility, iproute2-ss%s\n", SNAPSHOT);
exit(0);
} else if (matches(argv[1], "file") == 0) {
argc--;
argv++;
if (argc <= 1)
usage();
file = argv[1];
} else if (matches(argv[1], "link") == 0) {
llink = 1;
groups = 0;
} else if (matches(argv[1], "address") == 0) {
laddr = 1;
groups = 0;
} else if (matches(argv[1], "route") == 0) {
lroute = 1;
groups = 0;
} else if (strcmp(argv[1], "all") == 0) {
groups = ~0U;
} else if (matches(argv[1], "help") == 0) {
usage();
} else {
fprintf(stderr, "Argument \"%s\" is unknown, try \"rtmon help\".\n", argv[1]);
exit(-1);
}
argc--; argv++;
}
if (file == NULL) {
fprintf(stderr, "Not enough information: argument \"file\" is required\n");
exit(-1);
}
if (llink)
groups |= nl_mgrp(RTNLGRP_LINK);
if (laddr) {
if (!family || family == AF_INET)
groups |= nl_mgrp(RTNLGRP_IPV4_IFADDR);
if (!family || family == AF_INET6)
groups |= nl_mgrp(RTNLGRP_IPV6_IFADDR);
}
if (lroute) {
if (!family || family == AF_INET)
groups |= nl_mgrp(RTNLGRP_IPV4_ROUTE);
if (!family || family == AF_INET6)
groups |= nl_mgrp(RTNLGRP_IPV6_ROUTE);
}
fp = fopen(file, "w");
if (fp == NULL) {
perror("Cannot fopen");
exit(-1);
}
if (rtnl_open(&rth, groups) < 0)
exit(1);
if (rtnl_linkdump_req(&rth, AF_UNSPEC) < 0) {
perror("Cannot send dump request");
exit(1);
}
write_stamp(fp);
if (rtnl_dump_filter(&rth, dump_msg2, fp) < 0) {
fprintf(stderr, "Dump terminated\n");
return 1;
}
init_phase = 0;
if (rtnl_listen(&rth, dump_msg, (void *)fp) < 0)
exit(2);
exit(0);
}