Treat TVBs as opaque: use the accessor functions instead of accessing the fields
[obnox/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 2004, Jerry Talkington <jtalkington@users.sourceforge.net>
9  * Copyright 2002, Tim Potter <tpot@samba.org>
10  * Copyright 1999, Andrew Tridgell <tridge@samba.org>
11  *
12  * $Id$
13  *
14  * Wireshark - Network traffic analyzer
15  * By Gerald Combs <gerald@wireshark.org>
16  * Copyright 1998 Gerald Combs
17  *
18  * This program is free software; you can redistribute it and/or
19  * modify it under the terms of the GNU General Public License
20  * as published by the Free Software Foundation; either version 2
21  * of the License, or (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful,
24  * but WITHOUT ANY WARRANTY; without even the implied warranty of
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  * GNU General Public License for more details.
27  *
28  * You should have received a copy of the GNU General Public License
29  * along with this program; if not, write to the Free Software
30  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
31  */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <errno.h>
41
42 #include <glib.h>
43 #include <epan/conversation.h>
44 #include <epan/packet.h>
45 #include <epan/strutil.h>
46 #include <epan/base64.h>
47 #include <epan/emem.h>
48 #include <epan/stats_tree.h>
49
50 #include <epan/req_resp_hdrs.h>
51 #include "packet-http.h"
52 #include "packet-tcp.h"
53 #include "packet-ssl.h"
54 #include <epan/prefs.h>
55 #include <epan/expert.h>
56 #include <epan/uat.h>
57
58 typedef enum _http_type {
59         HTTP_REQUEST,
60         HTTP_RESPONSE,
61         HTTP_NOTIFICATION,
62         HTTP_OTHERS
63 } http_type_t;
64
65 #include <epan/tap.h>
66
67
68 static int http_tap = -1;
69 static int http_eo_tap = -1;
70
71 static int proto_http = -1;
72 static int hf_http_notification = -1;
73 static int hf_http_response = -1;
74 static int hf_http_request = -1;
75 static int hf_http_basic = -1;
76 static int hf_http_request_method = -1;
77 static int hf_http_request_uri = -1;
78 static int hf_http_request_full_uri = -1;
79 static int hf_http_version = -1;
80 static int hf_http_response_code = -1;
81 static int hf_http_response_phrase = -1;
82 static int hf_http_authorization = -1;
83 static int hf_http_proxy_authenticate = -1;
84 static int hf_http_proxy_authorization = -1;
85 static int hf_http_proxy_connect_host = -1;
86 static int hf_http_proxy_connect_port = -1;
87 static int hf_http_www_authenticate = -1;
88 static int hf_http_content_type = -1;
89 static int hf_http_content_length_header = -1;
90 static int hf_http_content_length = -1;
91 static int hf_http_content_encoding = -1;
92 static int hf_http_transfer_encoding = -1;
93 static int hf_http_user_agent = -1;
94 static int hf_http_host = -1;
95 static int hf_http_connection = -1;
96 static int hf_http_cookie = -1;
97 static int hf_http_accept = -1;
98 static int hf_http_referer = -1;
99 static int hf_http_accept_language = -1;
100 static int hf_http_accept_encoding = -1;
101 static int hf_http_date = -1;
102 static int hf_http_cache_control = -1;
103 static int hf_http_server = -1;
104 static int hf_http_location = -1;
105 static int hf_http_set_cookie = -1;
106 static int hf_http_last_modified = -1;
107 static int hf_http_x_forwarded_for = -1;
108
109 static gint ett_http = -1;
110 static gint ett_http_ntlmssp = -1;
111 static gint ett_http_kerberos = -1;
112 static gint ett_http_request = -1;
113 static gint ett_http_chunked_response = -1;
114 static gint ett_http_chunk_data = -1;
115 static gint ett_http_encoded_entity = -1;
116 static gint ett_http_header_item = -1;
117
118 static dissector_handle_t data_handle;
119 static dissector_handle_t media_handle;
120 static dissector_handle_t http_handle;
121
122 /* Stuff for generation/handling of fields for custom HTTP headers */
123 typedef struct _header_field_t {
124         gchar* header_name;
125         gchar* header_desc;
126 } header_field_t;
127
128 static header_field_t* header_fields = NULL;
129 static guint num_header_fields = 0;
130
131 static GHashTable* header_fields_hash = NULL;
132
133 static void
134 header_fields_update_cb(void* r, const char** err)
135 {
136         header_field_t* rec = r;
137
138         if (rec->header_name == NULL) {
139                 *err = ep_strdup_printf("Header name can't be empty");
140         } else {
141                 g_strstrip(rec->header_name);
142                 if (rec->header_name[0] != 0) {
143                         *err = NULL;
144                 } else {
145                         *err = ep_strdup_printf("Header name can't be empty");
146                 }
147         }
148 }
149
150 static void *
151 header_fields_copy_cb(void* n, const void* o, size_t siz _U_)
152 {
153     header_field_t* new_rec = n;
154     const header_field_t* old_rec = o;
155
156     if (old_rec->header_name) {
157         new_rec->header_name = g_strdup(old_rec->header_name);
158     } else {
159         new_rec->header_name = NULL;
160     }
161
162     if (old_rec->header_desc) {
163         new_rec->header_desc = g_strdup(old_rec->header_desc);
164     } else {
165         new_rec->header_desc = NULL;
166     }
167
168     return new_rec;
169 }
170
171 static void
172 header_fields_free_cb(void*r)
173 {
174     header_field_t* rec = r;
175
176     if (rec->header_name) g_free(rec->header_name);
177     if (rec->header_desc) g_free(rec->header_desc);
178 }
179
180 UAT_CSTRING_CB_DEF(header_fields, header_name, header_field_t)
181 UAT_CSTRING_CB_DEF(header_fields, header_desc, header_field_t)
182
183 /*
184  * desegmentation of HTTP headers
185  * (when we are over TCP or another protocol providing the desegmentation API)
186  */
187 static gboolean http_desegment_headers = TRUE;
188
189 /*
190  * desegmentation of HTTP bodies
191  * (when we are over TCP or another protocol providing the desegmentation API)
192  * TODO let the user filter on content-type the bodies he wants desegmented
193  */
194 static gboolean http_desegment_body = TRUE;
195
196 /*
197  * De-chunking of content-encoding: chunk entity bodies.
198  */
199 static gboolean http_dechunk_body = TRUE;
200
201 /*
202  * Decompression of zlib encoded entities.
203  */
204 #ifdef HAVE_LIBZ
205 static gboolean http_decompress_body = TRUE;
206 #else
207 static gboolean http_decompress_body = FALSE;
208 #endif
209
210 #define TCP_PORT_DAAP                   3689
211
212 /*
213  * SSDP is implemented atop HTTP (yes, it really *does* run over UDP).
214  */
215 #define TCP_PORT_SSDP                   1900
216 #define UDP_PORT_SSDP                   1900
217
218 /*
219  * tcp and ssl ports
220  */
221
222 #define TCP_DEFAULT_RANGE "80,3128,3132,5985,8080,8088,11371,1900,2869"
223 #define SSL_DEFAULT_RANGE "443"
224
225 static range_t *global_http_tcp_range = NULL;
226 static range_t *global_http_ssl_range = NULL;
227
228 static range_t *http_tcp_range = NULL;
229 static range_t *http_ssl_range = NULL;
230
231 typedef void (*ReqRespDissector)(tvbuff_t*, proto_tree*, int, const guchar*,
232                                  const guchar*, http_conv_t *);
233
234 /*
235  * Structure holding information from headers needed by main
236  * HTTP dissector code.
237  */
238 typedef struct {
239         char    *content_type;
240         char    *content_type_parameters;
241         gboolean have_content_length;
242         gint64  content_length;
243         char    *content_encoding;
244         char    *transfer_encoding;
245 } headers_t;
246
247 static int is_http_request_or_reply(const gchar *data, int linelen,
248                                     http_type_t *type, ReqRespDissector
249                                     *reqresp_dissector, http_conv_t *conv_data);
250 static int chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
251                                       proto_tree *tree, int offset);
252 static void process_header(tvbuff_t *tvb, int offset, int next_offset,
253                            const guchar *line, int linelen, int colon_offset,
254                            packet_info *pinfo, proto_tree *tree,
255                            headers_t *eh_ptr, http_conv_t *conv_data);
256 static gint find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len);
257 static gboolean check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb,
258                                    packet_info *pinfo, gchar *value);
259 static gboolean check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb,
260                                  gchar *value);
261 static gboolean check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb,
262                                    packet_info *pinfo, const gchar *value);
263
264 static dissector_table_t port_subdissector_table;
265 static dissector_table_t media_type_subdissector_table;
266 static heur_dissector_list_t heur_subdissector_list;
267
268 static dissector_handle_t ntlmssp_handle;
269 static dissector_handle_t gssapi_handle;
270
271 static const value_string vals_status_code[] = {
272         { 100, "Continue" },
273         { 101, "Switching Protocols" },
274         { 102, "Processing" },
275         { 199, "Informational - Others" },
276
277         { 200, "OK"},
278         { 201, "Created"},
279         { 202, "Accepted"},
280         { 203, "Non-authoritative Information"},
281         { 204, "No Content"},
282         { 205, "Reset Content"},
283         { 206, "Partial Content"},
284         { 207, "Multi-Status"},
285         { 299, "Success - Others"},
286
287         { 300, "Multiple Choices"},
288         { 301, "Moved Permanently"},
289         { 302, "Found"},
290         { 303, "See Other"},
291         { 304, "Not Modified"},
292         { 305, "Use Proxy"},
293         { 307, "Temporary Redirect"},
294         { 399, "Redirection - Others"},
295
296         { 400, "Bad Request"},
297         { 401, "Unauthorized"},
298         { 402, "Payment Required"},
299         { 403, "Forbidden"},
300         { 404, "Not Found"},
301         { 405, "Method Not Allowed"},
302         { 406, "Not Acceptable"},
303         { 407, "Proxy Authentication Required"},
304         { 408, "Request Time-out"},
305         { 409, "Conflict"},
306         { 410, "Gone"},
307         { 411, "Length Required"},
308         { 412, "Precondition Failed"},
309         { 413, "Request Entity Too Large"},
310         { 414, "Request-URI Too Long"},
311         { 415, "Unsupported Media Type"},
312         { 416, "Requested Range Not Satisfiable"},
313         { 417, "Expectation Failed"},
314         { 418, "I'm a teapot"},         /* RFC 2324 */
315         { 422, "Unprocessable Entity"},
316         { 423, "Locked"},
317         { 424, "Failed Dependency"},
318         { 499, "Client Error - Others"},
319
320         { 500, "Internal Server Error"},
321         { 501, "Not Implemented"},
322         { 502, "Bad Gateway"},
323         { 503, "Service Unavailable"},
324         { 504, "Gateway Time-out"},
325         { 505, "HTTP Version not supported"},
326         { 507, "Insufficient Storage"},
327         { 599, "Server Error - Others"},
328
329         { 0,    NULL}
330 };
331
332 static const gchar* st_str_reqs = "HTTP Requests by Server";
333 static const gchar* st_str_reqs_by_srv_addr = "HTTP Requests by Server Address";
334 static const gchar* st_str_reqs_by_http_host = "HTTP Requests by HTTP Host";
335 static const gchar* st_str_resps_by_srv_addr = "HTTP Responses by Server Address";
336
337 static int st_node_reqs = -1;
338 static int st_node_reqs_by_srv_addr = -1;
339 static int st_node_reqs_by_http_host = -1;
340 static int st_node_resps_by_srv_addr = -1;
341
342 /* HTTP/Load Distribution stats init function */
343 static void
344 http_reqs_stats_tree_init(stats_tree* st)
345 {
346         st_node_reqs = stats_tree_create_node(st, st_str_reqs, 0, TRUE);
347         st_node_reqs_by_srv_addr = stats_tree_create_node(st, st_str_reqs_by_srv_addr, st_node_reqs, TRUE);
348         st_node_reqs_by_http_host = stats_tree_create_node(st, st_str_reqs_by_http_host, st_node_reqs, TRUE);
349         st_node_resps_by_srv_addr = stats_tree_create_node(st, st_str_resps_by_srv_addr, 0, TRUE);
350 }
351
352 /* HTTP/Load Distribution stats packet function */
353 static int
354 http_reqs_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
355 {
356         const http_info_value_t* v = p;
357         int reqs_by_this_host;
358         int reqs_by_this_addr;
359         int resps_by_this_addr;
360         int i = v->response_code;
361         gchar *ip_str;
362
363
364         if (v->request_method) {
365                 ip_str = ep_address_to_str(&pinfo->dst);
366
367                 tick_stat_node(st, st_str_reqs, 0, FALSE);
368                 tick_stat_node(st, st_str_reqs_by_srv_addr, st_node_reqs, TRUE);
369                 tick_stat_node(st, st_str_reqs_by_http_host, st_node_reqs, TRUE);
370                 reqs_by_this_addr = tick_stat_node(st, ip_str, st_node_reqs_by_srv_addr, TRUE);
371
372                 if (v->http_host) {
373                         reqs_by_this_host = tick_stat_node(st, v->http_host, st_node_reqs_by_http_host, TRUE);
374                         tick_stat_node(st, ip_str, reqs_by_this_host, FALSE);
375
376                         tick_stat_node(st, v->http_host, reqs_by_this_addr, FALSE);
377                 }
378
379                 return 1;
380
381         } else if (i != 0) {
382                 ip_str = ep_address_to_str(&pinfo->src);
383
384                 tick_stat_node(st, st_str_resps_by_srv_addr, 0, FALSE);
385                 resps_by_this_addr = tick_stat_node(st, ip_str, st_node_resps_by_srv_addr, TRUE);
386
387                 if ( (i>100)&&(i<400) ) {
388                         tick_stat_node(st, "OK", resps_by_this_addr, FALSE);
389                 } else {
390                         tick_stat_node(st, "KO", resps_by_this_addr, FALSE);
391                 }
392
393                 return 1;
394         }
395
396         return 0;
397 }
398
399
400 static int st_node_requests_by_host = -1;
401 static const gchar *st_str_requests_by_host = "HTTP Requests by HTTP Host";
402
403 /* HTTP/Requests stats init function */
404 static void
405 http_req_stats_tree_init(stats_tree* st)
406 {
407         st_node_requests_by_host = stats_tree_create_node(st, st_str_requests_by_host, 0, TRUE);
408 }
409
410 /* HTTP/Requests stats packet function */
411 static int
412 http_req_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
413 {
414         const http_info_value_t* v = p;
415         int reqs_by_this_host;
416
417         if (v->request_method) {
418                 tick_stat_node(st, st_str_requests_by_host, 0, FALSE);
419
420                 if (v->http_host) {
421                         reqs_by_this_host = tick_stat_node(st, v->http_host, st_node_requests_by_host, TRUE);
422
423                         if (v->request_uri) {
424                                 tick_stat_node(st, v->request_uri, reqs_by_this_host, TRUE);
425                         }
426                 }
427
428                 return 1;
429         }
430
431         return 0;
432 }
433
434 static const gchar *st_str_packets = "Total HTTP Packets";
435 static const gchar *st_str_requests = "HTTP Request Packets";
436 static const gchar *st_str_responses = "HTTP Response Packets";
437 static const gchar *st_str_resp_broken = "???: broken";
438 static const gchar *st_str_resp_100 = "1xx: Informational";
439 static const gchar *st_str_resp_200 = "2xx: Success";
440 static const gchar *st_str_resp_300 = "3xx: Redirection";
441 static const gchar *st_str_resp_400 = "4xx: Client Error";
442 static const gchar *st_str_resp_500 = "5xx: Server Error";
443 static const gchar *st_str_other = "Other HTTP Packets";
444
445 static int st_node_packets = -1;
446 static int st_node_requests = -1;
447 static int st_node_responses = -1;
448 static int st_node_resp_broken = -1;
449 static int st_node_resp_100 = -1;
450 static int st_node_resp_200 = -1;
451 static int st_node_resp_300 = -1;
452 static int st_node_resp_400 = -1;
453 static int st_node_resp_500 = -1;
454 static int st_node_other = -1;
455
456
457 /* HTTP/Packet Counter stats init function */
458 static void
459 http_stats_tree_init(stats_tree* st)
460 {
461         st_node_packets = stats_tree_create_node(st, st_str_packets, 0, TRUE);
462         st_node_requests = stats_tree_create_pivot(st, st_str_requests, st_node_packets);
463         st_node_responses = stats_tree_create_node(st, st_str_responses, st_node_packets, TRUE);
464         st_node_resp_broken = stats_tree_create_node(st, st_str_resp_broken, st_node_responses, TRUE);
465         st_node_resp_100    = stats_tree_create_node(st, st_str_resp_100,    st_node_responses, TRUE);
466         st_node_resp_200    = stats_tree_create_node(st, st_str_resp_200,    st_node_responses, TRUE);
467         st_node_resp_300    = stats_tree_create_node(st, st_str_resp_300,    st_node_responses, TRUE);
468         st_node_resp_400    = stats_tree_create_node(st, st_str_resp_400,    st_node_responses, TRUE);
469         st_node_resp_500    = stats_tree_create_node(st, st_str_resp_500,    st_node_responses, TRUE);
470         st_node_other = stats_tree_create_node(st, st_str_other, st_node_packets,FALSE);
471 }
472
473 /* HTTP/Packet Counter stats packet function */
474 static int
475 http_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
476 {
477         const http_info_value_t* v = p;
478         guint i = v->response_code;
479         int resp_grp;
480         const gchar *resp_str;
481         gchar str[64];
482
483         tick_stat_node(st, st_str_packets, 0, FALSE);
484
485         if (i) {
486                 tick_stat_node(st, st_str_responses, st_node_packets, FALSE);
487
488                 if ( (i<100)||(i>=600) ) {
489                         resp_grp = st_node_resp_broken;
490                         resp_str = st_str_resp_broken;
491                 } else if (i<200) {
492                         resp_grp = st_node_resp_100;
493                         resp_str = st_str_resp_100;
494                 } else if (i<300) {
495                         resp_grp = st_node_resp_200;
496                         resp_str = st_str_resp_200;
497                 } else if (i<400) {
498                         resp_grp = st_node_resp_300;
499                         resp_str = st_str_resp_300;
500                 } else if (i<500) {
501                         resp_grp = st_node_resp_400;
502                         resp_str = st_str_resp_400;
503                 } else {
504                         resp_grp = st_node_resp_500;
505                         resp_str = st_str_resp_500;
506                 }
507
508                 tick_stat_node(st, resp_str, st_node_responses, FALSE);
509
510                 g_snprintf(str, sizeof(str), "%u %s", i,
511                            val_to_str(i, vals_status_code, "Unknown (%d)"));
512                 tick_stat_node(st, str, resp_grp, FALSE);
513         } else if (v->request_method) {
514                 stats_tree_tick_pivot(st,st_node_requests,v->request_method);
515         } else {
516                 tick_stat_node(st, st_str_other, st_node_packets, FALSE);
517         }
518
519         return 1;
520 }
521
522 static void
523 dissect_http_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
524                      const char *line)
525 {
526         tvbuff_t *ntlmssp_tvb;
527
528         ntlmssp_tvb = base64_to_tvb(tvb, line);
529         add_new_data_source(pinfo, ntlmssp_tvb, "NTLMSSP / GSSAPI Data");
530         if (tvb_strneql(ntlmssp_tvb, 0, "NTLMSSP", 7) == 0)
531                 call_dissector(ntlmssp_handle, ntlmssp_tvb, pinfo, tree);
532         else
533                 call_dissector(gssapi_handle, ntlmssp_tvb, pinfo, tree);
534 }
535
536 static void
537 dissect_http_kerberos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
538                      const char *line)
539 {
540         tvbuff_t *kerberos_tvb;
541
542         kerberos_tvb = base64_to_tvb(tvb, line + 9); /* skip 'Kerberos ' which is 9 chars */
543         add_new_data_source(pinfo, kerberos_tvb, "Kerberos Data");
544         call_dissector(gssapi_handle, kerberos_tvb, pinfo, tree);
545
546 }
547
548
549 static http_conv_t *
550 get_http_conversation_data(packet_info *pinfo)
551 {
552         conversation_t  *conversation;
553         http_conv_t     *conv_data;
554
555         conversation = find_or_create_conversation(pinfo);
556
557         /* Retrieve information from conversation
558          * or add it if it isn't there yet
559          */
560         conv_data = conversation_get_proto_data(conversation, proto_http);
561         if(!conv_data) {
562                 /* Setup the conversation structure itself */
563                 conv_data = se_alloc0(sizeof(http_conv_t));
564
565                 conversation_add_proto_data(conversation, proto_http,
566                                             conv_data);
567         }
568
569         return conv_data;
570 }
571
572 /*
573  * TODO: remove this ugly global variable.
574  * XXX: do we really want to have to pass this from one function to another?
575  */
576 static http_info_value_t        *stat_info;
577
578 static int
579 dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
580                      proto_tree *tree, http_conv_t *conv_data)
581 {
582         const char      *proto_tag;
583         proto_tree      *http_tree = NULL;
584         proto_item      *ti = NULL;
585         proto_item      *hidden_item;
586         const guchar    *line;
587         gint            next_offset;
588         const guchar    *linep, *lineend;
589         int             orig_offset;
590         int             first_linelen, linelen;
591         gboolean        is_request_or_reply;
592         gboolean        saw_req_resp_or_header;
593         guchar          c;
594         http_type_t     http_type;
595         proto_item      *hdr_item = NULL;
596         ReqRespDissector reqresp_dissector;
597         proto_tree      *req_tree;
598         int             colon_offset;
599         headers_t       headers;
600         int             datalen;
601         int             reported_datalen = -1;
602         dissector_handle_t handle;
603         gboolean        dissected = FALSE;
604         /*guint         i;*/
605         /*http_info_value_t *si;*/
606         http_eo_t       *eo_info;
607
608         /*
609          * Is this a request or response?
610          *
611          * Note that "tvb_find_line_end()" will return a value that
612          * is not longer than what's in the buffer, so the
613          * "tvb_get_ptr()" call won't throw an exception.
614          */
615         first_linelen = tvb_find_line_end(tvb, offset,
616             tvb_ensure_length_remaining(tvb, offset), &next_offset,
617             FALSE);
618         /*
619          * Is the first line a request or response?
620          */
621         line = tvb_get_ptr(tvb, offset, first_linelen);
622         http_type = HTTP_OTHERS;        /* type not known yet */
623         is_request_or_reply = is_http_request_or_reply((const gchar *)line,
624             first_linelen, &http_type, NULL, conv_data);
625         if (is_request_or_reply) {
626                 /*
627                  * Yes, it's a request or response.
628                  * Do header desegmentation if we've been told to,
629                  * and do body desegmentation if we've been told to and
630                  * we find a Content-Length header.
631                  */
632                 if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
633                     http_desegment_headers, http_desegment_body)) {
634                         /*
635                          * More data needed for desegmentation.
636                          */
637                         return -1;
638                 }
639         }
640
641         stat_info = ep_alloc(sizeof(http_info_value_t));
642         stat_info->framenum = pinfo->fd->num;
643         stat_info->response_code = 0;
644         stat_info->request_method = NULL;
645         stat_info->request_uri = NULL;
646         stat_info->http_host = NULL;
647
648         switch (pinfo->match_uint) {
649
650         case TCP_PORT_SSDP:     /* TCP_PORT_SSDP = UDP_PORT_SSDP */
651                 proto_tag = "SSDP";
652                 break;
653
654         case TCP_PORT_DAAP:
655                 proto_tag = "DAAP";
656                 break;
657
658         default:
659                 proto_tag = "HTTP";
660                 break;
661         }
662
663         if (check_col(pinfo->cinfo, COL_PROTOCOL))
664                 col_set_str(pinfo->cinfo, COL_PROTOCOL, proto_tag);
665         if (check_col(pinfo->cinfo, COL_INFO)) {
666                 /*
667                  * Put the first line from the buffer into the summary
668                  * if it's an HTTP request or reply (but leave out the
669                  * line terminator).
670                  * Otherwise, just call it a continuation.
671                  *
672                  * Note that "tvb_find_line_end()" will return a value that
673                  * is not longer than what's in the buffer, so the
674                  * "tvb_get_ptr()" call won't throw an exception.
675                  */
676                 if (is_request_or_reply) {
677                     line = tvb_get_ptr(tvb, offset, first_linelen);
678                         col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", format_text(line, first_linelen));
679                 }
680                 else
681                         col_set_str(pinfo->cinfo, COL_INFO, "Continuation or non-HTTP traffic");
682         }
683
684         orig_offset = offset;
685         if (tree) {
686                 ti = proto_tree_add_item(tree, proto_http, tvb, offset, -1,
687                     FALSE);
688                 http_tree = proto_item_add_subtree(ti, ett_http);
689         }
690
691         /*
692          * Process the packet data, a line at a time.
693          */
694         http_type = HTTP_OTHERS;        /* type not known yet */
695         headers.content_type = NULL;    /* content type not known yet */
696         headers.content_type_parameters = NULL; /* content type parameters too */
697         headers.have_content_length = FALSE;    /* content length not known yet */
698         headers.content_length = 0;             /* content length set to 0 (avoid a gcc warning) */
699         headers.content_encoding = NULL; /* content encoding not known yet */
700         headers.transfer_encoding = NULL; /* transfer encoding not known yet */
701         saw_req_resp_or_header = FALSE; /* haven't seen anything yet */
702         while (tvb_reported_length_remaining(tvb, offset) != 0) {
703                 /*
704                  * Find the end of the line.
705                  * XXX - what if we don't find it because the packet
706                  * is cut short by a snapshot length or the header is
707                  * split across TCP segments?  How much dissection should
708                  * we do on it?
709                  */
710                 linelen = tvb_find_line_end(tvb, offset,
711                     tvb_ensure_length_remaining(tvb, offset), &next_offset,
712                     FALSE);
713                 if (linelen < 0)
714                         return -1;
715
716                 /*
717                  * Get a buffer that refers to the line.
718                  */
719                 line = tvb_get_ptr(tvb, offset, linelen);
720                 lineend = line + linelen;
721                 colon_offset = -1;
722
723                 /*
724                  * OK, does it look like an HTTP request or response?
725                  */
726                 reqresp_dissector = NULL;
727                 is_request_or_reply =
728                     is_http_request_or_reply((const gchar *)line,
729                     linelen, &http_type, &reqresp_dissector, conv_data);
730                 if (is_request_or_reply)
731                         goto is_http;
732
733                 /*
734                  * No.  Does it look like a blank line (as would appear
735                  * at the end of an HTTP request)?
736                  */
737                 if (linelen == 0)
738                         goto is_http;   /* Yes. */
739
740                 /*
741                  * No.  Does it look like a header?
742                  */
743                 linep = line;
744                 colon_offset = offset;
745                 while (linep < lineend) {
746                         c = *linep++;
747
748                         /*
749                          * This must be a CHAR to be part of a token; that
750                          * means it must be ASCII.
751                          */
752                         if (!isascii(c))
753                                 break;  /* not ASCII, thus not a CHAR */
754
755                         /*
756                          * This mustn't be a CTL to be part of a token.
757                          *
758                          * XXX - what about leading LWS on continuation
759                          * lines of a header?
760                          */
761                         if (iscntrl(c))
762                                 break;  /* CTL, not part of a header */
763
764                         /*
765                          * This mustn't be a SEP to be part of a token;
766                          * a ':' ends the token, everything else is an
767                          * indication that this isn't a header.
768                          */
769                         switch (c) {
770
771                         case '(':
772                         case ')':
773                         case '<':
774                         case '>':
775                         case '@':
776                         case ',':
777                         case ';':
778                         case '\\':
779                         case '"':
780                         case '/':
781                         case '[':
782                         case ']':
783                         case '?':
784                         case '=':
785                         case '{':
786                         case '}':
787                         case ' ':
788                                 /*
789                                  * It's a separator, so it's not part of a
790                                  * token, so it's not a field name for the
791                                  * beginning of a header.
792                                  *
793                                  * (We don't have to check for HT; that's
794                                  * already been ruled out by "iscntrl()".)
795                                  */
796                                 goto not_http;
797
798                         case ':':
799                                 /*
800                                  * This ends the token; we consider this
801                                  * to be a header.
802                                  */
803                                 goto is_http;
804
805                         default:
806                                 colon_offset++;
807                                 break;
808                         }
809                 }
810
811                 /*
812                  * We haven't seen the colon, but everything else looks
813                  * OK for a header line.
814                  *
815                  * If we've already seen an HTTP request or response
816                  * line, or a header line, and we're at the end of
817                  * the tvbuff, we assume this is an incomplete header
818                  * line.  (We quit this loop after seeing a blank line,
819                  * so if we've seen a request or response line, or a
820                  * header line, this is probably more of the request
821                  * or response we're presumably seeing.  There is some
822                  * risk of false positives, but the same applies for
823                  * full request or response lines or header lines,
824                  * although that's less likely.)
825                  *
826                  * We throw an exception in that case, by checking for
827                  * the existence of the next byte after the last one
828                  * in the line.  If it exists, "tvb_ensure_bytes_exist()"
829                  * throws no exception, and we fall through to the
830                  * "not HTTP" case.  If it doesn't exist,
831                  * "tvb_ensure_bytes_exist()" will throw the appropriate
832                  * exception.
833                  */
834                 if (saw_req_resp_or_header)
835                         tvb_ensure_bytes_exist(tvb, offset, linelen + 1);
836
837         not_http:
838                 /*
839                  * We don't consider this part of an HTTP request or
840                  * reply, so we don't display it.
841                  * (Yeah, that means we don't display, say, a text/http
842                  * page, but you can get that from the data pane.)
843                  */
844                 break;
845
846         is_http:
847                 /*
848                  * Process this line.
849                  */
850                 if (linelen == 0) {
851                         /*
852                          * This is a blank line, which means that
853                          * whatever follows it isn't part of this
854                          * request or reply.
855                          */
856                         proto_tree_add_text(http_tree, tvb, offset,
857                             next_offset - offset, "%s",
858                             tvb_format_text(tvb, offset, next_offset - offset));
859                         offset = next_offset;
860                         break;
861                 }
862
863                 /*
864                  * Not a blank line - either a request, a reply, or a header
865                  * line.
866                  */
867                 saw_req_resp_or_header = TRUE;
868                 if (is_request_or_reply) {
869                         char *text = tvb_format_text(tvb, offset, next_offset - offset);
870                         if (tree) {
871                                 hdr_item = proto_tree_add_text(http_tree, tvb,
872                                     offset, next_offset - offset, "%s", text);
873                         }
874                         expert_add_info_format(pinfo, hdr_item, PI_SEQUENCE, PI_CHAT, "%s", text);
875                         if (reqresp_dissector) {
876                                 if (tree) req_tree = proto_item_add_subtree(hdr_item, ett_http_request);
877                                 else req_tree = NULL;
878
879                                 reqresp_dissector(tvb, req_tree, offset, line,
880                                                   lineend, conv_data);
881                         }
882
883                 } else {
884                         /*
885                          * Header.
886                          */
887                         process_header(tvb, offset, next_offset, line, linelen,
888                             colon_offset, pinfo, http_tree, &headers, conv_data);
889                 }
890                 offset = next_offset;
891         }
892
893         if (tree && stat_info->http_host && stat_info->request_uri) {
894                 proto_item *e_ti;
895                 size_t size = strlen("http://") + strlen(stat_info->http_host)
896                             + strlen(stat_info->request_uri) + 1;
897                 char *uri = ep_alloc(size);
898
899                 g_snprintf(uri, (gulong)size, "%s://%s%s",
900                            "http",      /* XXX, https? */
901                             stat_info->http_host, stat_info->request_uri);
902
903                 e_ti = proto_tree_add_string(http_tree,
904                                              hf_http_request_full_uri, tvb, 0,
905                                              0, uri);
906
907                 PROTO_ITEM_SET_URL(e_ti);
908                 PROTO_ITEM_SET_GENERATED(e_ti);
909         }
910
911         if (tree) {
912                 switch (http_type) {
913
914                 case HTTP_NOTIFICATION:
915                         hidden_item = proto_tree_add_boolean(http_tree,
916                                             hf_http_notification, tvb, 0, 0, 1);
917                         PROTO_ITEM_SET_HIDDEN(hidden_item);
918                         break;
919
920                 case HTTP_RESPONSE:
921                         hidden_item = proto_tree_add_boolean(http_tree,
922                                             hf_http_response, tvb, 0, 0, 1);
923                         PROTO_ITEM_SET_HIDDEN(hidden_item);
924                         break;
925
926                 case HTTP_REQUEST:
927                         hidden_item = proto_tree_add_boolean(http_tree,
928                                             hf_http_request, tvb, 0, 0, 1);
929                         PROTO_ITEM_SET_HIDDEN(hidden_item);
930                         break;
931
932                 case HTTP_OTHERS:
933                 default:
934                         break;
935                 }
936         }
937
938         /*
939          * If a content length was supplied, the amount of data to be
940          * processed as HTTP payload is the minimum of the content
941          * length and the amount of data remaining in the frame.
942          *
943          * If no content length was supplied (or if a bad content length
944          * was supplied), the amount of data to be processed is the amount
945          * of data remaining in the frame.
946          *
947          * If there was no Content-Length entity header, we should
948          * accumulate all data until the end of the connection.
949          * That'd require that the TCP dissector call subdissectors
950          * for all frames with FIN, even if they contain no data,
951          * which would require subdissectors to deal intelligently
952          * with empty segments.
953          *
954          * Acccording to RFC 2616, however, 1xx responses, 204 responses,
955          * and 304 responses MUST NOT include a message body; if no
956          * content length is specified for them, we don't attempt to
957          * dissect the body.
958          *
959          * XXX - it says the same about responses to HEAD requests;
960          * unless there's a way to determine from the response
961          * whether it's a response to a HEAD request, we have to
962          * keep information about the request and associate that with
963          * the response in order to handle that.
964          */
965         datalen = tvb_length_remaining(tvb, offset);
966         if (headers.have_content_length && headers.content_length != -1) {
967                 if (datalen > headers.content_length)
968                         datalen = (int)headers.content_length;
969
970                 /*
971                  * XXX - limit the reported length in the tvbuff we'll
972                  * hand to a subdissector to be no greater than the
973                  * content length.
974                  *
975                  * We really need both unreassembled and "how long it'd
976                  * be if it were reassembled" lengths for tvbuffs, so
977                  * that we throw the appropriate exceptions for
978                  * "not enough data captured" (running past the length),
979                  * "packet needed reassembly" (within the length but
980                  * running past the unreassembled length), and
981                  * "packet is malformed" (running past the reassembled
982                  * length).
983                  */
984                 reported_datalen = tvb_reported_length_remaining(tvb, offset);
985                 if (reported_datalen > headers.content_length)
986                         reported_datalen = (int)headers.content_length;
987         } else {
988                 switch (http_type) {
989
990                 case HTTP_REQUEST:
991                         /*
992                          * Requests have no content if there's no
993                          * Content-Length header and no Transfer-Encoding
994                          * header.
995                          */
996                         if (headers.transfer_encoding == NULL)
997                                 datalen = 0;
998                         else
999                                 reported_datalen = -1;
1000                         break;
1001
1002                 case HTTP_RESPONSE:
1003                         if ((stat_info->response_code/100) == 1 ||
1004                             stat_info->response_code == 204 ||
1005                             stat_info->response_code == 304)
1006                                 datalen = 0;    /* no content! */
1007                         else {
1008                                 /*
1009                                  * XXX - responses to HEAD requests,
1010                                  * and possibly other responses,
1011                                  * "MUST NOT" include a
1012                                  * message-body.
1013                                  */
1014                                 reported_datalen = -1;
1015                         }
1016                         break;
1017
1018                 default:
1019                         /*
1020                          * XXX - what about HTTP_NOTIFICATION?
1021                          */
1022                         reported_datalen = -1;
1023                         break;
1024                 }
1025         }
1026
1027         if (datalen > 0) {
1028                 /*
1029                  * There's stuff left over; process it.
1030                  */
1031                 tvbuff_t *next_tvb;
1032                 void *save_private_data = NULL;
1033                 gboolean private_data_changed = FALSE;
1034                 gint chunks_decoded = 0;
1035
1036                 /*
1037                  * Create a tvbuff for the payload.
1038                  *
1039                  * The amount of data to be processed that's
1040                  * available in the tvbuff is "datalen", which
1041                  * is the minimum of the amount of data left in
1042                  * the tvbuff and any specified content length.
1043                  *
1044                  * The amount of data to be processed that's in
1045                  * this frame, regardless of whether it was
1046                  * captured or not, is "reported_datalen",
1047                  * which, if no content length was specified,
1048                  * is -1, i.e. "to the end of the frame.
1049                  */
1050                 next_tvb = tvb_new_subset(tvb, offset, datalen,
1051                     reported_datalen);
1052                 /*
1053                  * BEWARE - next_tvb is a subset of another tvb,
1054                  * so we MUST NOT attempt tvb_free(next_tvb);
1055                  */
1056
1057                 /*
1058                  * Handle *transfer* encodings other than "identity".
1059                  */
1060                 if (headers.transfer_encoding != NULL &&
1061                     g_ascii_strcasecmp(headers.transfer_encoding, "identity") != 0) {
1062                         if (http_dechunk_body &&
1063                             (g_ascii_strncasecmp(headers.transfer_encoding, "chunked", 7)
1064                             == 0)) {
1065
1066                                 chunks_decoded = chunked_encoding_dissector(
1067                                     &next_tvb, pinfo, http_tree, 0);
1068
1069                                 if (chunks_decoded <= 0) {
1070                                         /*
1071                                          * The chunks weren't reassembled,
1072                                          * or there was a single zero
1073                                          * length chunk.
1074                                          */
1075                                         goto body_dissected;
1076                                 } else {
1077                                         /*
1078                                          * Add a new data source for the
1079                                          * de-chunked data.
1080                                          */
1081                                         tvb_set_child_real_data_tvbuff(tvb,
1082                                                 next_tvb);
1083                                         add_new_data_source(pinfo, next_tvb,
1084                                                 "De-chunked entity body");
1085                                 }
1086                         } else {
1087                                 /*
1088                                  * We currently can't handle, for example,
1089                                  * "gzip", "compress", or "deflate" as
1090                                  * *transfer* encodings; just handle them
1091                                  * as data for now.
1092                                  */
1093                                 call_dissector(data_handle, next_tvb, pinfo,
1094                                     http_tree);
1095                                 goto body_dissected;
1096                         }
1097                 }
1098                 /*
1099                  * At this point, any chunked *transfer* coding has been removed
1100                  * (the entity body has been dechunked) so it can be presented
1101                  * for the following operation (*content* encoding), or it has
1102                  * been been handed off to the data dissector.
1103                  *
1104                  * Handle *content* encodings other than "identity" (which
1105                  * shouldn't appear in a Content-Encoding header, but
1106                  * we handle it in any case).
1107                  */
1108                 if (headers.content_encoding != NULL &&
1109                     g_ascii_strcasecmp(headers.content_encoding, "identity") != 0) {
1110                         /*
1111                          * We currently can't handle, for example, "compress";
1112                          * just handle them as data for now.
1113                          *
1114                          * After July 7, 2004 the LZW patent expires, so support
1115                          * might be added then.  However, I don't think that
1116                          * anybody ever really implemented "compress", due to
1117                          * the aforementioned patent.
1118                          */
1119                         tvbuff_t *uncomp_tvb = NULL;
1120                         proto_item *e_ti = NULL;
1121                         proto_tree *e_tree = NULL;
1122
1123                         if (http_decompress_body &&
1124                             (g_ascii_strcasecmp(headers.content_encoding, "gzip") == 0 ||
1125                              g_ascii_strcasecmp(headers.content_encoding, "deflate") == 0 ||
1126                              g_ascii_strcasecmp(headers.content_encoding, "x-gzip") == 0 ||
1127                              g_ascii_strcasecmp(headers.content_encoding, "x-deflate") == 0))
1128                         {
1129                                 uncomp_tvb = tvb_child_uncompress(tvb, next_tvb, 0,
1130                                     tvb_length(next_tvb));
1131                         }
1132
1133                         /*
1134                          * Add the encoded entity to the protocol tree
1135                          */
1136                         e_ti = proto_tree_add_text(http_tree, next_tvb,
1137                                         0, tvb_length(next_tvb),
1138                                         "Content-encoded entity body (%s): %u bytes",
1139                                         headers.content_encoding,
1140                                         tvb_length(next_tvb));
1141                         e_tree = proto_item_add_subtree(e_ti,
1142                                         ett_http_encoded_entity);
1143
1144                         if (uncomp_tvb != NULL) {
1145                                 /*
1146                                  * Decompression worked
1147                                  */
1148
1149                                 /* XXX - Don't free this, since it's possible
1150                                  * that the data was only partially
1151                                  * decompressed, such as when desegmentation
1152                                  * isn't enabled.
1153                                  *
1154                                 tvb_free(next_tvb);
1155                                 */
1156                                 proto_item_append_text(e_ti, " -> %u bytes", tvb_length(uncomp_tvb));
1157                                 next_tvb = uncomp_tvb;
1158                                 add_new_data_source(pinfo, next_tvb,
1159                                     "Uncompressed entity body");
1160                         } else {
1161                                 proto_item_append_text(e_ti, " [Error: Decompression failed]");
1162                                 call_dissector(data_handle, next_tvb, pinfo,
1163                                     e_tree);
1164
1165                                 goto body_dissected;
1166                         }
1167                 }
1168                 /*
1169                  * Note that a new data source is added for the entity body
1170                  * only if it was content-encoded and/or transfer-encoded.
1171                  */
1172
1173                 /* Save values for the Export Object GUI feature if we have
1174                  * an active listener to process it (which happens when
1175                  * the export object window is open). */
1176                 if(have_tap_listener(http_eo_tap)) {
1177                         eo_info = ep_alloc(sizeof(http_eo_t));
1178
1179                         eo_info->hostname = conv_data->http_host;
1180                         eo_info->filename = conv_data->request_uri;
1181                         eo_info->content_type = headers.content_type;
1182                         eo_info->payload_len = tvb_length(next_tvb);
1183                         eo_info->payload_data = tvb_get_ptr(next_tvb, 0, eo_info->payload_len);
1184
1185                         tap_queue_packet(http_eo_tap, pinfo, eo_info);
1186                 }
1187
1188                 /*
1189                  * Do subdissector checks.
1190                  *
1191                  * First, check whether some subdissector asked that they
1192                  * be called if something was on some particular port.
1193                  */
1194
1195                 handle = dissector_get_uint_handle(port_subdissector_table,
1196                     pinfo->match_uint);
1197                 if (handle == NULL && headers.content_type != NULL) {
1198                         /*
1199                          * We didn't find any subdissector that
1200                          * registered for the port, and we have a
1201                          * Content-Type value.  Is there any subdissector
1202                          * for that content type?
1203                          */
1204                         save_private_data = pinfo->private_data;
1205                         private_data_changed = TRUE;
1206
1207                         if (headers.content_type_parameters)
1208                                 pinfo->private_data = ep_strdup(headers.content_type_parameters);
1209                         else
1210                                 pinfo->private_data = NULL;
1211                         /*
1212                          * Calling the string handle for the media type
1213                          * dissector table will set pinfo->match_string
1214                          * to headers.content_type for us.
1215                          */
1216                         pinfo->match_string = headers.content_type;
1217                         handle = dissector_get_string_handle(
1218                             media_type_subdissector_table,
1219                             headers.content_type);
1220                         if (handle == NULL &&
1221                             !strncmp(headers.content_type, "multipart/", sizeof("multipart/")-1)) {
1222                                 /* Try to decode the unknown multipart subtype anyway */
1223                                 handle = dissector_get_string_handle(
1224                                     media_type_subdissector_table,
1225                                     "multipart/");
1226                         }
1227                 }
1228
1229                 if (handle != NULL) {
1230                         /*
1231                          * We have a subdissector - call it.
1232                          */
1233                         dissected = call_dissector_only(handle, next_tvb, pinfo, tree);
1234                         if (!dissected)
1235                                 expert_add_info_format(pinfo, http_tree, PI_MALFORMED, PI_NOTE,
1236                                                        "HTTP body subdissector failed, trying heuristic subdissector");
1237                 }
1238
1239                 if (!dissected) {
1240                         /*
1241                          * We don't have a subdissector or we have one and it did not
1242                          * dissect the payload - try the heuristic subdissectors.
1243                          */
1244                         dissected = dissector_try_heuristic(heur_subdissector_list,
1245                                                             next_tvb, pinfo, tree);
1246                 }
1247
1248                 if (dissected) {
1249                         /*
1250                          * The subdissector dissected the body.
1251                          * Fix up the top-level item so that it doesn't
1252                          * include the stuff for that protocol.
1253                          */
1254                         if (ti != NULL)
1255                                 proto_item_set_len(ti, offset);
1256                 } else {
1257                         if (headers.content_type != NULL) {
1258                                 /*
1259                                  * Calling the default media handle if there is a content-type that
1260                                  * wasn't handled above.
1261                                  */
1262                                 call_dissector(media_handle, next_tvb, pinfo, tree);
1263                         } else {
1264                                 /* Call the default data dissector */
1265                                 call_dissector(data_handle, next_tvb, pinfo, http_tree);
1266                         }
1267                 }
1268
1269         body_dissected:
1270                 /*
1271                  * Do *not* attempt at freeing the private data;
1272                  * it may be in use by subdissectors.
1273                  */
1274                 if (private_data_changed) /*restore even NULL value*/
1275                         pinfo->private_data = save_private_data;
1276                 /*
1277                  * We've processed "datalen" bytes worth of data
1278                  * (which may be no data at all); advance the
1279                  * offset past whatever data we've processed.
1280                  */
1281                 offset += datalen;
1282         }
1283
1284         tap_queue_packet(http_tap, pinfo, stat_info);
1285
1286         return offset - orig_offset;
1287 }
1288
1289 /* This can be used to dissect an HTTP request until such time
1290  * that a more complete dissector is written for that HTTP request.
1291  * This simple dissector only puts the request method, URI, and
1292  * protocol version into a sub-tree.
1293  */
1294 static void
1295 basic_request_dissector(tvbuff_t *tvb, proto_tree *tree, int offset,
1296                         const guchar *line, const guchar *lineend,
1297                         http_conv_t *conv_data)
1298 {
1299         const guchar *next_token;
1300         gchar *request_uri;
1301         int tokenlen;
1302
1303         /* The first token is the method. */
1304         tokenlen = get_token_len(line, lineend, &next_token);
1305         if (tokenlen == 0)
1306                 return;
1307         proto_tree_add_item(tree, hf_http_request_method, tvb, offset, tokenlen,
1308                             FALSE);
1309         if ((next_token - line) > 2 && next_token[-1] == ' ' && next_token[-2] == ' ') {
1310           /* Two spaces in a now indicates empty URI, so roll back one here */
1311           next_token--;
1312         }
1313         offset += (int) (next_token - line);
1314         line = next_token;
1315
1316         /* The next token is the URI. */
1317         tokenlen = get_token_len(line, lineend, &next_token);
1318
1319         /* Save the request URI for various later uses */
1320         request_uri = (gchar *)tvb_get_ephemeral_string(tvb, offset, tokenlen);
1321         stat_info->request_uri = ep_strdup(request_uri);
1322         conv_data->request_uri = se_strdup(request_uri);
1323
1324         proto_tree_add_string(tree, hf_http_request_uri, tvb, offset, tokenlen,
1325                               request_uri);
1326         offset += (int) (next_token - line);
1327         line = next_token;
1328
1329         /* Everything to the end of the line is the version. */
1330         tokenlen = (int) (lineend - line);
1331         proto_tree_add_item(tree, hf_http_version, tvb, offset, tokenlen,
1332             FALSE);
1333 }
1334
1335 static void
1336 basic_response_dissector(tvbuff_t *tvb, proto_tree *tree, int offset,
1337                          const guchar *line, const guchar *lineend,
1338                          http_conv_t *conv_data _U_)
1339 {
1340         const guchar *next_token;
1341         int tokenlen;
1342         gchar response_code_chars[4];
1343
1344         /*
1345          * The first token is the HTTP Version.
1346          */
1347         tokenlen = get_token_len(line, lineend, &next_token);
1348         if (tokenlen == 0)
1349                 return;
1350         proto_tree_add_item(tree, hf_http_version, tvb, offset, tokenlen,
1351                             FALSE);
1352         /* Advance to the start of the next token. */
1353         offset += (int) (next_token - line);
1354         line = next_token;
1355
1356         /*
1357          * The second token is the Status Code.
1358          */
1359         tokenlen = get_token_len(line, lineend, &next_token);
1360         if (tokenlen < 3)
1361                 return;
1362
1363         /* The Status Code characters must be copied into a null-terminated
1364          * buffer for strtoul() to parse them into an unsigned integer value.
1365          */
1366         memcpy(response_code_chars, line, 3);
1367         response_code_chars[3] = '\0';
1368
1369         stat_info->response_code = conv_data->response_code =
1370                 strtoul(response_code_chars, NULL, 10);
1371
1372         proto_tree_add_uint(tree, hf_http_response_code, tvb, offset, 3,
1373                             stat_info->response_code);
1374
1375         /* Advance to the start of the next token. */
1376         offset += (int) (next_token - line);
1377         line = next_token;
1378
1379         /*
1380          * The remaining tokens in the line comprise the Reason Phrase.
1381          */
1382         tokenlen = (int) (lineend - line);
1383         if (tokenlen < 1)
1384                 return;
1385         proto_tree_add_item(tree, hf_http_response_phrase, tvb, offset,
1386                                 tokenlen, FALSE);
1387
1388 }
1389
1390 /*
1391  * Dissect the http data chunks and add them to the tree.
1392  */
1393 static int
1394 chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
1395                            proto_tree *tree, int offset)
1396 {
1397         guint8 *chunk_string = NULL;
1398         guint32 chunk_size = 0;
1399         gint chunk_offset = 0;
1400         guint32 datalen = 0;
1401         gint linelen = 0;
1402         gint chunks_decoded = 0;
1403         tvbuff_t *tvb = NULL;
1404         tvbuff_t *new_tvb = NULL;
1405         gint chunked_data_size = 0;
1406         proto_tree *subtree = NULL;
1407         proto_item *ti = NULL;
1408
1409         if (tvb_ptr == NULL || *tvb_ptr == NULL) {
1410                 return 0;
1411         }
1412
1413         tvb = *tvb_ptr;
1414
1415         datalen = tvb_reported_length_remaining(tvb, offset);
1416
1417         if (tree) {
1418                 ti = proto_tree_add_text(tree, tvb, offset, datalen,
1419                                          "HTTP chunked response");
1420                 subtree = proto_item_add_subtree(ti, ett_http_chunked_response);
1421         }
1422
1423
1424         while (datalen != 0) {
1425                 proto_item *chunk_ti = NULL;
1426                 proto_tree *chunk_subtree = NULL;
1427                 tvbuff_t *data_tvb = NULL;
1428                 gchar *c = NULL;
1429                 guint8 *raw_data;
1430                 gint raw_len = 0;
1431
1432                 linelen = tvb_find_line_end(tvb, offset, -1, &chunk_offset, TRUE);
1433
1434                 if (linelen <= 0) {
1435                         /* Can't get the chunk size line */
1436                         break;
1437                 }
1438
1439                 chunk_string = tvb_get_ephemeral_string(tvb, offset, linelen);
1440
1441                 if (chunk_string == NULL) {
1442                         /* Can't get the chunk size line */
1443                         break;
1444                 }
1445
1446                 c = (gchar*) chunk_string;
1447
1448                 /*
1449                  * We don't care about the extensions.
1450                  */
1451                 if ((c = strchr(c, ';'))) {
1452                         *c = '\0';
1453                 }
1454
1455                 chunk_size = strtol((gchar*)chunk_string, NULL, 16);
1456
1457                 if (chunk_size > datalen) {
1458                         /*
1459                          * The chunk size is more than what's in the tvbuff,
1460                          * so either the user hasn't enabled decoding, or all
1461                          * of the segments weren't captured.
1462                          */
1463                         chunk_size = datalen;
1464                 }
1465 #if 0
1466                   else if (new_tvb == NULL) {
1467                         new_tvb = tvb_new_composite();
1468                 }
1469
1470
1471
1472                 if (new_tvb != NULL && chunk_size != 0) {
1473                         tvbuff_t *chunk_tvb = NULL;
1474
1475                         chunk_tvb = tvb_new_subset(tvb, chunk_offset,
1476                             chunk_size, datalen);
1477
1478                         tvb_composite_append(new_tvb, chunk_tvb);
1479
1480                 }
1481 #endif
1482
1483                 chunked_data_size += chunk_size;
1484
1485                 raw_data = g_malloc(chunked_data_size);
1486                 raw_len = 0;
1487
1488                 if (new_tvb != NULL) {
1489                         raw_len = tvb_length_remaining(new_tvb, 0);
1490                         tvb_memcpy(new_tvb, raw_data, 0, raw_len);
1491
1492                         tvb_free(new_tvb);
1493                 }
1494
1495                 tvb_memcpy(tvb, (guint8 *)(raw_data + raw_len),
1496                             chunk_offset, chunk_size);
1497
1498                 /* Don't create a new tvb if we have a single chunk with
1499                  * a size of zero (meaning it is the end of the chunks). */
1500                 if(chunked_data_size > 0) {
1501                         new_tvb = tvb_new_real_data(raw_data,
1502                               chunked_data_size, chunked_data_size);
1503                         tvb_set_free_cb(new_tvb, g_free);
1504                 }
1505
1506
1507                 if (subtree) {
1508                         if(chunk_size == 0) {
1509                                 chunk_ti = proto_tree_add_text(subtree, tvb,
1510                                             offset,
1511                                             chunk_offset - offset + chunk_size + 2,
1512                                             "End of chunked encoding");
1513                         } else {
1514                                 chunk_ti = proto_tree_add_text(subtree, tvb,
1515                                             offset,
1516                                             chunk_offset - offset + chunk_size + 2,
1517                                             "Data chunk (%u octets)", chunk_size);
1518                         }
1519
1520                         chunk_subtree = proto_item_add_subtree(chunk_ti,
1521                             ett_http_chunk_data);
1522
1523                         proto_tree_add_text(chunk_subtree, tvb, offset,
1524                             chunk_offset - offset, "Chunk size: %u octets",
1525                             chunk_size);
1526
1527                         data_tvb = tvb_new_subset(tvb, chunk_offset, chunk_size,
1528                             datalen);
1529
1530
1531                         /*
1532                          * XXX - just use "proto_tree_add_text()"?
1533                          * This means that, in TShark, you get
1534                          * the entire chunk dumped out in hex,
1535                          * in addition to whatever dissection is
1536                          * done on the reassembled data.
1537                          */
1538                         call_dissector(data_handle, data_tvb, pinfo,
1539                                     chunk_subtree);
1540
1541                         proto_tree_add_text(chunk_subtree, tvb, chunk_offset +
1542                             chunk_size, 2, "Chunk boundary");
1543                 }
1544
1545                 chunks_decoded++;
1546                 offset = chunk_offset + chunk_size + 2;
1547                 datalen = tvb_reported_length_remaining(tvb, offset);
1548         }
1549
1550         if (new_tvb != NULL) {
1551
1552                 /* Placeholder for the day that composite tvbuffer's will work.
1553                 tvb_composite_finalize(new_tvb);
1554                 / * tvb_set_reported_length(new_tvb, chunked_data_size); * /
1555                 */
1556
1557                 /*
1558                  * XXX - Don't free this, since the tvbuffer that was passed
1559                  * may be used if the data spans multiple frames and reassembly
1560                  * isn't enabled.
1561                  *
1562                 tvb_free(*tvb_ptr);
1563                  */
1564                 *tvb_ptr = new_tvb;
1565
1566         } else {
1567                 /*
1568                  * We didn't create a new tvb, so don't allow sub dissectors
1569                  * try to decode the non-existent entity body.
1570                  */
1571                 chunks_decoded = -1;
1572         }
1573
1574         return chunks_decoded;
1575
1576 }
1577
1578 /* Call a subdissector to handle HTTP CONNECT's traffic */
1579 static void
1580 http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
1581                           packet_info *pinfo, http_conv_t *conv_data)
1582 {
1583         guint32 *ptr = NULL;
1584         guint32 dissect_as, saved_port;
1585         gchar **strings; /* An array for splitting the request URI into hostname and port */
1586         proto_item *item;
1587         proto_tree *proxy_tree;
1588
1589         /* Grab the destination port number from the request URI to find the right subdissector */
1590         strings = g_strsplit(conv_data->request_uri, ":", 2);
1591
1592         if(strings[0] != NULL && strings[1] != NULL) {
1593                 /*
1594                  * The string was successfuly split in two
1595                  * Create a proxy-connect subtree
1596                  */
1597                 if(tree) {
1598                         item = proto_tree_add_item(tree, proto_http, tvb, 0, -1, FALSE);
1599                         proxy_tree = proto_item_add_subtree(item, ett_http);
1600
1601                         item = proto_tree_add_string(proxy_tree, hf_http_proxy_connect_host,
1602                                                      tvb, 0, 0, strings[0]);
1603                         PROTO_ITEM_SET_GENERATED(item);
1604
1605                         item = proto_tree_add_uint(proxy_tree, hf_http_proxy_connect_port,
1606                                                    tvb, 0, 0, strtol(strings[1], NULL, 10) );
1607                         PROTO_ITEM_SET_GENERATED(item);
1608                 }
1609
1610                 /* We're going to get stuck in a loop if we let process_tcp_payload call
1611                    us, so call the data dissector instead for proxy connections to http ports. */
1612                 dissect_as = (int)strtol(strings[1], NULL, 10); /* Convert string to a base-10 integer */
1613
1614                 if (value_is_in_range(http_tcp_range, dissect_as)) {
1615                         call_dissector(data_handle, tvb, pinfo, tree);
1616                 } else {
1617                         /* set pinfo->{src/dst port} and call the TCP sub-dissector lookup */
1618                         if ( !ptr && value_is_in_range(http_tcp_range, pinfo->destport) )
1619                                 ptr = &pinfo->destport;
1620                         else
1621                                 ptr = &pinfo->srcport;
1622
1623                         /* Increase pinfo->can_desegment because we are traversing
1624                          * http and want to preserve desegmentation functionality for
1625                          * the proxied protocol
1626                          */
1627                         if( pinfo->can_desegment>0 )
1628                                 pinfo->can_desegment++;
1629
1630                         saved_port = *ptr;
1631                         *ptr = dissect_as;
1632                         decode_tcp_ports(tvb, 0, pinfo, tree,
1633                                 pinfo->srcport, pinfo->destport, NULL);
1634                         *ptr = saved_port;
1635                 }
1636         }
1637         g_strfreev(strings); /* Free the result of g_strsplit() above */
1638 }
1639
1640
1641
1642 /*
1643  * XXX - this won't handle HTTP 0.9 replies, but they're all data
1644  * anyway.
1645  */
1646 static int
1647 is_http_request_or_reply(const gchar *data, int linelen, http_type_t *type,
1648                          ReqRespDissector *reqresp_dissector,
1649                          http_conv_t *conv_data)
1650 {
1651         int isHttpRequestOrReply = FALSE;
1652
1653         /*
1654          * From RFC 2774 - An HTTP Extension Framework
1655          *
1656          * Support the command prefix that identifies the presence of
1657          * a "mandatory" header.
1658          */
1659         if (linelen >= 2 && strncmp(data, "M-", 2) == 0) {
1660                 data += 2;
1661                 linelen -= 2;
1662         }
1663
1664         /*
1665          * From draft-cohen-gena-client-01.txt, available from the uPnP forum:
1666          *      NOTIFY, SUBSCRIBE, UNSUBSCRIBE
1667          *
1668          * From draft-ietf-dasl-protocol-00.txt, a now vanished Microsoft draft:
1669          *      SEARCH
1670          */
1671         if (linelen >= 5 && strncmp(data, "HTTP/", 5) == 0) {
1672                 *type = HTTP_RESPONSE;
1673                 isHttpRequestOrReply = TRUE;    /* response */
1674                 if (reqresp_dissector)
1675                         *reqresp_dissector = basic_response_dissector;
1676         } else {
1677                 const guchar * ptr = (const guchar *)data;
1678                 int              indx = 0;
1679
1680                 /* Look for the space following the Method */
1681                 while (indx < linelen) {
1682                         if (*ptr == ' ')
1683                                 break;
1684                         else {
1685                                 ptr++;
1686                                 indx++;
1687                         }
1688                 }
1689
1690                 /* Check the methods that have same length */
1691                 switch (indx) {
1692
1693                 case 3:
1694                         if (strncmp(data, "GET", indx) == 0 ||
1695                             strncmp(data, "PUT", indx) == 0) {
1696                                 *type = HTTP_REQUEST;
1697                                 isHttpRequestOrReply = TRUE;
1698                         }
1699                         else if (strncmp(data, "ICY", indx) == 0) {
1700                                 *type = HTTP_RESPONSE;
1701                                 isHttpRequestOrReply = TRUE;
1702                         }
1703                         break;
1704
1705                 case 4:
1706                         if (strncmp(data, "COPY", indx) == 0 ||
1707                             strncmp(data, "HEAD", indx) == 0 ||
1708                             strncmp(data, "LOCK", indx) == 0 ||
1709                             strncmp(data, "MOVE", indx) == 0 ||
1710                             strncmp(data, "POLL", indx) == 0 ||
1711                             strncmp(data, "POST", indx) == 0) {
1712                                 *type = HTTP_REQUEST;
1713                                 isHttpRequestOrReply = TRUE;
1714                         }
1715                         break;
1716
1717                 case 5:
1718                         if (strncmp(data, "BCOPY", indx) == 0 ||
1719                                 strncmp(data, "BMOVE", indx) == 0 ||
1720                                 strncmp(data, "MKCOL", indx) == 0 ||
1721                                 strncmp(data, "TRACE", indx) == 0 ||
1722                                 strncmp(data, "LABEL", indx) == 0 ||  /* RFC 3253 8.2 */
1723                                 strncmp(data, "MERGE", indx) == 0) {  /* RFC 3253 11.2 */
1724                                 *type = HTTP_REQUEST;
1725                                 isHttpRequestOrReply = TRUE;
1726                         }
1727                         break;
1728
1729                 case 6:
1730                         if (strncmp(data, "DELETE", indx) == 0 ||
1731                                 strncmp(data, "SEARCH", indx) == 0 ||
1732                                 strncmp(data, "UNLOCK", indx) == 0 ||
1733                                 strncmp(data, "REPORT", indx) == 0 ||  /* RFC 3253 3.6 */
1734                                 strncmp(data, "UPDATE", indx) == 0) {  /* RFC 3253 7.1 */
1735                                 *type = HTTP_REQUEST;
1736                                 isHttpRequestOrReply = TRUE;
1737                         }
1738                         else if (strncmp(data, "NOTIFY", indx) == 0) {
1739                                 *type = HTTP_NOTIFICATION;
1740                                 isHttpRequestOrReply = TRUE;
1741                         }
1742                         break;
1743
1744                 case 7:
1745                         if (strncmp(data, "BDELETE", indx) == 0 ||
1746                             strncmp(data, "CONNECT", indx) == 0 ||
1747                             strncmp(data, "OPTIONS", indx) == 0 ||
1748                             strncmp(data, "CHECKIN", indx) == 0) {  /* RFC 3253 4.4, 9.4 */
1749                                 *type = HTTP_REQUEST;
1750                                 isHttpRequestOrReply = TRUE;
1751                         }
1752                         break;
1753
1754                 case 8:
1755                         if (strncmp(data, "PROPFIND", indx) == 0 ||
1756                             strncmp(data, "CHECKOUT", indx) == 0 || /* RFC 3253 4.3, 9.3 */
1757                             strncmp(data, "CCM_POST", indx) == 0) {
1758                                 *type = HTTP_REQUEST;
1759                                 isHttpRequestOrReply = TRUE;
1760                         }
1761                         break;
1762
1763                 case 9:
1764                         if (strncmp(data, "SUBSCRIBE", indx) == 0) {
1765                                 *type = HTTP_NOTIFICATION;
1766                                 isHttpRequestOrReply = TRUE;
1767                         } else if (strncmp(data, "PROPPATCH", indx) == 0 ||
1768                             strncmp(data, "BPROPFIND", indx) == 0) {
1769                                 *type = HTTP_REQUEST;
1770                                 isHttpRequestOrReply = TRUE;
1771                         }
1772                         break;
1773
1774                 case 10:
1775                         if (strncmp(data, "BPROPPATCH", indx) == 0 ||
1776                                 strncmp(data, "UNCHECKOUT", indx) == 0 ||  /* RFC 3253 4.5 */
1777                                 strncmp(data, "MKACTIVITY", indx) == 0) {  /* RFC 3253 13.5 */
1778                                 *type = HTTP_REQUEST;
1779                                 isHttpRequestOrReply = TRUE;
1780                         }
1781                         break;
1782
1783                 case 11:
1784                         if (strncmp(data, "MKWORKSPACE", indx) == 0 || /* RFC 3253 6.3 */
1785                             strncmp(data, "RPC_CONNECT", indx) == 0 || /* [MS-RPCH] 2.1.1.1.1 */
1786                             strncmp(data, "RPC_IN_DATA", indx) == 0) { /* [MS-RPCH] 2.1.2.1.1 */
1787                                 *type = HTTP_REQUEST;
1788                                 isHttpRequestOrReply = TRUE;
1789                         } else if (strncmp(data, "UNSUBSCRIBE", indx) == 0) {
1790                                 *type = HTTP_NOTIFICATION;
1791                                 isHttpRequestOrReply = TRUE;
1792                         }
1793                         break;
1794
1795                 case 12:
1796                         if (strncmp(data, "RPC_OUT_DATA", indx) == 0) { /* [MS-RPCH] 2.1.2.1.2 */
1797                                 *type = HTTP_REQUEST;
1798                                 isHttpRequestOrReply = TRUE;
1799                         }
1800                         break;
1801
1802                 case 15:
1803                         if (strncmp(data, "VERSION-CONTROL", indx) == 0) {  /* RFC 3253 3.5 */
1804                                 *type = HTTP_REQUEST;
1805                                 isHttpRequestOrReply = TRUE;
1806                         }
1807                         break;
1808
1809                 case 16:
1810                         if (strncmp(data, "BASELINE-CONTROL", indx) == 0) {  /* RFC 3253 12.6 */
1811                                 *type = HTTP_REQUEST;
1812                                 isHttpRequestOrReply = TRUE;
1813                         }
1814                         break;
1815
1816                 default:
1817                         break;
1818                 }
1819
1820                 if (isHttpRequestOrReply && reqresp_dissector) {
1821                         *reqresp_dissector = basic_request_dissector;
1822
1823                         stat_info->request_method = ep_strndup(data, indx+1);
1824                         conv_data->request_method = se_strndup(data, indx+1);
1825                 }
1826
1827
1828
1829         }
1830
1831         return isHttpRequestOrReply;
1832 }
1833
1834 /*
1835  * Process headers.
1836  */
1837 typedef struct {
1838         const char      *name;
1839         gint            *hf;
1840         int             special;
1841 } header_info;
1842
1843 #define HDR_NO_SPECIAL          0
1844 #define HDR_AUTHORIZATION       1
1845 #define HDR_AUTHENTICATE        2
1846 #define HDR_CONTENT_TYPE        3
1847 #define HDR_CONTENT_LENGTH      4
1848 #define HDR_CONTENT_ENCODING    5
1849 #define HDR_TRANSFER_ENCODING   6
1850 #define HDR_HOST  7
1851
1852 static const header_info headers[] = {
1853         { "Authorization", &hf_http_authorization, HDR_AUTHORIZATION },
1854         { "Proxy-Authorization", &hf_http_proxy_authorization, HDR_AUTHORIZATION },
1855         { "Proxy-Authenticate", &hf_http_proxy_authenticate, HDR_AUTHENTICATE },
1856         { "WWW-Authenticate", &hf_http_www_authenticate, HDR_AUTHENTICATE },
1857         { "Content-Type", &hf_http_content_type, HDR_CONTENT_TYPE },
1858         { "Content-Length", &hf_http_content_length_header, HDR_CONTENT_LENGTH },
1859         { "Content-Encoding", &hf_http_content_encoding, HDR_CONTENT_ENCODING },
1860         { "Transfer-Encoding", &hf_http_transfer_encoding, HDR_TRANSFER_ENCODING },
1861         { "User-Agent", &hf_http_user_agent, HDR_NO_SPECIAL },
1862         { "Host", &hf_http_host, HDR_HOST },
1863         { "Connection", &hf_http_connection, HDR_NO_SPECIAL },
1864         { "Cookie", &hf_http_cookie, HDR_NO_SPECIAL },
1865         { "Accept", &hf_http_accept, HDR_NO_SPECIAL },
1866         { "Referer", &hf_http_referer, HDR_NO_SPECIAL },
1867         { "Accept-Language", &hf_http_accept_language, HDR_NO_SPECIAL },
1868         { "Accept-Encoding", &hf_http_accept_encoding, HDR_NO_SPECIAL },
1869         { "Date", &hf_http_date, HDR_NO_SPECIAL },
1870         { "Cache-Control", &hf_http_cache_control, HDR_NO_SPECIAL },
1871         { "Server", &hf_http_server, HDR_NO_SPECIAL },
1872         { "Location", &hf_http_location, HDR_NO_SPECIAL },
1873         { "Set-Cookie", &hf_http_set_cookie, HDR_NO_SPECIAL },
1874         { "Last-Modified", &hf_http_last_modified, HDR_NO_SPECIAL },
1875         { "X-Forwarded-For", &hf_http_x_forwarded_for, HDR_NO_SPECIAL },
1876 };
1877
1878 /*
1879  *
1880  */
1881 static gint*
1882 get_hf_for_header(char* header_name)
1883 {
1884         gint* hf_id = NULL;
1885
1886         if (header_fields_hash) {
1887                 hf_id = (gint*) g_hash_table_lookup(header_fields_hash, header_name);
1888         } else {
1889                 hf_id = NULL;
1890         }
1891
1892         return hf_id;
1893 }
1894
1895 /*
1896  *
1897  */
1898 static void
1899 add_hf_info_for_headers(void)
1900 {
1901         hf_register_info* hf = NULL;
1902         gint* hf_id = NULL;
1903         guint i = 0;
1904         gchar* header_name;
1905         GPtrArray* array;
1906         guint new_entries = 0;
1907         header_field_t* tmp_hdr = NULL;
1908
1909         if (!header_fields_hash) {
1910                 header_fields_hash = g_hash_table_new(g_str_hash, g_str_equal);
1911         }
1912
1913         if (num_header_fields) {
1914                 array = g_ptr_array_new();
1915
1916                 /* Make a list of fields which are not already added. This is useful only if
1917                  * preferences are reloaded and a new header field has been added. Perhaps unlikely
1918                  * to be used, but no harm in adding it...
1919                  */
1920
1921                 /* Not checking if the UAT has more or same number of entries as the hash table
1922                  * because it is possible that some entries are removed and some more added.
1923                  * WARNING: We will not de-register fields which have been removed from the UAT
1924                  *
1925                  * XXX: PS, it turns out that in case of change in UAT, the prefs apply callback is not
1926                  * called... so, some of this code will not work at the moment. However, I leave it
1927                  * in here for now because if the callback is called in future, it will work (at least
1928                  * in theory ;-).
1929                  */
1930                 for (i = 0; i < num_header_fields; i++) {
1931                         if ((g_hash_table_lookup(header_fields_hash, header_fields[i].header_name)) == NULL) {
1932                                 new_entries++;
1933                                 g_ptr_array_add(array, &header_fields[i]);
1934                         }
1935                 }
1936
1937                 if (new_entries) {
1938                         hf = g_malloc0(sizeof(hf_register_info) * new_entries);
1939                         for (i = 0; i < new_entries; i++) {
1940                                 tmp_hdr = (header_field_t*) g_ptr_array_index(array, i);
1941                                 hf_id = g_malloc(sizeof(gint));
1942                                 *hf_id = -1;
1943                                 header_name = g_strdup(tmp_hdr->header_name);
1944
1945                                 hf[i].p_id = hf_id;
1946                                 hf[i].hfinfo.name = header_name;
1947                                 hf[i].hfinfo.abbrev = g_strdup_printf("http.header.%s", header_name);
1948                                 hf[i].hfinfo.type = FT_STRING;
1949                                 hf[i].hfinfo.display = BASE_NONE;
1950                                 hf[i].hfinfo.strings = NULL;
1951                                 hf[i].hfinfo.blurb = g_strdup(tmp_hdr->header_desc);
1952                                 hf[i].hfinfo.same_name_prev = NULL;
1953                                 hf[i].hfinfo.same_name_next = NULL;
1954
1955                                 g_hash_table_insert(header_fields_hash, header_name, hf_id);
1956                         }
1957
1958                         proto_register_field_array(proto_http, hf, num_header_fields);
1959                 }
1960         }
1961 }
1962
1963 static void
1964 process_header(tvbuff_t *tvb, int offset, int next_offset,
1965                const guchar *line, int linelen, int colon_offset,
1966                packet_info *pinfo, proto_tree *tree, headers_t *eh_ptr,
1967                http_conv_t *conv_data)
1968 {
1969         int len;
1970         int line_end_offset;
1971         int header_len;
1972         gint hf_index;
1973         guchar c;
1974         int value_offset;
1975         int value_len;
1976         char *value;
1977         char *header_name;
1978         char *p;
1979         guchar *up;
1980         proto_item *hdr_item;
1981         int i;
1982         int* hf_id;
1983
1984         len = next_offset - offset;
1985         line_end_offset = offset + linelen;
1986         header_len = colon_offset - offset;
1987         header_name = se_strndup(&line[0], header_len);
1988         hf_index = find_header_hf_value(tvb, offset, header_len);
1989
1990         /*
1991          * Skip whitespace after the colon.
1992          */
1993         value_offset = colon_offset + 1;
1994         while (value_offset < line_end_offset
1995                         && ((c = line[value_offset - offset]) == ' ' || c == '\t'))
1996                 value_offset++;
1997
1998         /*
1999          * Fetch the value.
2000          */
2001         value_len = line_end_offset - value_offset;
2002         value = ep_strndup(&line[value_offset - offset], value_len);
2003
2004         if (hf_index == -1) {
2005                 /*
2006                  * Not a header we know anything about.
2007                  * Check if a HF generated from UAT information exists.
2008                  */
2009                 hf_id = get_hf_for_header(header_name);
2010
2011                 if (tree) {
2012                         if (!hf_id) {
2013                                 proto_tree_add_text(tree, tvb, offset, len,
2014                                     "%s", format_text(line, len));
2015                         } else {
2016                                 proto_tree_add_string_format(tree,
2017                                         *hf_id, tvb, offset, len,
2018                                     value, "%s", format_text(line, len));
2019                         }
2020                 }
2021         } else {
2022                 /*
2023                  * Skip whitespace after the colon.
2024                  */
2025                 value_offset = colon_offset + 1;
2026                 while (value_offset < line_end_offset
2027                     && ((c = line[value_offset - offset]) == ' ' || c == '\t'))
2028                         value_offset++;
2029
2030                 /*
2031                  * Fetch the value.
2032                  */
2033                 value_len = line_end_offset - value_offset;
2034                 value = ep_strndup(&line[value_offset - offset], value_len);
2035
2036                 /*
2037                  * Add it to the protocol tree as a particular field,
2038                  * but display the line as is.
2039                  */
2040                 if (tree) {
2041                         header_field_info *hfinfo;
2042                         guint32 tmp;
2043
2044                         hfinfo = proto_registrar_get_nth(*headers[hf_index].hf);
2045                         switch(hfinfo->type){
2046                         case FT_UINT8:
2047                         case FT_UINT16:
2048                         case FT_UINT24:
2049                         case FT_UINT32:
2050                         case FT_INT8:
2051                         case FT_INT16:
2052                         case FT_INT24:
2053                         case FT_INT32:
2054                                 tmp=strtol(value, NULL, 10);
2055                                 hdr_item = proto_tree_add_uint(tree, *headers[hf_index].hf, tvb, offset, len, tmp);
2056                                 break;
2057                         default:
2058                                 hdr_item = proto_tree_add_string_format(tree,
2059                                     *headers[hf_index].hf, tvb, offset, len,
2060                                     value, "%s", format_text(line, len));
2061                         }
2062                 } else
2063                         hdr_item = NULL;
2064
2065                 /*
2066                  * Do any special processing that particular headers
2067                  * require.
2068                  */
2069                 switch (headers[hf_index].special) {
2070
2071                 case HDR_AUTHORIZATION:
2072                         if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
2073                                 break;  /* dissected NTLMSSP */
2074                         if (check_auth_basic(hdr_item, tvb, value))
2075                                 break; /* dissected basic auth */
2076                         check_auth_kerberos(hdr_item, tvb, pinfo, value);
2077                         break;
2078
2079                 case HDR_AUTHENTICATE:
2080                         if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
2081                                 break; /* dissected NTLMSSP */
2082                         check_auth_kerberos(hdr_item, tvb, pinfo, value);
2083                         break;
2084
2085                 case HDR_CONTENT_TYPE:
2086                         eh_ptr->content_type = (gchar*) ep_memdup((guint8*)value,value_len + 1);
2087
2088                         for (i = 0; i < value_len; i++) {
2089                                 c = value[i];
2090                                 if (c == ';' || isspace(c)) {
2091                                         /*
2092                                          * End of subtype - either
2093                                          * white space or a ";"
2094                                          * separating the subtype from
2095                                          * a parameter.
2096                                          */
2097                                         break;
2098                                 }
2099
2100                                 /*
2101                                  * Map the character to lower case;
2102                                  * content types are case-insensitive.
2103                                  */
2104                                 eh_ptr->content_type[i] = tolower(eh_ptr->content_type[i]);
2105                         }
2106                         eh_ptr->content_type[i] = '\0';
2107                         /*
2108                          * Now find the start of the optional parameters;
2109                          * skip the optional white space and the semicolon
2110                          * if this has not been done before.
2111                          */
2112                         i++;
2113                         while (i < value_len) {
2114                                 c = eh_ptr->content_type[i];
2115                                 if (c == ';' || isspace(c))
2116                                         /* Skip till start of parameters */
2117                                         i++;
2118                                 else
2119                                         break;
2120                         }
2121                         if (i < value_len)
2122                                 eh_ptr->content_type_parameters = eh_ptr->content_type + i;
2123                         else
2124                                 eh_ptr->content_type_parameters = NULL;
2125                         break;
2126
2127                 case HDR_CONTENT_LENGTH:
2128                         errno = 0;
2129 #if GLIB_CHECK_VERSION(2,12,0)
2130                         eh_ptr->content_length = g_ascii_strtoll(value, &p, 10);
2131 #elif defined(HAVE_STRTOLL)
2132                         eh_ptr->content_length = strtoll(value, &p, 10);
2133 #else
2134                         /* Punt and grab a 32-bit value */
2135                         eh_ptr->content_length = strtol(value, &p, 10);
2136 #endif
2137
2138                         up = (guchar *)p;
2139                         if (eh_ptr->content_length < 0 ||
2140                             p == value ||
2141                             errno == ERANGE ||
2142                             (*up != '\0' && !isspace(*up))) {
2143                                 /*
2144                                  * Content length not valid; pretend
2145                                  * we don't have it.
2146                                  */
2147                                 eh_ptr->have_content_length = FALSE;
2148                         } else {
2149                                 proto_tree *header_tree;
2150                                 proto_item *tree_item;
2151                                 /*
2152                                  * We do have a valid content length.
2153                                  */
2154                                 eh_ptr->have_content_length = TRUE;
2155                                 header_tree = proto_item_add_subtree(hdr_item, ett_http_header_item);
2156                                 tree_item = proto_tree_add_uint64(header_tree, hf_http_content_length,
2157                                         tvb, offset, len, eh_ptr->content_length);
2158                                 PROTO_ITEM_SET_GENERATED(tree_item);
2159                         }
2160                         break;
2161
2162                 case HDR_CONTENT_ENCODING:
2163                         eh_ptr->content_encoding = ep_strndup(value, value_len);
2164                         break;
2165
2166                 case HDR_TRANSFER_ENCODING:
2167                         eh_ptr->transfer_encoding = ep_strndup(value, value_len);
2168                         break;
2169
2170                 case HDR_HOST:
2171                         stat_info->http_host = ep_strndup(value, value_len);
2172                         conv_data->http_host = se_strndup(value, value_len);
2173                         break;
2174
2175                 }
2176         }
2177 }
2178
2179 /* Returns index of header tag in headers */
2180 static gint
2181 find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len)
2182 {
2183         guint i;
2184
2185         for (i = 0; i < array_length(headers); i++) {
2186                 if (header_len == strlen(headers[i].name) &&
2187                         tvb_strncaseeql(tvb, offset,
2188                                     headers[i].name, header_len) == 0)
2189                         return i;
2190         }
2191
2192         return -1;
2193 }
2194
2195 /*
2196  * Dissect Microsoft's abomination called NTLMSSP over HTTP.
2197  */
2198 static gboolean
2199 check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo,
2200     gchar *value)
2201 {
2202         static const char *ntlm_headers[] = {
2203                 "NTLM ",
2204                 "Negotiate ",
2205                 NULL
2206         };
2207         const char **header;
2208         size_t hdrlen;
2209         proto_tree *hdr_tree;
2210
2211         /*
2212          * Check for NTLM credentials and challenge; those can
2213          * occur with WWW-Authenticate.
2214          */
2215         for (header = &ntlm_headers[0]; *header != NULL; header++) {
2216                 hdrlen = strlen(*header);
2217                 if (strncmp(value, *header, hdrlen) == 0) {
2218                         if (hdr_item != NULL) {
2219                                 hdr_tree = proto_item_add_subtree(hdr_item,
2220                                     ett_http_ntlmssp);
2221                         } else
2222                                 hdr_tree = NULL;
2223                         value += hdrlen;
2224                         dissect_http_ntlmssp(tvb, pinfo, hdr_tree, value);
2225                         return TRUE;
2226                 }
2227         }
2228         return FALSE;
2229 }
2230
2231 /*
2232  * Dissect HTTP Basic authorization.
2233  */
2234 static gboolean
2235 check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value)
2236 {
2237         static const char *basic_headers[] = {
2238                 "Basic ",
2239                 NULL
2240         };
2241         const char **header;
2242         size_t hdrlen;
2243         proto_tree *hdr_tree;
2244         size_t len;
2245
2246         for (header = &basic_headers[0]; *header != NULL; header++) {
2247                 hdrlen = strlen(*header);
2248                 if (strncmp(value, *header, hdrlen) == 0) {
2249                         if (hdr_item != NULL) {
2250                                 hdr_tree = proto_item_add_subtree(hdr_item,
2251                                     ett_http_ntlmssp);
2252                         } else
2253                                 hdr_tree = NULL;
2254                         value += hdrlen;
2255
2256                         len = epan_base64_decode(value);
2257                         value[len] = '\0';
2258                         proto_tree_add_string(hdr_tree, hf_http_basic, tvb,
2259                             0, 0, value);
2260
2261                         return TRUE;
2262                 }
2263         }
2264         return FALSE;
2265 }
2266
2267 static gboolean
2268 check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo,
2269     const gchar *value)
2270 {
2271         proto_tree *hdr_tree;
2272
2273         if (strncmp(value, "Kerberos ", 9) == 0) {
2274                 if (hdr_item != NULL) {
2275                         hdr_tree = proto_item_add_subtree(hdr_item, ett_http_kerberos);
2276                 } else
2277                         hdr_tree = NULL;
2278
2279                 dissect_http_kerberos(tvb, pinfo, hdr_tree, value);
2280                 return TRUE;
2281         }
2282         return FALSE;
2283 }
2284
2285 static void
2286 dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2287 {
2288         http_conv_t     *conv_data;
2289         int             offset = 0;
2290         int             len;
2291
2292         /*
2293          * Check if this is proxied connection and if so, hand of dissection to the
2294          * payload-dissector.
2295          * Response code 200 means "OK" and strncmp() == 0 means the strings match exactly */
2296         conv_data = get_http_conversation_data(pinfo);
2297         if(pinfo->fd->num >= conv_data->startframe &&
2298            conv_data->response_code == 200 &&
2299            conv_data->request_method &&
2300            strncmp(conv_data->request_method, "CONNECT", 7) == 0 &&
2301            conv_data->request_uri) {
2302                 if(conv_data->startframe == 0 && !pinfo->fd->flags.visited)
2303                         conv_data->startframe = pinfo->fd->num;
2304                 http_payload_subdissector(tvb, tree, pinfo, conv_data);
2305         } else {
2306                 while (tvb_reported_length_remaining(tvb, offset) != 0) {
2307                         len = dissect_http_message(tvb, offset, pinfo, tree, conv_data);
2308                         if (len == -1)
2309                                 break;
2310                         offset += len;
2311
2312                         /*
2313                          * OK, we've set the Protocol and Info columns for the
2314                          * first HTTP message; set a fence so that subsequent
2315                          * HTTP messages don't overwrite the Info column.
2316                          */
2317                         if (check_col(pinfo->cinfo, COL_INFO))
2318                                 col_set_fence(pinfo->cinfo, COL_INFO);
2319                 }
2320         }
2321 }
2322
2323 static void
2324 dissect_http_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2325 {
2326         http_conv_t     *conv_data;
2327
2328         conv_data = get_http_conversation_data(pinfo);
2329         dissect_http_message(tvb, 0, pinfo, tree, conv_data);
2330 }
2331
2332 static void
2333 range_delete_http_tcp_callback(guint32 port) {
2334         dissector_delete_uint("tcp.port", port, http_handle);
2335 }
2336
2337 static void
2338 range_add_http_tcp_callback(guint32 port) {
2339         dissector_add_uint("tcp.port", port, http_handle);
2340 }
2341
2342 static void
2343 range_delete_http_ssl_callback(guint32 port) {
2344         ssl_dissector_delete(port, "http", TRUE);
2345 }
2346
2347 static void
2348 range_add_http_ssl_callback(guint32 port) {
2349         ssl_dissector_add(port, "http", TRUE);
2350 }
2351
2352 static void reinit_http(void) {
2353         range_foreach(http_tcp_range, range_delete_http_tcp_callback);
2354         g_free(http_tcp_range);
2355         http_tcp_range = range_copy(global_http_tcp_range);
2356         range_foreach(http_tcp_range, range_add_http_tcp_callback);
2357
2358         range_foreach(http_ssl_range, range_delete_http_ssl_callback);
2359         g_free(http_ssl_range);
2360         http_ssl_range = range_copy(global_http_ssl_range);
2361         range_foreach(http_ssl_range, range_add_http_ssl_callback);
2362
2363         /* Attempt to add additional headers that might have been added
2364          * once the preferences are applied.
2365          */
2366         add_hf_info_for_headers();
2367 }
2368
2369 void
2370 proto_register_http(void)
2371 {
2372         static hf_register_info hf[] = {
2373             { &hf_http_notification,
2374               { "Notification",         "http.notification",
2375                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2376                 "TRUE if HTTP notification", HFILL }},
2377             { &hf_http_response,
2378               { "Response",             "http.response",
2379                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2380                 "TRUE if HTTP response", HFILL }},
2381             { &hf_http_request,
2382               { "Request",              "http.request",
2383                 FT_BOOLEAN, BASE_NONE, NULL, 0x0,
2384                 "TRUE if HTTP request", HFILL }},
2385             { &hf_http_basic,
2386               { "Credentials",          "http.authbasic",
2387                 FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2388             { &hf_http_request_method,
2389               { "Request Method",       "http.request.method",
2390                 FT_STRING, BASE_NONE, NULL, 0x0,
2391                 "HTTP Request Method", HFILL }},
2392             { &hf_http_request_uri,
2393               { "Request URI",  "http.request.uri",
2394                 FT_STRING, BASE_NONE, NULL, 0x0,
2395                 "HTTP Request-URI", HFILL }},
2396             { &hf_http_version,
2397               { "Request Version",      "http.request.version",
2398                 FT_STRING, BASE_NONE, NULL, 0x0,
2399                 "HTTP Request HTTP-Version", HFILL }},
2400             { &hf_http_request_full_uri,
2401               { "Full request URI",     "http.request.full_uri",
2402                 FT_STRING, BASE_NONE, NULL, 0x0,
2403                 "The full requested URI (including host name)", HFILL }},
2404             { &hf_http_response_code,
2405               { "Status Code",  "http.response.code",
2406                 FT_UINT16, BASE_DEC, NULL, 0x0,
2407                 "HTTP Response Status Code", HFILL }},
2408                 { &hf_http_response_phrase,
2409                   { "Response Phrase", "http.response.phrase",
2410             FT_STRING, BASE_NONE, NULL, 0x0,
2411                 "HTTP Response Reason Phrase", HFILL }},
2412             { &hf_http_authorization,
2413               { "Authorization",        "http.authorization",
2414                 FT_STRING, BASE_NONE, NULL, 0x0,
2415                 "HTTP Authorization header", HFILL }},
2416             { &hf_http_proxy_authenticate,
2417               { "Proxy-Authenticate",   "http.proxy_authenticate",
2418                 FT_STRING, BASE_NONE, NULL, 0x0,
2419                 "HTTP Proxy-Authenticate header", HFILL }},
2420             { &hf_http_proxy_authorization,
2421               { "Proxy-Authorization",  "http.proxy_authorization",
2422                 FT_STRING, BASE_NONE, NULL, 0x0,
2423                 "HTTP Proxy-Authorization header", HFILL }},
2424             { &hf_http_proxy_connect_host,
2425               { "Proxy-Connect-Hostname", "http.proxy_connect_host",
2426                 FT_STRING, BASE_NONE, NULL, 0x0,
2427                 "HTTP Proxy Connect Hostname", HFILL }},
2428             { &hf_http_proxy_connect_port,
2429               { "Proxy-Connect-Port",   "http.proxy_connect_port",
2430                 FT_UINT16, BASE_DEC, NULL, 0x0,
2431                 "HTTP Proxy Connect Port", HFILL }},
2432             { &hf_http_www_authenticate,
2433               { "WWW-Authenticate",     "http.www_authenticate",
2434                 FT_STRING, BASE_NONE, NULL, 0x0,
2435                 "HTTP WWW-Authenticate header", HFILL }},
2436             { &hf_http_content_type,
2437               { "Content-Type", "http.content_type",
2438                 FT_STRING, BASE_NONE, NULL, 0x0,
2439                 "HTTP Content-Type header", HFILL }},
2440             { &hf_http_content_length_header,
2441               { "Content-Length",       "http.content_length_header",
2442                 FT_STRING, BASE_NONE, NULL, 0x0,
2443                 "HTTP Content-Length header", HFILL }},
2444             { &hf_http_content_length,
2445               { "Content length",       "http.content_length",
2446                 FT_UINT64, BASE_DEC, NULL, 0x0,
2447                 NULL, HFILL }},
2448             { &hf_http_content_encoding,
2449               { "Content-Encoding",     "http.content_encoding",
2450                 FT_STRING, BASE_NONE, NULL, 0x0,
2451                 "HTTP Content-Encoding header", HFILL }},
2452             { &hf_http_transfer_encoding,
2453               { "Transfer-Encoding",    "http.transfer_encoding",
2454                 FT_STRING, BASE_NONE, NULL, 0x0,
2455                 "HTTP Transfer-Encoding header", HFILL }},
2456             { &hf_http_user_agent,
2457               { "User-Agent",   "http.user_agent",
2458                 FT_STRING, BASE_NONE, NULL, 0x0,
2459                 "HTTP User-Agent header", HFILL }},
2460             { &hf_http_host,
2461               { "Host", "http.host",
2462                 FT_STRING, BASE_NONE, NULL, 0x0,
2463                 "HTTP Host", HFILL }},
2464             { &hf_http_connection,
2465               { "Connection",   "http.connection",
2466                 FT_STRING, BASE_NONE, NULL, 0x0,
2467                 "HTTP Connection", HFILL }},
2468             { &hf_http_cookie,
2469               { "Cookie",       "http.cookie",
2470                 FT_STRING, BASE_NONE, NULL, 0x0,
2471                 "HTTP Cookie", HFILL }},
2472             { &hf_http_accept,
2473               { "Accept",       "http.accept",
2474                 FT_STRING, BASE_NONE, NULL, 0x0,
2475                 "HTTP Accept", HFILL }},
2476             { &hf_http_referer,
2477               { "Referer",      "http.referer",
2478                 FT_STRING, BASE_NONE, NULL, 0x0,
2479                 "HTTP Referer", HFILL }},
2480             { &hf_http_accept_language,
2481               { "Accept-Language",      "http.accept_language",
2482                 FT_STRING, BASE_NONE, NULL, 0x0,
2483                 "HTTP Accept Language", HFILL }},
2484             { &hf_http_accept_encoding,
2485               { "Accept Encoding",      "http.accept_encoding",
2486                 FT_STRING, BASE_NONE, NULL, 0x0,
2487                 "HTTP Accept Encoding", HFILL }},
2488             { &hf_http_date,
2489               { "Date", "http.date",
2490                 FT_STRING, BASE_NONE, NULL, 0x0,
2491                 "HTTP Date", HFILL }},
2492             { &hf_http_cache_control,
2493               { "Cache-Control",        "http.cache_control",
2494                 FT_STRING, BASE_NONE, NULL, 0x0,
2495                 "HTTP Cache Control", HFILL }},
2496             { &hf_http_server,
2497               { "Server",       "http.server",
2498                 FT_STRING, BASE_NONE, NULL, 0x0,
2499                 "HTTP Server", HFILL }},
2500             { &hf_http_location,
2501               { "Location",     "http.location",
2502                 FT_STRING, BASE_NONE, NULL, 0x0,
2503                 "HTTP Location", HFILL }},
2504             { &hf_http_set_cookie,
2505               { "Set-Cookie",   "http.set_cookie",
2506                 FT_STRING, BASE_NONE, NULL, 0x0,
2507                 "HTTP Set Cookie", HFILL }},
2508             { &hf_http_last_modified,
2509               { "Last-Modified",        "http.last_modified",
2510                 FT_STRING, BASE_NONE, NULL, 0x0,
2511                 "HTTP Last Modified", HFILL }},
2512             { &hf_http_x_forwarded_for,
2513               { "X-Forwarded-For",      "http.x_forwarded_for",
2514                 FT_STRING, BASE_NONE, NULL, 0x0,
2515                 "HTTP X-Forwarded-For", HFILL }}
2516         };
2517         static gint *ett[] = {
2518                 &ett_http,
2519                 &ett_http_ntlmssp,
2520                 &ett_http_kerberos,
2521                 &ett_http_request,
2522                 &ett_http_chunked_response,
2523                 &ett_http_chunk_data,
2524                 &ett_http_encoded_entity,
2525                 &ett_http_header_item
2526         };
2527         /* UAT for header fields */
2528         static uat_field_t custom_header_uat_fields[] = {
2529                 UAT_FLD_CSTRING(header_fields, header_name, "Header name", "HTTP header name"),
2530                 UAT_FLD_CSTRING(header_fields, header_desc, "Field desc", "Description of the value contained in the header"),
2531                 UAT_END_FIELDS
2532         };
2533
2534         module_t *http_module;
2535         uat_t* headers_uat;
2536         char* uat_load_err;
2537
2538         proto_http = proto_register_protocol("Hypertext Transfer Protocol",
2539             "HTTP", "http");
2540         proto_register_field_array(proto_http, hf, array_length(hf));
2541         proto_register_subtree_array(ett, array_length(ett));
2542         register_dissector("http", dissect_http, proto_http);
2543         http_module = prefs_register_protocol(proto_http, reinit_http);
2544         prefs_register_bool_preference(http_module, "desegment_headers",
2545             "Reassemble HTTP headers spanning multiple TCP segments",
2546             "Whether the HTTP dissector should reassemble headers "
2547             "of a request spanning multiple TCP segments. "
2548                 "To use this option, you must also enable "
2549         "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2550             &http_desegment_headers);
2551         prefs_register_bool_preference(http_module, "desegment_body",
2552             "Reassemble HTTP bodies spanning multiple TCP segments",
2553             "Whether the HTTP dissector should use the "
2554             "\"Content-length:\" value, if present, to reassemble "
2555             "the body of a request spanning multiple TCP segments, "
2556             "and reassemble chunked data spanning multiple TCP segments. "
2557                 "To use this option, you must also enable "
2558         "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2559             &http_desegment_body);
2560         prefs_register_bool_preference(http_module, "dechunk_body",
2561             "Reassemble chunked transfer-coded bodies",
2562             "Whether to reassemble bodies of entities that are transfered "
2563             "using the \"Transfer-Encoding: chunked\" method",
2564             &http_dechunk_body);
2565 #ifdef HAVE_LIBZ
2566         prefs_register_bool_preference(http_module, "decompress_body",
2567             "Uncompress entity bodies",
2568             "Whether to uncompress entity bodies that are compressed "
2569             "using \"Content-Encoding: \"",
2570             &http_decompress_body);
2571 #endif
2572         prefs_register_obsolete_preference(http_module, "tcp_alternate_port");
2573
2574         range_convert_str(&global_http_tcp_range, TCP_DEFAULT_RANGE, 65535);
2575         http_tcp_range = range_empty();
2576         prefs_register_range_preference(http_module, "tcp.port", "TCP Ports",
2577                                         "TCP Ports range",
2578                                         &global_http_tcp_range, 65535);
2579
2580         range_convert_str(&global_http_ssl_range, SSL_DEFAULT_RANGE, 65535);
2581         http_ssl_range = range_empty();
2582         prefs_register_range_preference(http_module, "ssl.port", "SSL/TLS Ports",
2583                                         "SSL/TLS Ports range",
2584                                         &global_http_ssl_range, 65535);
2585         /* UAT */
2586         headers_uat = uat_new("Custom HTTP headers fields Table",
2587                               sizeof(header_field_t),
2588                               "custom_http_header_fields",
2589                               TRUE,
2590                               (void*) &header_fields,
2591                               &num_header_fields,
2592                               UAT_CAT_GENERAL,
2593                               NULL,
2594                               header_fields_copy_cb,
2595                               header_fields_update_cb,
2596                               header_fields_free_cb,
2597                               NULL,
2598                               custom_header_uat_fields
2599         );
2600
2601         prefs_register_uat_preference(http_module, "custom_http_header_fields", "Custom HTTP headers fields",
2602             "A table to define custom HTTP header for which fields can be setup and used for filtering/data extraction etc.",
2603            headers_uat);
2604
2605         http_handle = create_dissector_handle(dissect_http, proto_http);
2606
2607         /*
2608          * Dissectors shouldn't register themselves in this table;
2609          * instead, they should call "http_dissector_add()", and
2610          * we'll register the port number they specify as a port
2611          * for HTTP, and register them in our subdissector table.
2612          *
2613          * This only works for protocols such as IPP that run over
2614          * HTTP on a specific non-HTTP port.
2615          */
2616         port_subdissector_table = register_dissector_table("http.port",
2617             "TCP port for protocols using HTTP", FT_UINT16, BASE_DEC);
2618
2619         /*
2620          * Dissectors can register themselves in this table.
2621          * It's just "media_type", not "http.content_type", because
2622          * it's an Internet media type, usable by other protocols as well.
2623          */
2624         media_type_subdissector_table =
2625             register_dissector_table("media_type",
2626                 "Internet media type", FT_STRING, BASE_NONE);
2627
2628         /*
2629          * Heuristic dissectors SHOULD register themselves in
2630          * this table using the standard heur_dissector_add()
2631          * function.
2632          */
2633         register_heur_dissector_list("http", &heur_subdissector_list);
2634
2635         /*
2636          * Register for tapping
2637          */
2638         http_tap = register_tap("http"); /* HTTP statistics tap */
2639         http_eo_tap = register_tap("http_eo"); /* HTTP Export Object tap */
2640
2641         /*
2642          * Add additional HFs for HTTP headers from the UAT (which is loaded manually first).
2643          */
2644         if (uat_load(headers_uat, &uat_load_err)) {
2645                 add_hf_info_for_headers();
2646         }
2647 }
2648
2649 /*
2650  * Called by dissectors for protocols that run atop HTTP/TCP.
2651  */
2652 void
2653 http_dissector_add(guint32 port, dissector_handle_t handle)
2654 {
2655         /*
2656          * Register ourselves as the handler for that port number
2657          * over TCP.
2658          */
2659         dissector_add_uint("tcp.port", port, http_handle);
2660
2661         /*
2662          * And register them in *our* table for that port.
2663          */
2664         dissector_add_uint("http.port", port, handle);
2665 }
2666
2667 void
2668 proto_reg_handoff_http(void)
2669 {
2670         dissector_handle_t http_udp_handle;
2671
2672         data_handle = find_dissector("data");
2673         media_handle = find_dissector("media");
2674
2675         /*
2676          * XXX - is there anything to dissect in the body of an SSDP
2677          * request or reply?  I.e., should there be an SSDP dissector?
2678          */
2679         http_udp_handle = create_dissector_handle(dissect_http_udp, proto_http);
2680         dissector_add_uint("udp.port", UDP_PORT_SSDP, http_udp_handle);
2681
2682         ntlmssp_handle = find_dissector("ntlmssp");
2683         gssapi_handle = find_dissector("gssapi");
2684
2685         stats_tree_register("http", "http",     "HTTP/Packet Counter",   0, http_stats_tree_packet,      http_stats_tree_init, NULL );
2686         stats_tree_register("http", "http_req", "HTTP/Requests",         0, http_req_stats_tree_packet,  http_req_stats_tree_init, NULL );
2687         stats_tree_register("http", "http_srv", "HTTP/Load Distribution",0, http_reqs_stats_tree_packet, http_reqs_stats_tree_init, NULL );
2688
2689 }
2690
2691 /*
2692  * Content-Type: message/http
2693  */
2694
2695 static gint proto_message_http = -1;
2696 static gint ett_message_http = -1;
2697
2698 static void
2699 dissect_message_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2700 {
2701         proto_tree      *subtree;
2702         proto_item      *ti;
2703         gint            offset = 0, next_offset;
2704         gint            len;
2705
2706         col_append_str(pinfo->cinfo, COL_INFO, " (message/http)");
2707         if (tree) {
2708                 ti = proto_tree_add_item(tree, proto_message_http,
2709                                 tvb, 0, -1, FALSE);
2710                 subtree = proto_item_add_subtree(ti, ett_message_http);
2711                 while (tvb_reported_length_remaining(tvb, offset) != 0) {
2712                         len = tvb_find_line_end(tvb, offset,
2713                                         tvb_ensure_length_remaining(tvb, offset),
2714                                         &next_offset, FALSE);
2715                         if (len == -1)
2716                                 break;
2717                         proto_tree_add_text(subtree, tvb, offset, next_offset - offset,
2718                                         "%s", tvb_format_text(tvb, offset, len));
2719                         offset = next_offset;
2720                 }
2721         }
2722 }
2723
2724 void
2725 proto_register_message_http(void)
2726 {
2727         static gint *ett[] = {
2728                 &ett_message_http,
2729         };
2730
2731         proto_message_http = proto_register_protocol(
2732                         "Media Type: message/http",
2733                         "message/http",
2734                         "message-http"
2735         );
2736         proto_register_subtree_array(ett, array_length(ett));
2737 }
2738
2739 void
2740 proto_reg_handoff_message_http(void)
2741 {
2742         dissector_handle_t message_http_handle;
2743
2744         message_http_handle = create_dissector_handle(dissect_message_http,
2745                         proto_message_http);
2746
2747         dissector_add_string("media_type", "message/http", message_http_handle);
2748
2749         reinit_http();
2750 }