|
/* Sendbuffer sends "Length" bytes from "Buffer" through the socket "sock". */ size_t SendBuffer(struct socket *sock, const char *Buffer, size_t Length) { struct msghdr msg; mm_segment_t oldfs; // mm_segment_t is just a long
struct iovec iov; // structure containing a base addr. and length
int len2;
//printk("Entering SendBuffer\n");
msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; //point to be noted
msg.msg_control = NULL; msg.msg_controllen = 0;
msg.msg_flags = MSG_NOSIGNAL; //0/*MSG_DONTWAIT*/;
iov.iov_base = (char*) Buffer; // as we know that iovec is
iov.iov_len = (__kernel_size_t) Length; // nothing but a base addr and length
// #define get_fs() (current_thread_info()->addr_limit)
// similar for set_fs;
/* Therefore this line sets the "fs" to KERNEL_DS and saves its old value */ oldfs = get_fs(); set_fs(KERNEL_DS);
/* Actual Sending of the Message */ len2 = sock_sendmsg(sock, &msg, (size_t)(Length));
/* retrieve the old value of fs (whatever it is) */ set_fs(oldfs);
return len2; }
/* Recieves data from the socket "sock" and puts it in the 'Buffer'. Returns the length of data recieved
The Calling function must do a: Buffer = (char*) get_free_page(GFP_KERNEL); or a kmalloc to allocate kernel's memory (or it can use the kernel's stack space [very small] ) */ size_t RecvBuffer(struct socket *sock, const char *Buffer, size_t Length) { struct msghdr msg; struct iovec iov; int len; mm_segment_t oldfs;
/* Set the msghdr structure*/ msg.msg_name = 0; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0;
/* Set the iovec structure*/ iov.iov_base = (void *) &Buffer[0]; iov.iov_len = (size_t)Length;
/* Recieve the message */ oldfs = get_fs(); set_fs(KERNEL_DS);
len = sock_recvmsg(sock,&msg,Length,0/*MSG_DONTWAIT*/); // let it wait if there is no message
set_fs(oldfs);
// if ((len!=-EAGAIN)&&(len!=0))
// printk("RecvBuffer Recieved %i bytes \n",len);
return len; }
/* Sets up a server-side socket
1. Create a new socket 2. Bind the address to the socket 3. Start listening on the socket */ struct socket* set_up_server_socket(int port_no) { struct socket *sock; struct sockaddr_in sin;
int error;
/* First create a socket */ error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&sock) ; if (error<0) printk("Error during creation of socket; terminating\n");
/* Now bind the socket */ sin.sin_family = AF_INET; sin.sin_addr.s_addr = INADDR_ANY; sin.sin_port = htons(port_no);
error = sock->ops->bind(sock,(struct sockaddr*)&sin,sizeof(sin)); if (error<0) { printk("Error binding socket \n"); return 0; }
/* Now, start listening on the socket */ error=sock->ops->listen(sock,32); if (error!=0) printk("Error listening on socket \n");
/* Now start accepting */ // Accepting is performed by the function server_accept_connection
return sock; }
/* Accepts a new connection (server calls this function)
1. Create a new socket 2. Call socket->ops->accept 3. return the newly created socket */
struct socket* server_accept_connection(struct socket *sock) { struct socket * newsock; int error;
/* Before accept: Clone the socket */ error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&newsock); if (error<0) printk("Error during creation of the other socket; terminating\n");
newsock->type = sock->type; newsock->ops=sock->ops;
/* Do the actual accept */ error = newsock->ops->accept(sock,newsock,0); if (error<0) { /* must add release the socket code here */ printk("Error accepting socket\n") ; return 0; }
return newsock; }
struct socket * set_up_client_socket(unsigned int IP_addr, int port_no) { struct socket *clientsock; struct sockaddr_in sin; int error, i;
/* First create a socket */ error = sock_create(PF_INET,SOCK_STREAM,IPPROTO_TCP,&clien tsock); if (error<0) { printk("Error during creation of socket; terminating\n"); return 0; }
/* Now bind and connect the socket */ sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(IP_addr); sin.sin_port = htons(port_no);
for(i=0; i<10; i++) { error = clientsock->ops->connect(clientsock,(struct sockaddr*)&sin,sizeof(sin),0); if (error<0) { printk("Error connecting client socket to server: %i, retrying .. %d \n",error, i); if(i == 10-1) { printk("Giving Up!\n"); return 0; } } else break; //connected
}
return clientsock; }
|