module: added initial implementation
[p2p-kernel-protocol.git] / module / p2psp.c
1 /*
2  * Simple UDP implementation
3  *
4  * Răzvan Crainea
5  * Tudor Cazangiu
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/net.h>
12 #include <linux/in.h>
13
14 MODULE_DESCRIPTION("P2P Swift Protocol");
15 MODULE_AUTHOR("Razvan Crainea and Tudor Cazangiu");
16 MODULE_LICENSE("GPL");
17
18 #define LOG_LEVEL               KERN_ALERT
19 #define P2PSP_LOCAL_PORT        60000
20 #define P2PSP_REMOTE_PORT1      60001
21 #define P2PSP_REMOTE_PORT2      60002
22 #define MY_TEST_MESSAGE         "kernelsocket\n"
23
24 #define ON                      1
25 #define OFF                     0
26 #define DEBUG                   ON
27
28 #if DEBUG == ON
29 #define LOG(s)                                  \
30         do {                                    \
31                 printk(KERN_DEBUG s "\n");      \
32         } while (0)
33 #else
34 #define LOG(s)                                  \
35         do {} while (0)
36 #endif
37
38 #define print_sock_address(addr)                \
39         do {                                    \
40                 printk(LOG_LEVEL "connection established to "   \
41                                 NIPQUAD_FMT ":%d\n",            \
42                                 NIPQUAD(addr.sin_addr.s_addr),  \
43                                 ntohs(addr.sin_port));          \
44         } while (0)
45
46 static struct socket *sock;     /* UDP server */
47
48 /* send datagram */
49 static int p2psp_msgsend(struct socket *s, short port)
50 {
51         /* address to send to */
52         struct sockaddr_in raddr = {
53                 .sin_family     = AF_INET,
54                 .sin_port       = htons(port),
55                 .sin_addr       = { htonl(INADDR_LOOPBACK) }
56         };
57         int raddrlen = sizeof(raddr);
58         /* message */
59         struct msghdr msg;
60         struct iovec iov;
61         char *buffer = MY_TEST_MESSAGE;
62         int len = strlen(buffer) + 1;
63
64         /* build message */
65         iov.iov_base = buffer;
66         iov.iov_len = len;
67         msg.msg_name = &raddr;
68         msg.msg_namelen = raddrlen;
69         msg.msg_iov = &iov;
70         msg.msg_iovlen = 1;
71         msg.msg_control = NULL;
72         msg.msg_controllen = 0;
73         msg.msg_flags = 0;
74
75         /* send the message down the socket */
76         return kernel_sendmsg(s, &msg, (struct kvec *) msg.msg_iov, 1, len);
77 }
78
79 int __init p2psp_sock_init(void)
80 {
81         int err;
82         /* address to bind on */
83         struct sockaddr_in addr = {
84                 .sin_family     = AF_INET,
85                 .sin_port       = htons(P2PSP_LOCAL_PORT),
86                 .sin_addr       = { htonl(INADDR_LOOPBACK) }
87         };
88         int addrlen = sizeof(addr);
89
90         /* create UDP socket */
91         err = sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &sock);
92         if (err < 0) {
93                 printk(LOG_LEVEL "can't create socket\n");
94                 goto out;
95         }
96
97         /* bind socket to loopback on port P2PSP_LOCAL_PORT */
98         err = sock->ops->bind(sock, (struct sockaddr *) &addr, addrlen);
99         if (err < 0) {
100                 printk(LOG_LEVEL "can't bind socket\n");
101                 goto out_release;
102         }
103
104         /* send first message */
105         err = p2psp_msgsend(sock, P2PSP_REMOTE_PORT1);
106         if (err < 0) {
107                 printk(LOG_LEVEL "can't send first message\n");
108                 goto out_release;
109         }
110
111         /* send second message */
112         err = p2psp_msgsend(sock, P2PSP_REMOTE_PORT2);
113         if (err < 0) {
114                 printk(LOG_LEVEL "can't send second message\n");
115                 goto out_release;
116         }
117
118
119         return 0;
120
121 out_release:
122         /* cleanup socket */
123         sock_release(sock);
124 out:
125         return err;
126 }
127
128 void __exit p2psp_sock_exit(void)
129 {
130         /* cleanup socket */
131         sock_release(sock);
132 }
133
134 module_init(p2psp_sock_init);
135 module_exit(p2psp_sock_exit);