144d362409d5469aed47d19e7908d19bd194493aThomas Graf/* 244d362409d5469aed47d19e7908d19bd194493aThomas Graf * src/nl-monitor.c Monitor events 344d362409d5469aed47d19e7908d19bd194493aThomas Graf * 444d362409d5469aed47d19e7908d19bd194493aThomas Graf * This library is free software; you can redistribute it and/or 544d362409d5469aed47d19e7908d19bd194493aThomas Graf * modify it under the terms of the GNU Lesser General Public 644d362409d5469aed47d19e7908d19bd194493aThomas Graf * License as published by the Free Software Foundation version 2.1 744d362409d5469aed47d19e7908d19bd194493aThomas Graf * of the License. 844d362409d5469aed47d19e7908d19bd194493aThomas Graf * 98808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch> 1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */ 1144d362409d5469aed47d19e7908d19bd194493aThomas Graf 128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/utils.h> 138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/link.h> 1444d362409d5469aed47d19e7908d19bd194493aThomas Graf 1544d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void obj_input(struct nl_object *obj, void *arg) 1644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 1744d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_dump_params dp = { 1844d362409d5469aed47d19e7908d19bd194493aThomas Graf .dp_type = NL_DUMP_STATS, 1944d362409d5469aed47d19e7908d19bd194493aThomas Graf .dp_fd = stdout, 2044d362409d5469aed47d19e7908d19bd194493aThomas Graf .dp_dump_msgtype = 1, 2144d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 2244d362409d5469aed47d19e7908d19bd194493aThomas Graf 2344d362409d5469aed47d19e7908d19bd194493aThomas Graf nl_object_dump(obj, &dp); 2444d362409d5469aed47d19e7908d19bd194493aThomas Graf} 2544d362409d5469aed47d19e7908d19bd194493aThomas Graf 2644d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic int event_input(struct nl_msg *msg, void *arg) 2744d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 2844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (nl_msg_parse(msg, &obj_input, NULL) < 0) 2944d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "<<EVENT>> Unknown message type\n"); 3044d362409d5469aed47d19e7908d19bd194493aThomas Graf 3144d362409d5469aed47d19e7908d19bd194493aThomas Graf /* Exit nl_recvmsgs_def() and return to the main select() */ 3244d362409d5469aed47d19e7908d19bd194493aThomas Graf return NL_STOP; 3344d362409d5469aed47d19e7908d19bd194493aThomas Graf} 3444d362409d5469aed47d19e7908d19bd194493aThomas Graf 3544d362409d5469aed47d19e7908d19bd194493aThomas Grafint main(int argc, char *argv[]) 3644d362409d5469aed47d19e7908d19bd194493aThomas Graf{ 3710cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf struct nl_sock *sock; 3844d362409d5469aed47d19e7908d19bd194493aThomas Graf struct nl_cache *link_cache; 3944d362409d5469aed47d19e7908d19bd194493aThomas Graf int err = 1; 4044d362409d5469aed47d19e7908d19bd194493aThomas Graf int i, idx; 4144d362409d5469aed47d19e7908d19bd194493aThomas Graf 4244d362409d5469aed47d19e7908d19bd194493aThomas Graf static const struct { 4344d362409d5469aed47d19e7908d19bd194493aThomas Graf enum rtnetlink_groups gr_id; 4444d362409d5469aed47d19e7908d19bd194493aThomas Graf const char* gr_name; 4544d362409d5469aed47d19e7908d19bd194493aThomas Graf } known_groups[] = { 4644d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_LINK, "link" }, 4744d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_NOTIFY, "notify" }, 4844d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_NEIGH, "neigh" }, 4944d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_TC, "tc" }, 5044d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV4_IFADDR, "ipv4-ifaddr" }, 5144d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV4_MROUTE, "ipv4-mroute" }, 5244d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV4_ROUTE, "ipv4-route" }, 5344d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV6_IFADDR, "ipv6-ifaddr" }, 5444d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV6_MROUTE, "ipv6-mroute" }, 5544d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV6_ROUTE, "ipv6-route" }, 5644d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV6_IFINFO, "ipv6-ifinfo" }, 5744d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_DECnet_IFADDR, "decnet-ifaddr" }, 5844d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_DECnet_ROUTE, "decnet-route" }, 5944d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_IPV6_PREFIX, "ipv6-prefix" }, 6044d362409d5469aed47d19e7908d19bd194493aThomas Graf { RTNLGRP_NONE, NULL } 6144d362409d5469aed47d19e7908d19bd194493aThomas Graf }; 6244d362409d5469aed47d19e7908d19bd194493aThomas Graf 638808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf sock = nl_cli_alloc_socket(); 64f9071054d0f2512dea9e95f99c308e931ed78dbaPatrick McHardy nl_socket_disable_seq_check(sock); 6510cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL); 6644d362409d5469aed47d19e7908d19bd194493aThomas Graf 6744d362409d5469aed47d19e7908d19bd194493aThomas Graf if (argc > 1 && !strcasecmp(argv[1], "-h")) { 6844d362409d5469aed47d19e7908d19bd194493aThomas Graf printf("Usage: nl-monitor [<groups>]\n"); 6944d362409d5469aed47d19e7908d19bd194493aThomas Graf 7044d362409d5469aed47d19e7908d19bd194493aThomas Graf printf("Known groups:"); 7144d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) 7244d362409d5469aed47d19e7908d19bd194493aThomas Graf printf(" %s", known_groups[i].gr_name); 7344d362409d5469aed47d19e7908d19bd194493aThomas Graf printf("\n"); 7444d362409d5469aed47d19e7908d19bd194493aThomas Graf return 2; 7544d362409d5469aed47d19e7908d19bd194493aThomas Graf } 7644d362409d5469aed47d19e7908d19bd194493aThomas Graf 778808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_connect(sock, NETLINK_ROUTE); 7844d362409d5469aed47d19e7908d19bd194493aThomas Graf 7944d362409d5469aed47d19e7908d19bd194493aThomas Graf for (idx = 1; argc > idx; idx++) { 8044d362409d5469aed47d19e7908d19bd194493aThomas Graf for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) { 8144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (!strcmp(argv[idx], known_groups[i].gr_name)) { 8244d362409d5469aed47d19e7908d19bd194493aThomas Graf 8310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf if ((err = nl_socket_add_membership(sock, known_groups[i].gr_id)) < 0) { 848808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_cli_fatal(err, "%s: %s\n", argv[idx], 858808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf nl_geterror(err)); 8644d362409d5469aed47d19e7908d19bd194493aThomas Graf } 8744d362409d5469aed47d19e7908d19bd194493aThomas Graf 8844d362409d5469aed47d19e7908d19bd194493aThomas Graf break; 8944d362409d5469aed47d19e7908d19bd194493aThomas Graf } 9044d362409d5469aed47d19e7908d19bd194493aThomas Graf } 9144d362409d5469aed47d19e7908d19bd194493aThomas Graf if (known_groups[i].gr_id == RTNLGRP_NONE) 9244d362409d5469aed47d19e7908d19bd194493aThomas Graf fprintf(stderr, "Warning: Unknown group: %s\n", argv[idx]); 9344d362409d5469aed47d19e7908d19bd194493aThomas Graf } 9444d362409d5469aed47d19e7908d19bd194493aThomas Graf 958808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf link_cache = nl_cli_link_alloc_cache(sock); 9644d362409d5469aed47d19e7908d19bd194493aThomas Graf 9744d362409d5469aed47d19e7908d19bd194493aThomas Graf while (1) { 9844d362409d5469aed47d19e7908d19bd194493aThomas Graf fd_set rfds; 9944d362409d5469aed47d19e7908d19bd194493aThomas Graf int fd, retval; 10044d362409d5469aed47d19e7908d19bd194493aThomas Graf 10110cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf fd = nl_socket_get_fd(sock); 10244d362409d5469aed47d19e7908d19bd194493aThomas Graf 10344d362409d5469aed47d19e7908d19bd194493aThomas Graf FD_ZERO(&rfds); 10444d362409d5469aed47d19e7908d19bd194493aThomas Graf FD_SET(fd, &rfds); 10544d362409d5469aed47d19e7908d19bd194493aThomas Graf /* wait for an incoming message on the netlink socket */ 10644d362409d5469aed47d19e7908d19bd194493aThomas Graf retval = select(fd+1, &rfds, NULL, NULL, NULL); 10744d362409d5469aed47d19e7908d19bd194493aThomas Graf 10844d362409d5469aed47d19e7908d19bd194493aThomas Graf if (retval) { 10944d362409d5469aed47d19e7908d19bd194493aThomas Graf /* FD_ISSET(fd, &rfds) will be true */ 11010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf nl_recvmsgs_default(sock); 11144d362409d5469aed47d19e7908d19bd194493aThomas Graf } 11244d362409d5469aed47d19e7908d19bd194493aThomas Graf } 11344d362409d5469aed47d19e7908d19bd194493aThomas Graf 11410cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf return 0; 11544d362409d5469aed47d19e7908d19bd194493aThomas Graf} 116