#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/net.h>
#include <net/sock.h>
#define err(msg) printk(KERN_INFO "%s failed.\n", msg)
#define SA struct sockaddr
static struct socket * create_sock(const char *ip, int port)
{
struct socket *sock;
struct sockaddr_in addr;
if (sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock) != 0) {
err("sock_create_kern");
goto out;
}
sock->sk->sk_reuse = 1;
memset(&addr, '\0', sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = in_aton(ip);
if (kernel_bind(sock, (SA *)&addr, sizeof(addr)) != 0) {
err("kernel_bind");
goto err;
}
if (kernel_listen(sock, 10) != 0) {
err("kernel_listen");
goto err;
}
return sock;
err:
sock_release(sock);
out:
return NULL;
}
static void transfer_data(struct socket *newsock)
{
struct msghdr msg;
struct kvec vec;
char buff[1024];
int len;
int num;
for (;;) {
memset(&msg, '\0', sizeof(msg));
memset(buff, '\0', sizeof(buff));
vec.iov_base = (void *)buff;
vec.iov_len = 1024;
len = kernel_recvmsg(newsock, &msg, &vec, 1, 1024, 0);
if (len <= 0)
break;
printk(KERN_INFO "len = %d\n", len);
memset(&msg, '\0', sizeof(msg));
vec.iov_base = (void *)buff;
vec.iov_len = len;
num = kernel_sendmsg(newsock, &msg, &vec, 1, len);
}
}
static void do_loop(struct socket *sock)
{
struct socket *newsock;
for (;;) {
if (kernel_accept(sock, &newsock, 0) != 0) {
err("kernel_accept");
break;
}
transfer_data(newsock);
sock_release(newsock);
}
}
static int __init hello_init(void)
{
struct socket *sock;
sock = create_sock("0.0.0.0", 7777);
if (sock == NULL) {
err("create_sock");
goto out;
}
do_loop(sock);
sock_release(sock);
return 0;
out:
return -1;
}
static void __exit hello_exit(void)
{
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
|