Hi,

I want to use netlink socket between kernel and userspace in order to
get some information from kernel code.
I use netlink_broadcast function in order to send information to a
specific group, and my user-level code connect to this socket with the
correct groupId but doesn't receive anythings.
Everythings works when I use netlink_unicast.

I use centos5.2, kernel 2.6.18-92.1.22

If someone can help me...

Thierry





---------------------------

kernel-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>
//#include <net/netlink.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;

        //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);
        nlh = (struct nlmsghdr *)skb->data;

        nlh->nlmsg_len =  NLMSG_SPACE(MAX_PAYLOAD);
        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;

        //Envoi des donnees
        printk( KERN_ALERT "j'envoi els donnees\n");
        netlink_broadcast(nl_sk, skb, 0, GROUP_IB, GFP_KERNEL);
        sock_release(nl_sk->sk_socket);
}

static int __init netlink_ib_module_init(void)
{
        printk(KERN_INFO "netlink_ib module: Initialisation de la Netlink 
Socket\n");
        netlink_ib_open();
        return 0;
}

static void __exit netlink_ib_module_exit(void)
{
        printk(KERN_INFO "Dechargement de netlink_ib module\n");
}

MODULE_DESCRIPTION("Kernel/User socket for IB support");
module_init(netlink_ib_module_init);
module_exit(netlink_ib_module_exit);

----------------------------

and the user-level code:

#include <sys/socket.h>
#include <linux/netlink.h>
#define NETLINK_IB 24
#define GROUP_IB 59

#define MAX_PAYLOAD 1024

struct sockaddr_nl src_addr, dst_addr;
struct nlmsghdr *nlh = NULL;
struct msghdr msg;
struct iovec iov;
int sock_fd;


int main()
{
        /* Ouverture de la socket Netlink*/
        sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_IB);

        memset(&src_addr, 0, sizeof(src_addr));
        src_addr.nl_family = AF_NETLINK;
        src_addr.nl_pid = getpid();
        src_addr.nl_groups = GROUP_IB; // Multicast
        bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));

        memset(&dst_addr, 0, sizeof(dst_addr));
        nlh = (struct nlhmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
        memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));

        iov.iov_base = (void *)nlh;
        iov.iov_len = nlh->nlmsg_len;
        msg.msg_name = (void *)&dst_addr;
        msg.msg_namelen = sizeof(dst_addr);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;

        printf("On ecoute...\n");
        /* On ecoute ce que le kernel renvoi */
        recvmsg(sock_fd, &msg, 0);
printf("jai recu");
        char * truc = NLMSG_DATA(nlh);
        printf("Message recu dans lespace utilisateur: %s\n", truc);
        close(sock_fd);

        return 0;

}

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to [email protected]
Please read the FAQ at http://kernelnewbies.org/FAQ

Reply via email to