xref: /aosp_15_r20/external/libnl/src/nf-monitor.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2003-2008 Thomas Graf <[email protected]>
4  * Copyright (c) 2007 Philip Craig <[email protected]>
5  * Copyright (c) 2007 Secure Computing Corporation
6  */
7 
8 #include "nl-default.h"
9 
10 #include <linux/netlink.h>
11 #include <linux/netfilter/nfnetlink.h>
12 
13 #include <netlink/cli/utils.h>
14 #include <netlink/netfilter/nfnl.h>
15 
obj_input(struct nl_object * obj,void * arg)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 
event_input(struct nl_msg * msg,void * arg)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 
main(int argc,char * argv[])36 int main(int argc, char *argv[])
37 {
38 	struct nl_sock *sock;
39 	int err;
40 	int i, idx;
41 
42 	static const struct {
43 		enum nfnetlink_groups gr_id;
44 		const char* gr_name;
45 	} groups[] = {
46 		{ NFNLGRP_CONNTRACK_NEW, "ct-new" },
47 		{ NFNLGRP_CONNTRACK_UPDATE, "ct-update" },
48 		{ NFNLGRP_CONNTRACK_DESTROY, "ct-destroy" },
49 		{ NFNLGRP_NONE, NULL }
50 	};
51 
52 	sock = nl_cli_alloc_socket();
53 	nl_socket_disable_seq_check(sock);
54 	nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
55 
56 	if (argc > 1 && !strcasecmp(argv[1], "-h")) {
57 		printf("Usage: nf-monitor [<groups>]\n");
58 
59 		printf("Known groups:");
60 		for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++)
61 			printf(" %s", groups[i].gr_name);
62 		printf("\n");
63 		return 2;
64 	}
65 
66 	nl_cli_connect(sock, NETLINK_NETFILTER);
67 
68 	for (idx = 1; argc > idx; idx++) {
69 		for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) {
70 			if (strcmp(argv[idx], groups[i].gr_name))
71 				continue;
72 
73 			err = nl_socket_add_membership(sock, groups[i].gr_id);
74 			if (err < 0)
75 				nl_cli_fatal(err,
76 					     "Unable to add membership: %s",
77 					     nl_geterror(err));
78 			break;
79 		}
80 
81 		if (groups[i].gr_id == NFNLGRP_NONE)
82 			nl_cli_fatal(NLE_OBJ_NOTFOUND, "Unknown group: \"%s\"",
83 				     argv[idx]);
84 	}
85 
86 	while (1) {
87 		fd_set rfds;
88 		int fd, retval;
89 
90 		fd = nl_socket_get_fd(sock);
91 
92 		FD_ZERO(&rfds);
93 		FD_SET(fd, &rfds);
94 		/* wait for an incoming message on the netlink socket */
95 		retval = select(fd+1, &rfds, NULL, NULL, NULL);
96 
97 		if (retval) {
98 			/* FD_ISSET(fd, &rfds) will be true */
99 			nl_recvmsgs_default(sock);
100 		}
101 	}
102 
103 	return 0;
104 }
105