--- /dev/null
+/*
+ * Simple UDP implementation
+ *
+ * Răzvan Crainea
+ * Tudor Cazangiu
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/net.h>
+#include <linux/in.h>
+
+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);