ipmonitor.c revision fb063322b4339507157b5030978b5aeb7342e68b
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));
28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void usage(void)
30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	fprintf(stderr, "Usage: ip monitor [ all | LISTofOBJECTS ]\n");
32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	exit(-1);
33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
366dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemmingerint accept_msg(const struct sockaddr_nl *who,
3750772dc51ac02239958e1ebcdb21277fcdf133a7osdl.net!shemminger	       struct nlmsghdr *n, void *arg)
38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	FILE *fp = (FILE*)arg;
40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
4190f93024a0818dc691138d8401721e797004b042shemminger	if (timestamp)
4290f93024a0818dc691138d8401721e797004b042shemminger		print_timestamp(fp);
4390f93024a0818dc691138d8401721e797004b042shemminger
44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWROUTE || n->nlmsg_type == RTM_DELROUTE) {
45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_route(who, n, arg);
46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWLINK || n->nlmsg_type == RTM_DELLINK) {
49aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		ll_remember_index(who, n, NULL);
50aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_linkinfo(who, n, arg);
51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWADDR || n->nlmsg_type == RTM_DELADDR) {
54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_addrinfo(who, n, arg);
55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
574759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明	if (n->nlmsg_type == RTM_NEWADDRLABEL || n->nlmsg_type == RTM_DELADDRLABEL) {
584759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明		print_addrlabel(who, n, arg);
594759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明		return 0;
604759758c05b3bda53b743a1c3238f1479bb61b43YOSHIFUJI Hideaki / 吉藤英明	}
61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWNEIGH || n->nlmsg_type == RTM_DELNEIGH) {
62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		print_neigh(who, n, arg);
63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
651cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (n->nlmsg_type == RTM_NEWPREFIX) {
661cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		print_prefix(who, n, arg);
671cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		return 0;
681cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
6998bde989db679153ee7a5f6425037b5a002eb95dThomas Graf	if (n->nlmsg_type == RTM_NEWRULE || n->nlmsg_type == RTM_DELRULE) {
7098bde989db679153ee7a5f6425037b5a002eb95dThomas Graf		print_rule(who, n, arg);
7198bde989db679153ee7a5f6425037b5a002eb95dThomas Graf		return 0;
7298bde989db679153ee7a5f6425037b5a002eb95dThomas Graf	}
73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == 15) {
74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		char *tstr;
75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		time_t secs = ((__u32*)NLMSG_DATA(n))[0];
76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		long usecs = ((__u32*)NLMSG_DATA(n))[1];
77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		tstr = asctime(localtime(&secs));
78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		tstr[strlen(tstr)-1] = 0;
79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(fp, "Timestamp: %s %lu us\n", tstr, usecs);
80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type == RTM_NEWQDISC ||
83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_DELQDISC ||
84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_NEWTCLASS ||
85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_DELTCLASS ||
86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_NEWTFILTER ||
87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type == RTM_DELTFILTER)
88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		return 0;
89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (n->nlmsg_type != NLMSG_ERROR && n->nlmsg_type != NLMSG_NOOP &&
90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	    n->nlmsg_type != NLMSG_DONE) {
91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fprintf(fp, "Unknown message: %08x %08x %08x\n",
92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	return 0;
95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint do_ipmonitor(int argc, char **argv)
98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{
99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	char *file = NULL;
100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	unsigned groups = ~RTMGRP_TC;
101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int llink=0;
102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int laddr=0;
103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	int lroute=0;
1041cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	int lprefix=0;
105fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan	int lneigh=0;
106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
107fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger	rtnl_close(&rth);
108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ipaddr_reset_filter(1);
109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	iproute_reset_filter();
110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ipneigh_reset_filter();
111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	while (argc > 0) {
113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (matches(*argv, "file") == 0) {
114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			NEXT_ARG();
115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			file = *argv;
116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "link") == 0) {
117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			llink=1;
118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = 0;
119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "address") == 0) {
120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			laddr=1;
121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = 0;
122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "route") == 0) {
123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			lroute=1;
124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = 0;
1251cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		} else if (matches(*argv, "prefix") == 0) {
1261cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger			lprefix=1;
1271cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger			groups = 0;
128fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan		} else if (matches(*argv, "neigh") == 0) {
129fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan			lneigh=1;
130fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan			groups = 0;
131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (strcmp(*argv, "all") == 0) {
132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			groups = ~RTMGRP_TC;
133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else if (matches(*argv, "help") == 0) {
134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			usage();
135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		} else {
136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			fprintf(stderr, "Argument \"%s\" is unknown, try \"ip monitor help\".\n", *argv);
137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		argc--;	argv++;
140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (llink)
143b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal		groups |= nl_mgrp(RTNLGRP_LINK);
144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (laddr) {
145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET)
146b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV4_IFADDR);
147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET6)
148b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV6_IFADDR);
149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (lroute) {
151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET)
152b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV4_ROUTE);
153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (!preferred_family || preferred_family == AF_INET6)
154b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV6_ROUTE);
155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
1561cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	if (lprefix) {
1571cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger		if (!preferred_family || preferred_family == AF_INET6)
158b64f58b01354a1cfdc56f9617aabc9997f9fb01ejamal			groups |= nl_mgrp(RTNLGRP_IPV6_PREFIX);
1591cb54e58069fb413bd20738754b4e49f0403da0cnet[shemminger]!shemminger	}
160fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan	if (lneigh) {
161fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan		groups |= nl_mgrp(RTNLGRP_NEIGH);
162fb063322b4339507157b5030978b5aeb7342e68bVarun Chandramohan	}
163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	if (file) {
164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		FILE *fp;
165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		fp = fopen(file, "r");
166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		if (fp == NULL) {
167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			perror("Cannot fopen");
168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger			exit(-1);
169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		}
170fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger		return rtnl_from_file(fp, accept_msg, stdout);
171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	}
172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
173fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger	if (rtnl_open(&rth, groups) < 0)
174fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger		exit(1);
175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger	ll_init_map(&rth);
176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
177fc57a9df1bee719c86a4f0bc82bafae05bb92fc2shemminger	if (rtnl_listen(&rth, accept_msg, stdout) < 0)
178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger		exit(2);
179aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger
180351efcde4e62967362a10b29f3b701cfecd7cdfcshemminger	return 0;
181aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger}
182