rtmon.c revision ae665a522bd46bea44c5ea84c89c8b1731954170
1aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger/* 2aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger * rtmon.c RTnetlink listener. 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 <sys/time.h> 20aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <net/if.h> 21aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <netinet/in.h> 22aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include <string.h> 23aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 24aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "SNAPSHOT.h" 25aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 26aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "utils.h" 27aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger#include "libnetlink.h" 28aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 29aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint resolve_hosts = 0; 30aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic int init_phase = 1; 31aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 32aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerstatic void write_stamp(FILE *fp) 33aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 34aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char buf[128]; 35aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct nlmsghdr *n1 = (void*)buf; 36aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct timeval tv; 37aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 38aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n1->nlmsg_type = 15; 39aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n1->nlmsg_flags = 0; 40aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n1->nlmsg_seq = 0; 41aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n1->nlmsg_pid = 0; 42aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger n1->nlmsg_len = NLMSG_LENGTH(4*2); 43aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger gettimeofday(&tv, NULL); 44aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ((__u32*)NLMSG_DATA(n1))[0] = tv.tv_sec; 45aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger ((__u32*)NLMSG_DATA(n1))[1] = tv.tv_usec; 46aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fwrite((void*)n1, 1, NLMSG_ALIGN(n1->nlmsg_len), fp); 47aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 48aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 49ae665a522bd46bea44c5ea84c89c8b1731954170Stephen Hemmingerstatic int dump_msg(const struct sockaddr_nl *who, struct nlmsghdr *n, 506dc9f016347441fbf94cf851c054b0f45ba32c1cosdl.net!shemminger void *arg) 51aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 52aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp = (FILE*)arg; 53aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!init_phase) 54aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger write_stamp(fp); 55aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fwrite((void*)n, 1, NLMSG_ALIGN(n->nlmsg_len), fp); 56aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fflush(fp); 57aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 0; 58aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 59aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 60aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingervoid usage(void) 61aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 62aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Usage: rtmon file FILE [ all | LISTofOBJECTS]\n"); 63aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "LISTofOBJECTS := [ link ] [ address ] [ route ]\n"); 64aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 65aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 66aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 67aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingerint 68aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemmingermain(int argc, char **argv) 69aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger{ 70aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger FILE *fp; 71aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger struct rtnl_handle rth; 72aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int family = AF_UNSPEC; 73aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger unsigned groups = ~0U; 74aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int llink = 0; 75aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int laddr = 0; 76aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger int lroute = 0; 77aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger char *file = NULL; 78aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 79aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger while (argc > 1) { 80aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (matches(argv[1], "-family") == 0) { 81aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; 82aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argv++; 83aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc <= 1) 84aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 85aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (strcmp(argv[1], "inet") == 0) 86aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger family = AF_INET; 87aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(argv[1], "inet6") == 0) 88aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger family = AF_INET6; 89aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(argv[1], "link") == 0) 90aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger family = AF_INET6; 91aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else if (strcmp(argv[1], "help") == 0) 92aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 93aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger else { 94aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Protocol ID \"%s\" is unknown, try \"rtmon help\".\n", argv[1]); 95aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 96aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 97aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(argv[1], "-4") == 0) { 98aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger family = AF_INET; 99aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(argv[1], "-6") == 0) { 100aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger family = AF_INET6; 101aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(argv[1], "-0") == 0) { 102aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger family = AF_PACKET; 103aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(argv[1], "-Version") == 0) { 104aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger printf("rtmon utility, iproute2-ss%s\n", SNAPSHOT); 105aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(0); 106aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(argv[1], "file") == 0) { 107aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; 108aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argv++; 109aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (argc <= 1) 110aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 111aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger file = argv[1]; 112aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(argv[1], "link") == 0) { 113aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger llink=1; 114aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups = 0; 115aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(argv[1], "address") == 0) { 116aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger laddr=1; 117aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups = 0; 118aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(argv[1], "route") == 0) { 119aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger lroute=1; 120aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups = 0; 121aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (strcmp(argv[1], "all") == 0) { 122aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups = ~0U; 123aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else if (matches(argv[1], "help") == 0) { 124aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger usage(); 125aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } else { 126aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Argument \"%s\" is unknown, try \"rtmon help\".\n", argv[1]); 127aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 128aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 129aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger argc--; argv++; 130aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 131aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 132aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (file == NULL) { 133aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Not enough information: argument \"file\" is required\n"); 134aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 135aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 136aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (llink) 137aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups |= RTMGRP_LINK; 138aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (laddr) { 139aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!family || family == AF_INET) 140aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups |= RTMGRP_IPV4_IFADDR; 141aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!family || family == AF_INET6) 142aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups |= RTMGRP_IPV6_IFADDR; 143aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 144aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (lroute) { 145aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!family || family == AF_INET) 146aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups |= RTMGRP_IPV4_ROUTE; 147aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (!family || family == AF_INET6) 148aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger groups |= RTMGRP_IPV6_ROUTE; 149aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 150aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 151aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fp = fopen(file, "w"); 152aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (fp == NULL) { 153aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot fopen"); 154aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(-1); 155aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 156aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 157aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_open(&rth, groups) < 0) 158aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 159aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 160aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_wilddump_request(&rth, AF_UNSPEC, RTM_GETLINK) < 0) { 161aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger perror("Cannot send dump request"); 162aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(1); 163aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 164aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 165aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger write_stamp(fp); 166aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 167aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_dump_filter(&rth, dump_msg, fp, NULL, NULL) < 0) { 168aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger fprintf(stderr, "Dump terminated\n"); 169aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger return 1; 170aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger } 171aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 172aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger init_phase = 0; 173aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 174aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger if (rtnl_listen(&rth, dump_msg, (void*)fp) < 0) 175aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(2); 176aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger 177aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger exit(0); 178aba5acdfdb347d2c21fc67d613d83d4430ca3937osdl.org!shemminger} 179