Skip to content

Instantly share code, notes, and snippets.

@proelbtn
Created August 31, 2020 03:11
Show Gist options
  • Save proelbtn/8a0cf7031a3c3fa66be2ee29ef825eda to your computer and use it in GitHub Desktop.
Save proelbtn/8a0cf7031a3c3fa66be2ee29ef825eda to your computer and use it in GitHub Desktop.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <net/net_namespace.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/delay.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Ryoga Saito (proelbtn)");
MODULE_DESCRIPTION("");
MODULE_VERSION("");
struct socket *sock;
struct task_struct *handler;
int listen_fn(void *data) {
int err;
struct socket *newsock;
unsigned char buf[1024];
struct kvec vec;
struct msghdr msg;
while (1) {
if (kthread_should_stop()) break;
err = kernel_accept(sock, &newsock, SOCK_NONBLOCK);
if (err) continue;
memset(&vec, 0, sizeof(vec));
memset(&msg, 0, sizeof(msg));
vec.iov_base = buf;
vec.iov_len = 1024;
kernel_recvmsg(newsock, &msg, &vec, 1, 1024, 0);
memset(&vec, 0, sizeof(vec));
memset(&msg, 0, sizeof(msg));
vec.iov_base = buf;
vec.iov_len = 1024;
kernel_sendmsg(newsock, &msg, &vec, 1, 1024);
sock_release(newsock);
}
do_exit(0);
schedule();
return 0;
}
static int __init http_init(void) {
int err;
struct sockaddr_in addr;
err = sock_create_kern(&init_net, AF_INET, SOCK_STREAM, 0, &sock);
if (err) {
pr_err("sock_create (%d)\n", err);
goto err1;
}
pr_info("sock created (0x%p)\n", sock);
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(80);
err = kernel_bind(sock, (struct sockaddr *)&addr, sizeof(addr));
if (err) {
pr_err("bind (%d)\n", err);
goto err2;
}
pr_info("sock binded\n");
err = kernel_listen(sock, 1);
if (err) {
pr_err("listen (%d)\n", err);
goto err2;
}
pr_info("sock listened\n");
handler = kthread_create(listen_fn, NULL, "http-handler");
if (!handler) {
pr_err("kthread_create\n");
goto err2;
}
pr_info("kthread created (0x%p)\n", handler);
wake_up_process(handler);
pr_info("wake_up_process\n");
return err;
err2:
sock_release(sock);
pr_info("sock released\n");
err1:
return err;
}
static void __exit http_exit(void) {
pr_info("kthread %p\n", handler);
kthread_stop(handler);
pr_info("kthread stopped\n");
sock_release(sock);
pr_info("sock released\n");
}
module_init(http_init);
module_exit(http_exit);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment