add packaging
[platform/upstream/libnl1.git] / src / nf-log.c
1 /*
2  * src/nf-log.c     Monitor netfilter log 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  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
11  * Copyright (c) 2007 Secure Computing Corporation
12  */
13
14 #include <sys/types.h>
15 #include <linux/netfilter/nfnetlink_log.h>
16
17 #include "utils.h"
18 #include <netlink/netfilter/nfnl.h>
19 #include <netlink/netfilter/log.h>
20
21 static void obj_input(struct nl_object *obj, void *arg)
22 {
23         struct nl_dump_params dp = {
24                 .dp_type = NL_DUMP_STATS,
25                 .dp_fd = stdout,
26                 .dp_dump_msgtype = 1,
27         };
28
29         nl_object_dump(obj, &dp);
30 }
31
32 static int event_input(struct nl_msg *msg, void *arg)
33 {
34         if (nl_msg_parse(msg, &obj_input, NULL) < 0)
35                 fprintf(stderr, "<<EVENT>> Unknown message type\n");
36
37         /* Exit nl_recvmsgs_def() and return to the main select() */
38         return NL_STOP;
39 }
40
41 int main(int argc, char *argv[])
42 {
43         struct nl_handle *nfnlh;
44         struct nl_handle *rtnlh;
45         struct nl_cache *link_cache;
46         int err = 1;
47         int family, group;
48
49         if (nltool_init(argc, argv) < 0)
50                 return -1;
51
52         nfnlh = nltool_alloc_handle();
53         if (nfnlh == NULL)
54                 return -1;
55
56         nl_disable_sequence_check(nfnlh);
57
58         nl_socket_modify_cb(nfnlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
59
60         if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
61                 printf("Usage: nf-log family group\n");
62                 return 2;
63         }
64
65         if (nfnl_connect(nfnlh) < 0) {
66                 fprintf(stderr, "%s\n", nl_geterror());
67                 goto errout;
68         }
69
70         family = nl_str2af(argv[1]);
71         if (family == AF_UNSPEC) {
72                 fprintf(stderr, "Unknown family: %s\n", argv[1]);
73                 goto errout;
74         }
75         if (nfnl_log_pf_unbind(nfnlh, family) < 0) {
76                 fprintf(stderr, "%s\n", nl_geterror());
77                 goto errout;
78         }
79         if (nfnl_log_pf_bind(nfnlh, family) < 0) {
80                 fprintf(stderr, "%s\n", nl_geterror());
81                 goto errout;
82         }
83
84         group = nl_str2af(argv[2]);
85         if (nfnl_log_bind(nfnlh, group) < 0) {
86                 fprintf(stderr, "%s\n", nl_geterror());
87                 goto errout;
88         }
89
90         if (nfnl_log_set_mode(nfnlh, 0, NFULNL_COPY_PACKET, 0xffff) < 0) {
91                 fprintf(stderr, "%s\n", nl_geterror());
92                 goto errout;
93         }
94
95         rtnlh = nltool_alloc_handle();
96         if (rtnlh == NULL) {
97                 goto errout_close;
98         }
99
100         if (nl_connect(rtnlh, NETLINK_ROUTE) < 0) {
101                 fprintf(stderr, "%s\n", nl_geterror());
102                 goto errout;
103         }
104
105         if ((link_cache = rtnl_link_alloc_cache(rtnlh)) == NULL) {
106                 fprintf(stderr, "%s\n", nl_geterror());
107                 goto errout_close;
108         }
109
110         nl_cache_mngt_provide(link_cache);
111
112         while (1) {
113                 fd_set rfds;
114                 int nffd, rtfd, maxfd, retval;
115
116                 FD_ZERO(&rfds);
117
118                 maxfd = nffd = nl_socket_get_fd(nfnlh);
119                 FD_SET(nffd, &rfds);
120
121                 rtfd = nl_socket_get_fd(rtnlh);
122                 FD_SET(rtfd, &rfds);
123                 if (maxfd < rtfd)
124                         maxfd = rtfd;
125
126                 /* wait for an incoming message on the netlink socket */
127                 retval = select(maxfd+1, &rfds, NULL, NULL, NULL);
128
129                 if (retval) {
130                         if (FD_ISSET(nffd, &rfds))
131                                 nl_recvmsgs_default(nfnlh);
132                         if (FD_ISSET(rtfd, &rfds))
133                                 nl_recvmsgs_default(rtnlh);
134                 }
135         }
136
137         nl_close(rtnlh);
138 errout_close:
139         nl_close(nfnlh);
140 errout:
141         return err;
142 }