Start renaming SSL to TLS.
[metze/wireshark/wip.git] / epan / dissectors / packet-http.c
1 /* packet-http.c
2  * Routines for HTTP packet disassembly
3  * RFC 1945 (HTTP/1.0)
4  * RFC 2616 (HTTP/1.1)
5  *
6  * Guy Harris <guy@alum.mit.edu>
7  *
8  * Copyright 2017, Eugene Adell <eugene.adell@gmail.com>
9  * Copyright 2004, Jerry Talkington <jtalkington@users.sourceforge.net>
10  * Copyright 2002, Tim Potter <tpot@samba.org>
11  * Copyright 1999, Andrew Tridgell <tridge@samba.org>
12  *
13  * Wireshark - Network traffic analyzer
14  * By Gerald Combs <gerald@wireshark.org>
15  * Copyright 1998 Gerald Combs
16  *
17  * SPDX-License-Identifier: GPL-2.0-or-later
18  */
19
20 #include "config.h"
21
22 #include <errno.h>
23
24 #include <epan/packet.h>
25 #include <epan/prefs.h>
26 #include <epan/expert.h>
27 #include <epan/follow.h>
28 #include <epan/addr_resolv.h>
29 #include <epan/uat.h>
30 #include <epan/strutil.h>
31 #include <epan/stats_tree.h>
32 #include <epan/to_str.h>
33 #include <epan/req_resp_hdrs.h>
34 #include <epan/proto_data.h>
35 #include <epan/export_object.h>
36
37 #include "packet-http.h"
38 #include "packet-tcp.h"
39 #include "packet-ssl.h"
40
41 void proto_register_http(void);
42 void proto_reg_handoff_http(void);
43 void proto_register_message_http(void);
44 void proto_reg_handoff_message_http(void);
45
46 static int http_tap = -1;
47 static int http_eo_tap = -1;
48 static int http_follow_tap = -1;
49
50 static int proto_http = -1;
51 static int proto_http2 = -1;
52 static int proto_ssdp = -1;
53 static int hf_http_notification = -1;
54 static int hf_http_response = -1;
55 static int hf_http_request = -1;
56 static int hf_http_response_number = -1;
57 static int hf_http_request_number = -1;
58 static int hf_http_response_line = -1;
59 static int hf_http_request_line = -1;
60 static int hf_http_basic = -1;
61 static int hf_http_citrix = -1;
62 static int hf_http_citrix_user = -1;
63 static int hf_http_citrix_domain = -1;
64 static int hf_http_citrix_passwd = -1;
65 static int hf_http_citrix_session = -1;
66 static int hf_http_request_method = -1;
67 static int hf_http_request_uri = -1;
68 static int hf_http_request_full_uri = -1;
69 static int hf_http_request_path = -1;
70 static int hf_http_request_query = -1;
71 static int hf_http_request_query_parameter = -1;
72 static int hf_http_request_version = -1;
73 static int hf_http_response_version = -1;
74 static int hf_http_response_code = -1;
75 static int hf_http_response_code_desc = -1;
76 static int hf_http_response_phrase = -1;
77 static int hf_http_authorization = -1;
78 static int hf_http_proxy_authenticate = -1;
79 static int hf_http_proxy_authorization = -1;
80 static int hf_http_proxy_connect_host = -1;
81 static int hf_http_proxy_connect_port = -1;
82 static int hf_http_www_authenticate = -1;
83 static int hf_http_content_type = -1;
84 static int hf_http_content_length_header = -1;
85 static int hf_http_content_length = -1;
86 static int hf_http_content_encoding = -1;
87 static int hf_http_transfer_encoding = -1;
88 static int hf_http_upgrade = -1;
89 static int hf_http_user_agent = -1;
90 static int hf_http_host = -1;
91 static int hf_http_connection = -1;
92 static int hf_http_cookie = -1;
93 static int hf_http_cookie_pair = -1;
94 static int hf_http_accept = -1;
95 static int hf_http_referer = -1;
96 static int hf_http_accept_language = -1;
97 static int hf_http_accept_encoding = -1;
98 static int hf_http_date = -1;
99 static int hf_http_cache_control = -1;
100 static int hf_http_server = -1;
101 static int hf_http_location = -1;
102 static int hf_http_sec_websocket_accept = -1;
103 static int hf_http_sec_websocket_extensions = -1;
104 static int hf_http_sec_websocket_key = -1;
105 static int hf_http_sec_websocket_protocol = -1;
106 static int hf_http_sec_websocket_version = -1;
107 static int hf_http_set_cookie = -1;
108 static int hf_http_last_modified = -1;
109 static int hf_http_x_forwarded_for = -1;
110 static int hf_http_request_in = -1;
111 static int hf_http_response_in = -1;
112 static int hf_http_next_request_in = -1;
113 static int hf_http_next_response_in = -1;
114 static int hf_http_prev_request_in = -1;
115 static int hf_http_prev_response_in = -1;
116 static int hf_http_time = -1;
117 static int hf_http_chunk_size = -1;
118 static int hf_http_chunk_boundary = -1;
119 static int hf_http_chunked_trailer_part = -1;
120 static int hf_http_file_data = -1;
121 static int hf_http_unknown_header = -1;
122
123 static gint ett_http = -1;
124 static gint ett_http_ntlmssp = -1;
125 static gint ett_http_kerberos = -1;
126 static gint ett_http_request = -1;
127 static gint ett_http_request_path = -1;
128 static gint ett_http_request_query = -1;
129 static gint ett_http_chunked_response = -1;
130 static gint ett_http_chunk_data = -1;
131 static gint ett_http_encoded_entity = -1;
132 static gint ett_http_header_item = -1;
133
134 static expert_field ei_http_chat = EI_INIT;
135 static expert_field ei_http_te_and_length = EI_INIT;
136 static expert_field ei_http_te_unknown = EI_INIT;
137 static expert_field ei_http_subdissector_failed = EI_INIT;
138 static expert_field ei_http_ssl_port = EI_INIT;
139 static expert_field ei_http_leading_crlf = EI_INIT;
140 static expert_field ei_http_bad_header_name = EI_INIT;
141
142 static dissector_handle_t http_handle;
143 static dissector_handle_t http_tcp_handle;
144 static dissector_handle_t http_tls_handle;
145 static dissector_handle_t http_sctp_handle;
146
147 static dissector_handle_t media_handle;
148 static dissector_handle_t http2_handle;
149 static dissector_handle_t sstp_handle;
150 static dissector_handle_t ntlmssp_handle;
151 static dissector_handle_t gssapi_handle;
152
153 /* Stuff for generation/handling of fields for custom HTTP headers */
154 typedef struct _header_field_t {
155         gchar* header_name;
156         gchar* header_desc;
157 } header_field_t;
158
159 static header_field_t* header_fields;
160 static guint num_header_fields;
161
162 static GHashTable* header_fields_hash;
163 static hf_register_info* dynamic_hf;
164 static guint dynamic_hf_size;
165
166 static gboolean
167 header_fields_update_cb(void *r, char **err)
168 {
169         header_field_t *rec = (header_field_t *)r;
170         char c;
171
172         if (rec->header_name == NULL) {
173                 *err = g_strdup("Header name can't be empty");
174                 return FALSE;
175         }
176
177         g_strstrip(rec->header_name);
178         if (rec->header_name[0] == 0) {
179                 *err = g_strdup("Header name can't be empty");
180                 return FALSE;
181         }
182
183         /* Check for invalid characters (to avoid asserting out when
184          * registering the field).
185          */
186         c = proto_check_field_name(rec->header_name);
187         if (c) {
188                 *err = g_strdup_printf("Header name can't contain '%c'", c);
189                 return FALSE;
190         }
191
192         *err = NULL;
193         return TRUE;
194 }
195
196 static void *
197 header_fields_copy_cb(void* n, const void* o, size_t siz _U_)
198 {
199         header_field_t* new_rec = (header_field_t*)n;
200         const header_field_t* old_rec = (const header_field_t*)o;
201
202         new_rec->header_name = g_strdup(old_rec->header_name);
203         new_rec->header_desc = g_strdup(old_rec->header_desc);
204
205         return new_rec;
206 }
207
208 static void
209 header_fields_free_cb(void*r)
210 {
211         header_field_t* rec = (header_field_t*)r;
212
213         g_free(rec->header_name);
214         g_free(rec->header_desc);
215 }
216
217 UAT_CSTRING_CB_DEF(header_fields, header_name, header_field_t)
218 UAT_CSTRING_CB_DEF(header_fields, header_desc, header_field_t)
219
220 /*
221  * desegmentation of HTTP headers
222  * (when we are over TCP or another protocol providing the desegmentation API)
223  */
224 static gboolean http_desegment_headers = TRUE;
225
226 /*
227  * desegmentation of HTTP bodies
228  * (when we are over TCP or another protocol providing the desegmentation API)
229  * TODO let the user filter on content-type the bodies he wants desegmented
230  */
231 static gboolean http_desegment_body = TRUE;
232
233 /*
234  * De-chunking of content-encoding: chunk entity bodies.
235  */
236 static gboolean http_dechunk_body = TRUE;
237
238 /*
239  * Decompression of zlib encoded entities.
240  */
241 #ifdef HAVE_ZLIB
242 static gboolean http_decompress_body = TRUE;
243 #else
244 static gboolean http_decompress_body = FALSE;
245 #endif
246
247 /* Simple Service Discovery Protocol
248  * SSDP is implemented atop HTTP (yes, it really *does* run over UDP).
249  * SSDP is the discovery protocol of Universal Plug and Play
250  * UPnP   http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf
251  */
252 #define TCP_PORT_SSDP                   1900
253 #define UDP_PORT_SSDP                   1900
254
255 /*
256  * tcp and ssl ports
257  *
258  * 2710 is the XBT BitTorrent tracker
259  */
260
261 #define TCP_DEFAULT_RANGE "80,3128,3132,5985,8080,8088,11371,1900,2869,2710"
262 #define SCTP_DEFAULT_RANGE "80"
263 #define SSL_DEFAULT_RANGE "443"
264
265 static range_t *global_http_sctp_range = NULL;
266 static range_t *global_http_ssl_range = NULL;
267
268 static range_t *http_tcp_range = NULL;
269 static range_t *http_sctp_range = NULL;
270 static range_t *http_ssl_range = NULL;
271
272 typedef void (*ReqRespDissector)(tvbuff_t*, proto_tree*, int, const guchar*,
273                                  const guchar*, http_conv_t *);
274
275 /**
276  * Transfer codings from
277  * https://www.iana.org/assignments/http-parameters/http-parameters.xhtml#transfer-coding
278  * Note: chunked encoding is handled separately.
279  */
280 typedef enum _http_transfer_coding {
281         HTTP_TE_NONE,           /* Dummy value for header which is not set */
282         /* HTTP_TE_CHUNKED, */
283         HTTP_TE_COMPRESS,
284         HTTP_TE_DEFLATE,
285         HTTP_TE_GZIP,
286         HTTP_TE_IDENTITY,
287         HTTP_TE_UNKNOWN,    /* Header was set, but no valid name was found */
288 } http_transfer_coding;
289
290 /*
291  * Structure holding information from headers needed by main
292  * HTTP dissector code.
293  */
294 typedef struct {
295         char    *content_type;
296         char    *content_type_parameters;
297         gboolean have_content_length;
298         gint64   content_length;
299         char     *content_encoding;
300         gboolean transfer_encoding_chunked;
301         http_transfer_coding transfer_encoding;
302         char    *upgrade;
303 } headers_t;
304
305 static int is_http_request_or_reply(const gchar *data, int linelen,
306                                     http_type_t *type, ReqRespDissector
307                                     *reqresp_dissector, http_conv_t *conv_data);
308 static guint chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
309                                         proto_tree *tree, int offset);
310 static void process_header(tvbuff_t *tvb, int offset, int next_offset,
311                            const guchar *line, int linelen, int colon_offset,
312                            packet_info *pinfo, proto_tree *tree,
313                            headers_t *eh_ptr, http_conv_t *conv_data,
314                            http_type_t http_type);
315 static gint find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len);
316 static gboolean check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb,
317                                    packet_info *pinfo, gchar *value);
318 static gboolean check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb,
319                                  gchar *value);
320 static gboolean check_auth_citrixbasic(proto_item *hdr_item, tvbuff_t *tvb,
321                                  gchar *value, int offset);
322 static gboolean check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb,
323                                    packet_info *pinfo, const gchar *value);
324
325 static dissector_table_t port_subdissector_table;
326 static dissector_table_t media_type_subdissector_table;
327 static dissector_table_t upgrade_subdissector_table;
328 static heur_dissector_list_t heur_subdissector_list;
329
330 /* Used for HTTP Export Object feature */
331 typedef struct _http_eo_t {
332         guint32  pkt_num;
333         gchar   *hostname;
334         gchar   *filename;
335         gchar   *content_type;
336         guint32  payload_len;
337         const guint8 *payload_data;
338 } http_eo_t;
339
340 static gboolean
341 http_eo_packet(void *tapdata, packet_info *pinfo, epan_dissect_t *edt _U_, const void *data)
342 {
343         export_object_list_t *object_list = (export_object_list_t *)tapdata;
344         const http_eo_t *eo_info = (const http_eo_t *)data;
345         export_object_entry_t *entry;
346
347         if(eo_info) { /* We have data waiting for us */
348                 /* These values will be freed when the Export Object window
349                  * is closed. */
350                 entry = g_new(export_object_entry_t, 1);
351
352                 entry->pkt_num = pinfo->num;
353                 entry->hostname = g_strdup(eo_info->hostname);
354                 entry->content_type = g_strdup(eo_info->content_type);
355                 entry->filename = eo_info->filename ? g_path_get_basename(eo_info->filename) : NULL;
356                 entry->payload_len = eo_info->payload_len;
357                 entry->payload_data = (guint8 *)g_memdup(eo_info->payload_data, eo_info->payload_len);
358
359                 object_list->add_entry(object_list->gui_data, entry);
360
361                 return TRUE; /* State changed - window should be redrawn */
362         } else {
363                 return FALSE; /* State unchanged - no window updates needed */
364         }
365 }
366
367 /* --- HTTP Status Codes */
368 /* Note: The reference for uncommented entries is RFC 2616 */
369 const value_string vals_http_status_code[] = {
370         { 100, "Continue" },
371         { 101, "Switching Protocols" },
372         { 102, "Processing" },                     /* RFC 2518 */
373         { 103, "Early Hints" },                    /* RFC-ietf-httpbis-early-hints-05 */
374         { 199, "Informational - Others" },
375
376         { 200, "OK"},
377         { 201, "Created"},
378         { 202, "Accepted"},
379         { 203, "Non-authoritative Information"},
380         { 204, "No Content"},
381         { 205, "Reset Content"},
382         { 206, "Partial Content"},
383         { 207, "Multi-Status"},                    /* RFC 4918 */
384         { 208, "Already Reported"},                /* RFC 5842 */
385         { 226, "IM Used"},                         /* RFC 3229 */
386         { 299, "Success - Others"},
387
388         { 300, "Multiple Choices"},
389         { 301, "Moved Permanently"},
390         { 302, "Found"},
391         { 303, "See Other"},
392         { 304, "Not Modified"},
393         { 305, "Use Proxy"},
394         { 307, "Temporary Redirect"},
395         { 308, "Permanent Redirect"},              /* RFC 7538 */
396         { 399, "Redirection - Others"},
397
398         { 400, "Bad Request"},
399         { 401, "Unauthorized"},
400         { 402, "Payment Required"},
401         { 403, "Forbidden"},
402         { 404, "Not Found"},
403         { 405, "Method Not Allowed"},
404         { 406, "Not Acceptable"},
405         { 407, "Proxy Authentication Required"},
406         { 408, "Request Time-out"},
407         { 409, "Conflict"},
408         { 410, "Gone"},
409         { 411, "Length Required"},
410         { 412, "Precondition Failed"},
411         { 413, "Request Entity Too Large"},
412         { 414, "Request-URI Too Long"},
413         { 415, "Unsupported Media Type"},
414         { 416, "Requested Range Not Satisfiable"},
415         { 417, "Expectation Failed"},
416         { 418, "I'm a teapot"},                    /* RFC 2324 */
417         { 421, "Misdirected Request"},             /* RFC 7540 */
418         { 422, "Unprocessable Entity"},            /* RFC 4918 */
419         { 423, "Locked"},                          /* RFC 4918 */
420         { 424, "Failed Dependency"},               /* RFC 4918 */
421         { 426, "Upgrade Required"},                /* RFC 2817 */
422         { 428, "Precondition Required"},           /* RFC 6585 */
423         { 429, "Too Many Requests"},               /* RFC 6585 */
424         { 431, "Request Header Fields Too Large"}, /* RFC 6585 */
425         { 451, "Unavailable For Legal Reasons"},   /* RFC 7725 */
426         { 499, "Client Error - Others"},
427
428         { 500, "Internal Server Error"},
429         { 501, "Not Implemented"},
430         { 502, "Bad Gateway"},
431         { 503, "Service Unavailable"},
432         { 504, "Gateway Time-out"},
433         { 505, "HTTP Version not supported"},
434         { 506, "Variant Also Negotiates"},         /* RFC 2295 */
435         { 507, "Insufficient Storage"},            /* RFC 4918 */
436         { 508, "Loop Detected"},                   /* RFC 5842 */
437         { 510, "Not Extended"},                    /* RFC 2774 */
438         { 511, "Network Authentication Required"}, /* RFC 6585 */
439         { 599, "Server Error - Others"},
440
441         { 0,    NULL}
442 };
443
444 static const gchar* st_str_reqs = "HTTP Requests by Server";
445 static const gchar* st_str_reqs_by_srv_addr = "HTTP Requests by Server Address";
446 static const gchar* st_str_reqs_by_http_host = "HTTP Requests by HTTP Host";
447 static const gchar* st_str_resps_by_srv_addr = "HTTP Responses by Server Address";
448
449 static int st_node_reqs = -1;
450 static int st_node_reqs_by_srv_addr = -1;
451 static int st_node_reqs_by_http_host = -1;
452 static int st_node_resps_by_srv_addr = -1;
453
454 /* HTTP/Load Distribution stats init function */
455 static void
456 http_reqs_stats_tree_init(stats_tree* st)
457 {
458         st_node_reqs = stats_tree_create_node(st, st_str_reqs, 0, TRUE);
459         st_node_reqs_by_srv_addr = stats_tree_create_node(st, st_str_reqs_by_srv_addr, st_node_reqs, TRUE);
460         st_node_reqs_by_http_host = stats_tree_create_node(st, st_str_reqs_by_http_host, st_node_reqs, TRUE);
461         st_node_resps_by_srv_addr = stats_tree_create_node(st, st_str_resps_by_srv_addr, 0, TRUE);
462 }
463
464 /* HTTP/Load Distribution stats packet function */
465 static int
466 http_reqs_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
467 {
468         const http_info_value_t* v = (const http_info_value_t*)p;
469         int reqs_by_this_host;
470         int reqs_by_this_addr;
471         int resps_by_this_addr;
472         int i = v->response_code;
473         gchar *ip_str;
474
475
476         if (v->request_method) {
477                 ip_str = address_to_str(NULL, &pinfo->dst);
478
479                 tick_stat_node(st, st_str_reqs, 0, FALSE);
480                 tick_stat_node(st, st_str_reqs_by_srv_addr, st_node_reqs, TRUE);
481                 tick_stat_node(st, st_str_reqs_by_http_host, st_node_reqs, TRUE);
482                 reqs_by_this_addr = tick_stat_node(st, ip_str, st_node_reqs_by_srv_addr, TRUE);
483
484                 if (v->http_host) {
485                         reqs_by_this_host = tick_stat_node(st, v->http_host, st_node_reqs_by_http_host, TRUE);
486                         tick_stat_node(st, ip_str, reqs_by_this_host, FALSE);
487
488                         tick_stat_node(st, v->http_host, reqs_by_this_addr, FALSE);
489                 }
490
491                 wmem_free(NULL, ip_str);
492
493                 return 1;
494
495         } else if (i != 0) {
496                 ip_str = address_to_str(NULL, &pinfo->src);
497
498                 tick_stat_node(st, st_str_resps_by_srv_addr, 0, FALSE);
499                 resps_by_this_addr = tick_stat_node(st, ip_str, st_node_resps_by_srv_addr, TRUE);
500
501                 if ( (i>100)&&(i<400) ) {
502                         tick_stat_node(st, "OK", resps_by_this_addr, FALSE);
503                 } else {
504                         tick_stat_node(st, "KO", resps_by_this_addr, FALSE);
505                 }
506
507                 wmem_free(NULL, ip_str);
508
509                 return 1;
510         }
511
512         return 0;
513 }
514
515
516 static int st_node_requests_by_host = -1;
517 static const gchar *st_str_requests_by_host = "HTTP Requests by HTTP Host";
518
519 /* HTTP/Requests stats init function */
520 static void
521 http_req_stats_tree_init(stats_tree* st)
522 {
523         st_node_requests_by_host = stats_tree_create_node(st, st_str_requests_by_host, 0, TRUE);
524 }
525
526 /* HTTP/Requests stats packet function */
527 static int
528 http_req_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
529 {
530         const http_info_value_t* v = (const http_info_value_t*)p;
531         int reqs_by_this_host;
532
533         if (v->request_method) {
534                 tick_stat_node(st, st_str_requests_by_host, 0, FALSE);
535
536                 if (v->http_host) {
537                         reqs_by_this_host = tick_stat_node(st, v->http_host, st_node_requests_by_host, TRUE);
538
539                         if (v->request_uri) {
540                                 tick_stat_node(st, v->request_uri, reqs_by_this_host, TRUE);
541                         }
542                 }
543
544                 return 1;
545         }
546
547         return 0;
548 }
549
550 static const gchar *st_str_packets = "Total HTTP Packets";
551 static const gchar *st_str_requests = "HTTP Request Packets";
552 static const gchar *st_str_responses = "HTTP Response Packets";
553 static const gchar *st_str_resp_broken = "???: broken";
554 static const gchar *st_str_resp_100 = "1xx: Informational";
555 static const gchar *st_str_resp_200 = "2xx: Success";
556 static const gchar *st_str_resp_300 = "3xx: Redirection";
557 static const gchar *st_str_resp_400 = "4xx: Client Error";
558 static const gchar *st_str_resp_500 = "5xx: Server Error";
559 static const gchar *st_str_other = "Other HTTP Packets";
560
561 static int st_node_packets = -1;
562 static int st_node_requests = -1;
563 static int st_node_responses = -1;
564 static int st_node_resp_broken = -1;
565 static int st_node_resp_100 = -1;
566 static int st_node_resp_200 = -1;
567 static int st_node_resp_300 = -1;
568 static int st_node_resp_400 = -1;
569 static int st_node_resp_500 = -1;
570 static int st_node_other = -1;
571
572
573 /* HTTP/Packet Counter stats init function */
574 static void
575 http_stats_tree_init(stats_tree* st)
576 {
577         st_node_packets = stats_tree_create_node(st, st_str_packets, 0, TRUE);
578         st_node_requests = stats_tree_create_pivot(st, st_str_requests, st_node_packets);
579         st_node_responses = stats_tree_create_node(st, st_str_responses, st_node_packets, TRUE);
580         st_node_resp_broken = stats_tree_create_node(st, st_str_resp_broken, st_node_responses, TRUE);
581         st_node_resp_100    = stats_tree_create_node(st, st_str_resp_100,    st_node_responses, TRUE);
582         st_node_resp_200    = stats_tree_create_node(st, st_str_resp_200,    st_node_responses, TRUE);
583         st_node_resp_300    = stats_tree_create_node(st, st_str_resp_300,    st_node_responses, TRUE);
584         st_node_resp_400    = stats_tree_create_node(st, st_str_resp_400,    st_node_responses, TRUE);
585         st_node_resp_500    = stats_tree_create_node(st, st_str_resp_500,    st_node_responses, TRUE);
586         st_node_other = stats_tree_create_node(st, st_str_other, st_node_packets,FALSE);
587 }
588
589 /* HTTP/Packet Counter stats packet function */
590 static int
591 http_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
592 {
593         const http_info_value_t* v = (const http_info_value_t*)p;
594         guint i = v->response_code;
595         int resp_grp;
596         const gchar *resp_str;
597         gchar str[64];
598
599         tick_stat_node(st, st_str_packets, 0, FALSE);
600
601         if (i) {
602                 tick_stat_node(st, st_str_responses, st_node_packets, FALSE);
603
604                 if ( (i<100)||(i>=600) ) {
605                         resp_grp = st_node_resp_broken;
606                         resp_str = st_str_resp_broken;
607                 } else if (i<200) {
608                         resp_grp = st_node_resp_100;
609                         resp_str = st_str_resp_100;
610                 } else if (i<300) {
611                         resp_grp = st_node_resp_200;
612                         resp_str = st_str_resp_200;
613                 } else if (i<400) {
614                         resp_grp = st_node_resp_300;
615                         resp_str = st_str_resp_300;
616                 } else if (i<500) {
617                         resp_grp = st_node_resp_400;
618                         resp_str = st_str_resp_400;
619                 } else {
620                         resp_grp = st_node_resp_500;
621                         resp_str = st_str_resp_500;
622                 }
623
624                 tick_stat_node(st, resp_str, st_node_responses, FALSE);
625
626                 g_snprintf(str, sizeof(str), "%u %s", i,
627                            val_to_str(i, vals_http_status_code, "Unknown (%d)"));
628                 tick_stat_node(st, str, resp_grp, FALSE);
629         } else if (v->request_method) {
630                 stats_tree_tick_pivot(st,st_node_requests,v->request_method);
631         } else {
632                 tick_stat_node(st, st_str_other, st_node_packets, FALSE);
633         }
634
635         return 1;
636 }
637
638 /*
639 Generates a referer tree - a best-effort representation of which web request led to which.
640
641 Some challenges:
642 A user can be forwarded to a single sites from multiple sources. For example,
643 google.com -> foo.com and bing.com -> foo.com. A URI alone is not unique.
644
645 Additionally, if a user has a subsequent request to foo.com -> bar.com, the
646 full chain could either be:
647         google.com -> foo.com -> bar.com, or
648         bing.com   -> foo.com -> bar.com,
649
650 This indicates that a URI and its referer are not unique. Only a URI and its
651 full referer chain are unique. However, HTTP requests only contain the URI
652 and the immediate referer. This means that any attempt at generating a
653 referer tree is inherently going to be a best-effort approach.
654
655 This code assumes that the referer in a request is from the most-recent request
656 to that referer.
657
658 * To maintain readability of the statistics, whenever a site is visited, all
659 prior referers are 'ticked' as well, so that one can easily see the breakdown.
660 */
661
662 /* Root node for all referer statistics */
663 static int st_node_requests_by_referer = -1;
664 /* Referer statistics root node's text */
665 static const gchar *st_str_request_sequences = "HTTP Request Sequences";
666
667 /* Mapping of URIs to the most-recently seen node id */
668 static wmem_map_t* refstats_uri_to_node_id_hash = NULL;
669 /* Mapping of node ids to the node's URI ('name' value) */
670 static wmem_map_t* refstats_node_id_to_uri_hash = NULL;
671 /* Mapping of node ids to the parent node id */
672 static wmem_map_t* refstats_node_id_to_parent_node_id_hash = NULL;
673
674
675 /* HTTP/Request Sequences stats init function */
676 static void
677 http_seq_stats_tree_init(stats_tree* st)
678 {
679         gint root_node_id = 0;
680         gpointer root_node_id_p = GINT_TO_POINTER(root_node_id);
681         gpointer node_id_p = NULL;
682         gchar *uri = NULL;
683
684         refstats_node_id_to_parent_node_id_hash = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
685         refstats_node_id_to_uri_hash = wmem_map_new(wmem_file_scope(), g_direct_hash, g_direct_equal);
686         refstats_uri_to_node_id_hash = wmem_map_new(wmem_file_scope(), wmem_str_hash, g_str_equal);
687
688         /* Add the root node and its mappings */
689         st_node_requests_by_referer = stats_tree_create_node(st, st_str_request_sequences, root_node_id, TRUE);
690         node_id_p = GINT_TO_POINTER(st_node_requests_by_referer);
691         uri = wmem_strdup(wmem_file_scope(), st_str_request_sequences);
692
693         wmem_map_insert(refstats_uri_to_node_id_hash, uri, node_id_p);
694         wmem_map_insert(refstats_node_id_to_uri_hash, node_id_p, uri);
695         wmem_map_insert(refstats_node_id_to_parent_node_id_hash, node_id_p, root_node_id_p);
696 }
697
698 static gint
699 http_seq_stats_tick_referer(stats_tree* st, const gchar* arg_referer_uri)
700 {
701         gint root_node_id = st_node_requests_by_referer;
702         gpointer root_node_id_p = GINT_TO_POINTER(st_node_requests_by_referer);
703         gint referer_node_id;
704         gpointer referer_node_id_p;
705         gint referer_parent_node_id;
706         gpointer referer_parent_node_id_p;
707         gchar *referer_uri;
708
709         /* Tick the referer's URI */
710         /* Does the node exist? */
711         if (!wmem_map_lookup_extended(refstats_uri_to_node_id_hash, arg_referer_uri, NULL, &referer_node_id_p)) {
712                 /* The node for the referer didn't already exist, create the mappings */
713                 referer_node_id = tick_stat_node(st, arg_referer_uri, root_node_id, TRUE);
714                 referer_node_id_p = GINT_TO_POINTER(referer_node_id);
715                 referer_parent_node_id_p = root_node_id_p;
716
717                 referer_uri = wmem_strdup(wmem_file_scope(), arg_referer_uri);
718                 wmem_map_insert(refstats_uri_to_node_id_hash, referer_uri, referer_node_id_p);
719                 wmem_map_insert(refstats_node_id_to_uri_hash, referer_node_id_p, referer_uri);
720                 wmem_map_insert(refstats_node_id_to_parent_node_id_hash, referer_node_id_p, referer_parent_node_id_p);
721         } else {
722                 /* The node for the referer already exists, tick it */
723                 referer_parent_node_id_p = wmem_map_lookup(refstats_node_id_to_parent_node_id_hash, referer_node_id_p);
724                 referer_parent_node_id = GPOINTER_TO_INT(referer_parent_node_id_p);
725                 referer_node_id = tick_stat_node(st, arg_referer_uri, referer_parent_node_id, TRUE);
726         }
727         return referer_node_id;
728 }
729
730 static void
731 http_seq_stats_tick_request(stats_tree* st, const gchar* arg_full_uri, gint referer_node_id)
732 {
733         gpointer referer_node_id_p = GINT_TO_POINTER(referer_node_id);
734         gint node_id;
735         gpointer node_id_p;
736         gchar *uri;
737
738         node_id = tick_stat_node(st, arg_full_uri, referer_node_id, TRUE);
739         node_id_p = GINT_TO_POINTER(node_id);
740
741         /* Update the mappings. Even if the URI was already seen, the URI->node mapping may need to be updated */
742
743         /* Is this a new node? */
744         uri = (gchar *) wmem_map_lookup(refstats_node_id_to_uri_hash, node_id_p);
745         if (!uri) {
746                 /* node not found, add mappings for the node and uri */
747                 uri = wmem_strdup(wmem_file_scope(), arg_full_uri);
748
749                 wmem_map_insert(refstats_uri_to_node_id_hash, uri, node_id_p);
750                 wmem_map_insert(refstats_node_id_to_uri_hash, node_id_p, uri);
751                 wmem_map_insert(refstats_node_id_to_parent_node_id_hash, node_id_p, referer_node_id_p);
752         } else {
753                 /* We've seen the node id before. Update the URI mapping refer to this node id*/
754                 wmem_map_insert(refstats_uri_to_node_id_hash, uri, node_id_p);
755         }
756 }
757
758 static gchar*
759 determine_http_location_target(const gchar *base_url, const gchar * location_url)
760 {
761         /* Resolving a base URI + relative URI to an absolute URI ("Relative Resolution")
762         is complicated. Because of that, we take shortcuts that may result in
763         inaccurate results, but is also significantly simpler.
764         It would be best to use an external library to do this for us.
765         For reference, the RFC is located at https://tools.ietf.org/html/rfc3986#section-5.4
766
767         Returns NULL if the resolution fails
768         */
769         gchar *final_target;
770
771         /* base_url must be an absolute URL.*/
772         if (strstr(base_url, "://") == NULL){
773                 return NULL;
774         }
775
776         /* Empty Location */
777         if (location_url[0] == '\0') {
778                 final_target = wmem_strdup(wmem_packet_scope(), base_url);
779                 return final_target;
780         }
781         /* Protocol Relative */
782         else if (g_str_has_prefix(location_url, "//") ) {
783                 char *base_scheme = g_uri_parse_scheme(base_url);
784                 if (base_scheme == NULL) {
785                         return NULL;
786                 }
787                 final_target = wmem_strdup_printf(wmem_packet_scope(), "%s:%s", base_scheme, location_url);
788                 g_free(base_scheme);
789                 return final_target;
790         }
791         /* Absolute URL*/
792         else if (strstr(location_url, "://") != NULL) {
793                 final_target = wmem_strdup(wmem_packet_scope(), location_url);
794                 return final_target;
795         }
796         /* Relative */
797         else {
798                 gchar *start_fragment = strstr(base_url, "#");
799                 gchar *start_query = NULL;
800                 gchar *base_url_no_fragment = NULL;
801                 gchar *base_url_no_query = NULL;
802
803                 /* Strip off the fragment (which should never be present)*/
804                 if (start_fragment == NULL) {
805                         base_url_no_fragment = wmem_strdup(wmem_packet_scope(), base_url);
806                 }
807                 else {
808                         base_url_no_fragment = wmem_strndup(wmem_packet_scope(), base_url, start_fragment - base_url);
809                 }
810
811                 /* Strip off the query (Queries are stripped from all relative URIs) */
812                 start_query = strstr(base_url_no_fragment, "?");
813                 if (start_query == NULL) {
814                         base_url_no_query = wmem_strdup(wmem_packet_scope(), base_url_no_fragment);
815                 }
816                 else {
817                         base_url_no_query = wmem_strndup(wmem_packet_scope(), base_url_no_fragment, start_query - base_url_no_fragment);
818                 }
819
820                 /* A leading question mark (?) means to replace the old query with the new*/
821                 if (g_str_has_prefix(location_url, "?")) {
822                         final_target = wmem_strdup_printf(wmem_packet_scope(), "%s%s", base_url_no_query, location_url);
823                         return final_target;
824                 }
825                 /* A leading slash means to put the location after the netloc */
826                 else if (g_str_has_prefix(location_url, "/")) {
827                         gchar *scheme_end = strstr(base_url_no_query, "://") + 3;
828                         gchar *netloc_end;
829                         gint netloc_length;
830                         if (scheme_end[0] == '\0') {
831                                 return NULL;
832                         }
833                         netloc_end = strstr(scheme_end, "/");
834                         if (netloc_end == NULL) {
835                                 return NULL;
836                         }
837                         netloc_length = (gint) (netloc_end - base_url_no_query);
838                         final_target = wmem_strdup_printf(wmem_packet_scope(), "%.*s%s", netloc_length, base_url_no_query, location_url);
839                         return final_target;
840                 }
841                 /* Otherwise, it replaces the last element in the URI */
842                 else {
843                         gchar *scheme_end = strstr(base_url_no_query, "://") + 3;
844                         gchar *end_of_path = g_strrstr(scheme_end, "/");
845
846                         if (end_of_path != NULL) {
847                                 gint base_through_path = (gint) (end_of_path - base_url_no_query);
848                                 final_target = wmem_strdup_printf(wmem_packet_scope(), "%.*s/%s", base_through_path, base_url_no_query, location_url);
849                         }
850                         else {
851                                 final_target = wmem_strdup_printf(wmem_packet_scope(), "%s/%s", base_url_no_query, location_url);
852                         }
853
854                         return final_target;
855                 }
856         }
857         return NULL;
858 }
859
860 /* HTTP/Request Sequences stats packet function */
861 static int
862 http_seq_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
863 {
864         const http_info_value_t* v = (const http_info_value_t*)p;
865
866         /* Track HTTP Redirects */
867         if (v->location_target && v->location_base_uri) {
868                 gint referer_node_id;
869                 gint parent_node_id;
870                 gpointer parent_node_id_p;
871                 gpointer current_node_id_p;
872                 gchar *uri = NULL;
873
874                 gchar *absolute_target = determine_http_location_target(v->location_base_uri, v->location_target);
875                 /* absolute_target is NULL if the resolution fails */
876                 if (absolute_target != NULL) {
877                         /* We assume the user makes the request to the absolute_target */
878                         /* Tick the base URI */
879                         referer_node_id = http_seq_stats_tick_referer(st, v->location_base_uri);
880
881                         /* Tick the location header's resolved URI */
882                         http_seq_stats_tick_request(st, absolute_target, referer_node_id);
883
884                         /* Tick all stats nodes above the location */
885                         current_node_id_p = GINT_TO_POINTER(referer_node_id);
886                         while (wmem_map_lookup_extended(refstats_node_id_to_parent_node_id_hash, current_node_id_p, NULL, &parent_node_id_p)) {
887                                 parent_node_id = GPOINTER_TO_INT(parent_node_id_p);
888                                 uri = (gchar *) wmem_map_lookup(refstats_node_id_to_uri_hash, current_node_id_p);
889                                 tick_stat_node(st, uri, parent_node_id, TRUE);
890                                 current_node_id_p = parent_node_id_p;
891                         }
892                 }
893         }
894
895         /* Track HTTP Requests/Referers */
896         if (v->request_method && v->referer_uri && v->full_uri) {
897                 gint referer_node_id;
898                 gint parent_node_id;
899                 gpointer parent_node_id_p;
900                 gpointer current_node_id_p;
901                 gchar *uri = NULL;
902                 /* Tick the referer's URI */
903                 referer_node_id = http_seq_stats_tick_referer(st, v->referer_uri);
904
905                 /* Tick the request's URI */
906                 http_seq_stats_tick_request(st, v->full_uri, referer_node_id);
907
908                 /* Tick all stats nodes above the referer */
909                 current_node_id_p = GINT_TO_POINTER(referer_node_id);
910                 while (wmem_map_lookup_extended(refstats_node_id_to_parent_node_id_hash, current_node_id_p, NULL, &parent_node_id_p)) {
911                         parent_node_id = GPOINTER_TO_INT(parent_node_id_p);
912                         uri = (gchar *) wmem_map_lookup(refstats_node_id_to_uri_hash, current_node_id_p);
913                         tick_stat_node(st, uri, parent_node_id, TRUE);
914                         current_node_id_p = parent_node_id_p;
915                 }
916         }
917         return 0;
918 }
919
920
921 static void
922 dissect_http_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
923                      const char *line)
924 {
925         tvbuff_t *ntlmssp_tvb;
926
927         ntlmssp_tvb = base64_to_tvb(tvb, line);
928         add_new_data_source(pinfo, ntlmssp_tvb, "NTLMSSP / GSSAPI Data");
929         if (tvb_strneql(ntlmssp_tvb, 0, "NTLMSSP", 7) == 0)
930                 call_dissector(ntlmssp_handle, ntlmssp_tvb, pinfo, tree);
931         else
932                 call_dissector(gssapi_handle, ntlmssp_tvb, pinfo, tree);
933 }
934
935 static void
936 dissect_http_kerberos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
937                      const char *line)
938 {
939         tvbuff_t *kerberos_tvb;
940
941         kerberos_tvb = base64_to_tvb(tvb, line + 9); /* skip 'Kerberos ' which is 9 chars */
942         add_new_data_source(pinfo, kerberos_tvb, "Kerberos Data");
943         call_dissector(gssapi_handle, kerberos_tvb, pinfo, tree);
944
945 }
946
947
948 static http_conv_t *
949 get_http_conversation_data(packet_info *pinfo, conversation_t **conversation)
950 {
951         http_conv_t     *conv_data;
952
953         *conversation = find_or_create_conversation(pinfo);
954
955         /* Retrieve information from conversation
956          * or add it if it isn't there yet
957          */
958         conv_data = (http_conv_t *)conversation_get_proto_data(*conversation, proto_http);
959         if(!conv_data) {
960                 /* Setup the conversation structure itself */
961                 conv_data = (http_conv_t *)wmem_alloc0(wmem_file_scope(), sizeof(http_conv_t));
962
963                 conversation_add_proto_data(*conversation, proto_http,
964                                             conv_data);
965         }
966
967         return conv_data;
968 }
969
970 /**
971  * create a new http_req_res_t and add it to the conversation.
972  * @return the new allocated object which is already added to the linked list
973  */
974 static http_req_res_t* push_req_res(http_conv_t *conv_data)
975 {
976         http_req_res_t *req_res = (http_req_res_t *)wmem_alloc0(wmem_file_scope(), sizeof(http_req_res_t));
977         nstime_set_unset(&(req_res->req_ts));
978         req_res->number = ++conv_data->req_res_num;
979
980         if (! conv_data->req_res_tail) {
981                 conv_data->req_res_tail = req_res;
982         } else {
983                 req_res->prev = conv_data->req_res_tail;
984                 conv_data->req_res_tail->next = req_res;
985                 conv_data->req_res_tail = req_res;
986         }
987
988         return req_res;
989 }
990
991 /**
992  * push a request frame number and its time stamp to the conversation data.
993  */
994 static void push_req(http_conv_t *conv_data, packet_info *pinfo)
995 {
996         /* a request will always create a new http_req_res_t object */
997         http_req_res_t *req_res = push_req_res(conv_data);
998
999         req_res->req_framenum = pinfo->num;
1000         req_res->req_ts = pinfo->abs_ts;
1001
1002         p_add_proto_data(wmem_file_scope(), pinfo, proto_http, 0, req_res);
1003 }
1004
1005 /**
1006  * push a response frame number to the conversation data.
1007  */
1008 static void push_res(http_conv_t *conv_data, packet_info *pinfo)
1009 {
1010         /* a response will create a new http_req_res_t object: if no
1011            object exists, or if one exists for another response. In
1012            both cases the corresponding request was not
1013            detected/included in the conversation. In all other cases
1014            the http_req_res_t object created by the request is
1015            used. */
1016         http_req_res_t *req_res = conv_data->req_res_tail;
1017         if (!req_res || req_res->res_framenum > 0) {
1018                 req_res = push_req_res(conv_data);
1019         }
1020         req_res->res_framenum = pinfo->num;
1021         p_add_proto_data(wmem_file_scope(), pinfo, proto_http, 0, req_res);
1022 }
1023
1024 /*
1025  * TODO: remove this ugly global variable.
1026  * XXX: do we really want to have to pass this from one function to another?
1027  */
1028 static http_info_value_t        *stat_info;
1029
1030 static int
1031 dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
1032                      proto_tree *tree, http_conv_t *conv_data,
1033                      const char* proto_tag, int proto, gboolean end_of_stream)
1034 {
1035         proto_tree      *http_tree = NULL;
1036         proto_item      *ti = NULL;
1037         proto_item      *hidden_item;
1038         const guchar    *line, *firstline;
1039         gint            next_offset;
1040         const guchar    *linep, *lineend;
1041         int             orig_offset;
1042         int             first_linelen, linelen;
1043         gboolean        is_request_or_reply, is_ssl = FALSE;
1044         gboolean        saw_req_resp_or_header;
1045         http_type_t     http_type;
1046         proto_item      *hdr_item = NULL;
1047         ReqRespDissector reqresp_dissector;
1048         proto_tree      *req_tree;
1049         int             colon_offset;
1050         headers_t       headers;
1051         int             datalen;
1052         int             reported_datalen = -1;
1053         dissector_handle_t handle;
1054         gboolean        dissected = FALSE;
1055         gboolean        first_loop = TRUE;
1056         gboolean        have_seen_http = FALSE;
1057         /*guint         i;*/
1058         /*http_info_value_t *si;*/
1059         http_eo_t       *eo_info;
1060         heur_dtbl_entry_t *hdtbl_entry;
1061         int reported_length;
1062         guint16 word;
1063         gboolean        leading_crlf = FALSE;
1064         http_message_info_t message_info;
1065
1066         reported_length = tvb_reported_length_remaining(tvb, offset);
1067         if (reported_length < 1) {
1068                 return -1;
1069         }
1070
1071         /* RFC 2616
1072          *   In the interest of robustness, servers SHOULD ignore any empty
1073          *   line(s) received where a Request-Line is expected. In other words, if
1074          *   the server is reading the protocol stream at the beginning of a
1075          *   message and receives a CRLF first, it should ignore the CRLF.
1076          */
1077         if (reported_length > 3) {
1078                 word = tvb_get_ntohs(tvb,offset);
1079                 if (word == 0x0d0a) {
1080                         leading_crlf = TRUE;
1081                         offset += 2;
1082                 }
1083         }
1084
1085         /*
1086          * If we previously dissected an HTTP request in this conversation then
1087          * we should be pretty sure that whatever we got in this TVB is
1088          * actually HTTP (even if what we have here is part of a file being
1089          * transferred over HTTP).
1090          */
1091         if (conv_data->request_uri)
1092                 have_seen_http = TRUE;
1093
1094         /*
1095          * If this is binary data then there's no point in doing all the string
1096          * operations below: they'll just be slow on this data.
1097          */
1098         if (!g_ascii_isprint(tvb_get_guint8(tvb, offset))) {
1099                 /*
1100                  * But, if we've seen some real HTTP then we're sure this is
1101                  * an HTTP conversation.  Mark it as such.
1102                  */
1103                 if (have_seen_http) {
1104                         col_set_str(pinfo->cinfo, COL_PROTOCOL, proto_tag);
1105                         col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1106                         ti = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA);
1107                         http_tree = proto_item_add_subtree(ti, ett_http);
1108
1109                         call_data_dissector(tvb, pinfo, http_tree);
1110                 }
1111                 return -1;
1112         }
1113
1114         /*
1115          * Is this a request or response?
1116          *
1117          * Note that "tvb_find_line_end()" will return a value that
1118          * is not longer than what's in the buffer, so the
1119          * "tvb_get_ptr()" call won't throw an exception.
1120          */
1121         first_linelen = tvb_find_line_end(tvb, offset,
1122             tvb_ensure_captured_length_remaining(tvb, offset), &next_offset,
1123             TRUE);
1124
1125         if (first_linelen == -1) {
1126                 /* No complete line was found in this segment, do
1127                  * desegmentation if we're told to.
1128                  */
1129                 if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
1130                     http_desegment_headers, http_desegment_body)) {
1131                         /*
1132                          * More data needed for desegmentation.
1133                          */
1134                         return -1;
1135                 }
1136         }
1137
1138         /*
1139          * Is the first line a request or response?
1140          *
1141          * Note that "tvb_find_line_end()" will return a value that
1142          * is not longer than what's in the buffer, so the
1143          * "tvb_get_ptr()" call won't throw an exception.
1144          */
1145         firstline = tvb_get_ptr(tvb, offset, first_linelen);
1146         http_type = HTTP_OTHERS;        /* type not known yet */
1147         is_request_or_reply = is_http_request_or_reply((const gchar *)firstline,
1148             first_linelen, &http_type, NULL, conv_data);
1149         if (is_request_or_reply) {
1150                 gboolean try_desegment_body;
1151
1152                 /*
1153                  * Yes, it's a request or response.
1154                  * Put the first line from the buffer into the summary
1155                  * (but leave out the line terminator).
1156                  */
1157                 col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", format_text(wmem_packet_scope(), firstline, first_linelen));
1158
1159                 /*
1160                  * Do header desegmentation if we've been told to,
1161                  * and do body desegmentation if we've been told to and
1162                  * we find a Content-Length header. Responses to HEAD MUST NOT
1163                  * contain a message body, so ignore the Content-Length header
1164                  * which is done by disabling body desegmentation.
1165                  */
1166                 try_desegment_body = (http_desegment_body &&
1167                         !(http_type == HTTP_RESPONSE && conv_data->request_method && g_str_equal(conv_data->request_method, "HEAD")) &&
1168                         !end_of_stream);
1169                 if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
1170                     http_desegment_headers, try_desegment_body)) {
1171                         /*
1172                          * More data needed for desegmentation.
1173                          */
1174                         return -1;
1175                 }
1176         } else if (have_seen_http) {
1177                  /*
1178                   * If we know this is HTTP then call it continuation.
1179                   */
1180                 col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
1181         }
1182
1183         if (is_request_or_reply || have_seen_http) {
1184                 /*
1185                  * Now set COL_PROTOCOL and create the http tree for the
1186                  * cases where we set COL_INFO above.
1187                  */
1188                 col_set_str(pinfo->cinfo, COL_PROTOCOL, proto_tag);
1189                 ti = proto_tree_add_item(tree, proto, tvb, offset, -1, ENC_NA);
1190                 http_tree = proto_item_add_subtree(ti, ett_http);
1191
1192                 if (leading_crlf) {
1193                         proto_tree_add_expert(http_tree, pinfo, &ei_http_leading_crlf, tvb, offset-2, 2);
1194                 }
1195         }
1196
1197         is_ssl = proto_is_frame_protocol(pinfo->layers, "ssl");
1198
1199         stat_info = wmem_new(wmem_packet_scope(), http_info_value_t);
1200         stat_info->framenum = pinfo->num;
1201         stat_info->response_code = 0;
1202         stat_info->request_method = NULL;
1203         stat_info->request_uri = NULL;
1204         stat_info->referer_uri = NULL;
1205         stat_info->http_host = NULL;
1206         stat_info->full_uri = NULL;
1207         stat_info->location_target = NULL;
1208         stat_info->location_base_uri = NULL;
1209
1210         orig_offset = offset;
1211
1212         /*
1213          * Process the packet data, a line at a time.
1214          */
1215         http_type = HTTP_OTHERS;        /* type not known yet */
1216         headers.content_type = NULL;    /* content type not known yet */
1217         headers.content_type_parameters = NULL; /* content type parameters too */
1218         headers.have_content_length = FALSE;    /* content length not known yet */
1219         headers.content_length = 0;             /* content length set to 0 (avoid a gcc warning) */
1220         headers.content_encoding = NULL; /* content encoding not known yet */
1221         headers.transfer_encoding_chunked = FALSE;
1222         headers.transfer_encoding = HTTP_TE_NONE;
1223         headers.upgrade = NULL;         /* assume no upgrade header */
1224         saw_req_resp_or_header = FALSE; /* haven't seen anything yet */
1225         while (tvb_offset_exists(tvb, offset)) {
1226                 /*
1227                  * Find the end of the line.
1228                  * XXX - what if we don't find it because the packet
1229                  * is cut short by a snapshot length or the header is
1230                  * split across TCP segments?  How much dissection should
1231                  * we do on it?
1232                  */
1233                 linelen = tvb_find_line_end(tvb, offset,
1234                     tvb_ensure_captured_length_remaining(tvb, offset), &next_offset,
1235                     FALSE);
1236                 if (linelen < 0)
1237                         return -1;
1238
1239                 /*
1240                  * Get a buffer that refers to the line.
1241                  *
1242                  * Note that "tvb_find_line_end()" will return a value that
1243                  * is not longer than what's in the buffer, so the
1244                  * "tvb_get_ptr()" call won't throw an exception.
1245                  */
1246                 line = tvb_get_ptr(tvb, offset, linelen);
1247                 lineend = line + linelen;
1248                 colon_offset = -1;
1249
1250                 /*
1251                  * OK, does it look like an HTTP request or response?
1252                  */
1253                 reqresp_dissector = NULL;
1254                 is_request_or_reply =
1255                     is_http_request_or_reply((const gchar *)line,
1256                     linelen, &http_type, &reqresp_dissector, conv_data);
1257                 if (is_request_or_reply)
1258                         goto is_http;
1259
1260                 /*
1261                  * No.  Does it look like a blank line (as would appear
1262                  * at the end of an HTTP request)?
1263                  */
1264                 if (linelen == 0)
1265                         goto is_http;   /* Yes. */
1266
1267                 /*
1268                  * No.  Does it look like a header?
1269                  */
1270                 colon_offset = offset;
1271
1272                 linep = (const guchar *)memchr(line, ':', linelen);
1273                 if (linep) {
1274                         /*
1275                          * Colon found, assume it is a header.
1276                          */
1277                         colon_offset += (int)(linep - line);
1278                         goto is_http;
1279                 }
1280
1281                 /*
1282                  * We haven't seen the colon yet.
1283                  *
1284                  * If we've already seen an HTTP request or response
1285                  * line, or a header line, and we're at the end of
1286                  * the tvbuff, we assume this is an incomplete header
1287                  * line.  (We quit this loop after seeing a blank line,
1288                  * so if we've seen a request or response line, or a
1289                  * header line, this is probably more of the request
1290                  * or response we're presumably seeing.  There is some
1291                  * risk of false positives, but the same applies for
1292                  * full request or response lines or header lines,
1293                  * although that's less likely.)
1294                  *
1295                  * We throw an exception in that case, by checking for
1296                  * the existence of the next byte after the last one
1297                  * in the line.  If it exists, "tvb_ensure_bytes_exist()"
1298                  * throws no exception, and we fall through to the
1299                  * "not HTTP" case.  If it doesn't exist,
1300                  * "tvb_ensure_bytes_exist()" will throw the appropriate
1301                  * exception.
1302                  */
1303                 if (saw_req_resp_or_header)
1304                         tvb_ensure_bytes_exist(tvb, offset, linelen + 1);
1305
1306                 /*
1307                  * We don't consider this part of an HTTP request or
1308                  * reply, so we don't display it.
1309                  * (Yeah, that means we don't display, say, a text/http
1310                  * page, but you can get that from the data pane.)
1311                  */
1312                 break;
1313
1314         is_http:
1315                 if ((tree) && (http_tree == NULL)) {
1316                         ti = proto_tree_add_item(tree, proto, tvb, orig_offset, -1, ENC_NA);
1317                         http_tree = proto_item_add_subtree(ti, ett_http);
1318                         if (leading_crlf) {
1319                                 proto_tree_add_expert(http_tree, pinfo, &ei_http_leading_crlf, tvb, orig_offset-2, 2);
1320                         }
1321                 }
1322
1323                 if (first_loop && !is_ssl && pinfo->ptype == PT_TCP &&
1324                                 (pinfo->srcport == 443 || pinfo->destport == 443)) {
1325                         expert_add_info(pinfo, ti, &ei_http_ssl_port);
1326                 }
1327
1328                 first_loop = FALSE;
1329
1330                 /*
1331                  * Process this line.
1332                  */
1333
1334                 if (linelen == 0) {
1335                         /*
1336                          * This is a blank line, which means that
1337                          * whatever follows it isn't part of this
1338                          * request or reply.
1339                          */
1340                         proto_tree_add_format_text(http_tree, tvb, offset, next_offset - offset);
1341                         offset = next_offset;
1342                         break;
1343                 }
1344
1345                 /*
1346                  * Not a blank line - either a request, a reply, or a header
1347                  * line.
1348                  */
1349                 saw_req_resp_or_header = TRUE;
1350                 if (is_request_or_reply) {
1351                         char *text = tvb_format_text(tvb, offset, next_offset - offset);
1352
1353                         req_tree = proto_tree_add_subtree(http_tree, tvb,
1354                                     offset, next_offset - offset, ett_http_request, &hdr_item, text);
1355
1356                         expert_add_info_format(pinfo, hdr_item, &ei_http_chat, "%s", text);
1357                         if (reqresp_dissector) {
1358                                 reqresp_dissector(tvb, req_tree, offset, line,
1359                                                   lineend, conv_data);
1360                         }
1361                 } else {
1362                         /*
1363                          * Header.
1364                          */
1365                         process_header(tvb, offset, next_offset, line, linelen,
1366                             colon_offset, pinfo, http_tree, &headers, conv_data,
1367                             http_type);
1368                 }
1369                 offset = next_offset;
1370         }
1371         if (stat_info->http_host && stat_info->request_uri) {
1372                 proto_item *e_ti;
1373                 gchar      *uri;
1374
1375                 if ((g_ascii_strncasecmp(stat_info->request_uri, "http://", 7) == 0) ||
1376                     (g_ascii_strncasecmp(stat_info->request_uri, "https://", 8) == 0) ||
1377                     (g_ascii_strncasecmp(conv_data->request_method, "CONNECT", 7) == 0)) {
1378                         uri = wmem_strdup(wmem_packet_scope(), stat_info->request_uri);
1379                 }
1380                 else {
1381                         uri = wmem_strdup_printf(wmem_packet_scope(), "%s://%s%s",
1382                                     is_ssl ? "https" : "http",
1383                                     g_strstrip(wmem_strdup(wmem_packet_scope(), stat_info->http_host)), stat_info->request_uri);
1384                 }
1385                 stat_info->full_uri = wmem_strdup(wmem_packet_scope(), uri);
1386                 conv_data->full_uri = wmem_strdup(wmem_file_scope(), uri);
1387                 if (tree) {
1388                         e_ti = proto_tree_add_string(http_tree,
1389                                              hf_http_request_full_uri, tvb, 0,
1390                                              0, uri);
1391
1392                         PROTO_ITEM_SET_URL(e_ti);
1393                         PROTO_ITEM_SET_GENERATED(e_ti);
1394                 }
1395         }
1396
1397         if (!PINFO_FD_VISITED(pinfo)) {
1398                 if (http_type == HTTP_REQUEST) {
1399                         push_req(conv_data, pinfo);
1400                 } else if (http_type == HTTP_RESPONSE) {
1401                         push_res(conv_data, pinfo);
1402                 }
1403         }
1404
1405         if (tree) {
1406                 proto_item *pi;
1407                 http_req_res_t *curr = (http_req_res_t *)p_get_proto_data(wmem_file_scope(), pinfo, proto_http, 0);
1408                 http_req_res_t *prev = curr ? curr->prev : NULL;
1409                 http_req_res_t *next = curr ? curr->next : NULL;
1410
1411                 switch (http_type) {
1412
1413                 case HTTP_NOTIFICATION:
1414                         hidden_item = proto_tree_add_boolean(http_tree,
1415                                             hf_http_notification, tvb, 0, 0, 1);
1416                         PROTO_ITEM_SET_HIDDEN(hidden_item);
1417                         break;
1418
1419                 case HTTP_RESPONSE:
1420                         hidden_item = proto_tree_add_boolean(http_tree,
1421                                             hf_http_response, tvb, 0, 0, 1);
1422                         PROTO_ITEM_SET_HIDDEN(hidden_item);
1423
1424                         if (curr) {
1425                                 nstime_t delta;
1426
1427                                 pi = proto_tree_add_uint_format(http_tree, hf_http_response_number, tvb, 0, 0, curr->number, "HTTP response %u/%u", curr->number, conv_data->req_res_num);
1428                                 PROTO_ITEM_SET_GENERATED(pi);
1429
1430                                 if (! nstime_is_unset(&(curr->req_ts))) {
1431                                         nstime_delta(&delta, &pinfo->abs_ts, &(curr->req_ts));
1432                                         pi = proto_tree_add_time(http_tree, hf_http_time, tvb, 0, 0, &delta);
1433                                         PROTO_ITEM_SET_GENERATED(pi);
1434                                 }
1435                         }
1436                         if (prev && prev->req_framenum) {
1437                                 pi = proto_tree_add_uint(http_tree, hf_http_prev_request_in, tvb, 0, 0, prev->req_framenum);
1438                                 PROTO_ITEM_SET_GENERATED(pi);
1439                         }
1440                         if (prev && prev->res_framenum) {
1441                                 pi = proto_tree_add_uint(http_tree, hf_http_prev_response_in, tvb, 0, 0, prev->res_framenum);
1442                                 PROTO_ITEM_SET_GENERATED(pi);
1443                         }
1444                         if (curr && curr->req_framenum) {
1445                                 pi = proto_tree_add_uint(http_tree, hf_http_request_in, tvb, 0, 0, curr->req_framenum);
1446                                 PROTO_ITEM_SET_GENERATED(pi);
1447                         }
1448                         if (next && next->req_framenum) {
1449                                 pi = proto_tree_add_uint(http_tree, hf_http_next_request_in, tvb, 0, 0, next->req_framenum);
1450                                 PROTO_ITEM_SET_GENERATED(pi);
1451                         }
1452                         if (next && next->res_framenum) {
1453                                 pi = proto_tree_add_uint(http_tree, hf_http_next_response_in, tvb, 0, 0, next->res_framenum);
1454                                 PROTO_ITEM_SET_GENERATED(pi);
1455                         }
1456
1457                         break;
1458
1459                 case HTTP_REQUEST:
1460                         hidden_item = proto_tree_add_boolean(http_tree,
1461                                             hf_http_request, tvb, 0, 0, 1);
1462                         PROTO_ITEM_SET_HIDDEN(hidden_item);
1463
1464                         if (curr) {
1465                                 pi = proto_tree_add_uint_format(http_tree, hf_http_request_number, tvb, 0, 0, curr->number, "HTTP request %u/%u", curr->number, conv_data->req_res_num);
1466                                 PROTO_ITEM_SET_GENERATED(pi);
1467                         }
1468                         if (prev && prev->req_framenum) {
1469                                 pi = proto_tree_add_uint(http_tree, hf_http_prev_request_in, tvb, 0, 0, prev->req_framenum);
1470                                 PROTO_ITEM_SET_GENERATED(pi);
1471                         }
1472                         if (curr && curr->res_framenum) {
1473                                 pi = proto_tree_add_uint(http_tree, hf_http_response_in, tvb, 0, 0, curr->res_framenum);
1474                                 PROTO_ITEM_SET_GENERATED(pi);
1475                         }
1476                         if (next && next->req_framenum) {
1477                                 pi = proto_tree_add_uint(http_tree, hf_http_next_request_in, tvb, 0, 0, next->req_framenum);
1478                                 PROTO_ITEM_SET_GENERATED(pi);
1479                         }
1480
1481                         break;
1482
1483                 case HTTP_OTHERS:
1484                 default:
1485                         break;
1486                 }
1487         }
1488
1489         /* Give the follw tap what we've currently dissected */
1490         if(have_tap_listener(http_follow_tap)) {
1491                 tap_queue_packet(http_follow_tap, pinfo, tvb_new_subset_length(tvb, 0, offset));
1492         }
1493
1494         reported_datalen = tvb_reported_length_remaining(tvb, offset);
1495         datalen = tvb_captured_length_remaining(tvb, offset);
1496
1497         /*
1498          * If a content length was supplied, the amount of data to be
1499          * processed as HTTP payload is the minimum of the content
1500          * length and the amount of data remaining in the frame.
1501          *
1502          * If a message is received with both a Transfer-Encoding
1503          * header field and a Content-Length header field, the latter
1504          * MUST be ignored.
1505          *
1506          * If no content length was supplied (or if a bad content length
1507          * was supplied), the amount of data to be processed is the amount
1508          * of data remaining in the frame.
1509          *
1510          * If there was no Content-Length entity header, we should
1511          * accumulate all data until the end of the connection.
1512          * That'd require that the TCP dissector call subdissectors
1513          * for all frames with FIN, even if they contain no data,
1514          * which would require subdissectors to deal intelligently
1515          * with empty segments.
1516          *
1517          * According to RFC 2616, however, 1xx responses, 204 responses,
1518          * and 304 responses MUST NOT include a message body; if no
1519          * content length is specified for them, we don't attempt to
1520          * dissect the body.
1521          *
1522          * XXX - it says the same about responses to HEAD requests;
1523          * unless there's a way to determine from the response
1524          * whether it's a response to a HEAD request, we have to
1525          * keep information about the request and associate that with
1526          * the response in order to handle that.
1527          */
1528         if (headers.have_content_length &&
1529             headers.transfer_encoding == HTTP_TE_NONE) {
1530                 if (datalen > headers.content_length)
1531                         datalen = (int)headers.content_length;
1532
1533                 /*
1534                  * XXX - limit the reported length in the tvbuff we'll
1535                  * hand to a subdissector to be no greater than the
1536                  * content length.
1537                  *
1538                  * We really need both unreassembled and "how long it'd
1539                  * be if it were reassembled" lengths for tvbuffs, so
1540                  * that we throw the appropriate exceptions for
1541                  * "not enough data captured" (running past the length),
1542                  * "packet needed reassembly" (within the length but
1543                  * running past the unreassembled length), and
1544                  * "packet is malformed" (running past the reassembled
1545                  * length).
1546                  */
1547                 if (reported_datalen > headers.content_length)
1548                         reported_datalen = (int)headers.content_length;
1549         } else {
1550                 switch (http_type) {
1551
1552                 case HTTP_REQUEST:
1553                         /*
1554                          * Requests have no content if there's no
1555                          * Content-Length header and no Transfer-Encoding
1556                          * header.
1557                          */
1558                         if (headers.transfer_encoding == HTTP_TE_NONE)
1559                                 datalen = 0;
1560                         else
1561                                 reported_datalen = -1;
1562                         break;
1563
1564                 case HTTP_RESPONSE:
1565                         if ((stat_info->response_code/100) == 1 ||
1566                             stat_info->response_code == 204 ||
1567                             stat_info->response_code == 304)
1568                                 datalen = 0;    /* no content! */
1569                         else {
1570                                 /*
1571                                  * XXX - responses to HEAD requests,
1572                                  * and possibly other responses,
1573                                  * "MUST NOT" include a
1574                                  * message-body.
1575                                  */
1576                                 reported_datalen = -1;
1577                         }
1578                         break;
1579
1580                 default:
1581                         /*
1582                          * XXX - what about HTTP_NOTIFICATION?
1583                          */
1584                         reported_datalen = -1;
1585                         break;
1586                 }
1587         }
1588
1589         if (datalen > 0) {
1590                 /*
1591                  * There's stuff left over; process it.
1592                  */
1593                 tvbuff_t *next_tvb;
1594                 guint chunked_datalen = 0;
1595                 char *media_str = NULL;
1596                 const gchar *file_data;
1597
1598                 /*
1599                  * Create a tvbuff for the payload.
1600                  *
1601                  * The amount of data to be processed that's
1602                  * available in the tvbuff is "datalen", which
1603                  * is the minimum of the amount of data left in
1604                  * the tvbuff and any specified content length.
1605                  *
1606                  * The amount of data to be processed that's in
1607                  * this frame, regardless of whether it was
1608                  * captured or not, is "reported_datalen",
1609                  * which, if no content length was specified,
1610                  * is -1, i.e. "to the end of the frame.
1611                  */
1612                 next_tvb = tvb_new_subset_length_caplen(tvb, offset, datalen,
1613                     reported_datalen);
1614
1615                 /*
1616                  * Handle *transfer* encodings.
1617                  */
1618                 if (headers.transfer_encoding_chunked) {
1619                         if (!http_dechunk_body) {
1620                                 /* Chunking disabled, cannot dissect further. */
1621                                 call_data_dissector(next_tvb, pinfo, http_tree);
1622                                 goto body_dissected;
1623                         }
1624
1625                         chunked_datalen = chunked_encoding_dissector(
1626                             &next_tvb, pinfo, http_tree, 0);
1627
1628                         if (chunked_datalen == 0) {
1629                                 /*
1630                                  * The chunks weren't reassembled,
1631                                  * or there was a single zero
1632                                  * length chunk.
1633                                  */
1634                                 goto body_dissected;
1635                         } else {
1636                                 /*
1637                                  * Add a new data source for the
1638                                  * de-chunked data.
1639                                  */
1640 #if 0 /* Handled in chunked_encoding_dissector() */
1641                                 tvb_set_child_real_data_tvbuff(tvb,
1642                                         next_tvb);
1643 #endif
1644                                 add_new_data_source(pinfo, next_tvb,
1645                                         "De-chunked entity body");
1646                                 /* chunked-body might be smaller than
1647                                  * datalen. */
1648                                 datalen = chunked_datalen;
1649                         }
1650                 }
1651                 /* Handle other transfer codings after de-chunking. */
1652                 switch (headers.transfer_encoding) {
1653                 case HTTP_TE_COMPRESS:
1654                 case HTTP_TE_DEFLATE:
1655                 case HTTP_TE_GZIP:
1656                         /*
1657                          * We currently can't handle, for example, "gzip",
1658                          * "compress", or "deflate" as *transfer* encodings;
1659                          * just handle them as data for now.
1660                          */
1661                         call_data_dissector(next_tvb, pinfo, http_tree);
1662                         goto body_dissected;
1663                 default:
1664                         /* Nothing to do for "identity" or when header is
1665                          * missing or invalid. */
1666                         break;
1667                 }
1668                 /*
1669                  * At this point, any chunked *transfer* coding has been removed
1670                  * (the entity body has been dechunked) so it can be presented
1671                  * for the following operation (*content* encoding), or it has
1672                  * been been handed off to the data dissector.
1673                  *
1674                  * Handle *content* encodings other than "identity" (which
1675                  * shouldn't appear in a Content-Encoding header, but
1676                  * we handle it in any case).
1677                  */
1678                 if (headers.content_encoding != NULL &&
1679                     g_ascii_strcasecmp(headers.content_encoding, "identity") != 0) {
1680                         /*
1681                          * We currently don't handle, for example, "compress";
1682                          * just handle them as data for now.
1683                          *
1684                          * After July 7, 2004 the LZW patent expired, so
1685                          * support could be added.  However, I don't think
1686                          * that anybody ever really implemented "compress",
1687                          * due to the aforementioned patent.
1688                          */
1689                         tvbuff_t *uncomp_tvb = NULL;
1690                         proto_item *e_ti = NULL;
1691                         proto_tree *e_tree = NULL;
1692
1693                         if (http_decompress_body &&
1694                             (g_ascii_strcasecmp(headers.content_encoding, "gzip") == 0 ||
1695                              g_ascii_strcasecmp(headers.content_encoding, "deflate") == 0 ||
1696                              g_ascii_strcasecmp(headers.content_encoding, "x-gzip") == 0 ||
1697                              g_ascii_strcasecmp(headers.content_encoding, "x-deflate") == 0))
1698                         {
1699                                 uncomp_tvb = tvb_child_uncompress(tvb, next_tvb, 0,
1700                                     tvb_captured_length(next_tvb));
1701                         }
1702
1703                         /*
1704                          * Add the encoded entity to the protocol tree
1705                          */
1706                         e_tree = proto_tree_add_subtree_format(http_tree, next_tvb,
1707                                         0, tvb_captured_length(next_tvb), ett_http_encoded_entity, &e_ti,
1708                                         "Content-encoded entity body (%s): %u bytes",
1709                                         headers.content_encoding,
1710                                         tvb_captured_length(next_tvb));
1711
1712                         if (uncomp_tvb != NULL) {
1713                                 /*
1714                                  * Decompression worked
1715                                  */
1716
1717                                 /* XXX - Don't free this, since it's possible
1718                                  * that the data was only partially
1719                                  * decompressed, such as when desegmentation
1720                                  * isn't enabled.
1721                                  *
1722                                 tvb_free(next_tvb);
1723                                 */
1724                                 proto_item_append_text(e_ti, " -> %u bytes", tvb_captured_length(uncomp_tvb));
1725                                 next_tvb = uncomp_tvb;
1726                                 add_new_data_source(pinfo, next_tvb,
1727                                     "Uncompressed entity body");
1728                         } else {
1729                                 proto_item_append_text(e_ti, " [Error: Decompression failed]");
1730                                 call_data_dissector(next_tvb, pinfo, e_tree);
1731
1732                                 goto body_dissected;
1733                         }
1734                 }
1735                 /*
1736                  * Note that a new data source is added for the entity body
1737                  * only if it was content-encoded and/or transfer-encoded.
1738                  */
1739
1740                 /* Save values for the Export Object GUI feature if we have
1741                  * an active listener to process it (which happens when
1742                  * the export object window is open). */
1743                 if(have_tap_listener(http_eo_tap)) {
1744                         eo_info = wmem_new(wmem_packet_scope(), http_eo_t);
1745
1746                         eo_info->hostname = conv_data->http_host;
1747                         eo_info->filename = conv_data->request_uri;
1748                         eo_info->content_type = headers.content_type;
1749                         eo_info->payload_len = tvb_captured_length(next_tvb);
1750                         eo_info->payload_data = tvb_get_ptr(next_tvb, 0, eo_info->payload_len);
1751
1752                         tap_queue_packet(http_eo_tap, pinfo, eo_info);
1753                 }
1754
1755                 /* Save values for the Export Object GUI feature if we have
1756                  * an active listener to process it (which happens when
1757                  * the export object window is open). */
1758                 if(have_tap_listener(http_follow_tap)) {
1759                         tap_queue_packet(http_follow_tap, pinfo, next_tvb);
1760                 }
1761                 file_data = tvb_get_string_enc(wmem_packet_scope(), next_tvb, 0, tvb_captured_length(next_tvb), ENC_ASCII);
1762                 proto_tree_add_string_format_value(http_tree, hf_http_file_data,
1763                         next_tvb, 0, tvb_captured_length(next_tvb), file_data, "%u bytes", tvb_captured_length(next_tvb));
1764
1765                 /*
1766                  * Do subdissector checks.
1767                  *
1768                  * First, if we have a Content-Type value, check whether
1769                  * there's a subdissector for that media type.
1770                  */
1771                 handle = NULL;
1772                 if (headers.content_type != NULL) {
1773                         /*
1774                          * We didn't find any subdissector that
1775                          * registered for the port, and we have a
1776                          * Content-Type value.  Is there any subdissector
1777                          * for that content type?
1778                          */
1779                         if (headers.content_type_parameters)
1780                                 media_str = wmem_strdup(wmem_packet_scope(), headers.content_type_parameters);
1781
1782                         /*
1783                          * Calling the string handle for the media type
1784                          * dissector table will set pinfo->match_string
1785                          * to headers.content_type for us.
1786                          */
1787                         pinfo->match_string = headers.content_type;
1788                         handle = dissector_get_string_handle(
1789                             media_type_subdissector_table,
1790                             headers.content_type);
1791                         if (handle == NULL &&
1792                             strncmp(headers.content_type, "multipart/", sizeof("multipart/")-1) == 0) {
1793                                 /* Try to decode the unknown multipart subtype anyway */
1794                                 handle = dissector_get_string_handle(
1795                                     media_type_subdissector_table,
1796                                     "multipart/");
1797                         }
1798                 }
1799
1800                 /*
1801                  * Now, if we didn't find such a subdissector, check
1802                  * whether some subdissector asked that they be called
1803                  * if HTTP traffic was on some particular port.  This
1804                  * handles protocols that use HTTP syntax but don't have
1805                  * a media type and instead use a specified port.
1806                  */
1807                 if (handle == NULL) {
1808                         handle = dissector_get_uint_handle(port_subdissector_table,
1809                             pinfo->match_uint);
1810                 }
1811
1812                 message_info.type = http_type;
1813                 message_info.media_str = media_str;
1814                 if (handle != NULL) {
1815                         /*
1816                          * We have a subdissector - call it.
1817                          */
1818                         dissected = call_dissector_only(handle, next_tvb, pinfo, tree, &message_info);
1819                         if (!dissected)
1820                                 expert_add_info(pinfo, http_tree, &ei_http_subdissector_failed);
1821                 }
1822
1823                 if (!dissected) {
1824                         /*
1825                          * We don't have a subdissector or we have one and it did not
1826                          * dissect the payload - try the heuristic subdissectors.
1827                          */
1828                         dissected = dissector_try_heuristic(heur_subdissector_list,
1829                                                             next_tvb, pinfo, tree, &hdtbl_entry, NULL);
1830                 }
1831
1832                 if (dissected) {
1833                         /*
1834                          * The subdissector dissected the body.
1835                          * Fix up the top-level item so that it doesn't
1836                          * include the stuff for that protocol.
1837                          */
1838                         if (ti != NULL)
1839                                 proto_item_set_len(ti, offset);
1840                 } else {
1841                         if (headers.content_type != NULL) {
1842                                 /*
1843                                  * Calling the default media handle if there is a content-type that
1844                                  * wasn't handled above.
1845                                  */
1846                                 call_dissector_with_data(media_handle, next_tvb, pinfo, tree, &message_info);
1847                         } else {
1848                                 /* Call the default data dissector */
1849                                 call_data_dissector(next_tvb, pinfo, http_tree);
1850                         }
1851                 }
1852
1853         body_dissected:
1854                 /*
1855                  * We've processed "datalen" bytes worth of data
1856                  * (which may be no data at all); advance the
1857                  * offset past whatever data we've processed.
1858                  */
1859                 offset += datalen;
1860         }
1861
1862         /* Detect protocol changes after receiving full response headers. */
1863         if (conv_data->request_method && http_type == HTTP_RESPONSE && pinfo->desegment_offset <= 0 && pinfo->desegment_len <= 0) {
1864                 dissector_handle_t next_handle = NULL;
1865                 gboolean server_acked = FALSE;
1866
1867                 /*
1868                  * SSTP uses a special request method (instead of the Upgrade
1869                  * header) and expects a 200 response to set up the session.
1870                  */
1871                 if (strcmp(conv_data->request_method, "SSTP_DUPLEX_POST") == 0 && conv_data->response_code == 200) {
1872                         next_handle = sstp_handle;
1873                         server_acked = TRUE;
1874                 }
1875
1876                 /*
1877                  * An HTTP/1.1 upgrade only proceeds if the server responds
1878                  * with 101 Switching Protocols. See RFC 7230 Section 6.7.
1879                  */
1880                 if (headers.upgrade && conv_data->response_code == 101) {
1881                         next_handle = dissector_get_string_handle(upgrade_subdissector_table, headers.upgrade);
1882                         if (!next_handle) {
1883                                 char *slash_pos = strchr(headers.upgrade, '/');
1884                                 if (slash_pos) {
1885                                         /* Try again without version suffix. */
1886                                         next_handle = dissector_get_string_handle(upgrade_subdissector_table,
1887                                                         wmem_strndup(wmem_packet_scope(), headers.upgrade, slash_pos - headers.upgrade));
1888                                 }
1889                         }
1890                         server_acked = TRUE;
1891                 }
1892
1893                 if (server_acked) {
1894                         conv_data->startframe = pinfo->num;
1895                         conv_data->startoffset = offset;
1896                         conv_data->next_handle = next_handle;
1897                         copy_address_wmem(wmem_file_scope(), &conv_data->server_addr, &pinfo->src);
1898                         conv_data->server_port = pinfo->srcport;
1899                 }
1900         }
1901
1902         tap_queue_packet(http_tap, pinfo, stat_info);
1903
1904         return offset - orig_offset;
1905 }
1906
1907 /* This can be used to dissect an HTTP request until such time
1908  * that a more complete dissector is written for that HTTP request.
1909  * This simple dissector only puts the request method, URI, and
1910  * protocol version into a sub-tree.
1911  */
1912 static void
1913 basic_request_dissector(tvbuff_t *tvb, proto_tree *tree, int offset,
1914                         const guchar *line, const guchar *lineend,
1915                         http_conv_t *conv_data)
1916 {
1917         const guchar *next_token;
1918         const gchar *request_uri;
1919         gchar *query_str, *parameter_str, *path_str;
1920         int request_uri_len, query_str_len, parameter_str_len;
1921         int tokenlen, query_offset, path_len;
1922         proto_item *ti, *tj;
1923         proto_tree *query_tree, *path_tree;
1924
1925         /* The first token is the method. */
1926         tokenlen = get_token_len(line, lineend, &next_token);
1927         if (tokenlen == 0)
1928                 return;
1929         proto_tree_add_item(tree, hf_http_request_method, tvb, offset, tokenlen,
1930                             ENC_ASCII|ENC_NA);
1931         if ((next_token - line) > 2 && next_token[-1] == ' ' && next_token[-2] == ' ') {
1932           /* Two spaces in a now indicates empty URI, so roll back one here */
1933           next_token--;
1934         }
1935         offset += (int) (next_token - line);
1936         line = next_token;
1937
1938         /* The next token is the URI. */
1939         tokenlen = get_token_len(line, lineend, &next_token);
1940
1941         /* Save the request URI for various later uses */
1942         request_uri = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tokenlen, ENC_ASCII);
1943         stat_info->request_uri = wmem_strdup(wmem_packet_scope(), request_uri);
1944         conv_data->request_uri = wmem_strdup(wmem_file_scope(), request_uri);
1945
1946         tj = proto_tree_add_string(tree, hf_http_request_uri, tvb, offset, tokenlen, request_uri);
1947         if (( query_str = strchr(request_uri, '?')) != NULL) {
1948                 if (strlen(query_str) > 1) {
1949                         query_str++;
1950                         query_str_len = (int)strlen(query_str);
1951                         request_uri_len = (int)strlen(request_uri);
1952                         path_len = request_uri_len - query_str_len;
1953                         query_offset = offset + path_len;
1954                         path_tree = proto_item_add_subtree(tj, ett_http_request_path);
1955                         path_str = wmem_strndup(wmem_packet_scope(), request_uri, path_len-1);
1956                         proto_tree_add_string(path_tree, hf_http_request_path, tvb, offset, path_len-1, path_str);
1957                         ti = proto_tree_add_string(path_tree, hf_http_request_query, tvb, query_offset, query_str_len, query_str);
1958                         query_tree = proto_item_add_subtree(ti, ett_http_request_query);
1959                         for ( parameter_str = strtok(query_str, "&"); parameter_str; parameter_str = strtok(NULL, "&") ) {
1960                                 parameter_str_len = (int) strlen(parameter_str);
1961                                 proto_tree_add_string(query_tree, hf_http_request_query_parameter, tvb, query_offset, parameter_str_len, parameter_str);
1962                                 query_offset += parameter_str_len + 1;
1963                         }
1964                 }
1965         }
1966         offset += (int) (next_token - line);
1967         line = next_token;
1968
1969         /* Everything to the end of the line is the version. */
1970         tokenlen = (int) (lineend - line);
1971         proto_tree_add_item(tree, hf_http_request_version, tvb, offset, tokenlen,
1972             ENC_ASCII|ENC_NA);
1973 }
1974
1975 static void
1976 basic_response_dissector(tvbuff_t *tvb, proto_tree *tree, int offset,
1977                          const guchar *line, const guchar *lineend,
1978                          http_conv_t *conv_data _U_)
1979 {
1980         const guchar *next_token;
1981         int tokenlen;
1982         gchar response_code_chars[4];
1983         proto_item *r_ti;
1984
1985         /*
1986          * The first token is the HTTP Version.
1987          */
1988         tokenlen = get_token_len(line, lineend, &next_token);
1989         if (tokenlen == 0)
1990                 return;
1991         proto_tree_add_item(tree, hf_http_response_version, tvb, offset, tokenlen,
1992                             ENC_ASCII|ENC_NA);
1993         /* Advance to the start of the next token. */
1994         offset += (int) (next_token - line);
1995         line = next_token;
1996
1997         /*
1998          * The second token is the Status Code.
1999          */
2000         tokenlen = get_token_len(line, lineend, &next_token);
2001         if (tokenlen < 3)
2002                 return;
2003
2004         /* The Status Code characters must be copied into a null-terminated
2005          * buffer for strtoul() to parse them into an unsigned integer value.
2006          */
2007         memcpy(response_code_chars, line, 3);
2008         response_code_chars[3] = '\0';
2009
2010         stat_info->response_code = conv_data->response_code =
2011                 (guint)strtoul(response_code_chars, NULL, 10);
2012
2013         proto_tree_add_uint(tree, hf_http_response_code, tvb, offset, 3,
2014                             stat_info->response_code);
2015
2016         r_ti = proto_tree_add_string(tree, hf_http_response_code_desc,
2017                 tvb, offset, 3, val_to_str(stat_info->response_code,
2018                 vals_http_status_code, "Unknown (%d)"));
2019
2020         PROTO_ITEM_SET_GENERATED(r_ti);
2021
2022         /* Advance to the start of the next token. */
2023         offset += (int) (next_token - line);
2024         line = next_token;
2025
2026         /*
2027          * The remaining tokens in the line comprise the Reason Phrase.
2028          */
2029         tokenlen = (int) (lineend - line);
2030         if (tokenlen >= 1) {
2031                 proto_tree_add_item(tree, hf_http_response_phrase, tvb, offset,
2032                                 tokenlen, ENC_ASCII|ENC_NA);
2033         }
2034 }
2035
2036 #if 0 /* XXX: Replaced by code creating the "Dechunked" tvb O(N) rather than O(N^2) */
2037 /*
2038  * Dissect the http data chunks and add them to the tree.
2039  */
2040 static int
2041 chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
2042                            proto_tree *tree, int offset)
2043 {
2044         guint8 *chunk_string = NULL;
2045         guint32 chunk_size = 0;
2046         gint chunk_offset = 0;
2047         guint32 datalen = 0;
2048         gint linelen = 0;
2049         gint chunks_decoded = 0;
2050         tvbuff_t *tvb = NULL;
2051         tvbuff_t *new_tvb = NULL;
2052         gint chunked_data_size = 0;
2053         proto_tree *subtree;
2054         proto_item *ti;
2055
2056         if (tvb_ptr == NULL || *tvb_ptr == NULL) {
2057                 return 0;
2058         }
2059
2060         tvb = *tvb_ptr;
2061
2062         datalen = tvb_reported_length_remaining(tvb, offset);
2063
2064         subtree = proto_tree_add_subtree(tree, tvb, offset, datalen,
2065                                          ett_http_chunked_response, NULL, "HTTP chunked response");
2066
2067         while (datalen > 0) {
2068                 proto_item *chunk_ti = NULL, *chuck_size_item;
2069                 proto_tree *chunk_subtree = NULL;
2070                 tvbuff_t *data_tvb = NULL; /*  */
2071                 gchar *c = NULL;
2072                 guint8 *raw_data;
2073                 gint raw_len = 0;
2074
2075                 linelen = tvb_find_line_end(tvb, offset, -1, &chunk_offset, TRUE);
2076
2077                 if (linelen <= 0) {
2078                         /* Can't get the chunk size line */
2079                         break;
2080                 }
2081
2082                 chunk_string = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, linelen, ENC_ASCII);
2083
2084                 if (chunk_string == NULL) {
2085                         /* Can't get the chunk size line */
2086                         break;
2087                 }
2088
2089                 c = (gchar*) chunk_string;
2090
2091                 /*
2092                  * We don't care about the extensions.
2093                  */
2094                 if ((c = strchr(c, ';'))) {
2095                         *c = '\0';
2096                 }
2097
2098                 chunk_size = (guint32)strtol((gchar*)chunk_string, NULL, 16);
2099
2100                 if (chunk_size > datalen) {
2101                         /*
2102                          * The chunk size is more than what's in the tvbuff,
2103                          * so either the user hasn't enabled decoding, or all
2104                          * of the segments weren't captured.
2105                          */
2106                         chunk_size = datalen;
2107                 }
2108 #if 0
2109                   else if (new_tvb == NULL) {
2110                         new_tvb = tvb_new_composite();
2111                 }
2112
2113
2114
2115                 if (new_tvb != NULL && chunk_size != 0) {
2116                         tvbuff_t *chunk_tvb = NULL;
2117
2118                         chunk_tvb = tvb_new_subset_length_caplen(tvb, chunk_offset,
2119                             chunk_size, datalen);
2120
2121                         tvb_composite_append(new_tvb, chunk_tvb);
2122
2123                 }
2124 #endif
2125
2126                 chunked_data_size += chunk_size;
2127
2128                 raw_data = wmem_alloc(pinfo->pool, chunked_data_size);
2129                 raw_len = 0;
2130
2131                 if (new_tvb != NULL) {
2132                         raw_len = tvb_captured_length_remaining(new_tvb, 0);
2133                         tvb_memcpy(new_tvb, raw_data, 0, raw_len);
2134
2135                         tvb_free(new_tvb);
2136                 }
2137
2138                 tvb_memcpy(tvb, (guint8 *)(raw_data + raw_len),
2139                             chunk_offset, chunk_size);
2140
2141                 /* Don't create a new tvb if we have a single chunk with
2142                  * a size of zero (meaning it is the end of the chunks). */
2143                 if(chunked_data_size > 0) {
2144                         new_tvb = tvb_new_real_data(raw_data,
2145                               chunked_data_size, chunked_data_size);
2146                 }
2147
2148
2149                 if (subtree) {
2150                         if(chunk_size == 0) {
2151                                 chunk_subtree = proto_tree_add_subtree(subtree, tvb,
2152                                             offset, chunk_offset - offset + chunk_size + 2,
2153                                             ett_http_chunk_data, NULL, "End of chunked encoding");
2154                         } else {
2155                                 chunk_subtree = proto_tree_add_subtree_format(subtree, tvb,
2156                                             offset,
2157                                             chunk_offset - offset + chunk_size + 2,
2158                                             ett_http_chunk_data, NULL, "Data chunk (%u octets)", chunk_size);
2159                         }
2160
2161                         chuck_size_item = proto_tree_add_uint(chunk_subtree, hf_http_chunk_size, tvb, offset,
2162                             1, chunk_size);
2163                         proto_item_set_len(chuck_size_item, chunk_offset - offset);
2164
2165                         /*
2166                          * XXX - just add the chunk's data as an item?
2167                          *
2168                          * Using the data dissector means that, in
2169                          * TShark, you get the entire chunk dumped
2170                          * out in hex, in addition to whatever
2171                          * dissection is done on the reassembled data.
2172                          */
2173                         data_tvb = tvb_new_subset_length(tvb, chunk_offset, chunk_size);
2174                         call_data_dissector(data_tvb, pinfo, chunk_subtree);
2175
2176                         proto_tree_add_item(chunk_subtree, hf_http_chunked_boundary, tvb,
2177                                                                 chunk_offset + chunk_size, 2, ENC_NA);
2178                 }
2179
2180                 chunks_decoded++;
2181                 offset = chunk_offset + chunk_size + 2;
2182                 datalen = tvb_reported_length_remaining(tvb, offset);
2183         }
2184
2185         if (new_tvb != NULL) {
2186
2187                 /* Placeholder for the day that composite tvbuffer's will work.
2188                 tvb_composite_finalize(new_tvb);
2189                 / * tvb_set_reported_length(new_tvb, chunked_data_size); * /
2190                 */
2191
2192                 /*
2193                  * XXX - Don't free this, since the tvbuffer that was passed
2194                  * may be used if the data spans multiple frames and reassembly
2195                  * isn't enabled.
2196                  *
2197                 tvb_free(*tvb_ptr);
2198                  */
2199                 *tvb_ptr = new_tvb;
2200
2201         } else {
2202                 /*
2203                  * We didn't create a new tvb, so don't allow sub dissectors
2204                  * try to decode the non-existent entity body.
2205                  */
2206                 chunks_decoded = -1;
2207         }
2208
2209         return chunks_decoded;
2210
2211 }
2212 #else
2213 /*
2214  * Dissect the http data chunks and add them to the tree.
2215  */
2216 static guint
2217 chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
2218                            proto_tree *tree, int offset)
2219 {
2220         tvbuff_t        *tvb;
2221         guint32          datalen;
2222         guint32          orig_datalen;
2223         gint             chunked_data_size;
2224         proto_tree      *subtree;
2225         proto_item      *pi_chunked = NULL;
2226         guint8          *raw_data;
2227         gint             raw_len;
2228
2229         if ((tvb_ptr == NULL) || (*tvb_ptr == NULL)) {
2230                 return 0;
2231         }
2232
2233         tvb = *tvb_ptr;
2234
2235         datalen = tvb_reported_length_remaining(tvb, offset);
2236
2237         subtree = proto_tree_add_subtree(tree, tvb, offset, datalen,
2238                                          ett_http_chunked_response, &pi_chunked,
2239                                          "HTTP chunked response");
2240
2241         /* Dechunk the "chunked response" to a new memory buffer */
2242         orig_datalen      = datalen;
2243         raw_data              = (guint8 *)wmem_alloc(pinfo->pool, datalen);
2244         raw_len               = 0;
2245         chunked_data_size = 0;
2246
2247         while (datalen > 0) {
2248                 tvbuff_t *data_tvb;
2249                 guint32   chunk_size;
2250                 gint      chunk_offset;
2251                 guint8   *chunk_string;
2252                 gint      linelen;
2253                 gchar    *c;
2254
2255                 linelen = tvb_find_line_end(tvb, offset, -1, &chunk_offset, TRUE);
2256
2257                 if (linelen <= 0) {
2258                         /* Can't get the chunk size line */
2259                         break;
2260                 }
2261
2262                 chunk_string = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, linelen, ENC_ASCII);
2263
2264                 if (chunk_string == NULL) {
2265                         /* Can't get the chunk size line */
2266                         break;
2267                 }
2268
2269                 c = (gchar*)chunk_string;
2270
2271                 /*
2272                  * We don't care about the extensions.
2273                  */
2274                 if ((c = strchr(c, ';'))) {
2275                         *c = '\0';
2276                 }
2277
2278                 chunk_size = (guint32)strtol((gchar*)chunk_string, NULL, 16);
2279
2280                 if (chunk_size > datalen) {
2281                         /*
2282                          * The chunk size is more than what's in the tvbuff,
2283                          * so either the user hasn't enabled decoding, or all
2284                          * of the segments weren't captured.
2285                          */
2286                         chunk_size = datalen;
2287                 }
2288
2289                 chunked_data_size += chunk_size;
2290
2291                 DISSECTOR_ASSERT((raw_len+chunk_size) <= orig_datalen);
2292                 tvb_memcpy(tvb, (guint8 *)(raw_data + raw_len), chunk_offset, chunk_size);
2293                 raw_len += chunk_size;
2294
2295                 if (subtree) {
2296                         proto_tree *chunk_subtree;
2297                         proto_item *chunk_size_item;
2298
2299                         if(chunk_size == 0) {
2300                                 chunk_subtree = proto_tree_add_subtree(subtree, tvb,
2301                                             offset,
2302                                             chunk_offset - offset + chunk_size + 2,
2303                                             ett_http_chunk_data, NULL,
2304                                             "End of chunked encoding");
2305                         } else {
2306                                 chunk_subtree = proto_tree_add_subtree_format(subtree, tvb,
2307                                             offset,
2308                                             chunk_offset - offset + chunk_size + 2,
2309                                             ett_http_chunk_data, NULL,
2310                                             "Data chunk (%u octets)", chunk_size);
2311                         }
2312
2313                         chunk_size_item = proto_tree_add_uint(chunk_subtree, hf_http_chunk_size, tvb, offset,
2314                             1, chunk_size);
2315                         proto_item_set_len(chunk_size_item, chunk_offset - offset);
2316
2317                         /* last-chunk does not have chunk-data CRLF. */
2318                         if (chunk_size > 0) {
2319                                 /*
2320                                  * XXX - just add the chunk's data as an item?
2321                                  *
2322                                  * Using the data dissector means that, in
2323                                  * TShark, you get the entire chunk dumped
2324                                  * out in hex, in addition to whatever
2325                                  * dissection is done on the reassembled data.
2326                                  */
2327                                 data_tvb = tvb_new_subset_length(tvb, chunk_offset, chunk_size);
2328                                 call_data_dissector(data_tvb, pinfo, chunk_subtree);
2329
2330                                 proto_tree_add_item(chunk_subtree, hf_http_chunk_boundary, tvb,
2331                                                                         chunk_offset + chunk_size, 2, ENC_NA);
2332                         }
2333                 }
2334
2335                 offset  = chunk_offset + chunk_size;  /* beginning of next chunk */
2336                 if (chunk_size > 0) offset += 2; /* CRLF of chunk */
2337                 datalen = tvb_reported_length_remaining(tvb, offset);
2338
2339                 /* This is the last chunk */
2340                 if (chunk_size == 0) {
2341                         /* Check for: trailer-part CRLF.
2342                          * trailer-part   = *( header-field CRLF ) */
2343                         gint trailer_offset = offset, trailer_len;
2344                         gint header_field_len;
2345                         /* Skip all header-fields. */
2346                         do {
2347                                 trailer_len = trailer_offset - offset;
2348                                 header_field_len = tvb_find_line_end(tvb,
2349                                         trailer_offset,
2350                                         datalen - trailer_len,
2351                                         &trailer_offset, TRUE);
2352                         } while (header_field_len > 0);
2353                         if (trailer_len > 0) {
2354                                 proto_tree_add_item(subtree,
2355                                         hf_http_chunked_trailer_part,
2356                                         tvb, offset, trailer_len, ENC_ASCII|ENC_NA);
2357                                 offset += trailer_len;
2358                                 datalen -= trailer_len;
2359                         }
2360
2361                         /* last CRLF of chunked-body is found. */
2362                         if (header_field_len == 0) {
2363                                 proto_tree_add_format_text(subtree, tvb, offset,
2364                                         trailer_offset - offset);
2365                                 datalen -= trailer_offset - offset;
2366                         }
2367                         break;
2368                 }
2369         }
2370
2371         /* datalen is the remaining bytes that are available for consumption. If
2372          * smaller than orig_datalen, then bytes were consumed. */
2373         if (datalen < orig_datalen) {
2374                 tvbuff_t *new_tvb;
2375                 proto_item_set_len(pi_chunked, orig_datalen - datalen);
2376                 new_tvb = tvb_new_child_real_data(tvb, raw_data, chunked_data_size, chunked_data_size);
2377                 *tvb_ptr = new_tvb;
2378         }
2379
2380         /* Size of chunked-body or 0 if none was found. */
2381         return orig_datalen - datalen;
2382 }
2383 #endif
2384
2385 static gboolean
2386 conversation_dissector_is_http(conversation_t *conv, guint32 frame_num)
2387 {
2388         dissector_handle_t conv_handle;
2389
2390         if (conv == NULL)
2391                 return FALSE;
2392         conv_handle = conversation_get_dissector(conv, frame_num);
2393         return conv_handle == http_handle ||
2394                conv_handle == http_tcp_handle ||
2395                conv_handle == http_sctp_handle;
2396 }
2397
2398 /* Call a subdissector to handle HTTP CONNECT's traffic */
2399 static void
2400 http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
2401                           packet_info *pinfo, http_conv_t *conv_data, void* data)
2402 {
2403         guint32 *ptr = NULL;
2404         guint32 uri_port, saved_port, srcport, destport;
2405         gchar **strings; /* An array for splitting the request URI into hostname and port */
2406         proto_item *item;
2407         proto_tree *proxy_tree;
2408         conversation_t *conv;
2409         gboolean from_server = pinfo->srcport == conv_data->server_port &&
2410                 addresses_equal(&conv_data->server_addr, &pinfo->src);
2411
2412         /* Grab the destination port number from the request URI to find the right subdissector */
2413         strings = wmem_strsplit(wmem_packet_scope(), conv_data->request_uri, ":", 2);
2414
2415         if(strings[0] != NULL && strings[1] != NULL) {
2416                 /*
2417                  * The string was successfully split in two
2418                  * Create a proxy-connect subtree
2419                  */
2420                 if(tree) {
2421                         item = proto_tree_add_item(tree, proto_http, tvb, 0, -1, ENC_NA);
2422                         proxy_tree = proto_item_add_subtree(item, ett_http);
2423
2424                         item = proto_tree_add_string(proxy_tree, hf_http_proxy_connect_host,
2425                                                      tvb, 0, 0, strings[0]);
2426                         PROTO_ITEM_SET_GENERATED(item);
2427
2428                         item = proto_tree_add_uint(proxy_tree, hf_http_proxy_connect_port,
2429                                                    tvb, 0, 0, (guint32)strtol(strings[1], NULL, 10) );
2430                         PROTO_ITEM_SET_GENERATED(item);
2431                 }
2432
2433                 uri_port = (int)strtol(strings[1], NULL, 10); /* Convert string to a base-10 integer */
2434
2435                 if (!from_server) {
2436                         srcport = pinfo->srcport;
2437                         destport = uri_port;
2438                 } else {
2439                         srcport = uri_port;
2440                         destport = pinfo->destport;
2441                 }
2442
2443                 conv = find_conversation(pinfo->num, &pinfo->src, &pinfo->dst, ENDPOINT_TCP, srcport, destport, 0);
2444
2445                 /* We may get stuck in a recursion loop if we let process_tcp_payload() call us.
2446                  * So, if the port in the URI is one we're registered for or we have set up a
2447                  * conversation (e.g., one we detected heuristically or via Decode-As) call the data
2448                  * dissector directly.
2449                  */
2450                 if (value_is_in_range(http_tcp_range, uri_port) ||
2451                     conversation_dissector_is_http(conv, pinfo->num)) {
2452                         call_data_dissector(tvb, pinfo, tree);
2453                 } else {
2454                         /* set pinfo->{src/dst port} and call the TCP sub-dissector lookup */
2455                         if (!from_server)
2456                                 ptr = &pinfo->destport;
2457                         else
2458                                 ptr = &pinfo->srcport;
2459
2460                         /* Increase pinfo->can_desegment because we are traversing
2461                          * http and want to preserve desegmentation functionality for
2462                          * the proxied protocol
2463                          */
2464                         if( pinfo->can_desegment>0 )
2465                                 pinfo->can_desegment++;
2466
2467                         saved_port = *ptr;
2468                         *ptr = uri_port;
2469                         decode_tcp_ports(tvb, 0, pinfo, tree,
2470                                 pinfo->srcport, pinfo->destport, NULL,
2471                                 (struct tcpinfo *)data);
2472                         *ptr = saved_port;
2473                 }
2474         }
2475 }
2476
2477
2478
2479 /*
2480  * XXX - this won't handle HTTP 0.9 replies, but they're all data
2481  * anyway.
2482  */
2483 static int
2484 is_http_request_or_reply(const gchar *data, int linelen, http_type_t *type,
2485                          ReqRespDissector *reqresp_dissector,
2486                          http_conv_t *conv_data)
2487 {
2488         int isHttpRequestOrReply = FALSE;
2489
2490         /*
2491          * From RFC 2774 - An HTTP Extension Framework
2492          *
2493          * Support the command prefix that identifies the presence of
2494          * a "mandatory" header.
2495          */
2496         if (linelen >= 2 && strncmp(data, "M-", 2) == 0) {
2497                 data += 2;
2498                 linelen -= 2;
2499         }
2500
2501         /*
2502          * From draft-cohen-gena-client-01.txt, available from the uPnP forum:
2503          *      NOTIFY, SUBSCRIBE, UNSUBSCRIBE
2504          *
2505          * From draft-ietf-dasl-protocol-00.txt, a now vanished Microsoft draft:
2506          *      SEARCH
2507          */
2508         if ((linelen >= 5 && strncmp(data, "HTTP/", 5) == 0) ||
2509                 (linelen >= 3 && strncmp(data, "ICY", 3) == 0)) {
2510                 *type = HTTP_RESPONSE;
2511                 isHttpRequestOrReply = TRUE;    /* response */
2512                 if (reqresp_dissector)
2513                         *reqresp_dissector = basic_response_dissector;
2514         } else {
2515                 const guchar * ptr = (const guchar *)data;
2516                 int              indx = 0;
2517
2518                 /* Look for the space following the Method */
2519                 while (indx < linelen) {
2520                         if (*ptr == ' ')
2521                                 break;
2522                         else {
2523                                 ptr++;
2524                                 indx++;
2525                         }
2526                 }
2527
2528                 /* Check the methods that have same length */
2529                 switch (indx) {
2530
2531                 case 3:
2532                         if (strncmp(data, "GET", indx) == 0 ||
2533                             strncmp(data, "PUT", indx) == 0) {
2534                                 *type = HTTP_REQUEST;
2535                                 isHttpRequestOrReply = TRUE;
2536                         }
2537                         break;
2538
2539                 case 4:
2540                         if (strncmp(data, "COPY", indx) == 0 ||
2541                             strncmp(data, "HEAD", indx) == 0 ||
2542                             strncmp(data, "LOCK", indx) == 0 ||
2543                             strncmp(data, "MOVE", indx) == 0 ||
2544                             strncmp(data, "POLL", indx) == 0 ||
2545                             strncmp(data, "POST", indx) == 0) {
2546                                 *type = HTTP_REQUEST;
2547                                 isHttpRequestOrReply = TRUE;
2548                         }
2549                         break;
2550
2551                 case 5:
2552                         if (strncmp(data, "BCOPY", indx) == 0 ||
2553                                 strncmp(data, "BMOVE", indx) == 0 ||
2554                                 strncmp(data, "MKCOL", indx) == 0 ||
2555                                 strncmp(data, "TRACE", indx) == 0 ||
2556                                 strncmp(data, "PATCH", indx) == 0 ||  /* RFC 5789 */
2557                                 strncmp(data, "LABEL", indx) == 0 ||  /* RFC 3253 8.2 */
2558                                 strncmp(data, "MERGE", indx) == 0) {  /* RFC 3253 11.2 */
2559                                 *type = HTTP_REQUEST;
2560                                 isHttpRequestOrReply = TRUE;
2561                         }
2562                         break;
2563
2564                 case 6:
2565                         if (strncmp(data, "DELETE", indx) == 0 ||
2566                                 strncmp(data, "SEARCH", indx) == 0 ||
2567                                 strncmp(data, "UNLOCK", indx) == 0 ||
2568                                 strncmp(data, "REPORT", indx) == 0 ||  /* RFC 3253 3.6 */
2569                                 strncmp(data, "UPDATE", indx) == 0) {  /* RFC 3253 7.1 */
2570                                 *type = HTTP_REQUEST;
2571                                 isHttpRequestOrReply = TRUE;
2572                         }
2573                         else if (strncmp(data, "NOTIFY", indx) == 0) {
2574                                 *type = HTTP_NOTIFICATION;
2575                                 isHttpRequestOrReply = TRUE;
2576                         }
2577                         break;
2578
2579                 case 7:
2580                         if (strncmp(data, "BDELETE", indx) == 0 ||
2581                             strncmp(data, "CONNECT", indx) == 0 ||
2582                             strncmp(data, "OPTIONS", indx) == 0 ||
2583                             strncmp(data, "CHECKIN", indx) == 0) {  /* RFC 3253 4.4, 9.4 */
2584                                 *type = HTTP_REQUEST;
2585                                 isHttpRequestOrReply = TRUE;
2586                         }
2587                         break;
2588
2589                 case 8:
2590                         if (strncmp(data, "PROPFIND", indx) == 0 ||
2591                             strncmp(data, "CHECKOUT", indx) == 0 || /* RFC 3253 4.3, 9.3 */
2592                             strncmp(data, "CCM_POST", indx) == 0) {
2593                                 *type = HTTP_REQUEST;
2594                                 isHttpRequestOrReply = TRUE;
2595                         }
2596                         break;
2597
2598                 case 9:
2599                         if (strncmp(data, "SUBSCRIBE", indx) == 0) {
2600                                 *type = HTTP_NOTIFICATION;
2601                                 isHttpRequestOrReply = TRUE;
2602                         } else if (strncmp(data, "PROPPATCH", indx) == 0 ||
2603                             strncmp(data, "BPROPFIND", indx) == 0) {
2604                                 *type = HTTP_REQUEST;
2605                                 isHttpRequestOrReply = TRUE;
2606                         }
2607                         break;
2608
2609                 case 10:
2610                         if (strncmp(data, "BPROPPATCH", indx) == 0 ||
2611                                 strncmp(data, "UNCHECKOUT", indx) == 0 ||  /* RFC 3253 4.5 */
2612                                 strncmp(data, "MKACTIVITY", indx) == 0) {  /* RFC 3253 13.5 */
2613                                 *type = HTTP_REQUEST;
2614                                 isHttpRequestOrReply = TRUE;
2615                         }
2616                         break;
2617
2618                 case 11:
2619                         if (strncmp(data, "MKWORKSPACE", indx) == 0 || /* RFC 3253 6.3 */
2620                             strncmp(data, "RPC_CONNECT", indx) == 0 || /* [MS-RPCH] 2.1.1.1.1 */
2621                             strncmp(data, "RPC_IN_DATA", indx) == 0) { /* [MS-RPCH] 2.1.2.1.1 */
2622                                 *type = HTTP_REQUEST;
2623                                 isHttpRequestOrReply = TRUE;
2624                         } else if (strncmp(data, "UNSUBSCRIBE", indx) == 0) {
2625                                 *type = HTTP_NOTIFICATION;
2626                                 isHttpRequestOrReply = TRUE;
2627                         }
2628                         break;
2629
2630                 case 12:
2631                         if (strncmp(data, "RPC_OUT_DATA", indx) == 0) { /* [MS-RPCH] 2.1.2.1.2 */
2632                                 *type = HTTP_REQUEST;
2633                                 isHttpRequestOrReply = TRUE;
2634                         }
2635                         break;
2636
2637                 case 15:
2638                         if (strncmp(data, "VERSION-CONTROL", indx) == 0) {  /* RFC 3253 3.5 */
2639                                 *type = HTTP_REQUEST;
2640                                 isHttpRequestOrReply = TRUE;
2641                         }
2642                         break;
2643
2644                 case 16:
2645                         if (strncmp(data, "BASELINE-CONTROL", indx) == 0) {  /* RFC 3253 12.6 */
2646                                 *type = HTTP_REQUEST;
2647                                 isHttpRequestOrReply = TRUE;
2648                         } else if (strncmp(data, "SSTP_DUPLEX_POST", indx) == 0) {  /* MS SSTP */
2649                                 *type = HTTP_REQUEST;
2650                                 isHttpRequestOrReply = TRUE;
2651                         }
2652                         break;
2653
2654                 default:
2655                         break;
2656                 }
2657
2658                 if (isHttpRequestOrReply && reqresp_dissector) {
2659                         *reqresp_dissector = basic_request_dissector;
2660
2661                         stat_info->request_method = wmem_strndup(wmem_packet_scope(), data, indx);
2662                         conv_data->request_method = wmem_strndup(wmem_file_scope(), data, indx);
2663                 }
2664
2665
2666
2667         }
2668
2669         return isHttpRequestOrReply;
2670 }
2671
2672 /*
2673  * Process headers.
2674  */
2675 typedef struct {
2676         const char      *name;
2677         gint            *hf;
2678         int             special;
2679 } header_info;
2680
2681 #define HDR_NO_SPECIAL                  0
2682 #define HDR_AUTHORIZATION               1
2683 #define HDR_AUTHENTICATE                2
2684 #define HDR_CONTENT_TYPE                3
2685 #define HDR_CONTENT_LENGTH              4
2686 #define HDR_CONTENT_ENCODING            5
2687 #define HDR_TRANSFER_ENCODING           6
2688 #define HDR_HOST                        7
2689 #define HDR_UPGRADE                     8
2690 #define HDR_COOKIE                      9
2691 #define HDR_WEBSOCKET_PROTOCOL          10
2692 #define HDR_WEBSOCKET_EXTENSIONS        11
2693 #define HDR_REFERER                     12
2694 #define HDR_LOCATION                    13
2695
2696 static const header_info headers[] = {
2697         { "Authorization", &hf_http_authorization, HDR_AUTHORIZATION },
2698         { "Proxy-Authorization", &hf_http_proxy_authorization, HDR_AUTHORIZATION },
2699         { "Proxy-Authenticate", &hf_http_proxy_authenticate, HDR_AUTHENTICATE },
2700         { "WWW-Authenticate", &hf_http_www_authenticate, HDR_AUTHENTICATE },
2701         { "Content-Type", &hf_http_content_type, HDR_CONTENT_TYPE },
2702         { "Content-Length", &hf_http_content_length_header, HDR_CONTENT_LENGTH },
2703         { "Content-Encoding", &hf_http_content_encoding, HDR_CONTENT_ENCODING },
2704         { "Transfer-Encoding", &hf_http_transfer_encoding, HDR_TRANSFER_ENCODING },
2705         { "Upgrade", &hf_http_upgrade, HDR_UPGRADE },
2706         { "User-Agent", &hf_http_user_agent, HDR_NO_SPECIAL },
2707         { "Host", &hf_http_host, HDR_HOST },
2708         { "Connection", &hf_http_connection, HDR_NO_SPECIAL },
2709         { "Cookie", &hf_http_cookie, HDR_COOKIE },
2710         { "Accept", &hf_http_accept, HDR_NO_SPECIAL },
2711         { "Referer", &hf_http_referer, HDR_REFERER },
2712         { "Accept-Language", &hf_http_accept_language, HDR_NO_SPECIAL },
2713         { "Accept-Encoding", &hf_http_accept_encoding, HDR_NO_SPECIAL },
2714         { "Date", &hf_http_date, HDR_NO_SPECIAL },
2715         { "Cache-Control", &hf_http_cache_control, HDR_NO_SPECIAL },
2716         { "Server", &hf_http_server, HDR_NO_SPECIAL },
2717         { "Location", &hf_http_location, HDR_LOCATION },
2718         { "Sec-WebSocket-Accept", &hf_http_sec_websocket_accept, HDR_NO_SPECIAL },
2719         { "Sec-WebSocket-Extensions", &hf_http_sec_websocket_extensions, HDR_WEBSOCKET_EXTENSIONS },
2720         { "Sec-WebSocket-Key", &hf_http_sec_websocket_key, HDR_NO_SPECIAL },
2721         { "Sec-WebSocket-Protocol", &hf_http_sec_websocket_protocol, HDR_WEBSOCKET_PROTOCOL },
2722         { "Sec-WebSocket-Version", &hf_http_sec_websocket_version, HDR_NO_SPECIAL },
2723         { "Set-Cookie", &hf_http_set_cookie, HDR_NO_SPECIAL },
2724         { "Last-Modified", &hf_http_last_modified, HDR_NO_SPECIAL },
2725         { "X-Forwarded-For", &hf_http_x_forwarded_for, HDR_NO_SPECIAL },
2726 };
2727
2728 /*
2729  * Look up a header name (assume lower-case header_name).
2730  */
2731 static gint*
2732 get_hf_for_header(char* header_name)
2733 {
2734         gint* hf_id = NULL;
2735
2736         if (header_fields_hash) {
2737                 hf_id = (gint*) g_hash_table_lookup(header_fields_hash, header_name);
2738         } else {
2739                 hf_id = NULL;
2740         }
2741
2742         return hf_id;
2743 }
2744
2745 /*
2746  *
2747  */
2748 static void
2749 deregister_header_fields(void)
2750 {
2751         if (dynamic_hf) {
2752                 /* Deregister all fields */
2753                 for (guint i = 0; i < dynamic_hf_size; i++) {
2754                         proto_deregister_field (proto_http, *(dynamic_hf[i].p_id));
2755                         g_free (dynamic_hf[i].p_id);
2756                 }
2757
2758                 proto_add_deregistered_data (dynamic_hf);
2759                 dynamic_hf = NULL;
2760                 dynamic_hf_size = 0;
2761         }
2762
2763         if (header_fields_hash) {
2764                 g_hash_table_destroy (header_fields_hash);
2765                 header_fields_hash = NULL;
2766         }
2767 }
2768
2769 static void
2770 header_fields_post_update_cb(void)
2771 {
2772         gint* hf_id;
2773         gchar* header_name;
2774         gchar* header_name_key;
2775
2776         deregister_header_fields();
2777
2778         if (num_header_fields) {
2779                 header_fields_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
2780                 dynamic_hf = g_new0(hf_register_info, num_header_fields);
2781                 dynamic_hf_size = num_header_fields;
2782
2783                 for (guint i = 0; i < dynamic_hf_size; i++) {
2784                         hf_id = g_new(gint,1);
2785                         *hf_id = -1;
2786                         header_name = g_strdup(header_fields[i].header_name);
2787                         header_name_key = g_ascii_strdown(header_name, -1);
2788
2789                         dynamic_hf[i].p_id = hf_id;
2790                         dynamic_hf[i].hfinfo.name = header_name;
2791                         dynamic_hf[i].hfinfo.abbrev = g_strdup_printf("http.header.%s", header_name);
2792                         dynamic_hf[i].hfinfo.type = FT_STRING;
2793                         dynamic_hf[i].hfinfo.display = BASE_NONE;
2794                         dynamic_hf[i].hfinfo.strings = NULL;
2795                         dynamic_hf[i].hfinfo.bitmask = 0;
2796                         dynamic_hf[i].hfinfo.blurb = g_strdup(header_fields[i].header_desc);
2797                         HFILL_INIT(dynamic_hf[i]);
2798
2799                         g_hash_table_insert(header_fields_hash, header_name_key, hf_id);
2800                 }
2801
2802                 proto_register_field_array(proto_http, dynamic_hf, dynamic_hf_size);
2803         }
2804 }
2805
2806 static void
2807 header_fields_reset_cb(void)
2808 {
2809         deregister_header_fields();
2810 }
2811
2812 /**
2813  * Parses the transfer-coding, returning TRUE if everything was fully understood
2814  * or FALSE when unknown names were encountered.
2815  */
2816 static gboolean
2817 http_parse_transfer_coding(const char *value, headers_t *eh_ptr)
2818 {
2819         gboolean is_fully_parsed = TRUE;
2820
2821         /* Mark header as set, but with unknown encoding. */
2822         eh_ptr->transfer_encoding = HTTP_TE_UNKNOWN;
2823
2824         while (*value) {
2825                 /* skip OWS (SP / HTAB) and commas; stop at the end. */
2826                 while (*value == ' ' || *value == '\t' || *value == ',')
2827                         value++;
2828                 if (!*value)
2829                         break;
2830
2831                 if (g_str_has_prefix(value, "chunked")) {
2832                         eh_ptr->transfer_encoding_chunked = TRUE;
2833                         value += sizeof("chunked") - 1;
2834                         continue;
2835                 }
2836
2837                 /* For now assume that chunked can only combined with exactly
2838                  * one other (compression) encoding. Anything else is
2839                  * unsupported. */
2840                 if (eh_ptr->transfer_encoding != HTTP_TE_UNKNOWN) {
2841                         /* No more transfer codings are expected. */
2842                         is_fully_parsed = FALSE;
2843                         break;
2844                 }
2845
2846                 if (g_str_has_prefix(value, "compress")) {
2847                         eh_ptr->transfer_encoding = HTTP_TE_COMPRESS;
2848                         value += sizeof("compress") - 1;
2849                 } else if (g_str_has_prefix(value, "deflate")) {
2850                         eh_ptr->transfer_encoding = HTTP_TE_DEFLATE;
2851                         value += sizeof("deflate") - 1;
2852                 } else if (g_str_has_prefix(value, "gzip")) {
2853                         eh_ptr->transfer_encoding = HTTP_TE_GZIP;
2854                         value += sizeof("gzip") - 1;
2855                 } else if (g_str_has_prefix(value, "identity")) {
2856                         eh_ptr->transfer_encoding = HTTP_TE_IDENTITY;
2857                         value += sizeof("identity") - 1;
2858                 } else if (g_str_has_prefix(value, "x-compress")) {
2859                         eh_ptr->transfer_encoding = HTTP_TE_COMPRESS;
2860                         value += sizeof("x-compress") - 1;
2861                 } else if (g_str_has_prefix(value, "x-gzip")) {
2862                         eh_ptr->transfer_encoding = HTTP_TE_GZIP;
2863                         value += sizeof("x-gzip") - 1;
2864                 } else {
2865                         /* Unknown transfer encoding, skip until next comma.
2866                          * Stop when no more names are found. */
2867                         is_fully_parsed = FALSE;
2868                         value = strchr(value, ',');
2869                         if (!value)
2870                                 break;
2871                 }
2872         }
2873
2874         return is_fully_parsed;
2875 }
2876
2877 static gboolean
2878 is_token_char(char c)
2879 {
2880         /* tchar according to https://tools.ietf.org/html/rfc7230#section-3.2.6 */
2881         return strchr("!#$%&\\:*+-.^_`|~", c) || g_ascii_isalnum(c);
2882 }
2883
2884 static void
2885 process_header(tvbuff_t *tvb, int offset, int next_offset,
2886                const guchar *line, int linelen, int colon_offset,
2887                packet_info *pinfo, proto_tree *tree, headers_t *eh_ptr,
2888                http_conv_t *conv_data, http_type_t http_type)
2889 {
2890         int len;
2891         int line_end_offset;
2892         int header_len;
2893         gint hf_index;
2894         guchar c;
2895         int value_offset;
2896         int value_len;
2897         char *value;
2898         char *header_name;
2899         char *p;
2900         guchar *up;
2901         proto_item *hdr_item, *it;
2902         int i;
2903         int* hf_id;
2904
2905         len = next_offset - offset;
2906         line_end_offset = offset + linelen;
2907         header_len = colon_offset - offset;
2908
2909         /*
2910          * Validate the header name. This allows no space between the field name
2911          * and colon (RFC 7230, Section. 3.2.4).
2912          */
2913         gboolean valid_header_name = header_len != 0;
2914         if (valid_header_name) {
2915                 for (i = 0; i < header_len; i++) {
2916                         /*
2917                          * NUL is not a valid character; treat it specially
2918                          * due to C's notion that strings are NUL-terminated.
2919                          */
2920                         if (line[i] == '\0') {
2921                                 valid_header_name = FALSE;
2922                                 break;
2923                         }
2924                         if (!is_token_char(line[i])) {
2925                                 valid_header_name = FALSE;
2926                                 break;
2927                         }
2928                 }
2929         }
2930         /**
2931          * Not a valid header name? Just add a line plus expert info.
2932          */
2933         if (!valid_header_name) {
2934                 if (http_type == HTTP_REQUEST) {
2935                         hf_index = hf_http_request_line;
2936                 } else if (http_type == HTTP_RESPONSE) {
2937                         hf_index = hf_http_response_line;
2938                 } else {
2939                         hf_index = hf_http_unknown_header;
2940                 }
2941                 it = proto_tree_add_item(tree, hf_index, tvb, offset, len, ENC_NA|ENC_ASCII);
2942                 proto_item_set_text(it, "%s", format_text(wmem_packet_scope(), line, len));
2943                 expert_add_info(pinfo, it, &ei_http_bad_header_name);
2944                 return;
2945         }
2946
2947         /*
2948          * Make a null-terminated, all-lower-case version of the header
2949          * name.
2950          */
2951         header_name = wmem_ascii_strdown(wmem_packet_scope(), &line[0], header_len);
2952
2953         hf_index = find_header_hf_value(tvb, offset, header_len);
2954
2955         /*
2956          * Skip whitespace after the colon.
2957          */
2958         value_offset = colon_offset + 1;
2959         while (value_offset < line_end_offset
2960                         && ((c = line[value_offset - offset]) == ' ' || c == '\t'))
2961                 value_offset++;
2962
2963         /*
2964          * Fetch the value.
2965          *
2966          * XXX - the line may well have a NUL in it.  Wireshark should
2967          * really treat strings extracted from packets as counted
2968          * strings, so that NUL isn't any different from any other
2969          * character.  For now, we just allocate a buffer that's
2970          * value_len+1 bytes long, copy value_len bytes, and stick
2971          * in a NUL terminator, so that the buffer for value actually
2972          * has value_len bytes in it.
2973          */
2974         value_len = line_end_offset - value_offset;
2975         value = (char *)wmem_alloc(wmem_packet_scope(), value_len+1);
2976         memcpy(value, &line[value_offset - offset], value_len);
2977         value[value_len] = '\0';
2978
2979         if (hf_index == -1) {
2980                 /*
2981                  * Not a header we know anything about.
2982                  * Check if a HF generated from UAT information exists.
2983                  */
2984                 hf_id = get_hf_for_header(header_name);
2985
2986                 if (tree) {
2987                         if (!hf_id) {
2988                                 if (http_type == HTTP_REQUEST ||
2989                                         http_type == HTTP_RESPONSE) {
2990                                         it = proto_tree_add_item(tree,
2991                                                 http_type == HTTP_RESPONSE ?
2992                                                 hf_http_response_line :
2993                                                 hf_http_request_line,
2994                                                 tvb, offset, len,
2995                                                 ENC_NA|ENC_ASCII);
2996                                         proto_item_set_text(it, "%s",
2997                                                         format_text(wmem_packet_scope(), line, len));
2998                                 } else {
2999                                         gchar* str = format_text(wmem_packet_scope(), line, len);
3000                                         proto_tree_add_string_format(tree, hf_http_unknown_header, tvb, offset,
3001                                                 len, str, "%s", str);
3002                                 }
3003
3004                         } else {
3005                                 proto_tree_add_string_format(tree,
3006                                         *hf_id, tvb, offset, len,
3007                                         value, "%s", format_text(wmem_packet_scope(), line, len));
3008                                 if (http_type == HTTP_REQUEST ||
3009                                         http_type == HTTP_RESPONSE) {
3010                                         it = proto_tree_add_item(tree,
3011                                                 http_type == HTTP_RESPONSE ?
3012                                                 hf_http_response_line :
3013                                                 hf_http_request_line,
3014                                                 tvb, offset, len,
3015                                                 ENC_NA|ENC_ASCII);
3016                                         proto_item_set_text(it, "%s",
3017                                                         format_text(wmem_packet_scope(), line, len));
3018                                         PROTO_ITEM_SET_HIDDEN(it);
3019                                 }
3020                         }
3021                 }
3022         } else {
3023                 /*
3024                  * Add it to the protocol tree as a particular field,
3025                  * but display the line as is.
3026                  */
3027                 if (tree) {
3028                         header_field_info *hfinfo;
3029                         guint32 tmp;
3030
3031                         hfinfo = proto_registrar_get_nth(*headers[hf_index].hf);
3032                         switch(hfinfo->type){
3033                         case FT_UINT8:
3034                         case FT_UINT16:
3035                         case FT_UINT24:
3036                         case FT_UINT32:
3037                         case FT_INT8:
3038                         case FT_INT16:
3039                         case FT_INT24:
3040                         case FT_INT32:
3041                                 tmp=(guint32)strtol(value, NULL, 10);
3042                                 hdr_item = proto_tree_add_uint(tree, *headers[hf_index].hf, tvb, offset, len, tmp);
3043                                 if (http_type == HTTP_REQUEST ||
3044                                         http_type == HTTP_RESPONSE) {
3045                                         it = proto_tree_add_item(tree,
3046                                                 http_type == HTTP_RESPONSE ?
3047                                                 hf_http_response_line :
3048                                                 hf_http_request_line,
3049                                                 tvb, offset, len,
3050                                                 ENC_NA|ENC_ASCII);
3051                                         proto_item_set_text(it, "%d", tmp);
3052                                         PROTO_ITEM_SET_HIDDEN(it);
3053                                 }
3054                                 break;
3055                         default:
3056                                 hdr_item = proto_tree_add_string_format(tree,
3057                                     *headers[hf_index].hf, tvb, offset, len,
3058                                     value, "%s", format_text(wmem_packet_scope(), line, len));
3059                                 if (http_type == HTTP_REQUEST ||
3060                                         http_type == HTTP_RESPONSE) {
3061                                         it = proto_tree_add_item(tree,
3062                                                 http_type == HTTP_RESPONSE ?
3063                                                 hf_http_response_line :
3064                                                 hf_http_request_line,
3065                                                 tvb, offset, len,
3066                                                 ENC_NA|ENC_ASCII);
3067                                         proto_item_set_text(it, "%s",
3068                                                         format_text(wmem_packet_scope(), line, len));
3069                                         PROTO_ITEM_SET_HIDDEN(it);
3070                                 }
3071                         }
3072                 } else
3073                         hdr_item = NULL;
3074
3075                 /*
3076                  * Do any special processing that particular headers
3077                  * require.
3078                  */
3079                 switch (headers[hf_index].special) {
3080
3081                 case HDR_AUTHORIZATION:
3082                         if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
3083                                 break;  /* dissected NTLMSSP */
3084                         if (check_auth_basic(hdr_item, tvb, value))
3085                                 break; /* dissected basic auth */
3086                         if (check_auth_citrixbasic(hdr_item, tvb, value, offset))
3087                                 break; /* dissected citrix basic auth */
3088                         check_auth_kerberos(hdr_item, tvb, pinfo, value);
3089                         break;
3090
3091                 case HDR_AUTHENTICATE:
3092                         if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
3093                                 break; /* dissected NTLMSSP */
3094                         check_auth_kerberos(hdr_item, tvb, pinfo, value);
3095                         break;
3096
3097                 case HDR_CONTENT_TYPE:
3098                         eh_ptr->content_type = (gchar*) wmem_memdup(wmem_packet_scope(), (guint8*)value,value_len + 1);
3099
3100                         for (i = 0; i < value_len; i++) {
3101                                 c = value[i];
3102                                 if (c == ';' || g_ascii_isspace(c)) {
3103                                         /*
3104                                          * End of subtype - either
3105                                          * white space or a ";"
3106                                          * separating the subtype from
3107                                          * a parameter.
3108                                          */
3109                                         break;
3110                                 }
3111
3112                                 /*
3113                                  * Map the character to lower case;
3114                                  * content types are case-insensitive.
3115                                  */
3116                                 eh_ptr->content_type[i] = g_ascii_tolower(eh_ptr->content_type[i]);
3117                         }
3118                         eh_ptr->content_type[i] = '\0';
3119                         /*
3120                          * Now find the start of the optional parameters;
3121                          * skip the optional white space and the semicolon
3122                          * if this has not been done before.
3123                          */
3124                         i++;
3125                         while (i < value_len) {
3126                                 c = eh_ptr->content_type[i];
3127                                 if (c == ';' || g_ascii_isspace(c))
3128                                         /* Skip till start of parameters */
3129                                         i++;
3130                                 else
3131                                         break;
3132                         }
3133                         if (i < value_len)
3134                                 eh_ptr->content_type_parameters = eh_ptr->content_type + i;
3135                         else
3136                                 eh_ptr->content_type_parameters = NULL;
3137                         break;
3138
3139                 case HDR_CONTENT_LENGTH:
3140                         errno = 0;
3141                         eh_ptr->content_length = g_ascii_strtoll(value, &p, 10);
3142                         up = (guchar *)p;
3143                         if (eh_ptr->content_length < 0 ||
3144                             p == value ||
3145                             errno == ERANGE ||
3146                             (*up != '\0' && !g_ascii_isspace(*up))) {
3147                                 /*
3148                                  * Content length not valid; pretend
3149                                  * we don't have it.
3150                                  */
3151                                 eh_ptr->have_content_length = FALSE;
3152                         } else {
3153                                 proto_tree *header_tree;
3154                                 proto_item *tree_item;
3155                                 /*
3156                                  * We do have a valid content length.
3157                                  */
3158                                 eh_ptr->have_content_length = TRUE;
3159                                 header_tree = proto_item_add_subtree(hdr_item, ett_http_header_item);
3160                                 tree_item = proto_tree_add_uint64(header_tree, hf_http_content_length,
3161                                         tvb, offset, len, eh_ptr->content_length);
3162                                 PROTO_ITEM_SET_GENERATED(tree_item);
3163                                 if (eh_ptr->transfer_encoding != HTTP_TE_NONE) {
3164                                         expert_add_info(pinfo, hdr_item, &ei_http_te_and_length);
3165                                 }
3166                         }
3167                         break;
3168
3169                 case HDR_CONTENT_ENCODING:
3170                         eh_ptr->content_encoding = wmem_strndup(wmem_packet_scope(), value, value_len);
3171                         break;
3172
3173                 case HDR_TRANSFER_ENCODING:
3174                         if (eh_ptr->have_content_length) {
3175                                 expert_add_info(pinfo, hdr_item, &ei_http_te_and_length);
3176                         }
3177                         if (!http_parse_transfer_coding(value, eh_ptr)) {
3178                                 expert_add_info(pinfo, hdr_item, &ei_http_te_unknown);
3179                         }
3180                         break;
3181
3182                 case HDR_HOST:
3183                         stat_info->http_host = wmem_strndup(wmem_packet_scope(), value, value_len);
3184                         conv_data->http_host = wmem_strndup(wmem_file_scope(), value, value_len);
3185                         break;
3186
3187                 case HDR_UPGRADE:
3188                         eh_ptr->upgrade = wmem_ascii_strdown(wmem_packet_scope(), value, value_len);
3189                         break;
3190
3191                 case HDR_COOKIE:
3192                         if (hdr_item) {
3193                                 proto_tree *cookie_tree;
3194                                 char *part, *part_end;
3195                                 int part_len;
3196
3197                                 cookie_tree = proto_item_add_subtree(hdr_item, ett_http_header_item);
3198                                 for (i = 0; i < value_len; ) {
3199                                         /* skip whitespace and ';' (terminates at '\0' or earlier) */
3200                                         c = value[i];
3201                                         while (c == ';' || g_ascii_isspace(c))
3202                                                 c = value[++i];
3203
3204                                         if (i >= value_len)
3205                                                 break;
3206
3207                                         /* find "cookie=foo " in "cookie=foo ; bar" */
3208                                         part = value + i;
3209                                         part_end = (char *)memchr(part, ';', value_len - i);
3210                                         if (part_end)
3211                                                 part_len =(int)(part_end - part);
3212                                         else
3213                                                 part_len = value_len - i;
3214
3215                                         /* finally add cookie to tree */
3216                                         proto_tree_add_item(cookie_tree, hf_http_cookie_pair,
3217                                                 tvb, value_offset + i, part_len, ENC_NA|ENC_ASCII);
3218                                         i += part_len;
3219                                 }
3220                         }
3221                         break;
3222
3223                 case HDR_WEBSOCKET_PROTOCOL:
3224                         if (http_type == HTTP_RESPONSE) {
3225                                 conv_data->websocket_protocol = wmem_strndup(wmem_file_scope(), value, value_len);
3226                         }
3227                         break;
3228
3229                 case HDR_WEBSOCKET_EXTENSIONS:
3230                         if (http_type == HTTP_RESPONSE) {
3231                                 conv_data->websocket_extensions = wmem_strndup(wmem_file_scope(), value, value_len);
3232                         }
3233                         break;
3234
3235                 case HDR_REFERER:
3236                         stat_info->referer_uri = wmem_strndup(wmem_packet_scope(), value, value_len);
3237                         break;
3238
3239                 case HDR_LOCATION:
3240                         if (conv_data->request_uri){
3241                                 stat_info->location_target = wmem_strndup(wmem_packet_scope(), value, value_len);
3242                                 stat_info->location_base_uri = wmem_strdup(wmem_packet_scope(), conv_data->full_uri);
3243                         }
3244                         break;
3245                 }
3246         }
3247 }
3248
3249 /* Returns index of header tag in headers */
3250 static gint
3251 find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len)
3252 {
3253         guint i;
3254
3255         for (i = 0; i < array_length(headers); i++) {
3256                 if (header_len == strlen(headers[i].name) &&
3257                         tvb_strncaseeql(tvb, offset,
3258                                     headers[i].name, header_len) == 0)
3259                         return i;
3260         }
3261
3262         return -1;
3263 }
3264
3265 /*
3266  * Dissect Microsoft's abomination called NTLMSSP over HTTP.
3267  */
3268 static gboolean
3269 check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo, gchar *value)
3270 {
3271         static const char *ntlm_headers[] = {
3272                 "NTLM ",
3273                 "Negotiate ",
3274                 NULL
3275         };
3276         const char **header;
3277         size_t hdrlen;
3278         proto_tree *hdr_tree;
3279
3280         /*
3281          * Check for NTLM credentials and challenge; those can
3282          * occur with WWW-Authenticate.
3283          */
3284         for (header = &ntlm_headers[0]; *header != NULL; header++) {
3285                 hdrlen = strlen(*header);
3286                 if (strncmp(value, *header, hdrlen) == 0) {
3287                         if (hdr_item != NULL) {
3288                                 hdr_tree = proto_item_add_subtree(hdr_item,
3289                                     ett_http_ntlmssp);
3290                         } else
3291                                 hdr_tree = NULL;
3292                         value += hdrlen;
3293                         dissect_http_ntlmssp(tvb, pinfo, hdr_tree, value);
3294                         return TRUE;
3295                 }
3296         }
3297         return FALSE;
3298 }
3299
3300 /*
3301  * Dissect HTTP Basic authorization.
3302  */
3303 static gboolean
3304 check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value)
3305 {
3306         static const char *basic_headers[] = {
3307                 "Basic ",
3308                 NULL
3309         };
3310         const char **header;
3311         size_t hdrlen;
3312         proto_tree *hdr_tree;
3313         gsize len;
3314
3315         for (header = &basic_headers[0]; *header != NULL; header++) {
3316                 hdrlen = strlen(*header);
3317                 if (strncmp(value, *header, hdrlen) == 0) {
3318                         if (hdr_item != NULL) {
3319                                 hdr_tree = proto_item_add_subtree(hdr_item,
3320                                     ett_http_ntlmssp);
3321                         } else
3322                                 hdr_tree = NULL;
3323                         value += hdrlen;
3324
3325                         if (strlen(value) > 1) {
3326                                 g_base64_decode_inplace(value, &len);
3327                                 value[len] = 0;
3328                         }
3329                         proto_tree_add_string(hdr_tree, hf_http_basic, tvb,
3330                             0, 0, value);
3331
3332                         return TRUE;
3333                 }
3334         }
3335         return FALSE;
3336 }
3337
3338 /*
3339  * Dissect HTTP CitrixAGBasic authorization.
3340  */
3341 static gboolean
3342 check_auth_citrixbasic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value, int offset)
3343 {
3344         static const char *basic_headers[] = {
3345                 "CitrixAGBasic ",
3346                 NULL
3347         };
3348         const char **header;
3349         size_t hdrlen;
3350         proto_tree *hdr_tree;
3351         char *ch_ptr;
3352         int data_len;
3353         char *data_val;
3354         proto_item *hidden_item;
3355         proto_item *pi;
3356         gsize len;
3357
3358         for (header = &basic_headers[0]; *header != NULL; header++) {
3359                 hdrlen = strlen(*header);
3360                 if (strncmp(value, *header, hdrlen) == 0) {
3361                         if (hdr_item != NULL) {
3362                                 hdr_tree = proto_item_add_subtree(hdr_item,
3363                                     ett_http_ntlmssp);
3364                         } else
3365                                 hdr_tree = NULL;
3366                         value += hdrlen;
3367                         offset += (int)hdrlen + 15;
3368                         hidden_item = proto_tree_add_boolean(hdr_tree,
3369                                             hf_http_citrix, tvb, 0, 0, 1);
3370                         PROTO_ITEM_SET_HIDDEN(hidden_item);
3371
3372                         if(strncmp(value, "username=\"", 10) == 0) {
3373                                 value += 10;
3374                                 offset += 10;
3375                                 ch_ptr = strchr(value, '"');
3376                                 if ( ch_ptr != NULL ) {
3377                                         data_len = (int)(ch_ptr - value + 1);
3378                                         data_val = wmem_strndup(wmem_packet_scope(), value, data_len);
3379                                         if (data_len > 1) {
3380                                                 g_base64_decode_inplace(data_val, &len);
3381                                                 data_val[len] = 0;
3382                                         }
3383                                         pi = proto_tree_add_string(hdr_tree, hf_http_citrix_user, tvb,
3384                                             offset , data_len - 1, data_val);
3385                                         PROTO_ITEM_SET_GENERATED(pi);
3386                                         value += data_len;
3387                                         offset += data_len;
3388                                 }
3389                         }
3390                         if(strncmp(value, "; domain=\"", 10) == 0) {
3391                                 value += 10;
3392                                 offset += 10;
3393                                 ch_ptr = strchr(value, '"');
3394                                 if ( ch_ptr != NULL ) {
3395                                         data_len = (int)(ch_ptr - value + 1);
3396                                         data_val = wmem_strndup(wmem_packet_scope(), value, data_len);
3397                                         if (data_len > 1) {
3398                                                 g_base64_decode_inplace(data_val, &len);
3399                                                 data_val[len] = 0;
3400                                         }
3401                                         pi = proto_tree_add_string(hdr_tree, hf_http_citrix_domain, tvb,
3402                                             offset, data_len - 1, data_val);
3403                                         PROTO_ITEM_SET_GENERATED(pi);
3404                                         value += data_len;
3405                                         offset += data_len;
3406                                 }
3407                         }
3408                         if(strncmp(value, "; password=\"", 12) == 0) {
3409                                 value += 12;
3410                                 offset += 12;
3411                                 ch_ptr = strchr(value, '"');
3412                                 if ( ch_ptr != NULL ) {
3413                                         data_len = (int)(ch_ptr - value + 1);
3414                                         data_val = wmem_strndup(wmem_packet_scope(), value, data_len);
3415                                         if (data_len > 1) {
3416                                                 g_base64_decode_inplace(data_val, &len);
3417                                                 data_val[len] = 0;
3418                                         }
3419                                         pi = proto_tree_add_string(hdr_tree, hf_http_citrix_passwd, tvb,
3420                                             offset, data_len - 1, data_val);
3421                                         PROTO_ITEM_SET_GENERATED(pi);
3422                                         value += data_len;
3423                                         offset += data_len;
3424                                 }
3425                         }
3426                         if(strncmp(value, "; AGESessionId=\"", 16) == 0) {
3427                                 value += 16;
3428                                 offset += 16;
3429                                 ch_ptr = strchr(value, '"');
3430                                 if ( ch_ptr != NULL ) {
3431                                         data_len = (int)(ch_ptr - value + 1);
3432                                         data_val = wmem_strndup(wmem_packet_scope(), value, data_len);
3433                                         if (data_len > 1) {
3434                                                 g_base64_decode_inplace(data_val, &len);
3435                                                 data_val[len] = 0;
3436                                         }
3437                                         pi = proto_tree_add_string(hdr_tree, hf_http_citrix_session, tvb,
3438                                             offset, data_len - 1, data_val);
3439                                         PROTO_ITEM_SET_GENERATED(pi);
3440                                 }
3441                         }
3442                         return TRUE;
3443                 }
3444         }
3445         return FALSE;
3446 }
3447
3448 static gboolean
3449 check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo, const gchar *value)
3450 {
3451         proto_tree *hdr_tree;
3452
3453         if (strncmp(value, "Kerberos ", 9) == 0) {
3454                 if (hdr_item != NULL) {
3455                         hdr_tree = proto_item_add_subtree(hdr_item, ett_http_kerberos);
3456                 } else
3457                         hdr_tree = NULL;
3458
3459                 dissect_http_kerberos(tvb, pinfo, hdr_tree, value);
3460                 return TRUE;
3461         }
3462         return FALSE;
3463 }
3464
3465 static void
3466 dissect_http_on_stream(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3467     http_conv_t *conv_data, gboolean end_of_stream)
3468 {
3469         int             offset = 0;
3470         int             len;
3471
3472         while (tvb_reported_length_remaining(tvb, offset) > 0) {
3473                 /* Switch protocol if the data starts after response headers. */
3474                 if (conv_data->startframe &&
3475                                 (pinfo->num > conv_data->startframe ||
3476                                 (pinfo->num == conv_data->startframe && offset >= conv_data->startoffset))) {
3477                         /* Increase pinfo->can_desegment because we are traversing
3478                          * http and want to preserve desegmentation functionality for
3479                          * the proxied protocol
3480                          */
3481                         if (pinfo->can_desegment > 0)
3482                                 pinfo->can_desegment++;
3483                         if (conv_data->next_handle) {
3484                                 call_dissector_only(conv_data->next_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree, NULL);
3485                         } else {
3486                                 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
3487                         }
3488                         break;
3489                 }
3490                 len = dissect_http_message(tvb, offset, pinfo, tree, conv_data, "HTTP", proto_http, end_of_stream);
3491                 if (len == -1)
3492                         break;
3493                 offset += len;
3494
3495                 /*
3496                  * OK, we've set the Protocol and Info columns for the
3497                  * first HTTP message; set a fence so that subsequent
3498                  * HTTP messages don't overwrite the Info column.
3499                  */
3500                 col_set_fence(pinfo->cinfo, COL_INFO);
3501         }
3502 }
3503
3504 static int
3505 dissect_http_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
3506 {
3507         struct tcpinfo *tcpinfo = (struct tcpinfo *)data;
3508         conversation_t *conversation;
3509         http_conv_t *conv_data;
3510         gboolean end_of_stream;
3511
3512         conv_data = get_http_conversation_data(pinfo, &conversation);
3513
3514         /* Call HTTP2 dissector directly when detected via heuristics, but not
3515          * when it was upgraded (the conversation started with HTTP). */
3516         if (conversation_get_proto_data(conversation, proto_http2) &&
3517             !conv_data->startframe) {
3518                 if (pinfo->can_desegment > 0)
3519                         pinfo->can_desegment++;
3520                 return call_dissector_only(http2_handle, tvb, pinfo, tree, data);
3521         }
3522
3523         /*
3524          * Check if this is proxied connection and if so, hand of dissection to the
3525          * payload-dissector.
3526          * Response code 200 means "OK" and strncmp() == 0 means the strings match exactly */
3527         if(pinfo->num >= conv_data->startframe &&
3528            conv_data->response_code == 200 &&
3529            conv_data->request_method &&
3530            strncmp(conv_data->request_method, "CONNECT", 7) == 0 &&
3531            conv_data->request_uri) {
3532                 if (conv_data->startframe == 0 && !PINFO_FD_VISITED(pinfo)) {
3533                         conv_data->startframe = pinfo->num;
3534                         conv_data->startoffset = 0;
3535                         copy_address_wmem(wmem_file_scope(), &conv_data->server_addr, &pinfo->dst);
3536                         conv_data->server_port = pinfo->destport;
3537                 }
3538                 http_payload_subdissector(tvb, tree, pinfo, conv_data, data);
3539
3540                 return tvb_captured_length(tvb);
3541         }
3542
3543         /* XXX - how to detect end-of-stream without tcpinfo */
3544         end_of_stream = (tcpinfo && IS_TH_FIN(tcpinfo->flags));
3545         dissect_http_on_stream(tvb, pinfo, tree, conv_data, end_of_stream);
3546         return tvb_captured_length(tvb);
3547 }
3548
3549 static gboolean
3550 dissect_http_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
3551 {
3552         gint offset = 0, next_offset, linelen;
3553         conversation_t  *conversation;
3554
3555
3556         /* Check if we have a line terminated by CRLF
3557          * Return the length of the line (not counting the line terminator at
3558          * the end), or, if we don't find a line terminator:
3559          *
3560          *      if "deseg" is true, return -1;
3561          */
3562         linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, TRUE);
3563         if((linelen == -1)||(linelen == 8)){
3564                 return FALSE;
3565         }
3566
3567         /* Check if the line start or ends with the HTTP token */
3568         if((tvb_strncaseeql(tvb, linelen-8, "HTTP/1.", 7) == 0)||(tvb_strncaseeql(tvb, 0, "HTTP/1.", 7) == 0)){
3569                 conversation = find_or_create_conversation(pinfo);
3570                 conversation_set_dissector_from_frame_number(conversation, pinfo->num, http_tcp_handle);
3571                 dissect_http_tcp(tvb, pinfo, tree, data);
3572                 return TRUE;
3573         }
3574
3575         return FALSE;
3576 }
3577
3578 static int
3579 dissect_http_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3580 {
3581         conversation_t *conversation;
3582         http_conv_t *conv_data;
3583
3584         conv_data = get_http_conversation_data(pinfo, &conversation);
3585
3586         /*
3587          * XXX - we need to provide an end-of-stream indication.
3588          */
3589         dissect_http_on_stream(tvb, pinfo, tree, conv_data, FALSE);
3590         return tvb_captured_length(tvb);
3591 }
3592
3593 static int
3594 dissect_http_sctp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3595 {
3596         conversation_t *conversation;
3597         http_conv_t *conv_data;
3598
3599         conv_data = get_http_conversation_data(pinfo, &conversation);
3600
3601         /*
3602          * XXX - we need to provide an end-of-stream indication.
3603          */
3604         dissect_http_on_stream(tvb, pinfo, tree, conv_data, FALSE);
3605         return tvb_captured_length(tvb);
3606 }
3607
3608 static int
3609 dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3610 {
3611         conversation_t *conversation;
3612         http_conv_t *conv_data;
3613
3614         conv_data = get_http_conversation_data(pinfo, &conversation);
3615
3616         /*
3617          * XXX - what should be done about reassembly, pipelining, etc.
3618          * here?
3619          */
3620         dissect_http_on_stream(tvb, pinfo, tree, conv_data, FALSE);
3621         return tvb_captured_length(tvb);
3622 }
3623
3624 static int
3625 dissect_ssdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3626 {
3627         conversation_t  *conversation;
3628         http_conv_t     *conv_data;
3629
3630         conv_data = get_http_conversation_data(pinfo, &conversation);
3631         dissect_http_message(tvb, 0, pinfo, tree, conv_data, "SSDP", proto_ssdp, FALSE);
3632         return tvb_captured_length(tvb);
3633 }
3634
3635 static void
3636 range_delete_http_ssl_callback(guint32 port, gpointer ptr _U_) {
3637         ssl_dissector_delete(port, http_tls_handle);
3638 }
3639
3640 static void
3641 range_add_http_ssl_callback(guint32 port, gpointer ptr _U_) {
3642         ssl_dissector_add(port, http_tls_handle);
3643 }
3644
3645 static void reinit_http(void) {
3646         http_tcp_range = prefs_get_range_value("http", "tcp.port");
3647
3648         dissector_delete_uint_range("sctp.port", http_sctp_range, http_sctp_handle);
3649         wmem_free(wmem_epan_scope(), http_sctp_range);
3650         http_sctp_range = range_copy(wmem_epan_scope(), global_http_sctp_range);
3651         dissector_add_uint_range("sctp.port", http_sctp_range, http_sctp_handle);
3652
3653         range_foreach(http_ssl_range, range_delete_http_ssl_callback, NULL);
3654         wmem_free(wmem_epan_scope(), http_ssl_range);
3655         http_ssl_range = range_copy(wmem_epan_scope(), global_http_ssl_range);
3656         range_foreach(http_ssl_range, range_add_http_ssl_callback, NULL);
3657 }
3658
3659 void
3660 proto_register_http(void)
3661 {
3662         static hf_register_info hf[] = {
3663             { &hf_http_notification,
3664               { "Notification",         "http.notification",
3665                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3666                 "TRUE if HTTP notification", HFILL }},
3667             { &hf_http_response,
3668               { "Response",             "http.response",
3669                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3670                 "TRUE if HTTP response", HFILL }},
3671             { &hf_http_request,
3672               { "Request",              "http.request",
3673                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3674                 "TRUE if HTTP request", HFILL }},
3675             { &hf_http_response_number,
3676               { "Response number",              "http.response_number",
3677                 FT_UINT32, BASE_DEC, NULL, 0x0,
3678                 NULL, HFILL }},
3679             { &hf_http_request_number,
3680               { "Request number",               "http.request_number",
3681                 FT_UINT32, BASE_DEC, NULL, 0x0,
3682                 NULL, HFILL }},
3683             { &hf_http_basic,
3684               { "Credentials",          "http.authbasic",
3685                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3686             { &hf_http_citrix,
3687               { "Citrix AG Auth",       "http.authcitrix",
3688                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
3689                 "TRUE if CitrixAGBasic Auth", HFILL }},
3690             { &hf_http_citrix_user,
3691               { "Citrix AG Username",   "http.authcitrix.user",
3692                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3693             { &hf_http_citrix_domain,
3694               { "Citrix AG Domain",     "http.authcitrix.domain",
3695                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3696             { &hf_http_citrix_passwd,
3697               { "Citrix AG Password",   "http.authcitrix.password",
3698                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3699             { &hf_http_citrix_session,
3700               { "Citrix AG Session ID", "http.authcitrix.session",
3701                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3702             { &hf_http_response_line,
3703               { "Response line",        "http.response.line",
3704                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3705             { &hf_http_request_line,
3706               { "Request line",         "http.request.line",
3707                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3708             { &hf_http_request_method,
3709               { "Request Method",       "http.request.method",
3710                 FT_STRING, BASE_NONE, NULL, 0x0,
3711                 "HTTP Request Method", HFILL }},
3712             { &hf_http_request_uri,
3713               { "Request URI",  "http.request.uri",
3714                 FT_STRING, STR_UNICODE, NULL, 0x0,
3715                 "HTTP Request-URI", HFILL }},
3716             { &hf_http_request_path,
3717               { "Request URI Path",     "http.request.uri.path",
3718                 FT_STRING, STR_UNICODE, NULL, 0x0,
3719                 "HTTP Request-URI Path", HFILL }},
3720             { &hf_http_request_query,
3721               { "Request URI Query",    "http.request.uri.query",
3722                 FT_STRING, STR_UNICODE, NULL, 0x0,
3723                 "HTTP Request-URI Query", HFILL }},
3724             { &hf_http_request_query_parameter,
3725               { "Request URI Query Parameter",  "http.request.uri.query.parameter",
3726                 FT_STRING, STR_UNICODE, NULL, 0x0,
3727                 "HTTP Request-URI Query Parameter", HFILL }},
3728             { &hf_http_request_version,
3729               { "Request Version",      "http.request.version",
3730                 FT_STRING, BASE_NONE, NULL, 0x0,
3731                 "HTTP Request HTTP-Version", HFILL }},
3732             { &hf_http_response_version,
3733               { "Response Version",     "http.response.version",
3734                 FT_STRING, BASE_NONE, NULL, 0x0,
3735                 "HTTP Response HTTP-Version", HFILL }},
3736             { &hf_http_request_full_uri,
3737               { "Full request URI",     "http.request.full_uri",
3738                 FT_STRING, BASE_NONE, NULL, 0x0,
3739                 "The full requested URI (including host name)", HFILL }},
3740             { &hf_http_response_code,
3741               { "Status Code",  "http.response.code",
3742                 FT_UINT16, BASE_DEC, NULL, 0x0,
3743                 "HTTP Response Status Code", HFILL }},
3744             { &hf_http_response_code_desc,
3745               { "Status Code Description", "http.response.code.desc",
3746                 FT_STRING, BASE_NONE, NULL, 0x0,
3747                 "HTTP Response Status Code Description", HFILL }},
3748                 { &hf_http_response_phrase,
3749                   { "Response Phrase", "http.response.phrase",
3750             FT_STRING, BASE_NONE, NULL, 0x0,
3751                 "HTTP Response Reason Phrase", HFILL }},
3752             { &hf_http_authorization,
3753               { "Authorization",        "http.authorization",
3754                 FT_STRING, BASE_NONE, NULL, 0x0,
3755                 "HTTP Authorization header", HFILL }},
3756             { &hf_http_proxy_authenticate,
3757               { "Proxy-Authenticate",   "http.proxy_authenticate",
3758                 FT_STRING, BASE_NONE, NULL, 0x0,
3759                 "HTTP Proxy-Authenticate header", HFILL }},
3760             { &hf_http_proxy_authorization,
3761               { "Proxy-Authorization",  "http.proxy_authorization",
3762                 FT_STRING, BASE_NONE, NULL, 0x0,
3763                 "HTTP Proxy-Authorization header", HFILL }},
3764             { &hf_http_proxy_connect_host,
3765               { "Proxy-Connect-Hostname", "http.proxy_connect_host",
3766                 FT_STRING, BASE_NONE, NULL, 0x0,
3767                 "HTTP Proxy Connect Hostname", HFILL }},
3768             { &hf_http_proxy_connect_port,
3769               { "Proxy-Connect-Port",   "http.proxy_connect_port",
3770                 FT_UINT16, BASE_DEC, NULL, 0x0,
3771                 "HTTP Proxy Connect Port", HFILL }},
3772             { &hf_http_www_authenticate,
3773               { "WWW-Authenticate",     "http.www_authenticate",
3774                 FT_STRING, BASE_NONE, NULL, 0x0,
3775                 "HTTP WWW-Authenticate header", HFILL }},
3776             { &hf_http_content_type,
3777               { "Content-Type", "http.content_type",
3778                 FT_STRING, BASE_NONE, NULL, 0x0,
3779                 "HTTP Content-Type header", HFILL }},
3780             { &hf_http_content_length_header,
3781               { "Content-Length",       "http.content_length_header",
3782                 FT_STRING, BASE_NONE, NULL, 0x0,
3783                 "HTTP Content-Length header", HFILL }},
3784             { &hf_http_content_length,
3785               { "Content length",       "http.content_length",
3786                 FT_UINT64, BASE_DEC, NULL, 0x0,
3787                 NULL, HFILL }},
3788             { &hf_http_content_encoding,
3789               { "Content-Encoding",     "http.content_encoding",
3790                 FT_STRING, BASE_NONE, NULL, 0x0,
3791                 "HTTP Content-Encoding header", HFILL }},
3792             { &hf_http_transfer_encoding,
3793               { "Transfer-Encoding",    "http.transfer_encoding",
3794                 FT_STRING, BASE_NONE, NULL, 0x0,
3795                 "HTTP Transfer-Encoding header", HFILL }},
3796             { &hf_http_upgrade,
3797               { "Upgrade",      "http.upgrade",
3798                 FT_STRING, BASE_NONE, NULL, 0x0,
3799                 "HTTP Upgrade header", HFILL }},
3800             { &hf_http_user_agent,
3801               { "User-Agent",   "http.user_agent",
3802                 FT_STRING, BASE_NONE, NULL, 0x0,
3803                 "HTTP User-Agent header", HFILL }},
3804             { &hf_http_host,
3805               { "Host", "http.host",
3806                 FT_STRING, BASE_NONE, NULL, 0x0,
3807                 "HTTP Host", HFILL }},
3808             { &hf_http_connection,
3809               { "Connection",   "http.connection",
3810                 FT_STRING, BASE_NONE, NULL, 0x0,
3811                 "HTTP Connection", HFILL }},
3812             { &hf_http_cookie,
3813               { "Cookie",       "http.cookie",
3814                 FT_STRING, BASE_NONE, NULL, 0x0,
3815                 "HTTP Cookie", HFILL }},
3816             { &hf_http_cookie_pair,
3817               { "Cookie pair",  "http.cookie_pair",
3818                 FT_STRING, BASE_NONE, NULL, 0x0,
3819                 "A name/value HTTP cookie pair", HFILL }},
3820             { &hf_http_accept,
3821               { "Accept",       "http.accept",
3822                 FT_STRING, BASE_NONE, NULL, 0x0,
3823                 "HTTP Accept", HFILL }},
3824             { &hf_http_referer,
3825               { "Referer",      "http.referer",
3826                 FT_STRING, BASE_NONE, NULL, 0x0,
3827                 "HTTP Referer", HFILL }},
3828             { &hf_http_accept_language,
3829               { "Accept-Language",      "http.accept_language",
3830                 FT_STRING, BASE_NONE, NULL, 0x0,
3831                 "HTTP Accept Language", HFILL }},
3832             { &hf_http_accept_encoding,
3833               { "Accept Encoding",      "http.accept_encoding",
3834                 FT_STRING, BASE_NONE, NULL, 0x0,
3835                 "HTTP Accept Encoding", HFILL }},
3836             { &hf_http_date,
3837               { "Date", "http.date",
3838                 FT_STRING, BASE_NONE, NULL, 0x0,
3839                 "HTTP Date", HFILL }},
3840             { &hf_http_cache_control,
3841               { "Cache-Control",        "http.cache_control",
3842                 FT_STRING, BASE_NONE, NULL, 0x0,
3843                 "HTTP Cache Control", HFILL }},
3844             { &hf_http_server,
3845               { "Server",       "http.server",
3846                 FT_STRING, BASE_NONE, NULL, 0x0,
3847                 "HTTP Server", HFILL }},
3848             { &hf_http_location,
3849               { "Location",     "http.location",
3850                 FT_STRING, BASE_NONE, NULL, 0x0,
3851                 "HTTP Location", HFILL }},
3852             { &hf_http_sec_websocket_accept,
3853               { "Sec-WebSocket-Accept", "http.sec_websocket_accept",
3854                 FT_STRING, BASE_NONE, NULL, 0x0,
3855                 NULL, HFILL }},
3856             { &hf_http_sec_websocket_extensions,
3857               { "Sec-WebSocket-Extensions",     "http.sec_websocket_extensions",
3858                 FT_STRING, BASE_NONE, NULL, 0x0,
3859                 NULL, HFILL }},
3860             { &hf_http_sec_websocket_key,
3861               { "Sec-WebSocket-Key",    "http.sec_websocket_key",
3862                 FT_STRING, BASE_NONE, NULL, 0x0,
3863                 NULL, HFILL }},
3864             { &hf_http_sec_websocket_protocol,
3865               { "Sec-WebSocket-Protocol",       "http.sec_websocket_protocol",
3866                 FT_STRING, BASE_NONE, NULL, 0x0,
3867                 NULL, HFILL }},
3868             { &hf_http_sec_websocket_version,
3869               { "Sec-WebSocket-Version",        "http.sec_websocket_version",
3870                 FT_STRING, BASE_NONE, NULL, 0x0,
3871                 NULL, HFILL }},
3872             { &hf_http_set_cookie,
3873               { "Set-Cookie",   "http.set_cookie",
3874                 FT_STRING, BASE_NONE, NULL, 0x0,
3875                 "HTTP Set Cookie", HFILL }},
3876             { &hf_http_last_modified,
3877               { "Last-Modified",        "http.last_modified",
3878                 FT_STRING, BASE_NONE, NULL, 0x0,
3879                 "HTTP Last Modified", HFILL }},
3880             { &hf_http_x_forwarded_for,
3881               { "X-Forwarded-For",      "http.x_forwarded_for",
3882                 FT_STRING, BASE_NONE, NULL, 0x0,
3883                 "HTTP X-Forwarded-For", HFILL }},
3884             { &hf_http_request_in,
3885               { "Request in frame", "http.request_in",
3886                 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST), 0,
3887                 "This packet is a response to the packet with this number", HFILL }},
3888             { &hf_http_response_in,
3889               { "Response in frame","http.response_in",
3890                 FT_FRAMENUM, BASE_NONE, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE), 0,
3891                 "This packet will be responded in the packet with this number", HFILL }},
3892             { &hf_http_next_request_in,
3893               { "Next request in frame", "http.next_request_in",
3894                 FT_FRAMENUM, BASE_NONE, NULL, 0,
3895                 "The next HTTP request starts in packet number", HFILL }},
3896             { &hf_http_next_response_in,
3897               { "Next response in frame","http.next_response_in",
3898                 FT_FRAMENUM, BASE_NONE, NULL, 0,
3899                 "The next HTTP response starts in packet number", HFILL }},
3900             { &hf_http_prev_request_in,
3901               { "Prev request in frame", "http.prev_request_in",
3902                 FT_FRAMENUM, BASE_NONE, NULL, 0,
3903                 "The previous HTTP request starts in packet number", HFILL }},
3904             { &hf_http_prev_response_in,
3905               { "Prev response in frame","http.prev_response_in",
3906                 FT_FRAMENUM, BASE_NONE, NULL, 0,
3907                 "The previous HTTP response starts in packet number", HFILL }},
3908             { &hf_http_time,
3909               { "Time since request", "http.time",
3910                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0,
3911                 "Time since the request was sent", HFILL }},
3912             { &hf_http_chunked_trailer_part,
3913               { "trailer-part", "http.chunked_trailer_part",
3914                 FT_STRING, BASE_NONE, NULL, 0,
3915                 "Optional trailer in a chunked body", HFILL }},
3916             { &hf_http_chunk_boundary,
3917               { "Chunk boundary", "http.chunk_boundary",
3918                 FT_BYTES, BASE_NONE, NULL, 0,
3919                 NULL, HFILL }},
3920             { &hf_http_chunk_size,
3921               { "Chunk size", "http.chunk_size",
3922                 FT_UINT32, BASE_DEC|BASE_UNIT_STRING, &units_octet_octets, 0,
3923                 NULL, HFILL }},
3924             { &hf_http_file_data,
3925               { "File Data", "http.file_data",
3926                 FT_STRING, STR_UNICODE, NULL, 0,
3927                 NULL, HFILL }},
3928             { &hf_http_unknown_header,
3929               { "Unknown header", "http.unknown_header",
3930                 FT_STRING, BASE_NONE, NULL, 0,
3931                 NULL, HFILL }},
3932         };
3933         static gint *ett[] = {
3934                 &ett_http,
3935                 &ett_http_ntlmssp,
3936                 &ett_http_kerberos,
3937                 &ett_http_request,
3938                 &ett_http_request_path,
3939                 &ett_http_request_query,
3940                 &ett_http_chunked_response,
3941                 &ett_http_chunk_data,
3942                 &ett_http_encoded_entity,
3943                 &ett_http_header_item
3944         };
3945
3946         static ei_register_info ei[] = {
3947                 { &ei_http_chat, { "http.chat", PI_SEQUENCE, PI_CHAT, "Formatted text", EXPFILL }},
3948                 { &ei_http_te_and_length, { "http.te_and_length", PI_MALFORMED, PI_WARN, "The Content-Length and Transfer-Encoding header must not be set together", EXPFILL }},
3949                 { &ei_http_te_unknown, { "http.te_unknown", PI_UNDECODED, PI_WARN, "Unknown transfer coding name in Transfer-Encoding header", EXPFILL }},
3950                 { &ei_http_subdissector_failed, { "http.subdissector_failed", PI_MALFORMED, PI_NOTE, "HTTP body subdissector failed, trying heuristic subdissector", EXPFILL }},
3951                 { &ei_http_ssl_port, { "http.ssl_port", PI_SECURITY, PI_WARN, "Unencrypted HTTP protocol detected over encrypted port, could indicate a dangerous misconfiguration.", EXPFILL }},
3952                 { &ei_http_leading_crlf, { "http.leading_crlf", PI_MALFORMED, PI_ERROR, "Leading CRLF previous message in the stream may have extra CRLF", EXPFILL }},
3953                 { &ei_http_bad_header_name, { "http.bad_header_name", PI_PROTOCOL, PI_WARN, "Illegal characters found in header name", EXPFILL }},
3954         };
3955
3956         /* UAT for header fields */
3957         static uat_field_t custom_header_uat_fields[] = {
3958                 UAT_FLD_CSTRING(header_fields, header_name, "Header name", "HTTP header name"),
3959                 UAT_FLD_CSTRING(header_fields, header_desc, "Field desc", "Description of the value contained in the header"),
3960                 UAT_END_FIELDS
3961         };
3962
3963         module_t *http_module;
3964         expert_module_t* expert_http;
3965         uat_t* headers_uat;
3966
3967         proto_http = proto_register_protocol("Hypertext Transfer Protocol", "HTTP", "http");
3968         proto_ssdp = proto_register_protocol("Simple Service Discovery Protocol", "SSDP", "ssdp");
3969
3970         proto_register_field_array(proto_http, hf, array_length(hf));
3971         proto_register_subtree_array(ett, array_length(ett));
3972         expert_http = expert_register_protocol(proto_http);
3973         expert_register_field_array(expert_http, ei, array_length(ei));
3974
3975         http_handle = register_dissector("http", dissect_http, proto_http);
3976         http_tcp_handle = register_dissector("http-over-tcp", dissect_http_tcp, proto_http);
3977         http_tls_handle = register_dissector("http-over-tls", dissect_http_ssl, proto_http); /* RFC 2818 */
3978         http_sctp_handle = register_dissector("http-over-sctp", dissect_http_sctp, proto_http);
3979
3980         http_module = prefs_register_protocol(proto_http, reinit_http);
3981         prefs_register_bool_preference(http_module, "desegment_headers",
3982             "Reassemble HTTP headers spanning multiple TCP segments",
3983             "Whether the HTTP dissector should reassemble headers "
3984             "of a request spanning multiple TCP segments. "
3985                 "To use this option, you must also enable "
3986         "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3987             &http_desegment_headers);
3988         prefs_register_bool_preference(http_module, "desegment_body",
3989             "Reassemble HTTP bodies spanning multiple TCP segments",
3990             "Whether the HTTP dissector should use the "
3991             "\"Content-length:\" value, if present, to reassemble "
3992             "the body of a request spanning multiple TCP segments, "
3993             "and reassemble chunked data spanning multiple TCP segments. "
3994                 "To use this option, you must also enable "
3995         "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
3996             &http_desegment_body);
3997         prefs_register_bool_preference(http_module, "dechunk_body",
3998             "Reassemble chunked transfer-coded bodies",
3999             "Whether to reassemble bodies of entities that are transferred "
4000             "using the \"Transfer-Encoding: chunked\" method",
4001             &http_dechunk_body);
4002 #ifdef HAVE_ZLIB
4003         prefs_register_bool_preference(http_module, "decompress_body",
4004             "Uncompress entity bodies",
4005             "Whether to uncompress entity bodies that are compressed "
4006             "using \"Content-Encoding: \"",
4007             &http_decompress_body);
4008 #endif
4009         prefs_register_obsolete_preference(http_module, "tcp_alternate_port");
4010
4011         range_convert_str(wmem_epan_scope(), &global_http_sctp_range, SCTP_DEFAULT_RANGE, 65535);
4012         prefs_register_range_preference(http_module, "sctp.port", "SCTP Ports",
4013                                         "SCTP Ports range",
4014                                         &global_http_sctp_range, 65535);
4015
4016         range_convert_str(wmem_epan_scope(), &global_http_ssl_range, SSL_DEFAULT_RANGE, 65535);
4017         prefs_register_range_preference(http_module, "tls.port", "SSL/TLS Ports",
4018                                         "SSL/TLS Ports range",
4019                                         &global_http_ssl_range, 65535);
4020         /* UAT */
4021         headers_uat = uat_new("Custom HTTP Header Fields",
4022                               sizeof(header_field_t),
4023                               "custom_http_header_fields",
4024                               TRUE,
4025                               &header_fields,
4026                               &num_header_fields,
4027                               /* specifies named fields, so affects dissection
4028                                  and the set of named fields */
4029                               UAT_AFFECTS_DISSECTION|UAT_AFFECTS_FIELDS,
4030                               NULL,
4031                               header_fields_copy_cb,
4032                               header_fields_update_cb,
4033                               header_fields_free_cb,
4034                               header_fields_post_update_cb,
4035                               header_fields_reset_cb,
4036                               custom_header_uat_fields
4037         );
4038
4039         prefs_register_uat_preference(http_module, "custom_http_header_fields", "Custom HTTP header fields",
4040             "A table to define custom HTTP header for which fields can be setup and used for filtering/data extraction etc.",
4041            headers_uat);
4042
4043         /*
4044          * Dissectors shouldn't register themselves in this table;
4045          * instead, they should call "http_tcp_dissector_add()", and
4046          * we'll register the port number they specify as a port
4047          * for HTTP, and register them in our subdissector table.
4048          *
4049          * This only works for protocols such as IPP that run over
4050          * HTTP on a specific non-HTTP port.
4051          */
4052         port_subdissector_table = register_dissector_table("http.port",
4053             "TCP port for protocols using HTTP", proto_http, FT_UINT16, BASE_DEC);
4054
4055         /*
4056          * Dissectors can register themselves in this table.
4057          * It's just "media_type", not "http.content_type", because
4058          * it's an Internet media type, usable by other protocols as well.
4059          */
4060         media_type_subdissector_table =
4061             register_dissector_table("media_type",
4062                 "Internet media type", proto_http, FT_STRING, BASE_NONE);
4063
4064         /*
4065          * Maps the lowercase Upgrade header value.
4066          * https://tools.ietf.org/html/rfc7230#section-8.6
4067          */
4068         upgrade_subdissector_table = register_dissector_table("http.upgrade", "HTTP Upgrade", proto_http, FT_STRING, BASE_NONE);
4069
4070         /*
4071          * Heuristic dissectors SHOULD register themselves in
4072          * this table using the standard heur_dissector_add()
4073          * function.
4074          */
4075         heur_subdissector_list = register_heur_dissector_list("http", proto_http);
4076
4077         /*
4078          * Register for tapping
4079          */
4080         http_tap = register_tap("http"); /* HTTP statistics tap */
4081         http_follow_tap = register_tap("http_follow"); /* HTTP Follow tap */
4082
4083         register_follow_stream(proto_http, "http_follow", tcp_follow_conv_filter, tcp_follow_index_filter, tcp_follow_address_filter,
4084                                                         tcp_port_to_display, follow_tvb_tap_listener);
4085         http_eo_tap = register_export_object(proto_http, http_eo_packet, NULL);
4086 }
4087
4088 /*
4089  * Called by dissectors for protocols that run atop HTTP/TCP.
4090  */
4091 void
4092 http_tcp_dissector_add(guint32 port, dissector_handle_t handle)
4093 {
4094         /*
4095          * Register ourselves as the handler for that port number
4096          * over TCP.  "Auto-preference" not needed
4097          */
4098         dissector_add_uint("tcp.port", port, http_tcp_handle);
4099
4100         /*
4101          * And register them in *our* table for that port.
4102          */
4103         dissector_add_uint("http.port", port, handle);
4104 }
4105
4106 WS_DLL_PUBLIC
4107 void http_tcp_dissector_delete(guint32 port)
4108 {
4109         /*
4110          * Unregister ourselves as the handler for that port number
4111          * over TCP.  "Auto-preference" not needed
4112          */
4113         dissector_delete_uint("tcp.port", port, NULL);
4114
4115         /*
4116          * And unregister them in *our* table for that port.
4117          */
4118         dissector_delete_uint("http.port", port, NULL);
4119 }
4120
4121 void
4122 http_tcp_port_add(guint32 port)
4123 {
4124         /*
4125          * Register ourselves as the handler for that port number
4126          * over TCP.  We rely on our caller having registered
4127          * themselves for the appropriate media type.
4128          * No "auto-preference" used.
4129          */
4130         dissector_add_uint("tcp.port", port, http_tcp_handle);
4131 }
4132
4133 void
4134 proto_reg_handoff_http(void)
4135 {
4136         dissector_handle_t ssdp_handle;
4137
4138         media_handle = find_dissector_add_dependency("media", proto_http);
4139         http2_handle = find_dissector("http2");
4140         /*
4141          * XXX - is there anything to dissect in the body of an SSDP
4142          * request or reply?  I.e., should there be an SSDP dissector?
4143          */
4144         ssdp_handle = create_dissector_handle(dissect_ssdp, proto_ssdp);
4145         dissector_add_uint_with_preference("udp.port", UDP_PORT_SSDP, ssdp_handle);
4146
4147         /*
4148          * SSL/TLS Application-Layer Protocol Negotiation (ALPN) protocol
4149          * ID.
4150          */
4151         dissector_add_string("tls.handshake.extensions_alpn_str", "http/1.1", http_tls_handle);
4152
4153         ntlmssp_handle = find_dissector_add_dependency("ntlmssp", proto_http);
4154         gssapi_handle = find_dissector_add_dependency("gssapi", proto_http);
4155         sstp_handle = find_dissector_add_dependency("sstp", proto_http);
4156
4157         stats_tree_register("http", "http",     "HTTP/Packet Counter",   0, http_stats_tree_packet,      http_stats_tree_init, NULL );
4158         stats_tree_register("http", "http_req", "HTTP/Requests",         0, http_req_stats_tree_packet,  http_req_stats_tree_init, NULL );
4159         stats_tree_register("http", "http_srv", "HTTP/Load Distribution",0, http_reqs_stats_tree_packet, http_reqs_stats_tree_init, NULL );
4160         stats_tree_register("http", "http_seq", "HTTP/Request Sequences",0, http_seq_stats_tree_packet,  http_seq_stats_tree_init, NULL );
4161 }
4162
4163 /*
4164  * Content-Type: message/http
4165  */
4166
4167 static gint proto_message_http = -1;
4168 static gint ett_message_http = -1;
4169
4170 static int
4171 dissect_message_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4172 {
4173         proto_tree      *subtree;
4174         proto_item      *ti;
4175         gint            offset = 0, next_offset;
4176         gint            len;
4177
4178         col_append_str(pinfo->cinfo, COL_INFO, " (message/http)");
4179         if (tree) {
4180                 ti = proto_tree_add_item(tree, proto_message_http,
4181                                 tvb, 0, -1, ENC_NA);
4182                 subtree = proto_item_add_subtree(ti, ett_message_http);
4183                 while (tvb_offset_exists(tvb, offset)) {
4184                         len = tvb_find_line_end(tvb, offset,
4185                                         tvb_ensure_captured_length_remaining(tvb, offset),
4186                                         &next_offset, FALSE);
4187                         if (len == -1)
4188                                 break;
4189                         proto_tree_add_format_text(subtree, tvb, offset, len);
4190                         offset = next_offset;
4191                 }
4192         }
4193         return tvb_captured_length(tvb);
4194 }
4195
4196 void
4197 proto_register_message_http(void)
4198 {
4199         static gint *ett[] = {
4200                 &ett_message_http,
4201         };
4202
4203         proto_message_http = proto_register_protocol(
4204                         "Media Type: message/http",
4205                         "message/http",
4206                         "message-http"
4207         );
4208         proto_register_subtree_array(ett, array_length(ett));
4209 }
4210
4211 void
4212 proto_reg_handoff_message_http(void)
4213 {
4214         dissector_handle_t message_http_handle;
4215
4216         message_http_handle = create_dissector_handle(dissect_message_http,
4217                         proto_message_http);
4218
4219         dissector_add_string("media_type", "message/http", message_http_handle);
4220
4221         heur_dissector_add("tcp", dissect_http_heur_tcp, "HTTP over TCP", "http_tcp", proto_http, HEURISTIC_ENABLE);
4222
4223         proto_http2 = proto_get_id_by_filter_name("http2");
4224
4225         dissector_add_uint_range_with_preference("tcp.port", TCP_DEFAULT_RANGE, http_tcp_handle);
4226
4227         reinit_http();
4228 }
4229
4230 /*
4231  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
4232  *
4233  * Local variables:
4234  * c-basic-offset: 8
4235  * tab-width: 8
4236  * indent-tabs-mode: t
4237  * End:
4238  *
4239  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
4240  * :indentSize=8:tabSize=8:noTabs=false:
4241  */