Listening for netlink broadcasts in a kernel module -
the selinux module sends out netlink broadcast listening sockets. i'm wondering if it's possible listen netlink broadcast within kernel module?
from selinux netlink code:
netlink_broadcast(selnl, skb, 0, selnlgrp_avc, gfp_user);
i found can listen netlink data through use of regular sockets. and, yes, it's possible in kernel-space.
you need create , bind socket:
struct sock *sock = null; struct sockaddr_nl addr = { 0 }; /* create netlink socket selinux traffic */ int rc = sock_create_kern(af_netlink, sock_raw, netlink_selinux, &ctx.sock); if (rc) return rc; addr.nl_family = af_netlink; addr.nl_pid = 0; addr.nl_groups = selnlgrp_avc; rc = kernel_bind(ctx.sock, (struct sockaddr *) &addr, sizeof(addr)); if (rc) return rc; /* setup socket callback */ sock = ctx.sock->sk; sock->sk_data_ready = netlink_data_ready; sock->sk_allocation = gfp_kernel;
to receive data:
static void netlink_data_ready(struct sock *sk, int bytes) { struct sk_buff *skb = null; struct nlmsghdr *nlh = null; int rc = 0; /* receive data packet (blocking) */ skb = skb_recv_datagram(sk, 0, 0, &rc); if (rc) { printk(kern_error "failed on skb_recv_datagram(). rc=%d.", -rc); return; } nlh = (struct nlmsghdr *) skb->data; if (!nlh || !nlmsg_ok(nlh, bytes)) { printk(kern_error "invalid netlink header data."); return; } if (nlh->nlmsg_type == selnl_msg_policyload || nlh->nlmsg_type == selnl_msg_setenforce) { /* insert code here */ } }
Comments
Post a Comment