从Linux内核中获取TCP数据包到用户程序。

这段代码展示了如何在Linux内核中使用Netlink套接字捕获和处理TCP数据包。它创建了一个Netlink套接字来接收和发送消息,并通过Netfilter钩子函数`uc_parse_input_ip`和`uc_parse_output_ip`解析IP包,获取源和目的IP地址以及TCP头信息。此外,还有一个用户空间线程`uc_save_tcp_packet_thread`用于接收内核发送的消息。
摘要由CSDN通过智能技术生成


#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/ip.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <linux/netlink.h>

#define MAX_MSGSIZE 1024

struct sock *nl_sk = NULL;
char recv_ip_addr[20] = {0} ;
int pid = 1;

static void uc_send_nlmsg(u32 pid, char *data,int data_len)
{
    struct sk_buff  *skb;
    struct nlmsghdr  *nlh;
    const char *fn;
    char *datab;
    u32 skblen;
    int err;

    if (!nl_sk)
    {
        err = -ENOENT;
        fn = "netlink socket";
        goto msg_fail;
    }

    skblen = NLMSG_SPACE(MAX_MSGSIZE);
    skb = alloc_skb(skblen, GFP_KERNEL);
    if (!skb)
    {
        err = -ENOBUFS;
        fn = "alloc_skb";
        goto msg_fail;
    }

    nlh = nlmsg_put(skb, pid, 0, 0xF0, MAX_MSGSIZE, 0);
    if (!nlh)
    {
        err = -ENOBUFS;
        fn = "nlmsg_put";
        goto msg_fail_skb;
    }
   
    datab = NLMSG_DATA(nlh);
    memcpy(datab, data, data_len);
    *(datab+data_len) ='\0';
   
    err = nlmsg_unicast(nl_sk, skb, pid);
    if (err < 0)
    {
        fn = "nlmsg_unicast";
        goto msg_fail;
    }

    return;
   
msg_fail_skb:
    kfree_skb(skb);
msg_fail:

    printk("%s: Dropped Message : pid %d msg:%s msglen %d: %s : err %d\n",
            __func__, pid, data, data_len, fn, err);
   
    return;
}


void uc_kernel_user_comm_recv (struct sk_buff *__skb)
{
    struct sk_buff *skb = skb_get(__skb);
    struct nlmsghdr *nlh = nlmsg_hdr(skb);
    char buf[50] = {0} ;

    pid = nlh->nlmsg_pid;
   
    if (nlh->nlmsg_len < NLMSG_HDRLEN || skb->len < nlh->nlmsg_len)
    {
        return ;
    }
   
    memset(recv_ip_addr, 0x00, 20) ;
    strcpy(recv_ip_addr, (char*)NLMSG_DATA(nlh)) ;

    sprintf(buf, "recv ip.addr = %s", recv_ip_addr) ;
    uc_send_nlmsg(pid, buf, strlen(buf)) ;

    printk("received netlink message payload: %s   pid = %d\n", (char*)NLMSG_DATA(nlh), pid);
   
    return ;
}
   
void uc_kernel_user_comm_send(char *buf)
{
    uc_send_nlmsg(pid, buf, strlen(buf)) ;
}

int uc_kernel_user_comm_get_buf(char *src, int len)
{
    int recv_len = strlen(recv_ip_addr) ;
   
    if (src == NULL || (len < recv_len) || (recv_len == 0))
    {
        return  0;
    }
   
    strcpy(src, recv_ip_addr) ;

    return 1 ;
}


static int __init uc_kernel_user_comm_init(void)
{

  //  printk("netlink init 1 \

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值