From fcb994dd60875ff212c21ee44c0398316be9731c Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C4=83zvan=20Crainea?= Date: Sun, 27 May 2012 10:14:54 +0300 Subject: [PATCH] module: added initial implementation --- .gitignore | 7 +++ module/Kbuild | 3 ++ module/Makefile | 7 +++ module/p2psp.c | 135 ++++++++++++++++++++++++++++++++++++++++++++++++ module/test.sh | 30 +++++++++++ 5 files changed, 182 insertions(+) create mode 100644 module/Kbuild create mode 100644 module/Makefile create mode 100644 module/p2psp.c create mode 100755 module/test.sh diff --git a/.gitignore b/.gitignore index 0d08507..0c2157c 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,10 @@ cscope.files *.class *.jar *.pyc + +*.ko +*.cmd +*.mod +*.mod.c +Module.symvers +modules.order diff --git a/module/Kbuild b/module/Kbuild new file mode 100644 index 0000000..1934d9d --- /dev/null +++ b/module/Kbuild @@ -0,0 +1,3 @@ +EXTRA_CFLAGS = -Wall -g + +obj-m = p2psp.o diff --git a/module/Makefile b/module/Makefile new file mode 100644 index 0000000..ab6e95b --- /dev/null +++ b/module/Makefile @@ -0,0 +1,7 @@ +KDIR=/lib/modules/`uname -r`/build + +kbuild: + make -C $(KDIR) M=`pwd` + +clean: + make -C $(KDIR) M=`pwd` clean diff --git a/module/p2psp.c b/module/p2psp.c new file mode 100644 index 0000000..a29d930 --- /dev/null +++ b/module/p2psp.c @@ -0,0 +1,135 @@ +/* + * Simple UDP implementation + * + * Răzvan Crainea + * Tudor Cazangiu + */ + +#include +#include +#include +#include +#include + +MODULE_DESCRIPTION("P2P Swift Protocol"); +MODULE_AUTHOR("Razvan Crainea and Tudor Cazangiu"); +MODULE_LICENSE("GPL"); + +#define LOG_LEVEL KERN_ALERT +#define P2PSP_LOCAL_PORT 60000 +#define P2PSP_REMOTE_PORT1 60001 +#define P2PSP_REMOTE_PORT2 60002 +#define MY_TEST_MESSAGE "kernelsocket\n" + +#define ON 1 +#define OFF 0 +#define DEBUG ON + +#if DEBUG == ON +#define LOG(s) \ + do { \ + printk(KERN_DEBUG s "\n"); \ + } while (0) +#else +#define LOG(s) \ + do {} while (0) +#endif + +#define print_sock_address(addr) \ + do { \ + printk(LOG_LEVEL "connection established to " \ + NIPQUAD_FMT ":%d\n", \ + NIPQUAD(addr.sin_addr.s_addr), \ + ntohs(addr.sin_port)); \ + } while (0) + +static struct socket *sock; /* UDP server */ + +/* send datagram */ +static int p2psp_msgsend(struct socket *s, short port) +{ + /* address to send to */ + struct sockaddr_in raddr = { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr = { htonl(INADDR_LOOPBACK) } + }; + int raddrlen = sizeof(raddr); + /* message */ + struct msghdr msg; + struct iovec iov; + char *buffer = MY_TEST_MESSAGE; + int len = strlen(buffer) + 1; + + /* build message */ + iov.iov_base = buffer; + iov.iov_len = len; + msg.msg_name = &raddr; + msg.msg_namelen = raddrlen; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + /* send the message down the socket */ + return kernel_sendmsg(s, &msg, (struct kvec *) msg.msg_iov, 1, len); +} + +int __init p2psp_sock_init(void) +{ + int err; + /* address to bind on */ + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = htons(P2PSP_LOCAL_PORT), + .sin_addr = { htonl(INADDR_LOOPBACK) } + }; + int addrlen = sizeof(addr); + + /* create UDP socket */ + err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock); + if (err < 0) { + printk(LOG_LEVEL "can't create socket\n"); + goto out; + } + + /* bind socket to loopback on port P2PSP_LOCAL_PORT */ + err = sock->ops->bind(sock, (struct sockaddr *) &addr, addrlen); + if (err < 0) { + printk(LOG_LEVEL "can't bind socket\n"); + goto out_release; + } + + /* send first message */ + err = p2psp_msgsend(sock, P2PSP_REMOTE_PORT1); + if (err < 0) { + printk(LOG_LEVEL "can't send first message\n"); + goto out_release; + } + + /* send second message */ + err = p2psp_msgsend(sock, P2PSP_REMOTE_PORT2); + if (err < 0) { + printk(LOG_LEVEL "can't send second message\n"); + goto out_release; + } + + + return 0; + +out_release: + /* cleanup socket */ + sock_release(sock); +out: + return err; +} + +void __exit p2psp_sock_exit(void) +{ + /* cleanup socket */ + sock_release(sock); +} + +module_init(p2psp_sock_init); +module_exit(p2psp_sock_exit); diff --git a/module/test.sh b/module/test.sh new file mode 100755 index 0000000..a26b09e --- /dev/null +++ b/module/test.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +LISTENERS=2 +START_PORT=60001 + +#use nc.traditional +echo 2 | update-alternatives --config nc &> /dev/null + +#set -x + +# listen for UDP packets on localhost, port 60001 (run in background) +for listener in $(seq $LISTENERS); do + netcat -l -u -p $START_PORT & + pids="$pids $!" + START_PORT=$(($START_PORT + 1)) +done + +# wait for netcat to start listening +sleep 1 + +# insert module, causing the message to be sent +insmod p2psp.ko + +# remove module +rmmod p2psp + +# kill netcat +for pid in $pids; do + kill $pid &> /dev/null +done -- 2.20.1