hello,
im trying to send pages of 4096 bytes from kernel layer of server to kernel layer of client over a network.
can sumone plz tell me how to?
previously i tried the foll. code , for data less than a 100 bytes it worked fine , but for something larger than that the computer hangs......
(even the dmesg's wont say why)
i also wanted to know how we could use the 'sendpage' function to solve this problem.
Code:
CLIENT'S KERNEL MODULE
struct iovec iov;
char buf[1024];
struct msghdr msg;
mm_segment_t old_fs;
int addr_len, ret;
int len=6;
struct sockaddr_in addr_srv;
struct socket *sk = NULL;
printk(KERN_ALERT"hello");
console_print("Hello, world - this is the kernel speaking\n");
printk("current->comm: %s \n",current->comm);
printk("current->pid: %d \n",(int)current->pid);
printk(KERN_ALERT "\n\nHELLO THIS IS KURT EXP=> SENDING MSG : CORTEZ !!!!!!!!!\n\n");
//-------------------------------------------------------------------------------------------------------------------------
// create client socket
ret = sock_create(AF_INET, SOCK_STREAM, 0, &sk);
if (ret < 0){
printk("sock_create failed\n");
}
printk(KERN_ALERT "client sock %d\n",ret);
//-------------------------------------------------------------------------------------------------------------------------
// store server address and port in addr_srv struct
memset(&addr_srv, 0, sizeof(addr_srv));
addr_srv.sin_family = AF_INET;
addr_srv.sin_port = htons(port);
addr_srv.sin_addr.s_addr = INADDR_ANY;
addr_len = sizeof(struct sockaddr_in);
//-------------------------------------------------------------------------------------------------------------------------
// connect to server
if((sk->ops->connect))
printk(KERN_ALERT "function present\n"); //here
ret = sk->ops->connect(sk, (struct sockaddr *)&addr_srv, addr_len, 0); //null pointer
printk(KERN_ALERT "function present11111\n"); //here
printk(KERN_ALERT"cn::%d\n",ret);
//-------------------------------------------------------------------------------------------------------------------------
// recv from server
while (1){ //reving code
memset(buf, 0, sizeof(buf));
iov.iov_base = (void *)buf;
iov.iov_len = (__kernel_size_t)len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = sock_recvmsg(sk, &msg, sizeof(buf), 0);
set_fs(old_fs);
if (len > 0){
printk("got message : %s\n", buf);
break;
}
}
printk(KERN_ALERT "recv msg in client sucess:%d\n",ret);
ret=sk->ops->release(sk);
printk(KERN_ALERT "till the end !!!!!!!!!!!!!!\n");
//-------------------------------------------------------------------------------------------------------------------------
Code:
SERVER'S KERNEL MODULE
char buf[1024];
int addr_len, len=6;
struct sockaddr_in addr_srv;
struct sockaddr_in addr_cli;
struct msghdr msg;
struct iovec iov;
mm_segment_t old_fs;
struct socket *sk_cl = NULL;
struct socket *sk_srv = NULL;
int ret = 0;
//-------------------------------------------------------------------------------------------------------------------------
// create client socket
ret = sock_create(AF_INET, SOCK_STREAM, 0, &sk_srv);
if (ret < 0){
printk("sock_create failed\n");
}
//-------------------------------------------------------------------------------------------------------------------------
// bind server address and its port to server socket sk_srv
memset(&addr_cli, 0, sizeof(addr_cli));
memset(&addr_srv, 0, sizeof(addr_srv));
addr_srv.sin_family = AF_INET;
addr_srv.sin_port = htons(port);
addr_srv.sin_addr.s_addr = INADDR_ANY;
addr_len = sizeof(struct sockaddr_in);
ret = sk_srv->ops->bind(sk_srv, (struct sockaddr *)&addr_srv, addr_len);
printk("kbind ret = %d\n", ret);
if (ret < 0)
{
printk("bind failed\n");
return 1;
}
//-------------------------------------------------------------------------------------------------------------------------
// listen
ret = sk_srv->ops->listen(sk_srv, 10);
if (ret < 0){
printk("listen failed\n");
return -1;
}
//-------------------------------------------------------------------------------------------------------------------------
// fill remaining param to server socket
ret = sock_create(sk_srv->sk->sk_family, sk_srv->type, sk_srv->sk->sk_protocol, &sk_cl);
if (ret < 0)
return -1;
if (!sk_cl)
return -1;
sk_cl->type = sk_srv->type;
sk_cl->ops = sk_srv->ops;
//-------------------------------------------------------------------------------------------------------------------------
// accept client
ret = sk_srv->ops->accept(sk_srv, sk_cl, 0);
if (ret < 0){
sock_release(sk_cl);
return -1;
}
//-------------------------------------------------------------------------------------------------------------------------
// sending msg to client
memset(buf,0,((sizeof(char))*200));
strncpy(buf,"CORTEZ",6);
iov.iov_base = (void *)buf;
iov.iov_len = (__kernel_size_t)len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
old_fs = get_fs();
set_fs(KERNEL_DS);
len = sock_sendmsg(sk_cl, &msg, len);
set_fs(old_fs);
ret = sk_cl->ops->release(sk_cl);
ret = sk_srv->ops->release(sk_srv);
//-------------------------------------------------------------------------------------------------------------------------