【问题标题】:kernel communication内核通信
【发布时间】:2012-08-15 13:15:23
【问题描述】:

我想向内核空间发送一个数据数组,(我在我的 kext 中使用了回调函数) 问题是当我使用发送功能时,我看到一些奇怪的东西,我在 2 个场景中解释: 1) ... char f[]={'1','2','3','4','5','6'}; 发送(袜子,f,sizeof(f),0); 好吧,当我 printf 我在 kext 中收到的内容时: 123456

2) ... // 我用 0 替换 f[2]

char f[]={'1','2',0,'4','5','6'}; 发送 (sock,f,sizeof(f),0);

但这一次,当我 printf 我在 kext 中收到的内容时: 120000

似乎发送函数在第一个 0 字节之后的每个字节都为零? 到底是怎么回事?这是发送功能错误吗? 我用的是 xcode 4.1,我的操作系统是 lion 这是用户空间部分:

int main(int argc, char* const*argv)
{
    struct ctl_info ctl_info;
    struct sockaddr_ctl sc;
    char str[MAX_STRING_LEN];
    int sock = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
    if (sock < 0)
        return -1;
    bzero(&ctl_info, sizeof(struct ctl_info));
    strcpy(ctl_info.ctl_name, "pana.ifmonitor.nke.foo");
    if (ioctl(sock, CTLIOCGINFO, &ctl_info) == -1)
        return -1;
    bzero(&sc, sizeof(struct sockaddr_ctl));
    sc.sc_len = sizeof(struct sockaddr_ctl);
    sc.sc_family = AF_SYSTEM;
    sc.ss_sysaddr = SYSPROTO_CONTROL;
    sc.sc_id = ctl_info.ctl_id;
    sc.sc_unit = 0;
    if (connect(sock, (struct sockaddr *)&sc, sizeof(struct sockaddr_ctl)))
        return -1;


     unsigned char data_send[]={'a','l','i','0','1','2','4','l','i',0,'1','2','4','l','i','0','1'};


    size_t data_recive;
    int j=0;
    char data_rcv[8192];


        send( sock, data_send, 17*sizeof(char), 10 );


        printf("\n");
        sleep(1);


        close(sock);
        return 0;

    }

这是内核空间代码的一部分,负责获取用户空间数据:

errno_t EPHandleWrite(kern_ctl_ref ctlref, unsigned int unit, void *userdata,mbuf_t m, int flags)
{

    printf("\n EPHandleWrite called---------------------- \n");
    //char data_rec[50];

    //unsigned char *ptr = (unsigned char*)mbuf_data(m);
    //char ch;
    //mbuf_copydata(m, 0, 50, data_rec);

    //strncpy(&ch, ptr, 1 );


    size_t data_lenght;
    data_lenght = mbuf_pkthdr_len(m);

    char data_receive[data_lenght];
    strncpy( data_receive, ( char * ) mbuf_data(m) , data_lenght );

    printf("data recied %lu\n",data_lenght);

    for(int i=0;i<data_lenght;++i)
    {
        printf("%X ",data_receive[i]);
    }
 return 0
}

好吧,它在控制台中打印: 61 6C 69 30 31 32 34 6C 69 0 0 0 0 0 0 0 0 当我将发送数据更改为: {'a','l','i','0','1','2','4','l','i',**'0'**,'1','2','4','l','i','0','1'}; 我是正确的,事实上我在发送数据的第一个零字节之后得到了所有的 0

【问题讨论】:

  • 我注意到您使用整数 0,而不是字符 '0' 来初始化数组成员。您究竟如何打印接收到的缓冲区?
  • 当我收到 n 字节时,我会像这样对它们进行迭代并逐个打印它们:假设我收到 n 字节 for( int i=0;i
  • send 和 recv 函数是否可以将 0 后的零字符设置为零?我该如何调查这个??
  • 我认为您需要发布一些实际代码,无法分辨出您正在尝试做什么以及究竟什么不起作用。
  • 我正在尝试编写防火墙;事实上,我有两个程序:一个是加载到内核中的 kext,并假设将输入数据发送到用户空间,而其他程序等待传入数据并在进行一些更改后将操作数据重新注入内核空间;但是当我发送数据时会出现问题其中包含 0,recv 函数没有完全获取数据,并且我收到的一些数据在第一个 0 之后所有字节都为零,如上所示:我应该收到 120456 但我得到 120000????

标签: kernel-extension


【解决方案1】:

问题在于strncpy 行——如果您查看strncpy 的文档,您会注意到它只会复制到0 字节,因此它只适用于处理C 字符串。如果您需要复制任意二进制数据,请使用 memcpy。

【讨论】:

  • 我正在寻找一种方法,让内核通知用户空间进程传入或传出数据包,直到进程从缓冲区读取该数据包并对其进行一些处理,我知道有通知机制但它有开销(每个输入或输出数据包一个通知结构)是否有任何替代解决方案???
猜你喜欢
  • 2012-04-21
  • 2011-11-24
  • 2023-03-27
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
相关资源
最近更新 更多