diff options
author | Luca Deri <lucaderi@users.noreply.github.com> | 2015-05-20 08:54:10 +0200 |
---|---|---|
committer | Luca Deri <lucaderi@users.noreply.github.com> | 2015-05-20 08:54:10 +0200 |
commit | fd338a90c26396471c3dd9f4594335a9b4b8ecfc (patch) | |
tree | 4504530f3b3a1f731096fbe5ba577a596c69de15 /src | |
parent | 993665726aa807ff64ca28776af6aee43b19b66d (diff) | |
parent | 57926cc97da148a593f08191d09e3003427a8712 (diff) |
Merge pull request #6 from backer-and/dev
Added QUIC protocol
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_protocol_ids.h | 5 | ||||
-rw-r--r-- | src/include/ndpi_protocols.h | 1 | ||||
-rw-r--r-- | src/lib/Makefile.am | 1 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 14 | ||||
-rw-r--r-- | src/lib/protocols/quic.c | 156 |
5 files changed, 175 insertions, 2 deletions
diff --git a/src/include/ndpi_protocol_ids.h b/src/include/ndpi_protocol_ids.h index efa4f6d7d..db2179897 100644 --- a/src/include/ndpi_protocol_ids.h +++ b/src/include/ndpi_protocol_ids.h @@ -197,6 +197,7 @@ #define NDPI_PROTOCOL_PANDO 183 /* Tomasz Bujlow <tomasz@skatnet.dk> */ #define NDPI_PROTOCOL_VHUA 184 #define NDPI_PROTOCOL_TELEGRAM 185 /* Gianluca Costa <g.costa@xplico.org> */ +#define NDPI_PROTOCOL_QUIC 188 /* Andrea Buscarinu <andrea.buscarinu@gmail.com> - Michele Campus <michelecampus5@gmail.com> */ #define NDPI_CONTENT_AVI 39 @@ -235,8 +236,8 @@ #define NDPI_SERVICE_YAHOO NDPI_PROTOCOL_YAHOO /* Tomasz Bujlow <tomasz@skatnet.dk> */ #define NDPI_SERVICE_PANDORA 187 -/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE (NDPI_SERVICE_PANDORA) */ -#define NDPI_LAST_IMPLEMENTED_PROTOCOL 187 +/* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE (NDPI_PROTOCOL_QUIC) */ +#define NDPI_LAST_IMPLEMENTED_PROTOCOL 188 #define NDPI_MAX_SUPPORTED_PROTOCOLS (NDPI_LAST_IMPLEMENTED_PROTOCOL + 1) #define NDPI_MAX_NUM_CUSTOM_PROTOCOLS (NDPI_NUM_BITS-NDPI_LAST_IMPLEMENTED_PROTOCOL) diff --git a/src/include/ndpi_protocols.h b/src/include/ndpi_protocols.h index 5ab0da83a..4fc0516d8 100644 --- a/src/include/ndpi_protocols.h +++ b/src/include/ndpi_protocols.h @@ -177,5 +177,6 @@ void ndpi_search_zmq(struct ndpi_detection_module_struct *ndpi_struct, struct nd void ndpi_search_twitter(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_vhua(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); void ndpi_search_telegram(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); +void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow); #endif /* __NDPI_PROTOCOLS_INCLUDE_FILE__ */ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 4aec40aeb..86aeb6c68 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -93,6 +93,7 @@ libndpi_la_SOURCES = ndpi_content_match.c.inc \ protocols/pptp.c \ protocols/qq.c \ protocols/quake.c \ + protocols/quic.c \ protocols/radius.c \ protocols/rdp.c \ protocols/redis_net.c \ diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 8d39d8115..d8047825b 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -1456,6 +1456,11 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp no_master, "Telegram", 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_proto_defaults(ndpi_mod, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_QUIC, + no_master, + no_master, "Quic", + ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */, + ndpi_build_default_ports(ports_b, 443, 80, 0, 0, 0) /* UDP */); custom_master[0] = NDPI_PROTOCOL_HTTP, custom_master[1] = NDPI_PROTOCOL_UNKNOWN; custom_master1[0] = NDPI_PROTOCOL_DNS, custom_master1[1] = NDPI_PROTOCOL_UNKNOWN; @@ -3518,6 +3523,15 @@ void ndpi_set_protocol_detection_bitmask2(struct ndpi_detection_module_struct *n ADD_TO_DETECTION_BITMASK); #endif +#ifdef NDPI_PROTOCOL_QUIC + ndpi_set_bitmask_protocol_detection("QUIC", ndpi_struct, detection_bitmask, a++, + NDPI_PROTOCOL_QUIC, + ndpi_search_quic, + NDPI_SELECTION_BITMASK_PROTOCOL_V4_V6_UDP_WITH_PAYLOAD, + SAVE_DETECTION_BITMASK_AS_UNKNOWN, + ADD_TO_DETECTION_BITMASK); +#endif + ndpi_struct->callback_buffer_size = a; NDPI_LOG(NDPI_PROTOCOL_UNKNOWN, ndpi_struct, NDPI_LOG_DEBUG, diff --git a/src/lib/protocols/quic.c b/src/lib/protocols/quic.c new file mode 100644 index 000000000..2e1ad6628 --- /dev/null +++ b/src/lib/protocols/quic.c @@ -0,0 +1,156 @@ +/* + * quic.c + * + * Andrea Buscarinu - <andrea.buscarinu@gmail.com> + * Michele Campus - <michelecampus5@gmail.com> + * Copyright (C) 2012-15 - ntop.org + * + * This module is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This module is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License. + * If not, see <http://www.gnu.org/licenses/>. + * + */ + + +#include "ndpi_api.h" + +#define QUIC_NO_V_RES_RSV 0xC3 // 1100 0011 + +#define QUIC_CID_MASK 0x0C // 0000 1100 +#define QUIC_VER_MASK 0x01 // 0000 0001 +#define QUIC_SEQ_MASK 0x30 // 0011 0000 + +#define CID_LEN_8 0x0C // 0000 1100 +#define CID_LEN_4 0x08 // 0000 1000 +#define CID_LEN_1 0x04 // 0000 0100 +#define CID_LEN_0 0x00 // 0000 0000 + +#define SEQ_LEN_6 0x30 // 0011 0000 +#define SEQ_LEN_4 0x20 // 0010 0000 +#define SEQ_LEN_2 0x10 // 0001 0000 +#define SEQ_LEN_1 0x00 // 0000 0000 + +#define SEQ_CONV(ARR) (ARR[0] | ARR[1] | ARR[2] | ARR[3] | ARR[4] | ARR[5] << 8) + + +#ifdef NDPI_PROTOCOL_QUIC +static void ndpi_int_quic_add_connection(struct ndpi_detection_module_struct + *ndpi_struct, struct ndpi_flow_struct *flow) +{ + ndpi_int_add_connection(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, NDPI_REAL_PROTOCOL); +} + +int connect_id(const unsigned char pflags) +{ + u_int cid_len; + + // Check CID length. + switch (pflags & QUIC_CID_MASK) + { + case CID_LEN_8: cid_len = 8; break; + case CID_LEN_4: cid_len = 4; break; + case CID_LEN_1: cid_len = 1; break; + case CID_LEN_0: cid_len = 0; break; + default: + return -1; + + } + // Return offset. + return cid_len + 1; +} + +int sequence(const unsigned char *payload) +{ + unsigned char conv[6] = {0}; + u_int seq_value = -1; + u_int seq_lens; + u_int cid_offs; + int i; + + // Search SEQ bytes length. + switch (payload[0] & QUIC_SEQ_MASK) + { + case SEQ_LEN_6: seq_lens = 6; break; + case SEQ_LEN_4: seq_lens = 4; break; + case SEQ_LEN_2: seq_lens = 2; break; + case SEQ_LEN_1: seq_lens = 1; break; + default: + return -1; + } + // Retrieve SEQ offset. + cid_offs = connect_id(payload[0]); + + if (cid_offs >= 0 && seq_lens > 0) + { + for (i = 0; i < seq_lens; i++) + conv[i] = payload[cid_offs + i]; + + seq_value = SEQ_CONV(conv); + } + // Return SEQ dec value; + return seq_value; +} + +void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) +{ + struct ndpi_packet_struct *packet = &flow->packet; + u_int ver_offs; + + if(packet->udp != NULL) { + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "calculating quic over udp.\n"); + + // Settings without version. First check if PUBLIC FLAGS & SEQ bytes are 0x0. SEQ must be 1 at least. + if ((packet->payload[0] == 0x00 && packet->payload[1] != 0x00) || ((packet->payload[0] & QUIC_NO_V_RES_RSV) == 0)) + { + if (sequence(packet->payload) < 1) + { + + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); + } + + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); + ndpi_int_quic_add_connection(ndpi_struct, flow); + } + + // Check if version, than the CID length. + else if (packet->payload[0] & QUIC_VER_MASK) + { + // Skip CID length. + ver_offs = connect_id(packet->payload[0]); + + if (ver_offs >= 0){ + unsigned char vers[] = {packet->payload[ver_offs], packet->payload[ver_offs + 1], + packet->payload[ver_offs + 2], packet->payload[ver_offs + 3]}; + + // Version Match. + if (vers[0] == 'Q' && vers[1] == '0' && + (vers[2] == '2' && (vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || + vers[3] == '1' || vers[3] == '0')) || + (vers[2] == '1' && (vers[3] == '9' || vers[3] == '8' || vers[3] == '7' || vers[3] == '6' || + vers[3] == '5' || vers[3] == '4' || vers[3] == '3' || vers[3] == '2' || + vers[3] == '1' || vers[3] == '0')) || + (vers[2] == '0' && vers[3] == '9')) + + { + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "found quic.\n"); + ndpi_int_quic_add_connection(ndpi_struct, flow); + } + } + } else + { + NDPI_LOG(NDPI_PROTOCOL_QUIC, ndpi_struct, NDPI_LOG_DEBUG, "exclude quic.\n"); + NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_QUIC); + } + } +} +#endif |