Prerequisites : Socket and Module programming
Advantage of implementing application within the kernel :
- The overhead associated with user-space/kernel-space transition can be avoided by implementing the application completely in the Kernel Space .
- In specific research and high-performance computing environments, there is a need for achieving data transfers at great speeds. Kernel applications find use in such situations.
Disadvantages:
- Security is a primary concern within the kernel, since kernel process run with unlimited privileges.Consequently, special care needs to be taken while designing in-kernel applications.
- Large applications cannot be implemented in the kernel due to memory constraints.
- Every kernel needs a specific implementation route.
- Failure in the web server may cause the OS to crash.
/*
* Called when a process writes to dev file
* Stores the string written to the device in
* local buffer and sends the string using
* SOCK_STREAM to 127.0.0.1:2001
*/
static ssize_t
device_write(struct file *filp, const char *buff, size_t len, loff_t * off)
{
int ret; //return value
int k,leng;
struct sockaddr_in server;
struct socket *soc=NULL;
struct iovec iov;
struct msghdr msgh;
mm_segment_t oldmm;
printk(KERN_INFO "[device_write]File opened for writing\n");
ret=copy_from_user(msg,buff,80);
//buff : buffer that accepts the string from
// the program that issued a write.
// Points to user area memory
//msg : kernel/module space that hold the
// value written.
msgh.msg_name = 0;
msgh.msg_namelen = 0;
// Socket address members msg_name and msg_namelen.
// Required only when your socket is a datagram socket.
// msg_name member points to the socket address that
// you are sending to or receiving from.
msgh.msg_iov = &iov;
msgh.msg_iovlen = 1;
// I/O vector references msg_iov and msg_iovlen.
// msg_iov member points to the struct iovec array.
// msg_iovlen indicates how many elements are in your
// I/O vector array
msgh.msg_control = NULL;
msgh.msg_controllen = 0;
// Ancillary data buffer members msg_control
// and msg_controllen. Used to pass protocol-specific
// control messages. No control messages for TCP.
msgh.msg_flags = MSG_DONTWAIT;
// Received message flag bits msg_flags.
// MSG_DONTWAIT prevents the system call from blocking if,
// for example, there are no data to be received.
oldmm = get_fs();
set_fs(KERNEL_DS);
// get_fs returns the current segment descriptor stored in FS.
// set_fs stores a descriptor into FS, so it will be used for
// data transfer instructions.
msgh.msg_iov->iov_len = 80;
msgh.msg_iov->iov_base = (char *) msg;
printk(KERN_INFO "[chardev:device_write] msg : %s\n",msg);
k=sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&soc);
memset(&server,0,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=2001;
server.sin_addr.s_addr=inet_addr("127.0.0.1");
k=soc->ops->connect(soc,(struct sockaddr *)&server,sizeof(server),O_RDWR);
if(k!=-1) printk(KERN_INFO"[device_write] connect() OK. Next sock_sendmsg().\n");
else printk(KERN_INFO"[device_write] connect() FAILED. Next sock_sendmsg().\n");
leng = sock_sendmsg(soc, &msgh, 80);
//msg length 80
if(leng) printk(KERN_INFO"[device_write] sock_sendmsg() OK. Next close().\n");
else printk(KERN_INFO"[device_write] sock_sendmsg() FAILED. Next close().\n");
sock_release(soc);
return ret;
}
Further Reading :
In-Kernel Web Sever
kHTTPd