Here is sample code for socket programming via kernel modules.
-------------------------------------------------------------------------------------------------------------------
client.c
-------------------------------------------------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>
#include <linux/in.h>
#include <net/sock.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/inet.h>
#include <linux/kthread.h>
#define MODULE_NAME "Client Module"
struct kthread_t
{
struct task_struct *thread;
struct sockaddr_in sock_addr;
struct socket *sock_client;
};
struct kthread_t *kthread;
int socket_send(struct socket *sock, struct sockaddr_in *addr, unsigned char *buf, int len)
{
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
int size = 0;
if (sock->sk==NULL)
return 0;
iov.iov_base = buf;
iov.iov_len = len;
msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_sendmsg(sock,&msg,len);
set_fs(oldfs);
return size;
}
int socket_receive(struct socket* sock, struct sockaddr_in* addr, unsigned char* buf, int len)
{
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
int size = 0;
if (sock->sk==NULL) return 0;
iov.iov_base = buf;
iov.iov_len = len;
msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_recvmsg(sock,&msg,len,msg.msg_flags);
set_fs(oldfs);
return size;
}
void socket_start(void)
{
int err=0,ret=0;
int bufsize = 30;
unsigned long int server_addr;
unsigned char buf[bufsize+1];
err =sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &kthread->sock_client) ;
if ( err <0 ){
printk(KERN_INFO"\n Client : Socket creation failed\n");
goto out;
}
printk(KERN_INFO"\nClient : socket created sucessfully\n");
memset(&kthread->sock_addr, 0, sizeof(struct sockaddr)); // ?????
kthread->sock_addr.sin_family = AF_INET;
//server_addr = in_aton("127.0.0.1"); // local machine as server
server_addr = in_aton("172.17.27.16"); // server ip
kthread->sock_addr.sin_addr.s_addr =server_addr;
kthread->sock_addr.sin_port = htons(65123);
/* ----------------conneaction Request---------------- */
err = (kthread->sock_client->ops->connect(kthread->sock_client, (struct sockaddr *)&kthread->sock_addr, sizeof(struct sockaddr), 0) ) ;
if (err < 0){
printk(KERN_INFO"\n Client : Socket connection failed\n");
goto out;
}
printk(KERN_INFO"\nClient : socket connected sucessfully\n");
memset(buf, 0, bufsize+1);
strcat(buf, "This is client data ");
/* ----------------Send data---------------- */
ret=socket_send(kthread->sock_client, &kthread->sock_addr, buf, strlen(buf));
printk(KERN_INFO"\n Client : retrun value from socket send is = %d\n",ret);
ret=0;
memset(buf, 0, bufsize+1);
/* ----------------Recieve data ---------------- */ ret = socket_receive(kthread->sock_client, &kthread->sock_addr, buf, bufsize);
printk(KERN_INFO"\n Client : retrun value from socket recieve is = %d\n",ret);
printk(KERN_INFO"\nClient : Data received is -> %s\n",buf);
out :
printk("\nClient thread is done\n");
sock_release(kthread->sock_client);
kthread->sock_client = NULL;
kthread->thread = NULL;
}
int __init socket_init(void)
{
printk(KERN_INFO"\n\ Client side : Module registered...\n");
kthread = kmalloc(sizeof(struct kthread_t), GFP_KERNEL);
memset(kthread, 0, sizeof(struct kthread_t));
kthread->thread = kthread_run((void *)socket_start, NULL, MODULE_NAME);
if (IS_ERR(kthread->thread))
{
printk(KERN_INFO MODULE_NAME": unable to start kernel thread\n");
kfree(kthread);
kthread = NULL;
return -ENOMEM;
}
return 0;
}
void __exit socket_exit(void)
{
printk(KERN_INFO"\nClient side : Module unregistered...\n");
if (kthread->sock_client != NULL)
{
sock_release(kthread->sock_client);
kthread->sock_client = NULL;
}
kfree(kthread);
kthread = NULL;
}
module_init(socket_init);
module_exit(socket_exit);
/* module information */
MODULE_DESCRIPTION("kernel thread as client");
MODULE_AUTHOR("Narendra Pal ");
MODULE_LICENSE("GPL");
-----------------------------------------------------------------------------------------------------------------------
server.c
-----------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------
Makefile
----------------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------------
client.c
-------------------------------------------------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>
#include <linux/in.h>
#include <net/sock.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/inet.h>
#include <linux/kthread.h>
#define MODULE_NAME "Client Module"
struct kthread_t
{
struct task_struct *thread;
struct sockaddr_in sock_addr;
struct socket *sock_client;
};
struct kthread_t *kthread;
int socket_send(struct socket *sock, struct sockaddr_in *addr, unsigned char *buf, int len)
{
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
int size = 0;
if (sock->sk==NULL)
return 0;
iov.iov_base = buf;
iov.iov_len = len;
msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_sendmsg(sock,&msg,len);
set_fs(oldfs);
return size;
}
int socket_receive(struct socket* sock, struct sockaddr_in* addr, unsigned char* buf, int len)
{
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
int size = 0;
if (sock->sk==NULL) return 0;
iov.iov_base = buf;
iov.iov_len = len;
msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_recvmsg(sock,&msg,len,msg.msg_flags);
set_fs(oldfs);
return size;
}
void socket_start(void)
{
int err=0,ret=0;
int bufsize = 30;
unsigned long int server_addr;
unsigned char buf[bufsize+1];
err =sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &kthread->sock_client) ;
if ( err <0 ){
printk(KERN_INFO"\n Client : Socket creation failed\n");
goto out;
}
printk(KERN_INFO"\nClient : socket created sucessfully\n");
memset(&kthread->sock_addr, 0, sizeof(struct sockaddr)); // ?????
kthread->sock_addr.sin_family = AF_INET;
//server_addr = in_aton("127.0.0.1"); // local machine as server
server_addr = in_aton("172.17.27.16"); // server ip
kthread->sock_addr.sin_addr.s_addr =server_addr;
kthread->sock_addr.sin_port = htons(65123);
/* ----------------conneaction Request---------------- */
if (err < 0){
printk(KERN_INFO"\n Client : Socket connection failed\n");
goto out;
}
printk(KERN_INFO"\nClient : socket connected sucessfully\n");
memset(buf, 0, bufsize+1);
strcat(buf, "This is client data ");
/* ----------------Send data---------------- */
printk(KERN_INFO"\n Client : retrun value from socket send is = %d\n",ret);
ret=0;
memset(buf, 0, bufsize+1);
/* ----------------Recieve data ---------------- */ ret = socket_receive(kthread->sock_client, &kthread->sock_addr, buf, bufsize);
printk(KERN_INFO"\n Client : retrun value from socket recieve is = %d\n",ret);
printk(KERN_INFO"\nClient : Data received is -> %s\n",buf);
out :
printk("\nClient thread is done\n");
sock_release(kthread->sock_client);
kthread->sock_client = NULL;
kthread->thread = NULL;
}
int __init socket_init(void)
{
printk(KERN_INFO"\n\ Client side : Module registered...\n");
kthread = kmalloc(sizeof(struct kthread_t), GFP_KERNEL);
memset(kthread, 0, sizeof(struct kthread_t));
kthread->thread = kthread_run((void *)socket_start, NULL, MODULE_NAME);
if (IS_ERR(kthread->thread))
{
printk(KERN_INFO MODULE_NAME": unable to start kernel thread\n");
kfree(kthread);
kthread = NULL;
return -ENOMEM;
}
return 0;
}
void __exit socket_exit(void)
{
printk(KERN_INFO"\nClient side : Module unregistered...\n");
if (kthread->sock_client != NULL)
{
sock_release(kthread->sock_client);
kthread->sock_client = NULL;
}
kfree(kthread);
kthread = NULL;
}
module_init(socket_init);
module_exit(socket_exit);
/* module information */
MODULE_DESCRIPTION("kernel thread as client");
MODULE_AUTHOR("Narendra Pal ");
MODULE_LICENSE("GPL");
-----------------------------------------------------------------------------------------------------------------------
server.c
-----------------------------------------------------------------------------------------------------------------------
#include <linux/module.h>
#include <linux/init.h>
#include <linux/in.h>
#include <net/sock.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/inet.h>
#include <linux/kthread.h>
#define MODULE_NAME "Client Module"
#define CONNECT_PORT 2344
#define INADDR_SEND INADDR_LOOPBACK
struct kthread_t
{
struct task_struct *thread;
struct socket *sock_server;
struct sockaddr_in addr_server;
};
struct kthread_t *kthread;
//struct socket *newsocket=NULL;
int socket_receive(struct socket* sock, struct sockaddr_in* addr, unsigned char* buf, int len)
{
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
int size = 0;
if (sock->sk==NULL) return 0;
iov.iov_base = buf;
iov.iov_len = len;
msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
//for access to full virtual address space and perform syscall
oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_recvmsg(sock,&msg,len,msg.msg_flags);
set_fs(oldfs);
return size;
}
int socket_send(struct socket *sock, struct sockaddr_in *addr, unsigned char *buf, int len)
{
struct msghdr msg;
struct iovec iov;
mm_segment_t oldfs;
int size = 0;
if (sock->sk==NULL)
return 0;
iov.iov_base = buf;
iov.iov_len = len;
msg.msg_flags = 0;
msg.msg_name = addr;
msg.msg_namelen = sizeof(struct sockaddr_in);
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
oldfs = get_fs();
set_fs(KERNEL_DS);
size = sock_sendmsg(sock,&msg,len);
set_fs(oldfs);
return size;
}
void socket_start(void)
{
int err=0,size=0;
int confd=0;
unsigned long int server_addr; // for local machine
int bufsize = 30;
unsigned char buf[bufsize+1];
struct socket *newsocket=NULL;
err =sock_create(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &kthread->sock_server) ;
if ( err <0 ){
printk(KERN_INFO"\nServer : Socket creation failed");
goto out;
}
printk(KERN_INFO"\nServer : Socket created sucessfully");
memset(&kthread->addr_server, 0, sizeof(struct sockaddr));
kthread->addr_server.sin_family = AF_INET;
//server_addr = in_aton("127.0.0.1"); // for local machine
//kthread->addr_server.sin_addr.s_addr=server_addr; //for local machine
kthread->addr_server.sin_addr.s_addr =INADDR_ANY; // for other machine
kthread->addr_server.sin_port = htons(65123);
err = (kthread->sock_server->ops->bind(kthread->sock_server, (struct sockaddr *)&kthread->addr_server, sizeof(struct sockaddr) ) ) ;
if (err < 0){
printk(KERN_INFO"\nServer : Socket binding failed");
goto out;
}
printk(KERN_INFO"\nServer : Socket binded sucessfully");
printk(KERN_INFO"\nServer : Listening on port 65123");
/* ----------------Accept conneaction---------------- */
confd=kthread->sock_server->ops->accept(kthread->sock_server,newsocket,0);
/* -----------------Receive---------------- */
memset(buf, 0, bufsize+1);
size = socket_receive(kthread->sock_server, &kthread->addr_server, buf, bufsize);
printk(KERN_INFO"\nServer : Data received is -> %s",buf);
/* -----------------Send---------------- */
memset(buf, 0, bufsize+1);
strcpy(buf,"i am server data");
size=0;
size=socket_send(kthread->sock_server, &kthread->addr_server, buf, strlen(buf));
out :
printk("\nServer : Server thread is finished");
sock_release(kthread->sock_server);
kthread->sock_server = NULL;
kthread->thread = NULL;
}
/*--------------------module functions---------------- */
int __init socket_init(void)
{
printk(KERN_INFO"\n\n\nServer : Module registered");
kthread = kmalloc(sizeof(struct kthread_t), GFP_KERNEL);
memset(kthread, 0, sizeof(struct kthread_t));
kthread->thread = kthread_run((void *)socket_start, NULL, MODULE_NAME);
if (IS_ERR(kthread->thread))
{
printk(KERN_INFO"\nServer : unable to start kernel thread");
kfree(kthread);
kthread = NULL;
return -ENOMEM;
}
return 0;
}
void __exit socket_exit(void)
{
printk(KERN_INFO"\nServer side : Module unregistered...");
if (kthread->sock_server != NULL)
{
sock_release(kthread->sock_server);
kthread->sock_server = NULL;
}
kfree(kthread);
kthread = NULL;
}
module_init(socket_init);
module_exit(socket_exit);
/*-----------------module information ---------------------*/
MODULE_DESCRIPTION("kernel thread as Server");
MODULE_AUTHOR("Narendra Pal ");
MODULE_LICENSE("GPL");
----------------------------------------------------------------------------------------------------------------------
Makefile
----------------------------------------------------------------------------------------------------------------------
obj-m+=server.o
obj-m+=client.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
No comments:
Post a Comment