First, you should head over to this netlink discussion to get a sense of the overall netlink architecture.
Once you grasped the netlink architecture, you may follow these steps/algorithm to "listen" to the multicast address(es) provided by the kernel subsystem through netlink:
- Init a netlink socket to the kernel subsystem you wish to access. Remember to use #include<linux/[subsystem_header].h>.
- Carry-out initialization on the socket if needed.
- Bind the socket to the multicast address provided by the kernel subsystem. The multicast address is basically a combination of the following:
- The netlink address family, i.e. AF_NETLINK.
- The netlink multicast group which you can find in the kernel header. For example: the multicast group address for audit subsystem (a constant), is in the audit header file, i.e. <linux/audit.h>.
- Your application's Process ID (PID).
- Read from the socket, when there is data coming in. You might want to use event-based library here, such libev or libevent. In many cases, the kernel only provides a multicast "Read-Only" channel, i.e. you can only read from it. It's not meant to be used to "write" to the kernel.
// .. struct sockaddr_nl s_addr; memset(&s_addr, 0, sizeof(s_addr)); s_addr.nl_family = AF_NETLINK; s_addr.nl_pad = 0; s_addr.nl_pid = getpid(); s_addr.nl_groups = AUDIT_NLGRP_READLOG; retval = bind(fd, (struct sockaddr *)&s_addr, sizeof(s_addr)); if (retval != 0) { PRINT_ERR_MSG("Failed binding to kernel multicast address"); return -1; } // ..Anyway, because the channel used by the code is multicast channel, multiple user-space application can "listen" to the same kernel subsystem simultaneously. The scenario explained here is not the norm. But, some use cases required this approach.
Post a Comment
No comments:
Post a Comment