15bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim/*
25bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim * tc_monitor.c		"tc monitor".
35bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *
45bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *		This program is free software; you can redistribute it and/or
55bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *		modify it under the terms of the GNU General Public License
65bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *		as published by the Free Software Foundation; either version
75bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *		2 of the License, or (at your option) any later version.
85bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *
95bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim * Authors:	Jamal Hadi Salim
105bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim *
115bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim */
125bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
135bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <stdio.h>
145bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <stdlib.h>
155bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <unistd.h>
165bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <syslog.h>
175bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <fcntl.h>
185bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <sys/socket.h>
195bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <netinet/in.h>
205bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <arpa/inet.h>
215bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <string.h>
225bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include <time.h>
235bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include "rt_names.h"
245bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include "utils.h"
255bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include "tc_util.h"
265bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim#include "tc_common.h"
275bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
285bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
295bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salimstatic void usage(void) __attribute__((noreturn));
305bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
315bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salimstatic void usage(void)
325bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim{
3332a6fbe56316f8e1309dcccd77045d7ddf8e654eEric Dumazet	fprintf(stderr, "Usage: tc [-timestamp [-tshort] monitor\n");
345bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	exit(-1);
355bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim}
365bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
375bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
38d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemmingerstatic int accept_tcmsg(const struct sockaddr_nl *who,
390628cddd9d5c0cb9ed0e0aba136e50de93487150Nicolas Dichtel			struct rtnl_ctrl_data *ctrl,
40d1f28cf181a6f77f230d90267eef0ecfbcb25f30Stephen Hemminger			struct nlmsghdr *n, void *arg)
415bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim{
4232a121cba257954963fbdd56a1c4567c2efc779aStephen Hemminger	FILE *fp = (FILE *)arg;
435bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
4432a6fbe56316f8e1309dcccd77045d7ddf8e654eEric Dumazet	if (timestamp)
4532a6fbe56316f8e1309dcccd77045d7ddf8e654eEric Dumazet		print_timestamp(fp);
4632a6fbe56316f8e1309dcccd77045d7ddf8e654eEric Dumazet
475bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (n->nlmsg_type == RTM_NEWTFILTER || n->nlmsg_type == RTM_DELTFILTER) {
485bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		print_filter(who, n, arg);
495bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		return 0;
505bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
515bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (n->nlmsg_type == RTM_NEWTCLASS || n->nlmsg_type == RTM_DELTCLASS) {
525bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		print_class(who, n, arg);
535bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		return 0;
545bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
555bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (n->nlmsg_type == RTM_NEWQDISC || n->nlmsg_type == RTM_DELQDISC) {
565bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		print_qdisc(who, n, arg);
575bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		return 0;
585bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
595bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (n->nlmsg_type == RTM_GETACTION || n->nlmsg_type == RTM_NEWACTION ||
605bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	    n->nlmsg_type == RTM_DELACTION) {
615bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		print_action(who, n, arg);
625bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		return 0;
635bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
645bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
655bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	    n->nlmsg_type != NLMSG_DONE) {
665bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		fprintf(fp, "Unknown message: length %08d type %08x flags %08x\n",
675bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
685bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
695bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	return 0;
705bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim}
715bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
725bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salimint do_tcmonitor(int argc, char **argv)
735bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim{
745bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	struct rtnl_handle rth;
755bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	char *file = NULL;
7632a121cba257954963fbdd56a1c4567c2efc779aStephen Hemminger	unsigned int groups = nl_mgrp(RTNLGRP_TC);
775bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
785bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	while (argc > 0) {
795bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		if (matches(*argv, "file") == 0) {
805bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			NEXT_ARG();
815bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			file = *argv;
825bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		} else {
835bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			if (matches(*argv, "help") == 0) {
845bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim				usage();
855bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			} else {
865bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim				fprintf(stderr, "Argument \"%s\" is unknown, try \"tc monitor help\".\n", *argv);
875bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim				exit(-1);
885bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			}
895bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		}
905bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		argc--;	argv++;
915bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
925bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
935bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (file) {
94e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger		FILE *fp = fopen(file, "r");
95e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger		int ret;
96e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger
975bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		if (fp == NULL) {
985bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			perror("Cannot fopen");
995bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim			exit(-1);
1005bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		}
101e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger
102e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger		ret = rtnl_from_file(fp, accept_tcmsg, stdout);
103e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger		fclose(fp);
104e49b51d6631290bf2df0efd56aa511e3387216eaStephen Hemminger		return ret;
1055bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
1065bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
1075bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	if (rtnl_open(&rth, groups) < 0)
1085bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		exit(1);
1095bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
1105bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	ll_init_map(&rth);
1115bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
11232a121cba257954963fbdd56a1c4567c2efc779aStephen Hemminger	if (rtnl_listen(&rth, accept_tcmsg, (void *)stdout) < 0) {
1135bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		rtnl_close(&rth);
1145bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim		exit(2);
1155bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	}
1165bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim
1175bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	rtnl_close(&rth);
1185bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim	exit(0);
1195bec34845bba39dfc1efb409ebc2b158a9f0fbc4Jamal Hadi Salim}
120