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