-
-
Save dnice1987/adff470094ddbee35f30fe2778bbb7b9 to your computer and use it in GitHub Desktop.
netlink example code in c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1. Execute make first. This will result in a netlinkKernel.ko output among many others. | |
2. Execute $ gcc netlinkUser.c -o netlinkUser | |
3. Insert kernel module by :$ sudo insmod netlinkKernel.ko | |
4. Run ./netlinkUser to see message and run dmesg to see debug messages | |
5. Remove module by : $ sudo rmmod netlinkKernel | |
6. Finally make clean to remove output files. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
KDIR := /lib/modules/$(shell uname -r)/build | |
obj-m += netlinkKernel.o | |
all: | |
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules | |
clean: | |
rm -rf *.o *.ko *.mod.* *.cmd .module* modules* Module* .*.cmd .tmp* | |
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Taken from https://stackoverflow.com/questions/15215865/netlink-sockets-in-c-using-the-3-x-linux-kernel?lq=1 | |
#include <linux/module.h> | |
#include <net/sock.h> | |
#include <linux/netlink.h> | |
#include <linux/skbuff.h> | |
#define NETLINK_USER 31 | |
struct sock *nl_sk = NULL; | |
static void hello_nl_recv_msg(struct sk_buff *skb) { | |
struct nlmsghdr *nlh; | |
int pid; | |
struct sk_buff *skb_out; | |
int msg_size; | |
char *msg="Hello from kernel"; | |
int res; | |
printk(KERN_INFO "Entering: %s\n", __FUNCTION__); | |
msg_size=strlen(msg); | |
nlh=(struct nlmsghdr*)skb->data; | |
printk(KERN_INFO "Netlink received msg payload:%s\n",(char*)nlmsg_data(nlh)); | |
pid = nlh->nlmsg_pid; /*pid of sending process */ | |
skb_out = nlmsg_new(msg_size,0); | |
if(!skb_out) | |
{ | |
printk(KERN_ERR "Failed to allocate new skb\n"); | |
return; | |
} | |
nlh=nlmsg_put(skb_out,0,0,NLMSG_DONE,msg_size,0); | |
NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */ | |
strncpy(nlmsg_data(nlh),msg,msg_size); | |
res=nlmsg_unicast(nl_sk,skb_out,pid); | |
if(res<0) | |
printk(KERN_INFO "Error while sending bak to user\n"); | |
} | |
static int __init hello_init(void) { | |
printk("Entering: %s\n",__FUNCTION__); | |
//This is for 3.6 kernels and above. | |
struct netlink_kernel_cfg cfg = { | |
.input = hello_nl_recv_msg, | |
}; | |
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg); | |
//nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg,NULL,THIS_MODULE); | |
if(!nl_sk) | |
{ | |
printk(KERN_ALERT "Error creating socket.\n"); | |
return -10; | |
} | |
return 0; | |
} | |
static void __exit hello_exit(void) { | |
printk(KERN_INFO "exiting hello module\n"); | |
netlink_kernel_release(nl_sk); | |
} | |
module_init(hello_init); module_exit(hello_exit); | |
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//Taken from https://stackoverflow.com/questions/15215865/netlink-sockets-in-c-using-the-3-x-linux-kernel?lq=1 | |
#include <sys/socket.h> | |
#include <linux/netlink.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <errno.h> | |
#include <err.h> | |
#define MAX_PAYLOAD 1024 | |
#define NETLINK_UNICAST_SEND 0 | |
#define DST_KERNEL 0 | |
#define NETLINK_USER 31 | |
int main() { | |
struct sockaddr_nl src_addr, dest_addr; | |
struct nlmsghdr *nlh = NULL; | |
struct iovec iov; | |
int sock_fd; | |
struct msghdr msg; | |
if ((sock_fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_USERSOCK)) < 0) err(EXIT_FAILURE, "socket() "); | |
memset(&src_addr, 0, sizeof(src_addr)); | |
src_addr.nl_family = AF_NETLINK; | |
src_addr.nl_pid = getpid(); | |
if(bind(sock_fd, (struct sockaddr *)&src_addr, sizeof(src_addr)) < 0) err(EXIT_FAILURE, "bind() "); | |
memset(&dest_addr, 0, sizeof(dest_addr)); | |
dest_addr.nl_family = AF_NETLINK; | |
dest_addr.nl_pid = DST_KERNEL; | |
dest_addr.nl_groups = NETLINK_UNICAST_SEND; | |
if ((nlh = (struct nlmsghdr *)calloc(1, NLMSG_SPACE(MAX_PAYLOAD))) == NULL) err(EXIT_FAILURE, "calloc() "); | |
nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); | |
nlh->nlmsg_pid = getpid(); | |
nlh->nlmsg_flags = 0; | |
strcpy(NLMSG_DATA(nlh), "Hello from userspace"); | |
iov.iov_base = (void *)nlh; | |
iov.iov_len = nlh->nlmsg_len; | |
memset((void*)&msg, 0, sizeof(msg)); | |
msg.msg_name = (void *)&dest_addr; | |
msg.msg_namelen = sizeof(dest_addr); | |
msg.msg_iov = &iov; | |
msg.msg_iovlen = 1; | |
printf("Sending message to kernel\n"); | |
if (sendmsg(sock_fd, &msg, 0) < 0) | |
err(EXIT_FAILURE, "Sending error ", strerror(errno)); | |
printf("Waiting for message from kernel\n"); | |
if(recvmsg(sock_fd, &msg, 0) < 0) | |
err(EXIT_FAILURE, "Receive error ", strerror(errno)); | |
printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh)); | |
close(sock_fd); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment