有人通过github找我了解xplico,一直没有好好解答他的问题,于是想着手写这么一篇简单文章。
做协议识别:1、特征码
2、端口
3、正则
详细介绍,传送:http://www.sdnlab.com/17449.html
在tTcp_garbage.c \Udp_analysis.c 中使用,一般是将tcp层数据传给ndpi,使用是要在配置文件中进行配置;
/* nDPI library */
#include "ndpi_main.h"
#include "ndpi_api.h"
....
....
//申请内存
static void *nDPImalloc(unsigned long size)
{
return malloc(size);
}
//释放内存
static void nDPIfree(void *freeable)
{
free(freeable);
}
static void nDPIPrintf(u_int32_t protocol, void *id_struct, ndpi_log_level_t log_level, const char *format, ...)
{
return;
}
//匹配
static ndpi_protocol nDPIPacket(packet *pkt, struct ndpi_flow_struct *l7flow, struct ndpi_id_struct *l7src, struct ndpi_id_struct *l7dst, bool ipv4)
{
void *data;
size_t offset, size;
ftval voffset;
const pstack_f *ip;
unsigned long when;
ndpi_protocol l7prot_id;
if (ipv4) {
ip = ProtStackSearchProt(pkt->stk, ip_id);
ProtGetAttr(ip, ip_offset_id, &voffset);
offset = voffset.uint32;
data = pkt->raw + offset;
size = pkt->raw_len - offset;
}
else {
ip = ProtStackSearchProt(pkt->stk, ipv6_id);
ProtGetAttr(ip, ipv6_offset_id, &voffset);
offset = voffset.uint32;
data = pkt->raw + offset;
size = pkt->raw_len - offset;
}
when = pkt->cap_sec;
when = when * NDPI_TICK_RES;
when += pkt->cap_usec/1000; /* (1000000 / NDPI_TICK_RES) */
pthread_mutex_lock(&ndpi_mux);
/**
* Processes one packet and returns the ID of the detected protocol.
* This is the MAIN PACKET PROCESSING FUNCTION.
*
* @par ndpi_struct = the detection module
* @par flow = pointer to the connection state machine
* @par packet = unsigned char pointer to the Layer 3 (IP header)
* @par packetlen = the length of the packet
* @par current_tick = the current timestamp for the packet
* @par src = pointer to the source subscriber state machine
* @par dst = pointer to the destination subscriber state machine
* @return the detected ID of the protocol
*
*/
l7prot_id = ndpi_detection_process_packet(ndpi, l7flow, data, size, when, l7src, l7dst);
pthread_mutex_unlock(&ndpi_mux);
return l7prot_id;
}
packet *TcpGrbDissector(int flow_id)
{
char *l7prot_type;
struct ndpi_flow_struct *l7flow;
struct ndpi_id_struct *l7src, *l7dst;
ndpi_protocol l7prot_id
....
....
if (stage != 4 && (l7prot_type == NULL || l7prot_id.master_protocol == NDPI_PROTOCOL_HTTP) && l7flow != NULL) {
if (TcpGrbClientPkt(priv, pkt)) {
//做匹配
l7prot_id = nDPIPacket(pkt, l7flow, l7src, l7dst, ipv4);
}
else {
l7prot_id = nDPIPacket(pkt, l7flow, l7dst, l7src, ipv4);
}
if (l7prot_id.protocol != NDPI_PROTOCOL_UNKNOWN) {
stage++;
//根据id获取名字
l7prot_type = ndpi_protocol2name(ndpi, l7prot_id, buff, TCP_CFG_LINE_MAX_SIZE);
}
}
....
....
}
int DissectInit(void)
{
char tmp_dir[256];
unsigned short i;
/*协议掩码*/
NDPI_PROTOCOL_BITMASK all;
....
....
/* ndpi */
pthread_mutex_init(&ndpi_mux, NULL);
/*初始化,返回一个初始化检测模块*/
ndpi = ndpi_init_detection_module(NDPI_TICK_RES, nDPImalloc, nDPIfree, nDPIPrintf);
if (ndpi == NULL) {
LogPrintf(LV_ERROR, "nDPi initializzation failed");
return -1;
}
/* enable all protocols */
NDPI_BITMASK_SET_ALL(all);
//设定协议掩码
ndpi_set_protocol_detection_bitmask2(ndpi, &all);
//得到id结构的大小,用于动态申请ndpi_id_struct
ndpi_proto_size = ndpi_detection_get_sizeof_ndpi_id_struct();
//得到flow结构的大小,用于动态申请ndpi_flow_struct
ndpi_flow_struct_size = ndpi_detection_get_sizeof_ndpi_flow_struct();
return 0;
}
./xplico -l -c ./config/xplico_dpi.cfg -m pcap -f eyou.pcap
输出结果:
13:59:00 [tcp-grb]{9969}-DEBUG: DST: 172.16.2.54:56051
l7prot_type HTTP //添加的输出
13:59:00 [tcp-grb]{9969}-DEBUG: TCP->HTTP garbage... bye bye fid:9969 count:2
13:59:00 [tcp-grb]{9966}-DEBUG: TCP->Unknown garbage... bye bye fid:9966 count:2
13:59:00 [udp-grb]{9958}-DEBUG: DST: 239.255.255.250:1900
l7prot_type HTTP
13:59:00 [tcp-grb]{9894}-DEBUG: TCP->HTTP garbage... bye bye fid:9894 count:103