nl-monitor.c revision 44d362409d5469aed47d19e7908d19bd194493a4
1/* 2 * src/nl-monitor.c Monitor events 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> 10 */ 11 12#include "utils.h" 13#include <netlink/route/link.h> 14#include <netlink/route/addr.h> 15 16static void obj_input(struct nl_object *obj, void *arg) 17{ 18 struct nl_dump_params dp = { 19 .dp_type = NL_DUMP_STATS, 20 .dp_fd = stdout, 21 .dp_dump_msgtype = 1, 22 }; 23 24 nl_object_dump(obj, &dp); 25} 26 27static int event_input(struct nl_msg *msg, void *arg) 28{ 29 if (nl_msg_parse(msg, &obj_input, NULL) < 0) 30 fprintf(stderr, "<<EVENT>> Unknown message type\n"); 31 32 /* Exit nl_recvmsgs_def() and return to the main select() */ 33 return NL_STOP; 34} 35 36int main(int argc, char *argv[]) 37{ 38 struct nl_handle *nlh; 39 struct nl_cache *link_cache; 40 int err = 1; 41 int i, idx; 42 43 static const struct { 44 enum rtnetlink_groups gr_id; 45 const char* gr_name; 46 } known_groups[] = { 47 { RTNLGRP_LINK, "link" }, 48 { RTNLGRP_NOTIFY, "notify" }, 49 { RTNLGRP_NEIGH, "neigh" }, 50 { RTNLGRP_TC, "tc" }, 51 { RTNLGRP_IPV4_IFADDR, "ipv4-ifaddr" }, 52 { RTNLGRP_IPV4_MROUTE, "ipv4-mroute" }, 53 { RTNLGRP_IPV4_ROUTE, "ipv4-route" }, 54 { RTNLGRP_IPV6_IFADDR, "ipv6-ifaddr" }, 55 { RTNLGRP_IPV6_MROUTE, "ipv6-mroute" }, 56 { RTNLGRP_IPV6_ROUTE, "ipv6-route" }, 57 { RTNLGRP_IPV6_IFINFO, "ipv6-ifinfo" }, 58 { RTNLGRP_DECnet_IFADDR, "decnet-ifaddr" }, 59 { RTNLGRP_DECnet_ROUTE, "decnet-route" }, 60 { RTNLGRP_IPV6_PREFIX, "ipv6-prefix" }, 61 { RTNLGRP_NONE, NULL } 62 }; 63 64 if (nltool_init(argc, argv) < 0) 65 return -1; 66 67 nlh = nltool_alloc_handle(); 68 if (nlh == NULL) 69 return -1; 70 71 nl_disable_sequence_check(nlh); 72 73 nl_socket_modify_cb(nlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); 74 75 if (argc > 1 && !strcasecmp(argv[1], "-h")) { 76 printf("Usage: nl-monitor [<groups>]\n"); 77 78 printf("Known groups:"); 79 for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) 80 printf(" %s", known_groups[i].gr_name); 81 printf("\n"); 82 return 2; 83 } 84 85 if (nl_connect(nlh, NETLINK_ROUTE) < 0) { 86 fprintf(stderr, "%s\n", nl_geterror()); 87 goto errout; 88 } 89 90 for (idx = 1; argc > idx; idx++) { 91 for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) { 92 if (!strcmp(argv[idx], known_groups[i].gr_name)) { 93 94 if (nl_socket_add_membership(nlh, known_groups[i].gr_id) < 0) { 95 fprintf(stderr, "%s: %s\n", argv[idx], nl_geterror()); 96 goto errout; 97 } 98 99 break; 100 } 101 } 102 if (known_groups[i].gr_id == RTNLGRP_NONE) 103 fprintf(stderr, "Warning: Unknown group: %s\n", argv[idx]); 104 } 105 106 if ((link_cache = rtnl_link_alloc_cache(nlh)) == NULL) { 107 fprintf(stderr, "%s\n", nl_geterror()); 108 goto errout_close; 109 } 110 111 nl_cache_mngt_provide(link_cache); 112 113 while (1) { 114 fd_set rfds; 115 int fd, retval; 116 117 fd = nl_socket_get_fd(nlh); 118 119 FD_ZERO(&rfds); 120 FD_SET(fd, &rfds); 121 /* wait for an incoming message on the netlink socket */ 122 retval = select(fd+1, &rfds, NULL, NULL, NULL); 123 124 if (retval) { 125 /* FD_ISSET(fd, &rfds) will be true */ 126 nl_recvmsgs_default(nlh); 127 } 128 } 129 130 nl_cache_free(link_cache); 131errout_close: 132 nl_close(nlh); 133errout: 134 return err; 135} 136