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