netlink demo

NetLink Demo
Kernel

#include <linux/kernel.h>
#include <linux/module.h>
#include <net/net_namespace.h>
#include <linux/netlink.h>
#include <net/sock.h>

#define NETLINK_TEST 20

static struct sock *netlink_test_sk;

static void netlink_test_rcv(struct sk_buff *skb)
{
    struct sk_buff *skb_in, *skb_out;
    struct nlmsghdr *nlh;
    char message[32] = {0};
    int seq, pid;
    unsigned int datalength;

    skb_in = skb_get(skb);
    if (skb_in->len >= nlmsg_total_size(0)) {
        nlh = nlmsg_hdr(skb_in);
        pid = nlh->nlmsg_pid;
        seq = nlh->nlmsg_seq;
        printk("message received from process %d: %s\n", pid, (char*)NLMSG_DATA(nlh));
        sprintf(message, "哎~乖孙儿~ %d", pid);
        datalength = strlen(message) + 1;
        skb_out = nlmsg_new(NLMSG_LENGTH(datalength), GFP_KERNEL);
        nlh = nlmsg_put(skb_out, pid, seq, 0, NLMSG_ALIGN(datalength), 0);
        memcpy(nlmsg_data(nlh), message, datalength);
        netlink_unicast(netlink_test_sk, skb_out, pid, MSG_DONTWAIT);
    }
    kfree_skb(skb_in);
}

int __init netlink_test_init(void)
{
    struct netlink_kernel_cfg cfg = {
        .groups = 0,
        .input = netlink_test_rcv,
    };

    netlink_test_sk = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);
    
    if (!netlink_test_sk)
        return -ENOMEM;
    return 0;
}

void __exit netlink_test_exit(void)
{
    netlink_kernel_release(netlink_test_sk);
}

module_init(netlink_test_init);

module_exit(netlink_test_exit);

MODULE_LICENSE("GPL");

User

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/netlink.h>
#include <unistd.h>

#define NETLINK_TEST 20

#define MSG_LEN 100

int main(int argc, char* argv[])
{
    char *data = "爷爷,您孙子给你来消息啦";
    struct sockaddr_nl local, dest;
    int skfd, ret;
    unsigned int datalength, addrlength;
    struct nlmsghdr *msg_out, *msg_in;

    skfd = socket(PF_NETLINK, SOCK_RAW, NETLINK_TEST);
    if(skfd < 0){
        perror("create socket failed");
        return 0;
    }

    memset(&local, 0, sizeof(struct sockaddr_nl));
    local.nl_family = AF_NETLINK;
    local.nl_pid = getpid();
    local.nl_groups = 0;

    if(bind(skfd, (struct sockaddr *)&local, sizeof(struct sockaddr_nl)) != 0){
        perror("bind failed");
        close(skfd);
        return 0;
    }

    memset(&dest, 0, sizeof(struct sockaddr_nl));
    dest.nl_family = AF_NETLINK;
    dest.nl_pid = 0;
    dest.nl_groups = 0;
    datalength = strlen(data) + 1;
    msg_out = (struct nlmsghdr*)malloc(NLMSG_SPACE(datalength));
    memset(msg_out, 0, NLMSG_SPACE(datalength));
    msg_out->nlmsg_len = NLMSG_SPACE(datalength);
    msg_out->nlmsg_flags = 0;
    msg_out->nlmsg_type = 0;
    msg_out->nlmsg_seq = 0;
    msg_out->nlmsg_pid = local.nl_pid;
    
    memcpy(NLMSG_DATA(msg_out), data, strlen(data));

    ret = sendto(skfd, msg_out, msg_out->nlmsg_len, 0, (struct sockaddr*)&dest, sizeof(struct sockaddr_nl));
    if(!ret){
        perror("send failed");
        free(msg_out);
        close(skfd);
        return 0;
    }
    
    free(msg_out);
    msg_in = (struct nlmsghdr*)malloc(NLMSG_SPACE(MSG_LEN));
    memset(msg_in, 0, NLMSG_SPACE(MSG_LEN));
    addrlength = sizeof(struct sockaddr_nl);

    ret = recvfrom(skfd, msg_in, NLMSG_SPACE(MSG_LEN), 0, (struct sockaddr*)&dest, &addrlength);
    if(!ret){
        perror("recv failed");
        free(msg_in);
        close(skfd);
        return 0;
    }
    
    printf("message received from kernel: %s\n", (char*)NLMSG_DATA(msg_in));
    free(msg_in);
    close(skfd);
    return 0;
}

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值