add packaging
[platform/upstream/libnl1.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_STOP;
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_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);
131 errout_close:
132         nl_close(nlh);
133 errout:
134         return err;
135 }