From 171d42863bc9671d52021ca7c547ae7514666638 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Fri, 8 May 2020 23:12:04 +0200 Subject: [PATCH] Init with small code example --- .gitignore | 59 +++++++++++++++++++++++++++++++ kernel/Makefile | 8 +++++ kernel/netlink-test.c | 81 +++++++++++++++++++++++++++++++++++++++++++ user/main.c | 61 ++++++++++++++++++++++++++++++++ 4 files changed, 209 insertions(+) create mode 100644 .gitignore create mode 100644 kernel/Makefile create mode 100644 kernel/netlink-test.c create mode 100644 user/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5cdcfc8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,59 @@ + +# Created by https://www.gitignore.io/api/c +# Edit at https://www.gitignore.io/?templates=c + +### C ### +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +# End of https://www.gitignore.io/api/c diff --git a/kernel/Makefile b/kernel/Makefile new file mode 100644 index 0000000..6cd6e3a --- /dev/null +++ b/kernel/Makefile @@ -0,0 +1,8 @@ + +obj-m += netlink-test.o + +all: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules + +clean: + make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean diff --git a/kernel/netlink-test.c b/kernel/netlink-test.c new file mode 100644 index 0000000..3f7dc2c --- /dev/null +++ b/kernel/netlink-test.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +#define NETLINK_TESTPROTO (30) + +static struct sock *my_nl_sock; + + +static void nl_test_recv(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(my_nl_sock,skb_out,pid); + +if(res<0) + printk(KERN_INFO "Error while sending bak to user\n"); + +} + +static struct netlink_kernel_cfg nl_cfg = { + .groups = 0, + .input = nl_test_recv, +}; + +static int nl_test_init(void) +{ + + my_nl_sock = netlink_kernel_create(&init_net, NETLINK_TESTPROTO, &nl_cfg); + + if (!my_nl_sock) { + printk(KERN_ERR "%s: receive handler registration failed\n", __func__); + return -ENOMEM; + } + + printk(KERN_INFO "Hello :)\n"); + return 0; +} + +static void nl_test_exit(void) +{ + if (my_nl_sock) + netlink_kernel_release(my_nl_sock); + + printk(KERN_INFO "Goodbye :(\n"); +} + +module_init(nl_test_init); +module_exit(nl_test_exit); + +MODULE_AUTHOR("Mario Huettel "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Netlink communication test"); diff --git a/user/main.c b/user/main.c new file mode 100644 index 0000000..ba5198c --- /dev/null +++ b/user/main.c @@ -0,0 +1,61 @@ + +#include +#include +#include +#include +#include + +#define NETLINK_USER 30 + +#define MAX_PAYLOAD 1024 /* maximum payload size*/ + +int main() +{ + +struct sockaddr_nl src_addr, dest_addr; +struct nlmsghdr *nlh = NULL; +struct iovec iov; +int sock_fd; +struct msghdr msg; + + +sock_fd=socket(PF_NETLINK, SOCK_RAW, NETLINK_USER); +if(sock_fd<0) +return -1; + +memset(&src_addr, 0, sizeof(src_addr)); +src_addr.nl_family = AF_NETLINK; +src_addr.nl_pid = getpid(); /* self pid */ + +bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); + +memset(&dest_addr, 0, sizeof(dest_addr)); +memset(&msg, 0, sizeof(msg)); +dest_addr.nl_family = AF_NETLINK; +dest_addr.nl_pid = 0; /* For Linux Kernel */ +dest_addr.nl_groups = 0; /* unicast */ + +nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); +memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); +nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); +nlh->nlmsg_pid = getpid(); +nlh->nlmsg_flags = 0; + +strcpy(NLMSG_DATA(nlh), "Hello"); + +iov.iov_base = (void *)nlh; +iov.iov_len = nlh->nlmsg_len; +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"); +sendmsg(sock_fd,&msg,0); +printf("Waiting for message from kernel\n"); + +/* Read message from kernel */ +recvmsg(sock_fd, &msg, 0); +printf("Received message payload: %s\n", (char *)NLMSG_DATA(nlh)); +close(sock_fd); +}