1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/*
2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * ipmonitor.c		"ip monitor".
3aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
4aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		This program is free software; you can redistribute it and/or
5aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		modify it under the terms of the GNU General Public License
6aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		as published by the Free Software Foundation; either version
7aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *		2 of the License, or (at your option) any later version.
8aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
9aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger *
11aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger */
12aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
13aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdio.h>
14aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <stdlib.h>
15aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <unistd.h>
16aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <syslog.h>
17aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <fcntl.h>
18aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <sys/socket.h>
19aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h>
20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <arpa/inet.h>
21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h>
22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <time.h>
23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h"
25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "ip_common.h"
26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void) __attribute__((noreturn));
284b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohanint prefix_banner;
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void)
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: ip monitor [ all | LISTofOBJECTS ]\n");
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
376dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemmingerint accept_msg(const struct sockaddr_nl *who,
3850772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemminger	       struct nlmsghdr *n, void *arg)
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = (FILE*)arg;
41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
4290f93024a0818dc691138d8401721e797004b042shemminger	if (timestamp)
4390f93024a0818dc691138d8401721e797004b042shemminger		print_timestamp(fp);
4490f93024a0818dc691138d8401721e797004b042shemminger
45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWROUTE || n->nlmsg_type == RTM_DELROUTE) {
464b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
474b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[ROUTE]");
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_route(who, n, arg);
49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) {
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ll_remember_index(who, n, NULL);
534b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
544b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[LINK]");
55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_linkinfo(who, n, arg);
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
594b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
604b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[ADDR]");
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_addrinfo(who, n, arg);
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
644759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明	if (n->nlmsg_type == RTM_NEWADDRLABEL || n->nlmsg_type == RTM_DELADDRLABEL) {
654b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
664b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[ADDRLABEL]");
674759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明		print_addrlabel(who, n, arg);
684759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明		return 0;
694759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明	}
70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH) {
714b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
724b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[NEIGH]");
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_neigh(who, n, arg);
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
761cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (n->nlmsg_type == RTM_NEWPREFIX) {
774b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
784b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[PREFIX]");
791cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		print_prefix(who, n, arg);
801cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return 0;
811cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
8298bde989db679153ee7a5f6425037b5a002eb95dThomas Graf	if (n->nlmsg_type == RTM_NEWRULE || n->nlmsg_type == RTM_DELRULE) {
834b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan		if (prefix_banner)
844b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			fprintf(fp, "[RULE]");
8598bde989db679153ee7a5f6425037b5a002eb95dThomas Graf		print_rule(who, n, arg);
8698bde989db679153ee7a5f6425037b5a002eb95dThomas Graf		return 0;
8798bde989db679153ee7a5f6425037b5a002eb95dThomas Graf	}
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == 15) {
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char *tstr;
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		time_t secs = ((__u32*)NLMSG_DATA(n))[0];
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		long usecs = ((__u32*)NLMSG_DATA(n))[1];
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		tstr = asctime(localtime(&secs));
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		tstr[strlen(tstr)-1] = 0;
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWQDISC ||
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_DELQDISC ||
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_NEWTCLASS ||
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_DELTCLASS ||
101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_NEWTFILTER ||
102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_DELTFILTER)
103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type != NLMSG_DONE) {
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(fp, "Unknown message: %08x %08x %08x\n",
107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_ipmonitor(int argc, char **argv)
113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *file = NULL;
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned groups = ~RTMGRP_TC;
116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int llink=0;
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int laddr=0;
118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int lroute=0;
1191cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	int lprefix=0;
120fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan	int lneigh=0;
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
122fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger	rtnl_close(&rth);
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ipaddr_reset_filter(1);
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	iproute_reset_filter();
125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ipneigh_reset_filter();
126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "file") == 0) {
129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			file = *argv;
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "link") == 0) {
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			llink=1;
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = 0;
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "address") == 0) {
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			laddr=1;
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = 0;
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "route") == 0) {
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			lroute=1;
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = 0;
1401cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		} else if (matches(*argv, "prefix") == 0) {
1411cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger			lprefix=1;
1421cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger			groups = 0;
143fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan		} else if (matches(*argv, "neigh") == 0) {
1446cdbf3706350c4d724ea8d35267ae93a4d99eab0Andreas Henriksson			lneigh = 1;
1456cdbf3706350c4d724ea8d35267ae93a4d99eab0Andreas Henriksson			groups = 0;
146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "all") == 0) {
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = ~RTMGRP_TC;
1484b6e07d8fde629073a512bf0cb86956c1d55145eVarun Chandramohan			prefix_banner=1;
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "help") == 0) {
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Argument \"%s\" is unknown, try \"ip monitor help\".\n", *argv);
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--;	argv++;
156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (llink)
159b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal		groups |= nl_mgrp(RTNLGRP_LINK);
160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (laddr) {
161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET)
162b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV4_IFADDR);
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET6)
164b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV6_IFADDR);
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (lroute) {
167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET)
168b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV4_ROUTE);
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET6)
170b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV6_ROUTE);
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
1721cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (lprefix) {
1731cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		if (!preferred_family || preferred_family == AF_INET6)
174b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV6_PREFIX);
1751cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
176fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan	if (lneigh) {
177fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan		groups |= nl_mgrp(RTNLGRP_NEIGH);
178fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan	}
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (file) {
180aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		FILE *fp;
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fp = fopen(file, "r");
182aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fp == NULL) {
183aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("Cannot fopen");
184aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
185aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
186fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger		return rtnl_from_file(fp, accept_msg, stdout);
187aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
188aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
189fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger	if (rtnl_open(&rth, groups) < 0)
190fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger		exit(1);
191aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ll_init_map(&rth);
192aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
193fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger	if (rtnl_listen(&rth, accept_msg, stdout) < 0)
194aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(2);
195aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
196351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	return 0;
197aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
198