On Wed, Apr 15, 2009 at 8:32 PM, Thierry <[email protected]> wrote:
> Hi,
>
>
> I have tried 3 solutions:
>
> 1. using nlh = (struct nlmsghdr *) skb_put(skb,
> NLMSG_SPACE(MAX_PAYLOAD)); instead of nlh = (struct nlmsghdr
> *)skb->data;
> No kernel panic, but doesn't work (it is just like before)
>
> 2. with skb_copy_expand and skb_push like in the second example you
> gave me, No kernel panic, but doesn't work (juste like before)
>
> 3. with the example of wwrap.c (your last idea), doest compile, or kernel
> panic
> But i don't really now what I should put in *message type* argument in
> NLMSG_PUT.
> My code for last solution is bellow.
>
> If never you have others ideas.
>
> Thierry
>
>
>
Have to debug one step at a time. My first observation is that u did
not put the NLMSG_DONE as the type for your netlink message, which is
needed for last message.
Another hint possibly is due to alignment problem:
Yours is:
nlh = (struct nlmsghdr *) skb_put(skb, NLMSG_SPACE(MAX_PAYLOAD))
but kernel source showed something like this:
nlh = (struct nlmsghdr *) skb_put(skb, NLMSG_ALIGN(size))
might have to play around with different problem solving.........
> ------
>
>
> struct sk_buff *skb = NULL;
> struct nlmsghdr *nlh = NULL;
> int err;
> int size;
> unsigned char * old_tail;
> char * pos = NULL;
> size = NLMSG_SPACE(MAX_PAYLOAD);
> u32 pid;
>
> //Creation de la netlink socket <=> socket()
> nl_sk = netlink_kernel_create(NETLINK_IB, GROUP_IB, nl_ib_data_ready,
> THIS_MODULE);
>
> skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
>
> if (skb == NULL)
> {
> printk(KERN_ALERT "erreur\n");
> return;
> }
> old_tail = skb -> tail;
> //nlh = (struct nlmsghdr *)skb->data;
> nlh = NLMSG_PUT(skb, 0, 0, 0, size-sizeof(*nlh));
> int len = sizeof("Message du kernel =(");
> pos = NLMSG_DATA(len);
> memset(pos,0,len);
>
> nlh->nlmsg_pid = 0; //Depuis le noyau
> nlh->nlmsg_flags = 0;
>
> strcpy(NLMSG_DATA(nlh), "Message du kernel =(");
> NETLINK_CB(skb).pid = 0;
> NETLINK_CB(skb).dst_pid = 0; //Multicast
> NETLINK_CB(skb).dst_group = GROUP_IB;
> nlh->nlmsg_len = skb->tail - old_tail;
>
> //Envoi des donnees
> printk( KERN_ALERT "j'envoi els donnees\n");
> err = netlink_broadcast(nl_sk, skb, 0, GROUP_IB, GFP_KERNEL);
>
>
> On Fri, Apr 10, 2009 at 2:29 PM, Peter Teoh <[email protected]> wrote:
>> On Fri, Apr 10, 2009 at 4:12 AM, Thierry <[email protected]> wrote:
>>> Hi,
>>>
>>> I have tried to change groupId, with different value, but there should
>>> be somethings wrong: the userspace prgm doesn't receive message.
>>> I would like to know if there is a plugin for tcpdump or an way of
>>> capture trafic on netlink socket, just like usual network socket in
>>> order to see were is my problem: in kernel space code or userspace
>>> code.
>>> My program code is attached, with english commit (sorry for last mail).
>>> I have also tried my code on differents kernel (redhat 4.4 with kernel
>>> 2.6.9-42.ELsmp, centos52 kernel 2.6.18-92.1.22).
>>>
>>> If there is other ways to send information from kernel space to user
>>> space...
>>> My aim is to capture data trafic from infiniband and dump trafic, for
>>> example in a netlink socket. Then I will be able with a userspace code
>>> to translate informations in .cap files.
>>> Thats why I think netlink_broadcast is a good idea.
>>>
>>> I will be always looking at kernelnewbie mailinglsit for several month,
>>>
>>> Regards,
>>>
>>> Thierry
>>>
>>>
>>>
>>> --------------
>>> kernel-level code
>>>
>>>
>>> #include <linux/config.h>
>>> #include <linux/socket.h>
>>> #include <linux/kernel.h>
>>> #include <linux/module.h>
>>> #include <linux/netlink.h>
>>> #include <net/sock.h>
>>>
>>> #define NETLINK_IB 24
>>> #define MAX_PAYLOAD 1024
>>> #define GROUP_IB 59
>>>
>>>
>>> static struct sock *nl_sk = NULL;
>>>
>>> static void nl_ib_data_ready (struct sock *sk, int len)
>>> {
>>> wake_up_interruptible(sk->sk_sleep);
>>> }
>>>
>>> static void netlink_ib_open()
>>> {
>>> struct sk_buff *skb = NULL;
>>> struct nlmsghdr *nlh = NULL;
>>> int err;
>>> u32 pid;
>>>
>>> //Socket_create
>>> nl_sk = netlink_kernel_create(NETLINK_IB, GROUP_IB, nl_ib_data_ready,
>>> THIS_MODULE);
>>>
>>> skb = alloc_skb(NLMSG_SPACE(MAX_PAYLOAD),GFP_KERNEL);
>>> nlh = (struct nlmsghdr *)skb->data;
>>>
>>> nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
>>> nlh->nlmsg_pid = 0; //from kernel
>>> nlh->nlmsg_flags = 0;
>>>
>>> strcpy(NLMSG_DATA(nlh), "Message from kernel ");
>>> NETLINK_CB(skb).pid = 0;
>>> NETLINK_CB(skb).dst_pid = 0; //Multicast
>>> NETLINK_CB(skb).dst_group = GROUP_IB;
>>>
>>> //data send
>>> printk( KERN_ALERT "data sent\n");
>>> netlink_broadcast(nl_sk, skb, 0, GROUP_IB, GFP_KERNEL);
>>> sock_release(nl_sk->sk_socket);
>>> }
>>
>> check this out:
>>
>> http://www.linuxjournal.com/article/7356
>>
>> read the comment, amazingly, someone else HAVE EXACTLY THE SAME
>> PROBLEM as yours, and his comment:
>>
>> ========================
>>
>> here is missed one importang thing:
>>
>> before strcpy we should call
>>
>> skb_put(skb, NLMSG_SPACE(MAX_PAYLOAD))
>>
>> or change
>>
>>
>> nlh = (struct nlmsghdr *)skb->data;
>> nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
>> nlh->nlmsg_pid = 0; /* from kernel */
>> nlh->nlmsg_flags = 0;
>>
>> ==========================
>>
>> and looking into kernel source:
>>
>> s = skb_copy_expand(skb, 8, 0, GFP_ATOMIC);
>> skb_push(s, 8);
>> s->data[0] = 'z';
>> s->data[1] = 'y';
>> s->data[2] = 'd';
>> s->data[3] = 'a';
>> s->data[4] = 's';
>> printk("len1=%d, len2=%d", skb->len, s->len);
>> netlink_broadcast(rtnl, s, 0, RTMGRP_LINK, GFP_ATOMIC);
>>
>>
>> and this:
>>
>> /*ÌîдÊý¾Ý±¨Ïà¹ØÐÅÏ¢*/
>> nlh = NLMSG_PUT(skb, 0, 0, WAI_K_MSG, size-sizeof(*nlh));
>> pos = NLMSG_DATA(nlh);
>> memset(pos, 0, len);
>>
>> /*´«Êäµ½Óû§¿Õ¼äµÄÊý¾Ý*/
>> memcpy(pos, msg, len);
>> /*¼ÆËã¾¹ý×Ö½Ú¶ÔÆäºóµÄÊý¾Ýʵ¼Ê³¤¶È*/
>> nlh->nlmsg_len = skb->tail - old_tail;
>> NETLINK_CB(skb).dst_group = COMMTYPE_GROUP;
>> netlink_broadcast(netlink_sk, skb, 0, COMMTYPE_GROUP, GFP_ATOMIC);
>>
>> all having the same pattern as the comment.
>>
>> Hopefully this helps.
>>
>> --
>> Regards,
>> Peter Teoh
>>
>
--
Regards,
Peter Teoh
--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ