首页 > 解决方案 > NKE 套接字过滤器 (MacOS):无法正确重新注入输出数据包

问题描述

使用应过滤网络流量的内核扩展时,我在 MacOS 中遇到问题。

传入的数据效果很好。但是,上传大于 500kb 的数据会导致连接突然关闭。可以毫无问题地上传较小的文件。这是通过任何协议,在 ftp、http、https 等上测试的。

简化的驱动程序代码:

errno_t tl_data_fn(void *cookie, socket_t so, const struct sockaddr *addr, mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags, FilterSocketDataDirection direction) {     
    if (check_tag(data, gidtag, FILTER_TAG_TYPE, direction == FilterSocketDataDirectionIn ? IN_DONE : OUT_DONE)) {  
        return 0;  
    }  

    if (!cookie) return result;  

    filter_cookie *f_cookie = get_filter_cookie(cookie);  

    FilterNotification notification;   
    if (direction == FilterSocketDataDirectionIn) {  
        notification.event = FilterEventDataIn;  
    } else {  
        notification.event = FilterEventDataOut;  
    }  
    notification.socketId = (uint64_t)so;  
    notification.inputoutput.dataSize = (uint32_t)mbuf_pkthdr_len(*data);  

    mbuf_copydata(*data, offset, notification.inputoutput.dataSize, notification.inputoutput.data);  

    ctl_enqueuedata(f_cookie->ctl_ref, f_cookie->ctl_unit, &notification, sizeof(FilterNotification), CTL_DATA_EOR);  

    mbuf_freem(*data);  

    if (control != NULL && *control != NULL)  
        mbuf_freem(*control);  

    return EJUSTRETURN;  
}  

errno_t tl_data_in_fn(void *cookie, socket_t so, const struct sockaddr *from, mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags) {  
    return tl_data_fn(cookie, so, from, data, control, flags, FilterSocketDataDirectionIn);  
}  

errno_t tl_data_out_fn(void *cookie, socket_t so, const struct sockaddr *to, mbuf_t *data, mbuf_t *control, sflt_data_flag_t flags) {  
    return tl_data_fn(cookie, so, to, data, control, flags, FilterSocketDataDirectionOut);  
}  



errno_t ctl_send(kern_ctl_ref ctl_ref, u_int32_t unit, void *unitinfo, mbuf_t m, int flags) {      
    FilterClientResponse response;  
    mbuf_copydata(m, 0, sizeof(response), &response);  

    mbuf_t data;  
    mbuf_allocpacket(MBUF_WAITOK, response.dataSize, NULL, &data);  
    mbuf_copyback(data, 0, response.dataSize, response.data, MBUF_WAITOK);  
    set_tag(&data, gidtag, FILTER_TAG_TYPE, response.direction == FilterSocketDataDirectionIn ? IN_DONE : OUT_DONE);  

    if (response.direction == FilterSocketDataDirectionIn) {  
        sock_inject_data_in((socket_t)response.socketId, NULL, data, NULL, 0);  
    } else {  
        sock_inject_data_out((socket_t)response.socketId, NULL, data, NULL, 0);  
    }  

    mbuf_freem(m);  
    return 0;  
}  

tl_data_in_fntl_data_out_fn函数用于sftl_filter. ctl_send用于kern_ctl_regas ctl_send_func

简化的用户空间进程代码:

int s = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);  

//connect to driver  

FilterNotification notification;  
while (recv(s, &notification, sizeof(FilterNotification), 0) == sizeof(FilterNotification)) {  
    FilterClientResponse response;  
    response.socketId = notification.socketId;  
    response.direction = (notification.event == FilterEventDataIn) ? FilterSocketDataDirectionIn : FilterSocketDataDirectionOut;  
    response.dataSize = notification.inputoutput.dataSize;  
    memcpy(response.data, notification.inputoutput.data, notification.inputoutput.dataSize);  
    send(s, &response, sizeof(response), 0);  
}  

任何帮助/建议将不胜感激。Kext 和用户空间进程存储库

谢谢

标签: c++cmacoslinux-kernelkernel-extension

解决方案


推荐阅读