libnl  3.6.0
nf-monitor.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
4  * Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
5  * Copyright (c) 2007 Secure Computing Corporation
6  */
7 
8 #include <netlink/cli/utils.h>
9 #include <netlink/netfilter/nfnl.h>
10 
11 #include <linux/netlink.h>
12 #include <linux/netfilter/nfnetlink.h>
13 
14 static void obj_input(struct nl_object *obj, void *arg)
15 {
16  struct nl_dump_params dp = {
18  .dp_fd = stdout,
19  .dp_dump_msgtype = 1,
20  };
21 
22  nl_object_dump(obj, &dp);
23 }
24 
25 static int event_input(struct nl_msg *msg, void *arg)
26 {
27  if (nl_msg_parse(msg, &obj_input, NULL) < 0)
28  fprintf(stderr, "<<EVENT>> Unknown message type\n");
29 
30  /* Exit nl_recvmsgs_def() and return to the main select() */
31  return NL_STOP;
32 }
33 
34 int main(int argc, char *argv[])
35 {
36  struct nl_sock *sock;
37  int err;
38  int i, idx;
39 
40  static const struct {
41  enum nfnetlink_groups gr_id;
42  const char* gr_name;
43  } groups[] = {
44  { NFNLGRP_CONNTRACK_NEW, "ct-new" },
45  { NFNLGRP_CONNTRACK_UPDATE, "ct-update" },
46  { NFNLGRP_CONNTRACK_DESTROY, "ct-destroy" },
47  { NFNLGRP_NONE, NULL }
48  };
49 
50  sock = nl_cli_alloc_socket();
52  nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
53 
54  if (argc > 1 && !strcasecmp(argv[1], "-h")) {
55  printf("Usage: nf-monitor [<groups>]\n");
56 
57  printf("Known groups:");
58  for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++)
59  printf(" %s", groups[i].gr_name);
60  printf("\n");
61  return 2;
62  }
63 
64  nl_cli_connect(sock, NETLINK_NETFILTER);
65 
66  for (idx = 1; argc > idx; idx++) {
67  for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) {
68  if (strcmp(argv[idx], groups[i].gr_name))
69  continue;
70 
71  err = nl_socket_add_membership(sock, groups[i].gr_id);
72  if (err < 0)
73  nl_cli_fatal(err,
74  "Unable to add membership: %s",
75  nl_geterror(err));
76  break;
77  }
78 
79  if (groups[i].gr_id == NFNLGRP_NONE)
80  nl_cli_fatal(NLE_OBJ_NOTFOUND, "Unknown group: \"%s\"",
81  argv[idx]);
82  }
83 
84  while (1) {
85  fd_set rfds;
86  int fd, retval;
87 
88  fd = nl_socket_get_fd(sock);
89 
90  FD_ZERO(&rfds);
91  FD_SET(fd, &rfds);
92  /* wait for an incoming message on the netlink socket */
93  retval = select(fd+1, &rfds, NULL, NULL, NULL);
94 
95  if (retval) {
96  /* FD_ISSET(fd, &rfds) will be true */
97  nl_recvmsgs_default(sock);
98  }
99  }
100 
101  return 0;
102 }
@ NL_STOP
Stop parsing altogether and discard remaining messages.
Definition: handlers.h:62
@ NL_CB_VALID
Message is valid.
Definition: handlers.h:89
@ NL_CB_CUSTOM
Customized handler specified by the user.
Definition: handlers.h:77
void nl_cli_fatal(int err, const char *fmt,...)
Print error message and quit application.
Definition: utils.c:71
void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params)
Dump this object according to the specified parameters.
Definition: object.c:287
int nl_recvmsgs_default(struct nl_sock *sk)
Receive a set of message from a netlink socket using handlers in nl_sock.
Definition: nl.c:1087
int nl_socket_get_fd(const struct nl_sock *sk)
Return the file descriptor of the backing socket.
Definition: socket.c:577
void nl_socket_disable_seq_check(struct nl_sock *sk)
Disable sequence number checking.
Definition: socket.c:276
int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Modify the callback handler associated with the socket.
Definition: socket.c:764
@ NL_DUMP_STATS
Dump all attributes including statistics.
Definition: types.h:18
Dumping parameters.
Definition: types.h:28
enum nl_dump_type dp_type
Specifies the type of dump that is requested.
Definition: types.h:32