/*
 * 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 "version.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-%s\n", version);
			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);
}
