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