Hi All,
My kernel module use netlink socket to communicate with my program
user space the kernel code is show bellow. the code was compile and load
succesfull. but when my program in user space try to connect to my
kernel module then my computer is hang.
Could someone help me to fixed this thank you very much and appreciate
for help
Kernel code:
struct des_sock{
u32 p_grp;
u32 p_pid;
};
struct sock *g_mntr_sock;
struct usr_msg_t *usrmsg;
struct sk_buff *skb;
struct des_sock desip;
int mntr_create_handler()
{
g_mntr_sock=netlink_kernel_create(NETLINK_MONITOR,mntr_recieved_from_user);
if (!g_mntr_sock){
return -ENOMEM;
}else{
printk("Could not create netlink socket sucess \n");
return 1;
}
}
int send_to_user(struct sk_buff *skb_msg)
{
int status=0;
if (skb_msg == NULL)
{
printk(" Message send to user was null \n");
return -1;
}
//from kernel
NETLINK_CB(skb_msg).groups=0;
NETLINK_CB(skb_msg).pid=0;
//to user process
NETLINK_CB(skb_msg).dst_groups=desip.p_grp;
NETLINK_CB(skb_msg).dst_pid=desip.p_pid;
status=netlink_unicast(g_mntr_sock,skb_msg,desip.p_pid,MSG_DONTWAIT);
if (status < 0)
{
printk("Message could not send to user space \n");
}
else if (status == 0 )
{
printk("NO!!! Message was sent %i byte to user space \n",status);
}
else
{
printk("Message was sent %i byte to user space \n",status);
}
return status;
}
static inline void mntr_rcv_skb(struct sk_buff *skb)
{
int type, flags, nlmsglen, skblen;
struct nlmsghdr *nlh;
skblen = skb->len;
if (skblen < sizeof(*nlh))
{
printk("skblen < sizeof(*nlh) Message was broken\n");
return;
}
nlh = (struct nlmsghdr *)skb->data;
nlmsglen = nlh->nlmsg_len;
if (nlmsglen < sizeof(*nlh) || skblen < nlmsglen)
{
printk("nlmsglen < sizeof(*nlh) || skblen < nlmsglen Message was
broken \n");
return;
}
desip.p_grp=0;
desip.p_pid= nlh->nlmsg_pid;
printk("%s Process user id %i \n",__FUNCTION__,desip.p_pid);
flags = nlh->nlmsg_flags;
type = nlh->nlmsg_type;
usrmsg=NLMSG_DATA(nlh);
}
void mntr_recieved_from_user(struct sock *sk,int len)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
if (!g_mntr_sock)
return;
while((skb=skb_dequeue(&sk->receive_queue)) != NULL)
{
mntr_rcv_skb(skb);
nlh = (struct nlmsghdr *)skb->data;
printk("%s: message received: %s \n",__FUNCTION__,NLMSG_DATA(nlh));
send_to_user(skb);
//kfree_skb(skb);
}
}
My client code:
int fd;
struct sockaddr_nl proces_sk;
struct sockaddr_nl krnl_sk;
struct msghdr msg;
struct nlmsghdr *nlhdr;
struct iovec iov;
int main()
{
int status=0;
//char buf[MONITOR_BUFF_SIZE];
u_int32_t rcvbufsize=150000;
fd = socket(PF_NETLINK,SOCK_RAW,NETLINK_MONITOR);
memset(&proces_sk,0,sizeof(proces_sk));
proces_sk.nl_family=AF_NETLINK;
proces_sk.nl_pid=getpid();
proces_sk.nl_groups=0;
status =bind(fd,(struct sockaddr *)&proces_sk,sizeof(proces_sk));
if(status < 0){
perror("Binding..");
printf("Could not bind \n");
return -1;
}
status = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rcvbufsize,
sizeof(rcvbufsize));
nlhdr =(struct nlmsghdr *)malloc(NLMSG_SPACE(MONITOR_BUFF_SIZE));
//initialize nl message header
nlhdr->nlmsg_len=NLMSG_SPACE(MONITOR_BUFF_SIZE);
nlhdr->nlmsg_pid=getpid();
nlhdr->nlmsg_type=NETLINK_MONITOR;
nlhdr->nlmsg_flags=0;
strcpy(NLMSG_DATA(nlhdr),"Hello kernel, I am from user space");
iov.iov_base = (void *)nlhdr;
iov.iov_len = nlhdr->nlmsg_len;
msg.msg_name = (void *)&krnl_sk; /* optional address */
msg.msg_namelen = sizeof(krnl_sk);/* size of address */
msg.msg_iov =&iov; /* scatter/gather array */
msg.msg_iovlen=1;
sendmsg(fd,&msg,0);
//send to kernel
memset(&krnl_sk,0,sizeof(krnl_sk));
krnl_sk.nl_family=AF_NETLINK;
krnl_sk.nl_pid=0;
krnl_sk.nl_groups=0;
recvmsg(fd,&msg,0);
close(fd);
return 0;
}
Nhanle
--
Kernelnewbies: Help each other learn about the Linux kernel.
Archive: http://mail.nl.linux.org/kernelnewbies/
FAQ: http://kernelnewbies.org/faq/