【问题标题】:Monitoring Network Packets Using Network Kernal Extension使用网络内核扩展监控网络数据包
【发布时间】:2019-02-12 14:59:12
【问题描述】:

我正在构建 NKE(网络内核扩展)来动态过滤和修改数据包。 myipfilter_output_redirect 回调给 mbuf_t 指针,并根据研究知识,它具有与网络调用相关的所有信息。 我想从这个 mbuf_t 中读取 html 并将一个 css/html 注入其中。我怎样才能实现它?

static errno_t myipfilter_output(void* cookie, mbuf_t* data, ipf_pktopts_t options) {
    if (data)
        log_ip_packet(data, kMyFiltDirOut);
    return 0;
}

static errno_t myipfilter_input(void* cookie, mbuf_t* data, int offset, u_int8_t protocol) {
    if (data)
        log_ip_packet(data, kMyFiltDirIn);
    return 0;
}

static void myipfilter_detach(void* cookie) {
    /* cookie isn't dynamically allocated, no need to free in this case */
    struct myfilter_stats* stats = (struct myfilter_stats*)cookie;
    printf("UDP_IN %lu UDP OUT: %lu TCP_IN: %lu TCP_OUT: %lu ICMP_IN: %lu ICMP OUT: %lu OTHER_IN: %lu OTHER_OUT: %lu\n",
           stats->udp_packets[kMyFiltDirIn],
           stats->udp_packets[kMyFiltDirOut],
           stats->tcp_packets[kMyFiltDirIn],
           stats->tcp_packets[kMyFiltDirOut],
           stats->icmp_packets[kMyFiltDirIn],
           stats->icmp_packets[kMyFiltDirOut],
           stats->other_packets[kMyFiltDirIn],
           stats->other_packets[kMyFiltDirOut]);
    g_filter_detached = TRUE;
}

static struct ipf_filter g_my_ip_filter = {
    &g_filter_stats,
    "com.xxx.NetworKext",
    myipfilter_input,
    myipfilter_output_redirect,  //    myipfilter_output,
    myipfilter_detach
};

kern_return_t MyIPFilter_start () {
    printf("MyIPFilter_start called");
    int result;
    result = ipf_addv4(&g_my_ip_filter, &g_filter_ref);
    return result;
}

kern_return_t MyIPFilter_stop () {
    printf("MyIPFilter_stop called");
    ipf_remove(g_filter_ref);
    return KERN_SUCCESS;
}


static errno_t myipfilter_output_redirect(void* cookie, mbuf_t* data, ipf_pktopts_t options)
{
    // not printing all html and css tags
    printf("myipfilter_output_redirect called");
    unsigned char* dataString = NULL;
    for (mbuf_t mb = *data; mb; mb = mbuf_next(mb))
    {
        dataString = mbuf_data(mb);
        size_t len = mbuf_len(mb);
        for (size_t i = 0; i < len; i++)
        {
            printf("%c", dataString[i]);
        }
    }

    printf("dataString: %s", dataString);
}

如果您可以在这里提供任何帮助,我已经制作了一个示例 repo。

【问题讨论】:

  • 一个网络缓冲区可能只包含发送到/从您的节点发送的任何 HTML 资源的一部分。您尝试做的事情不会奏效。
  • 现在我得到的是 http 标头,但不是 html。那么我应该在哪里寻找html? @ewindes
  • HTML(通常)将被拆分为多个 mbuf,这些 mbuf 跟在带有标题的那个之后。你需要一个新的计划。您是否考虑过 HTTP 代理?

标签: c memory buffer packet-sniffers kernel-extension


【解决方案1】:

您应该选择套接字过滤器,并且为了检索 HTML 有效负载,您应该使用 mbuf_t 数据读取 mbuf_t。下面的方法从头开始打印每个字节,所以把它放在你的sf_data_in_func 回调中。

print_mbuf_data(*data);

这对你有用。

static void print_mbuf_data(mbuf_t mb){
    //    unsigned char *tmp_buffer = (unsigned char *) mbuf_datastart(mb);
        unsigned char *tmp_buffer = (unsigned char *) mbuf_data(mb);
        unsigned long line = 0, index = 0, character = 0, hex_length = 0x80; // hex_length has limit of 64 decimal
        unsigned long length = mbuf_len(mb);
        unsigned char hex_temp [0x80]; // buffer has limit of 64 decimal

    for (index = 0; index < length; index += 0x80)
    {
        memset(hex_temp, 0, hex_length);
        line = length - index > 0x80 ? 0x80 : length - index;
        for (character = 0; character < line; character++)
        {
            snprintf(((char *) hex_temp + strlen((char *) hex_temp)),
                     hex_length - strlen((char *) hex_temp), "%c", tmp_buffer[index + character]);
        }
        printf("%s", hex_temp);
    }
}

【讨论】:

    猜你喜欢
    • 2020-05-02
    • 2018-01-14
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-26
    • 1970-01-01
    相关资源
    最近更新 更多