oops
[libnl.git] / src / nl-monitor.c
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
16 static 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
27 static 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_EXIT;
34 }
35
36 int 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_FIB_MAGIC, "fib-magic" },
62                 { RTNLGRP_NONE, NULL }
63         };
64
65         if (nltool_init(argc, argv) < 0)
66                 return -1;
67
68         nlh = nl_handle_alloc_nondefault(nltool_cbset);
69         if (nlh == NULL)
70                 return -1;
71
72         nl_disable_sequence_check(nlh);
73
74         nl_cb_set(nl_handle_get_cb(nlh), NL_CB_VALID, NL_CB_CUSTOM,
75                   event_input, NULL);
76
77         if (argc > 1 && !strcasecmp(argv[1], "-h")) {
78                 printf("Usage: nl-monitor [<groups>]\n");
79
80                 printf("Known groups:");
81                 for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++)
82                         printf(" %s", known_groups[i].gr_name);
83                 printf("\n");
84                 return 2;
85         }
86
87         nl_join_groups(nlh, RTMGRP_LINK);
88
89         if (nl_connect(nlh, NETLINK_ROUTE) < 0) {
90                 fprintf(stderr, "%s\n", nl_geterror());
91                 goto errout;
92         }
93
94         for (idx = 1; argc > idx; idx++) {
95                 for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) {
96                         if (!strcmp(argv[idx], known_groups[i].gr_name)) {
97
98                                 if (nl_join_group(nlh, known_groups[i].gr_id) < 0) {
99                                         fprintf(stderr, "%s: %s\n", argv[idx], nl_geterror());
100                                         goto errout;
101                                 }
102
103                                 break;
104                         }
105                 }
106                 if (known_groups[i].gr_id == RTNLGRP_NONE)
107                         fprintf(stderr, "Warning: Unknown group: %s\n", argv[idx]);
108         }
109
110         if ((link_cache = rtnl_link_alloc_cache(nlh)) == NULL) {
111                 fprintf(stderr, "%s\n", nl_geterror());
112                 goto errout_close;
113         }
114
115         nl_cache_mngt_provide(link_cache);
116
117         while (1) {
118                 fd_set rfds;
119                 int fd, retval;
120
121                 fd = nl_handle_get_fd(nlh);
122
123                 FD_ZERO(&rfds);
124                 FD_SET(fd, &rfds);
125                 /* wait for an incoming message on the netlink socket */
126                 retval = select(fd+1, &rfds, NULL, NULL, NULL);
127
128                 if (retval) {
129                         /* FD_ISSET(fd, &rfds) will be true */
130                         nl_recvmsgs_def(nlh);
131                 }
132         }
133
134         nl_cache_free(link_cache);
135 errout_close:
136         nl_close(nlh);
137 errout:
138         return err;
139 }