日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國(guó)內(nèi)最全I(xiàn)T社區(qū)平臺(tái) 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁(yè) > php開(kāi)源 > php教程 > 【智能路由器】ndpi深度報(bào)文分析之協(xié)議分析器

【智能路由器】ndpi深度報(bào)文分析之協(xié)議分析器

來(lái)源:程序員人生   發(fā)布時(shí)間:2016-11-09 16:37:52 閱讀次數(shù):2442次

【智能路由器】系列文章連接
http://blog.csdn.net/u012819339/article/category/5803489


本篇博客講述ndpi已實(shí)現(xiàn)的QQ協(xié)議分析器的實(shí)現(xiàn) 和 編寫(xiě)1個(gè)微信協(xié)議分析器的框架要點(diǎn)。
關(guān)于ndpi源碼的敘述在上篇博客已有提及,點(diǎn)擊這里(或查看鏈接http://blog.csdn.net/u012819339/article/details/52443705)

ndpi協(xié)議分析器結(jié)構(gòu)框架

每一個(gè)協(xié)議分析器都必須定義1個(gè)獨(dú)有的id,例如:

/*ndpi_protocol_ids.h*/ #define NDPI_PROTOCOL_QQ 48

協(xié)議分析器格式

#include "ndpi_utils.h" #ifdef NDPI_PROTOCOL_QQ ..... #endif

協(xié)議分析器的初始化函數(shù),初始化函數(shù)中調(diào)用ndpi_set_bitmask_protocol_detection來(lái)輸入自己的注冊(cè)信息,和處理數(shù)據(jù)包的類(lèi)型

void init_qq_dissector(struct ndpi_detection_module_struct *ndpi_struct, u_int32_t *id, NDPI_PROTOCOL_BITMASK *detection_bitmask) { ndpi_set_bitmask_protocol_detection("QQ", ndpi_struct, detection_bitmask, *id, NDPI_PROTOCOL_QQ, ndpi_search_qq, NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, SAVE_DETECTION_BITMASK_AS_UNKNOWN, ADD_TO_DETECTION_BITMASK); *id += 1; }

1個(gè)回調(diào)函數(shù),用來(lái)處理數(shù)據(jù)包,這個(gè)函數(shù)就是初始化中注冊(cè)的函數(shù),這個(gè)函數(shù)將細(xì)分情況,然后交給實(shí)際的分析函數(shù),這里分別是ndpi_search_qq_udpndpi_search_qq_tcp。雖然也能夠直接在這里分析處理,但這樣會(huì)顯得層次結(jié)構(gòu)不清晰

void ndpi_search_qq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if (packet->udp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ) ndpi_search_qq_udp(ndpi_struct, flow); if (packet->tcp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ) ndpi_search_qq_tcp(ndpi_struct, flow); }

協(xié)議分析器的框架就到此為止,然后將初始化函數(shù)添加到ndpi_main.c文件的ndpi_init_protocol_defaults函數(shù)中,像這樣:

static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndpi_mod) { int i; ndpi_port_range ports_a[MAX_DEFAULT_PORTS], ports_b[MAX_DEFAULT_PORTS]; u_int16_t no_master[2] = { NDPI_PROTOCOL_NO_MASTER_PROTO, NDPI_PROTOCOL_NO_MASTER_PROTO }, custom_master[2]; /* Reset all settings */ memset(ndpi_mod->proto_defaults, 0, sizeof(ndpi_mod->proto_defaults)); //...... ndpi_set_proto_defaults(ndpi_mod, NDPI_PROTOCOL_FUN, NDPI_PROTOCOL_QQ, no_master, no_master, "QQ", 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_PROTOCOL_LONG_STRINGNDPI_PROTOCOL_SHORT_STRING中添加協(xié)議名稱(chēng)字符串。
協(xié)議分析器的結(jié)構(gòu)框架大概如此了

ndpi協(xié)議分析中QQ協(xié)議分析器的代碼概要

根據(jù)packet是tcp還是udp將探測(cè)進(jìn)程被分為兩中情況:

void ndpi_search_qq(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; if (packet->udp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ) ndpi_search_qq_udp(ndpi_struct, flow); if (packet->tcp != NULL && flow->detected_protocol_stack[0] != NDPI_PROTOCOL_QQ) ndpi_search_qq_tcp(ndpi_struct, flow); }

看1下qq的udp報(bào)文是怎樣探測(cè)的,在下面這個(gè)函數(shù)中

static void ndpi_search_qq_udp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &flow->packet; static const u_int16_t p8000_patt_02[13] = // maybe version numbers { 0x1549, 0x1801, 0x180d, 0x0961, 0x01501, 0x0e35, 0x113f, 0x0b37, 0x1131, 0x163a, 0x1e0d, 0x3619,}; u_int16_t no_of_patterns = 12, index = 0; NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "search qq udp.\n"); if (flow->qq_stage <= 3) { if ((packet->payload_packet_len == 27 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0300 && packet->payload[2] == 0x01) || (packet->payload_packet_len == 84 && ((ntohs(get_u_int16_t(packet->payload, 0)) == 0x000e && packet->payload[2] == 0x35) || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0015 && packet->payload[2] == 0x01) || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x000b && packet->payload[2] == 0x37) || (ntohs(get_u_int16_t(packet->payload, 0)) == 0x0015 && packet->payload[2] == 0x49))) || (packet->payload_packet_len > 10 && ((get_u_int16_t(packet->payload, 0) == htons(0x000b) && packet->payload[2] == 0x37) || (get_u_int32_t(packet->payload, 0) == htonl(0x04163a00) && packet->payload[packet->payload_packet_len - 1] == 0x03 && packet->payload[4] == packet->payload_packet_len)))) { /* if (flow->qq_stage == 3 && flow->detected_protocol == NDPI_PROTOCOL_QQ) { if (flow->packet_direction_counter[0] > 0 && flow->packet_direction_counter[1] > 0) { flow->protocol_subtype = NDPI_PROTOCOL_QQ_SUBTYPE_AUDIO; return; } else if (flow->packet_counter < 10) { return; } } */ flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 030001 or 000e35 four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x02 || packet->payload[0] == 0x04)) { u_int16_t pat = ntohs(get_u_int16_t(packet->payload, 1)); for (index = 0; index < no_of_patterns; index++) { if (pat == p8000_patt_02[index] && packet->payload[packet->payload_packet_len - 1] == 0x03) { flow->qq_stage++; // maybe we can test here packet->payload[4] == packet->payload_packet_len if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02 ... 03 four times.\n"); /* if (packet->payload[0] == 0x04) { ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } */ ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } } } if (packet->payload_packet_len == 84 && (packet->payload[0] == 0 || packet->payload[0] == 0x03)) { u_int16_t pat = ntohs(get_u_int16_t(packet->payload, 1)); for (index = 0; index < no_of_patterns; index++) { if (pat == p8000_patt_02[index]) { flow->qq_stage++; /* if (flow->qq_stage == 3 && flow->packet_direction_counter[0] > 0 && flow->packet_direction_counter[1] > 0) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow, NDPI_REAL_PROTOCOL); return; } else */ if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } } } if (packet->payload_packet_len > 2 && packet->payload[0] == 0x04 && ((ntohs(get_u_int16_t(packet->payload, 1)) == 0x1549 || ntohs(get_u_int16_t(packet->payload, 1)) == 0x1801 || ntohs(get_u_int16_t(packet->payload, 1)) == 0x0961) || (packet->payload_packet_len > 16 && (ntohs(get_u_int16_t(packet->payload, 1)) == 0x180d || ntohs(get_u_int16_t(packet->payload, 1)) == 0x096d) && ntohl(get_u_int32_t(packet->payload, 12)) == 0x28000000 && ntohs(get_u_int16_t(packet->payload, 3)) == packet->payload_packet_len)) && packet->payload[packet->payload_packet_len - 1] == 0x03) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 04 1159 ... 03 four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x06 || packet->payload[0] == 0x02) && ntohs(get_u_int16_t(packet->payload, 1)) == 0x0100 && (packet->payload[packet->payload_packet_len - 1] == 0x00 || packet->payload[packet->payload_packet_len - 1] == 0x03)) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02/06 0100 ... 03/00 four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } if (packet->payload_packet_len > 2 && (packet->payload[0] == 0x02) && ntohs(get_u_int16_t(packet->payload, 1)) == 0x1131 && packet->payload[packet->payload_packet_len - 1] == 0x03) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02 1131 ... 03 four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } if (packet->payload_packet_len > 5 && get_u_int16_t(packet->payload, 0) == htons(0x0203) && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len && get_u_int16_t(packet->payload, 4) == htons(0x0b0b)) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 0203[packet_length_0b0b] three times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } if (packet->udp->dest == htons(9000) || packet->udp->source == htons(9000)) { if (packet->payload_packet_len > 3 && ntohs(get_u_int16_t(packet->payload, 0)) == 0x0202 && ntohs(get_u_int16_t(packet->payload, 2)) == packet->payload_packet_len) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq udp pattern 02 02 <length> four times.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } } } if (ndpi_is_valid_qq_packet(packet)) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq over udp.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq packet stage %d\n", flow->qq_stage); return; } if (ndpi_is_valid_qq_ft_packet(packet)) { flow->qq_stage++; if (flow->qq_stage == 3) { NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "found qq ft over udp.\n"); ndpi_int_qq_add_connection(ndpi_struct, flow); return; } return; } if (flow->qq_stage && flow->packet_counter <= 5) { return; } NDPI_LOG(NDPI_PROTOCOL_QQ, ndpi_struct, NDPI_LOG_DEBUG, "QQ excluded\n"); NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QQ); }

該函數(shù)有點(diǎn)長(zhǎng),不過(guò)基本都是屬于探測(cè)OICQ協(xié)議的報(bào)頭,oicq協(xié)議是qq用于即時(shí)通訊的協(xié)議,數(shù)據(jù)流經(jīng)8000端口,具體oicq協(xié)議頭的解釋可參看arvik的另外一篇博客http://blog.csdn.net/u012819339/article/details/50374252

得到payload頭指針后起始可以直接強(qiáng)迫指針類(lèi)型轉(zhuǎn)換成 oicqhdr *,就比較方便啦

typedef struct _oicqhdr { uint8_t flag; uint16_t ver; uint16_t command; uint16_t sequence; uint32_t qq; } __attribute__((packed)) oicqhdr;

tcp檢測(cè)就不敘述了,總之都是先抓包分析QQ報(bào)文頭的結(jié)構(gòu)特點(diǎn),然后拿到協(xié)議分析器中做匹配。

ndpi協(xié)議分析中編寫(xiě)1個(gè)微信協(xié)議分析器的方法指點(diǎn)

協(xié)議分析器框架見(jiàn)上文所述,可以參照QQ協(xié)議分析器依葫蘆畫(huà)瓢,
這里主要是弄清微信協(xié)議的格式,這需要自己抓包分析,arvik已做好了1部份微信抓包分析的進(jìn)程,見(jiàn)我的博客微信數(shù)據(jù)包(鏈接地址http://blog.csdn.net/u012819339/article/details/52588288),微信客戶(hù)端有很多模塊,比如發(fā)紅包,飄流瓶,搖1搖,傳圖片,發(fā)語(yǔ)音,發(fā)短視頻等等,每一個(gè)模塊都可能會(huì)有1種協(xié)議格式,arvik并沒(méi)有完全對(duì)這些模塊進(jìn)行分析,需要開(kāi)發(fā)者自行抓包。


好了,本文到此結(jié)束,作者arvik。
【智能路由器】系列文章連接
http://blog.csdn.net/u012819339/article/category/5803489

生活不易,碼農(nóng)辛苦
如果您覺(jué)得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)
程序員人生
------分隔線(xiàn)----------------------------
分享到:
------分隔線(xiàn)----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 日韩激情 | 日韩欧美在线观看 | 欧美日韩国产在线看 | 久久久精品一区二区 | 青草网 | 欧美日韩中文在线观看 | 国产免费黄网站 | 一级一级一级毛片 | 亚洲另类欧美日韩 | 国产一区二区久久精品 | 午夜精品久久久久久久99无限制 | 国产尤物精品视频 | 一区中文| 日韩视频在线免费观看 | 成人免费视频观看视频 | 成人天堂 | 91成人免费看 | 欧美日本成人 | 久久久久美女 | av一二三区 | 涩涩视频免费观看 | 日本精品久久久久久久 | 国产一区不卡 | 日日草视频 | 99久久精品免费看国产免费软件 | 精品久久久久久久久久久久久久 | 91骚视频 | 99re| 在线电影91 | 精品国产自在精品国产浪潮 | 精品日韩一区二区三区 | 欧美久久久久久 | 国产一区二区视频在线 | 在线成人一区 | 免费大片黄在线观看视频网站 | 亚洲综合国产一区二区三区 | 国产精品一区电影 | 一区二区三区 欧美 | 麻豆av免费 | 黄色一级片在线 | 国产精品免费在线 |