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