新版nDPI开发自定义协议

1 篇文章 0 订阅

一、前言
最近因项目需要用到nDPI采集流量进行报文深度检测,主要在nDPI基础上进行协议扩展,根据官网用户手册描述有两种方式支持协议扩展,在此通过nDPI示例程序ndpiReader进行展示。
在ndpiReader中增加自定义协议的方式如下:
1、是通过编辑example/protos.txt文件来使ndpiReader匹配相应的协议,但是这种的匹配条件有限,只能通过端口、host和IP地址来定义新协议。
2、通过在源码中注册自定义协议以及自己编写自定义协议的匹配逻辑,来自定义协议。这种方法需要编码,但是协议自定义匹配方式更为灵活。

二、开发自定义协议
1、修改protos.txt
此种方法网上介绍的资料很多,在此省略。
2、修改源码
以下说明基于nDPI 最新版本3.4版本中的源码添加自定义协议。为了方便说明,假设我们需要自定义的协议名字叫做ONEONEPROTOCOL。顾名思义,当应用层协议中的数据全为1,那么就认为这是ONEONEPROTOCOL协议。
详细步骤如下:
1)添加新的协议ID
首先,每一个协议都必须在头文件ndpi_protocol_ids.h中有一个对应的协议ID的定义,ID号数字不能随便写,需要在现有的ID编号后新增。

 // Reddragon
  NDPI_PROTOCOL_ONEONEPROTOCOL        = 254, /* all of the tcp payload is 1*/

2)编写协议源文件
在定义完协议ID后,我们必须在src/lib/protocols/文件夹中创建自定义协议的源文件:oneoneprotocol.c。该文件用来识别协议格式。

#include "ndpi_protocol_ids.h"
#define NDPI_CURRENT_PROTO NDPI_PROTOCOL_ONEONEPROTOCOL
#include "ndpi_api.h"

void ndpi_search_oneoneprotocol(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) {
    struct ndpi_packet_struct *packet = &flow->packet;
    u_int nIndex = 0;
    u_int count = 0;
    u_int16_t dport = 0;
    
    NDPI_LOG_DBG(ndpi_struct, "search oneoneprotocol\n");
    printf("\n packet_len = %d\n", packet->payload_packet_len);
    
    while(nIndex < packet->payload_packet_len) {
        printf("\n nIndex = %d, payloadValue = %d \n", nIndex, packet->payload[nIndex]);
        if (packet->payload[nIndex] == 0x31){
            count++;
        }
        nIndex++;
    }

    if(count == packet->payload_packet_len){
        printf("\n count = %d, found oneoneprotocol \n", count);
        NDPI_LOG_INFO(ndpi_struct, "found oneoneprotocol\n");
        ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_ONEONEPROTOCOL, NDPI_PROTOCOL_UNKNOWN);
        return;
    }

    NDPI_EXCLUDE_PROTO(ndpi_struct, flow);
}

void init_oneoneprotocol_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id,
                             NDPI_PROTOCOL_BITMASK *detection_bitmask)
{
    ndpi_set_bitmask_protocol_detection(
        "oneoneprotocol", ndpi_struct, detection_bitmask, *id,
                                        NDPI_PROTOCOL_ONEONEPROTOCOL,
                                        ndpi_search_oneoneprotocol,
                                        NDPI_SELECTION_BITMASK_PROTOCOL_TCP_WITH_PAYLOAD,
                                        SAVE_DETECTION_BITMASK_AS_UNKNOWN,
                                        ADD_TO_DETECTION_BITMASK);
    *id += 1;
}

3)添加你的协议到nDPI
在ndpi_main.c中注册,依葫芦画瓢在1508行后面添加ndpi_set_proto_defaults函数。

        // oneoneprotocol
  ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_ONEONEPROTOCOL, 1 /* no subprotocol */,
        no_master,
        no_master, "ONEONEPROTOCOL", NDPI_PROTOCOL_CATEGORY_CHAT,
        ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
        ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);

通过适当的宏并将他们设置到检测模块中来启用协议。在ndpi_set_protocol_detection_bitmask2函数3362行后面添加我们的函数:init_oneoneprotocol_dissector(ndpi_str, &a, detection_bitmask)。

  // ONEONEPROTOCOL
  init_oneoneprotocol_dissector(ndpi_str, &a, detection_bitmask);

4)完成
三、自测
在虚拟机linux上通过nc工具监听11011端口,windows通过NetAssist工具选择TCP Client连接到linux主机端口,发生数字111,ndpiReader抓包测试。测试结果如下图所示。
在这里插入图片描述

本文主要步骤参考如下链接,原文测试很多细节有误,特重新测试发布。详细介绍可参考原链接。
参考连接:
https://blog.csdn.net/ACMer_L/article/details/107594060

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值