Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F102688298
D40372.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D40372.diff
View Options
diff --git a/usr.bin/genl/genl.1 b/usr.bin/genl/genl.1
--- a/usr.bin/genl/genl.1
+++ b/usr.bin/genl/genl.1
@@ -24,23 +24,44 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd May 20, 2023
+.Dd Oct 5, 2023
.Dt GENL 1
.Os
.Sh NAME
.Nm genl
-.Nd "generic netlink list"
+.Nd "generic netlink"
.Sh SYNOPSIS
.Nm
+.Pp
+.Nm Cm list
+.Pp
+.Nm Cm monitor Ao family Ac Ao multicast group Ac
.Sh DESCRIPTION
+The
.Nm
-lists all available generic netlink protocols, and presents its details:
+utility is design to provide access to the user to generic netlink
+protocols.
+.Pp
+The following commands are available:
+.Bl -tag -ident
+.It Cm list Po default Pc
+Lists all available generic netlink protocols, and presents its details:
.Bl -tag -width "multicast groups"
.It operations
Id of the operation if any and associated capabilities
.It multicast groups
If of the available multicast group if any and it associated name
.El
+.It Cm monitor Ao family Ac Ao multicast group Ac
+Connect to the
+.Ar family
+protocol and subscribe to the
+.Ar mulicast group
+then print the received messages in a readable format if the protocol is known.
+So far only
+.Qq nlctrl
+is known.
+.El
.Sh SEE ALSO
.Xr genetlink 4 ,
.Xr netlink 4
diff --git a/usr.bin/genl/genl.c b/usr.bin/genl/genl.c
--- a/usr.bin/genl/genl.c
+++ b/usr.bin/genl/genl.c
@@ -27,18 +27,41 @@
#include <sys/param.h>
#include <sys/module.h>
+#include <sys/socket.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <stdio.h>
+#include <poll.h>
#include <netlink/netlink.h>
#include <netlink/netlink_generic.h>
#include <netlink/netlink_snl.h>
#include <netlink/netlink_snl_generic.h>
+static int monitor_mcast(int argc, char **argv);
+static int list_families(int argc, char **argv);
+static void parser_nlctrl_notify(struct snl_state *ss, struct nlmsghdr *hdr);
+static void parser_fallback(struct snl_state *ss, struct nlmsghdr *hdr);
+
+static struct commands {
+ const char *name;
+ const char *usage;
+ int (*cmd)(int argc, char **argv);
+} cmds[] = {
+ { "monitor", "monitor <family> <multicast group>", monitor_mcast },
+ { "list", "list", list_families },
+};
+
+static struct mcast_parsers {
+ const char *family;
+ void (*parser)(struct snl_state *ss, struct nlmsghdr *hdr);
+} mcast_parsers [] = {
+ { "nlctrl", parser_nlctrl_notify },
+};
+
struct genl_ctrl_op {
uint32_t id;
uint32_t flags;
@@ -131,6 +154,13 @@
mcast_groups->groups[i]->mcast_grp_name);
}
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: %s\n", getprogname());
+ for (size_t i = 0; i < nitems(cmds); i++)
+ fprintf(stderr, " %s %s\n", getprogname(), cmds[i].usage);
+}
static void
dump_family(struct genl_family *family)
@@ -143,8 +173,87 @@
dump_mcast_groups(&family->mcast_groups);
}
+void
+parser_nlctrl_notify(struct snl_state *ss, struct nlmsghdr *hdr)
+{
+ struct genl_family family = {};
+
+ if (snl_parse_nlmsg(ss, hdr, &genl_family_parser,
+ &family))
+ dump_family(&family);
+}
+
+void
+parser_fallback(struct snl_state *ss __unused, struct nlmsghdr *hdr __unused)
+{
+ printf("New unknown message\n");
+}
+
+int
+monitor_mcast(int argc __unused, char **argv)
+{
+ struct snl_state ss;
+ struct nlmsghdr *hdr;
+ struct _getfamily_attrs attrs;
+ struct pollfd pfd;
+ bool found = false;
+ void (*parser)(struct snl_state *ss, struct nlmsghdr *hdr);
+
+ parser = parser_fallback;
+
+ if (!snl_init(&ss, NETLINK_GENERIC))
+ err(EXIT_FAILURE, "snl_init()");
+
+ if (argc != 2) {
+ usage();
+ return (EXIT_FAILURE);
+ }
+ if (!snl_get_genl_family_info(&ss, argv[0], &attrs))
+ errx(EXIT_FAILURE, "Unknown family '%s'", argv[0]);
+ for (uint32_t i = 0; i < attrs.mcast_groups.num_groups; i++) {
+ if (strcmp(attrs.mcast_groups.groups[i]->mcast_grp_name,
+ argv[1]) == 0) {
+ found = true;
+ if (setsockopt(ss.fd, SOL_NETLINK,
+ NETLINK_ADD_MEMBERSHIP,
+ (void *)&attrs.mcast_groups.groups[i]->mcast_grp_id,
+ sizeof(attrs.mcast_groups.groups[i]->mcast_grp_id))
+ == -1)
+ err(EXIT_FAILURE, "Cannot subscribe to command "
+ "notify");
+ break;
+ }
+ }
+ if (!found)
+ errx(EXIT_FAILURE, "No such multicat group '%s'"
+ " in family '%s'", argv[1], argv[0]);
+ for (size_t i= 0; i < nitems(mcast_parsers); i++) {
+ if (strcmp(mcast_parsers[i].family, argv[0]) == 0) {
+ parser = mcast_parsers[i].parser;
+ break;
+ }
+ }
+ memset(&pfd, 0, sizeof(pfd));
+ pfd.fd = ss.fd;
+ pfd.events = POLLIN | POLLERR;
+ while (true) {
+ pfd.revents = 0;
+ if (poll(&pfd, 1, -1) == -1) {
+ if (errno == EINTR)
+ continue;
+ err(EXIT_FAILURE, "poll()");
+ }
+ hdr = snl_read_message(&ss);
+ if (hdr != NULL && hdr->nlmsg_type != NLMSG_ERROR)
+ parser(&ss, hdr);
+
+ }
+
+ return (EXIT_SUCCESS);
+}
+
int
-main(int argc, char **argv __unused)
+list_families(int argc, char **argv __unused)
{
struct snl_state ss;
struct snl_writer nw;
@@ -152,16 +261,16 @@
struct snl_errmsg_data e = {};
uint32_t seq_id;
- if (argc > 1)
- errx(EXIT_FAILURE, "usage: genl does not accept any argument");
- if (modfind("netlink") == -1)
- err(EXIT_FAILURE, "require netlink module to be loaded");
-
+ if (argc != 0) {
+ usage();
+ return (EXIT_FAILURE);
+ }
if (!snl_init(&ss, NETLINK_GENERIC))
err(EXIT_FAILURE, "snl_init()");
snl_init_writer(&ss, &nw);
- hdr = snl_create_genl_msg_request(&nw, GENL_ID_CTRL, CTRL_CMD_GETFAMILY);
+ hdr = snl_create_genl_msg_request(&nw, GENL_ID_CTRL,
+ CTRL_CMD_GETFAMILY);
if ((hdr = snl_finalize_msg(&nw)) == NULL)
err(EXIT_FAILURE, "snl_finalize_msg");
seq_id = hdr->nlmsg_seq;
@@ -179,3 +288,21 @@
return (EXIT_SUCCESS);
}
+
+int
+main(int argc, char **argv)
+{
+ if (modfind("netlink") == -1)
+ err(EXIT_FAILURE, "require netlink module to be loaded");
+
+ if (argc == 1)
+ return (list_families(0, NULL));
+
+ for (size_t i = 0; i < nitems(cmds); i++) {
+ if (strcmp(argv[1], cmds[i].name) == 0)
+ return (cmds[i].cmd(argc - 2, argv + 2));
+ }
+ usage();
+
+ return (EXIT_FAILURE);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 16, 9:37 PM (21 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14664680
Default Alt Text
D40372.diff (5 KB)
Attached To
Mode
D40372: genl: add the monitor subcommand
Attached
Detach File
Event Timeline
Log In to Comment