PageRenderTime 57ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 1ms

/epan/dissectors/packet-http.c

https://github.com/labx-technologies-llc/wireshark
C | 3187 lines | 2182 code | 382 blank | 623 comment | 385 complexity | a669e9c4fa2a4a2bb6fc252d5a4a4a3d MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  31. */
  32. #include "config.h"
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include <errno.h>
  37. #include <glib.h>
  38. #include <epan/conversation.h>
  39. #include <epan/packet.h>
  40. #include <epan/strutil.h>
  41. #include <epan/base64.h>
  42. #include <epan/emem.h>
  43. #include <epan/stats_tree.h>
  44. #include <epan/req_resp_hdrs.h>
  45. #include "packet-http.h"
  46. #include "packet-tcp.h"
  47. #include "packet-ssl.h"
  48. #include <epan/prefs.h>
  49. #include <epan/expert.h>
  50. #include <epan/uat.h>
  51. #include <epan/wmem/wmem.h>
  52. typedef enum _http_type {
  53. HTTP_REQUEST,
  54. HTTP_RESPONSE,
  55. HTTP_NOTIFICATION,
  56. HTTP_OTHERS
  57. } http_type_t;
  58. #include <epan/tap.h>
  59. static int http_tap = -1;
  60. static int http_eo_tap = -1;
  61. static int proto_http = -1;
  62. static int hf_http_notification = -1;
  63. static int hf_http_response = -1;
  64. static int hf_http_request = -1;
  65. static int hf_http_basic = -1;
  66. static int hf_http_request_method = -1;
  67. static int hf_http_request_uri = -1;
  68. static int hf_http_request_full_uri = -1;
  69. static int hf_http_version = -1;
  70. static int hf_http_response_code = -1;
  71. static int hf_http_response_phrase = -1;
  72. static int hf_http_authorization = -1;
  73. static int hf_http_proxy_authenticate = -1;
  74. static int hf_http_proxy_authorization = -1;
  75. static int hf_http_proxy_connect_host = -1;
  76. static int hf_http_proxy_connect_port = -1;
  77. static int hf_http_www_authenticate = -1;
  78. static int hf_http_content_type = -1;
  79. static int hf_http_content_length_header = -1;
  80. static int hf_http_content_length = -1;
  81. static int hf_http_content_encoding = -1;
  82. static int hf_http_transfer_encoding = -1;
  83. static int hf_http_upgrade = -1;
  84. static int hf_http_user_agent = -1;
  85. static int hf_http_host = -1;
  86. static int hf_http_connection = -1;
  87. static int hf_http_cookie = -1;
  88. static int hf_http_accept = -1;
  89. static int hf_http_referer = -1;
  90. static int hf_http_accept_language = -1;
  91. static int hf_http_accept_encoding = -1;
  92. static int hf_http_date = -1;
  93. static int hf_http_cache_control = -1;
  94. static int hf_http_server = -1;
  95. static int hf_http_location = -1;
  96. static int hf_http_sec_websocket_accept = -1;
  97. static int hf_http_sec_websocket_extensions = -1;
  98. static int hf_http_sec_websocket_key = -1;
  99. static int hf_http_sec_websocket_protocol = -1;
  100. static int hf_http_sec_websocket_version = -1;
  101. static int hf_http_set_cookie = -1;
  102. static int hf_http_last_modified = -1;
  103. static int hf_http_x_forwarded_for = -1;
  104. static int hf_http_request_in = -1;
  105. static int hf_http_response_in = -1;
  106. static int hf_http_next_request_in = -1;
  107. static int hf_http_next_response_in = -1;
  108. static int hf_http_prev_request_in = -1;
  109. static int hf_http_prev_response_in = -1;
  110. static int hf_http_time = -1;
  111. static gint ett_http = -1;
  112. static gint ett_http_ntlmssp = -1;
  113. static gint ett_http_kerberos = -1;
  114. static gint ett_http_request = -1;
  115. static gint ett_http_chunked_response = -1;
  116. static gint ett_http_chunk_data = -1;
  117. static gint ett_http_encoded_entity = -1;
  118. static gint ett_http_header_item = -1;
  119. static expert_field ei_http_chat = EI_INIT;
  120. static expert_field ei_http_subdissector_failed = EI_INIT;
  121. static dissector_handle_t http_handle;
  122. static dissector_handle_t data_handle;
  123. static dissector_handle_t media_handle;
  124. static dissector_handle_t websocket_handle;
  125. /* Stuff for generation/handling of fields for custom HTTP headers */
  126. typedef struct _header_field_t {
  127. gchar* header_name;
  128. gchar* header_desc;
  129. } header_field_t;
  130. static header_field_t* header_fields = NULL;
  131. static guint num_header_fields = 0;
  132. static GHashTable* header_fields_hash = NULL;
  133. static void
  134. header_fields_update_cb(void *r, const char **err)
  135. {
  136. header_field_t *rec = (header_field_t *)r;
  137. char c;
  138. if (rec->header_name == NULL) {
  139. *err = ep_strdup_printf("Header name can't be empty");
  140. return;
  141. }
  142. g_strstrip(rec->header_name);
  143. if (rec->header_name[0] == 0) {
  144. *err = ep_strdup_printf("Header name can't be empty");
  145. return;
  146. }
  147. /* Check for invalid characters (to avoid asserting out when
  148. * registering the field).
  149. */
  150. c = proto_check_field_name(rec->header_name);
  151. if (c) {
  152. *err = ep_strdup_printf("Header name can't contain '%c'", c);
  153. return;
  154. }
  155. *err = NULL;
  156. }
  157. static void *
  158. header_fields_copy_cb(void* n, const void* o, size_t siz _U_)
  159. {
  160. header_field_t* new_rec = (header_field_t*)n;
  161. const header_field_t* old_rec = (const header_field_t*)o;
  162. if (old_rec->header_name) {
  163. new_rec->header_name = g_strdup(old_rec->header_name);
  164. } else {
  165. new_rec->header_name = NULL;
  166. }
  167. if (old_rec->header_desc) {
  168. new_rec->header_desc = g_strdup(old_rec->header_desc);
  169. } else {
  170. new_rec->header_desc = NULL;
  171. }
  172. return new_rec;
  173. }
  174. static void
  175. header_fields_free_cb(void*r)
  176. {
  177. header_field_t* rec = (header_field_t*)r;
  178. if (rec->header_name) g_free(rec->header_name);
  179. if (rec->header_desc) g_free(rec->header_desc);
  180. }
  181. UAT_CSTRING_CB_DEF(header_fields, header_name, header_field_t)
  182. UAT_CSTRING_CB_DEF(header_fields, header_desc, header_field_t)
  183. /*
  184. * desegmentation of HTTP headers
  185. * (when we are over TCP or another protocol providing the desegmentation API)
  186. */
  187. static gboolean http_desegment_headers = TRUE;
  188. /*
  189. * desegmentation of HTTP bodies
  190. * (when we are over TCP or another protocol providing the desegmentation API)
  191. * TODO let the user filter on content-type the bodies he wants desegmented
  192. */
  193. static gboolean http_desegment_body = TRUE;
  194. /*
  195. * De-chunking of content-encoding: chunk entity bodies.
  196. */
  197. static gboolean http_dechunk_body = TRUE;
  198. /*
  199. * Decompression of zlib encoded entities.
  200. */
  201. #ifdef HAVE_LIBZ
  202. static gboolean http_decompress_body = TRUE;
  203. #else
  204. static gboolean http_decompress_body = FALSE;
  205. #endif
  206. /* Simple Service Discovery Protocol
  207. * SSDP is implemented atop HTTP (yes, it really *does* run over UDP).
  208. * SSDP is the discovery protocol of Universal Plug and Play
  209. * UPnP http://www.upnp.org/specs/arch/UPnP-arch-DeviceArchitecture-v1.1.pdf
  210. */
  211. #define TCP_PORT_SSDP 1900
  212. #define UDP_PORT_SSDP 1900
  213. /*
  214. * tcp and ssl ports
  215. *
  216. * 2710 is the XBT BitTorrent tracker
  217. */
  218. #define TCP_DEFAULT_RANGE "80,3128,3132,5985,8080,8088,11371,1900,2869,2710"
  219. #define SSL_DEFAULT_RANGE "443"
  220. #define UPGRADE_WEBSOCKET 1
  221. static range_t *global_http_tcp_range = NULL;
  222. static range_t *global_http_ssl_range = NULL;
  223. static range_t *http_tcp_range = NULL;
  224. static range_t *http_ssl_range = NULL;
  225. typedef void (*ReqRespDissector)(tvbuff_t*, proto_tree*, int, const guchar*,
  226. const guchar*, http_conv_t *);
  227. /*
  228. * Structure holding information from headers needed by main
  229. * HTTP dissector code.
  230. */
  231. typedef struct {
  232. char *content_type;
  233. char *content_type_parameters;
  234. gboolean have_content_length;
  235. gint64 content_length;
  236. char *content_encoding;
  237. char *transfer_encoding;
  238. guint8 upgrade;
  239. } headers_t;
  240. static int is_http_request_or_reply(const gchar *data, int linelen,
  241. http_type_t *type, ReqRespDissector
  242. *reqresp_dissector, http_conv_t *conv_data);
  243. static int chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
  244. proto_tree *tree, int offset);
  245. static void process_header(tvbuff_t *tvb, int offset, int next_offset,
  246. const guchar *line, int linelen, int colon_offset,
  247. packet_info *pinfo, proto_tree *tree,
  248. headers_t *eh_ptr, http_conv_t *conv_data);
  249. static gint find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len);
  250. static gboolean check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb,
  251. packet_info *pinfo, gchar *value);
  252. static gboolean check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb,
  253. gchar *value);
  254. static gboolean check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb,
  255. packet_info *pinfo, const gchar *value);
  256. static dissector_table_t port_subdissector_table;
  257. static dissector_table_t media_type_subdissector_table;
  258. static heur_dissector_list_t heur_subdissector_list;
  259. static dissector_handle_t ntlmssp_handle;
  260. static dissector_handle_t gssapi_handle;
  261. /* --- HTTP Status Codes */
  262. /* Note: The reference for uncommented entries is RFC 2616 */
  263. static const value_string vals_status_code[] = {
  264. { 100, "Continue" },
  265. { 101, "Switching Protocols" },
  266. { 102, "Processing" }, /* RFC 2518 */
  267. { 199, "Informational - Others" },
  268. { 200, "OK"},
  269. { 201, "Created"},
  270. { 202, "Accepted"},
  271. { 203, "Non-authoritative Information"},
  272. { 204, "No Content"},
  273. { 205, "Reset Content"},
  274. { 206, "Partial Content"},
  275. { 207, "Multi-Status"}, /* RFC 4918 */
  276. { 226, "IM Used"}, /* RFC 3229 */
  277. { 299, "Success - Others"},
  278. { 300, "Multiple Choices"},
  279. { 301, "Moved Permanently"},
  280. { 302, "Found"},
  281. { 303, "See Other"},
  282. { 304, "Not Modified"},
  283. { 305, "Use Proxy"},
  284. { 307, "Temporary Redirect"},
  285. { 399, "Redirection - Others"},
  286. { 400, "Bad Request"},
  287. { 401, "Unauthorized"},
  288. { 402, "Payment Required"},
  289. { 403, "Forbidden"},
  290. { 404, "Not Found"},
  291. { 405, "Method Not Allowed"},
  292. { 406, "Not Acceptable"},
  293. { 407, "Proxy Authentication Required"},
  294. { 408, "Request Time-out"},
  295. { 409, "Conflict"},
  296. { 410, "Gone"},
  297. { 411, "Length Required"},
  298. { 412, "Precondition Failed"},
  299. { 413, "Request Entity Too Large"},
  300. { 414, "Request-URI Too Long"},
  301. { 415, "Unsupported Media Type"},
  302. { 416, "Requested Range Not Satisfiable"},
  303. { 417, "Expectation Failed"},
  304. { 418, "I'm a teapot"}, /* RFC 2324 */
  305. { 422, "Unprocessable Entity"}, /* RFC 4918 */
  306. { 423, "Locked"}, /* RFC 4918 */
  307. { 424, "Failed Dependency"}, /* RFC 4918 */
  308. { 426, "Upgrade Required"}, /* RFC 2817 */
  309. { 428, "Precondition Required"}, /* RFC 6585 */
  310. { 429, "Too Many Requests"}, /* RFC 6585 */
  311. { 431, "Request Header Fields Too Large"}, /* RFC 6585 */
  312. { 499, "Client Error - Others"},
  313. { 500, "Internal Server Error"},
  314. { 501, "Not Implemented"},
  315. { 502, "Bad Gateway"},
  316. { 503, "Service Unavailable"},
  317. { 504, "Gateway Time-out"},
  318. { 505, "HTTP Version not supported"},
  319. { 507, "Insufficient Storage"}, /* RFC 4918 */
  320. { 511, "Network Authentication Required"}, /* RFC 6585 */
  321. { 599, "Server Error - Others"},
  322. { 0, NULL}
  323. };
  324. static const gchar* st_str_reqs = "HTTP Requests by Server";
  325. static const gchar* st_str_reqs_by_srv_addr = "HTTP Requests by Server Address";
  326. static const gchar* st_str_reqs_by_http_host = "HTTP Requests by HTTP Host";
  327. static const gchar* st_str_resps_by_srv_addr = "HTTP Responses by Server Address";
  328. static int st_node_reqs = -1;
  329. static int st_node_reqs_by_srv_addr = -1;
  330. static int st_node_reqs_by_http_host = -1;
  331. static int st_node_resps_by_srv_addr = -1;
  332. /* HTTP/Load Distribution stats init function */
  333. static void
  334. http_reqs_stats_tree_init(stats_tree* st)
  335. {
  336. st_node_reqs = stats_tree_create_node(st, st_str_reqs, 0, TRUE);
  337. st_node_reqs_by_srv_addr = stats_tree_create_node(st, st_str_reqs_by_srv_addr, st_node_reqs, TRUE);
  338. st_node_reqs_by_http_host = stats_tree_create_node(st, st_str_reqs_by_http_host, st_node_reqs, TRUE);
  339. st_node_resps_by_srv_addr = stats_tree_create_node(st, st_str_resps_by_srv_addr, 0, TRUE);
  340. }
  341. /* HTTP/Load Distribution stats packet function */
  342. static int
  343. http_reqs_stats_tree_packet(stats_tree* st, packet_info* pinfo, epan_dissect_t* edt _U_, const void* p)
  344. {
  345. const http_info_value_t* v = (const http_info_value_t*)p;
  346. int reqs_by_this_host;
  347. int reqs_by_this_addr;
  348. int resps_by_this_addr;
  349. int i = v->response_code;
  350. gchar *ip_str;
  351. if (v->request_method) {
  352. ip_str = ep_address_to_str(&pinfo->dst);
  353. tick_stat_node(st, st_str_reqs, 0, FALSE);
  354. tick_stat_node(st, st_str_reqs_by_srv_addr, st_node_reqs, TRUE);
  355. tick_stat_node(st, st_str_reqs_by_http_host, st_node_reqs, TRUE);
  356. reqs_by_this_addr = tick_stat_node(st, ip_str, st_node_reqs_by_srv_addr, TRUE);
  357. if (v->http_host) {
  358. reqs_by_this_host = tick_stat_node(st, v->http_host, st_node_reqs_by_http_host, TRUE);
  359. tick_stat_node(st, ip_str, reqs_by_this_host, FALSE);
  360. tick_stat_node(st, v->http_host, reqs_by_this_addr, FALSE);
  361. }
  362. return 1;
  363. } else if (i != 0) {
  364. ip_str = ep_address_to_str(&pinfo->src);
  365. tick_stat_node(st, st_str_resps_by_srv_addr, 0, FALSE);
  366. resps_by_this_addr = tick_stat_node(st, ip_str, st_node_resps_by_srv_addr, TRUE);
  367. if ( (i>100)&&(i<400) ) {
  368. tick_stat_node(st, "OK", resps_by_this_addr, FALSE);
  369. } else {
  370. tick_stat_node(st, "KO", resps_by_this_addr, FALSE);
  371. }
  372. return 1;
  373. }
  374. return 0;
  375. }
  376. static int st_node_requests_by_host = -1;
  377. static const gchar *st_str_requests_by_host = "HTTP Requests by HTTP Host";
  378. /* HTTP/Requests stats init function */
  379. static void
  380. http_req_stats_tree_init(stats_tree* st)
  381. {
  382. st_node_requests_by_host = stats_tree_create_node(st, st_str_requests_by_host, 0, TRUE);
  383. }
  384. /* HTTP/Requests stats packet function */
  385. static int
  386. http_req_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
  387. {
  388. const http_info_value_t* v = (const http_info_value_t*)p;
  389. int reqs_by_this_host;
  390. if (v->request_method) {
  391. tick_stat_node(st, st_str_requests_by_host, 0, FALSE);
  392. if (v->http_host) {
  393. reqs_by_this_host = tick_stat_node(st, v->http_host, st_node_requests_by_host, TRUE);
  394. if (v->request_uri) {
  395. tick_stat_node(st, v->request_uri, reqs_by_this_host, TRUE);
  396. }
  397. }
  398. return 1;
  399. }
  400. return 0;
  401. }
  402. static const gchar *st_str_packets = "Total HTTP Packets";
  403. static const gchar *st_str_requests = "HTTP Request Packets";
  404. static const gchar *st_str_responses = "HTTP Response Packets";
  405. static const gchar *st_str_resp_broken = "???: broken";
  406. static const gchar *st_str_resp_100 = "1xx: Informational";
  407. static const gchar *st_str_resp_200 = "2xx: Success";
  408. static const gchar *st_str_resp_300 = "3xx: Redirection";
  409. static const gchar *st_str_resp_400 = "4xx: Client Error";
  410. static const gchar *st_str_resp_500 = "5xx: Server Error";
  411. static const gchar *st_str_other = "Other HTTP Packets";
  412. static int st_node_packets = -1;
  413. static int st_node_requests = -1;
  414. static int st_node_responses = -1;
  415. static int st_node_resp_broken = -1;
  416. static int st_node_resp_100 = -1;
  417. static int st_node_resp_200 = -1;
  418. static int st_node_resp_300 = -1;
  419. static int st_node_resp_400 = -1;
  420. static int st_node_resp_500 = -1;
  421. static int st_node_other = -1;
  422. /* HTTP/Packet Counter stats init function */
  423. static void
  424. http_stats_tree_init(stats_tree* st)
  425. {
  426. st_node_packets = stats_tree_create_node(st, st_str_packets, 0, TRUE);
  427. st_node_requests = stats_tree_create_pivot(st, st_str_requests, st_node_packets);
  428. st_node_responses = stats_tree_create_node(st, st_str_responses, st_node_packets, TRUE);
  429. st_node_resp_broken = stats_tree_create_node(st, st_str_resp_broken, st_node_responses, TRUE);
  430. st_node_resp_100 = stats_tree_create_node(st, st_str_resp_100, st_node_responses, TRUE);
  431. st_node_resp_200 = stats_tree_create_node(st, st_str_resp_200, st_node_responses, TRUE);
  432. st_node_resp_300 = stats_tree_create_node(st, st_str_resp_300, st_node_responses, TRUE);
  433. st_node_resp_400 = stats_tree_create_node(st, st_str_resp_400, st_node_responses, TRUE);
  434. st_node_resp_500 = stats_tree_create_node(st, st_str_resp_500, st_node_responses, TRUE);
  435. st_node_other = stats_tree_create_node(st, st_str_other, st_node_packets,FALSE);
  436. }
  437. /* HTTP/Packet Counter stats packet function */
  438. static int
  439. http_stats_tree_packet(stats_tree* st, packet_info* pinfo _U_, epan_dissect_t* edt _U_, const void* p)
  440. {
  441. const http_info_value_t* v = (const http_info_value_t*)p;
  442. guint i = v->response_code;
  443. int resp_grp;
  444. const gchar *resp_str;
  445. gchar str[64];
  446. tick_stat_node(st, st_str_packets, 0, FALSE);
  447. if (i) {
  448. tick_stat_node(st, st_str_responses, st_node_packets, FALSE);
  449. if ( (i<100)||(i>=600) ) {
  450. resp_grp = st_node_resp_broken;
  451. resp_str = st_str_resp_broken;
  452. } else if (i<200) {
  453. resp_grp = st_node_resp_100;
  454. resp_str = st_str_resp_100;
  455. } else if (i<300) {
  456. resp_grp = st_node_resp_200;
  457. resp_str = st_str_resp_200;
  458. } else if (i<400) {
  459. resp_grp = st_node_resp_300;
  460. resp_str = st_str_resp_300;
  461. } else if (i<500) {
  462. resp_grp = st_node_resp_400;
  463. resp_str = st_str_resp_400;
  464. } else {
  465. resp_grp = st_node_resp_500;
  466. resp_str = st_str_resp_500;
  467. }
  468. tick_stat_node(st, resp_str, st_node_responses, FALSE);
  469. g_snprintf(str, sizeof(str), "%u %s", i,
  470. val_to_str(i, vals_status_code, "Unknown (%d)"));
  471. tick_stat_node(st, str, resp_grp, FALSE);
  472. } else if (v->request_method) {
  473. stats_tree_tick_pivot(st,st_node_requests,v->request_method);
  474. } else {
  475. tick_stat_node(st, st_str_other, st_node_packets, FALSE);
  476. }
  477. return 1;
  478. }
  479. static void
  480. dissect_http_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  481. const char *line)
  482. {
  483. tvbuff_t *ntlmssp_tvb;
  484. ntlmssp_tvb = base64_to_tvb(tvb, line);
  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. static void
  492. dissect_http_kerberos(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
  493. const char *line)
  494. {
  495. tvbuff_t *kerberos_tvb;
  496. kerberos_tvb = base64_to_tvb(tvb, line + 9); /* skip 'Kerberos ' which is 9 chars */
  497. add_new_data_source(pinfo, kerberos_tvb, "Kerberos Data");
  498. call_dissector(gssapi_handle, kerberos_tvb, pinfo, tree);
  499. }
  500. static http_conv_t *
  501. get_http_conversation_data(packet_info *pinfo)
  502. {
  503. conversation_t *conversation;
  504. http_conv_t *conv_data;
  505. conversation = find_or_create_conversation(pinfo);
  506. /* Retrieve information from conversation
  507. * or add it if it isn't there yet
  508. */
  509. conv_data = (http_conv_t *)conversation_get_proto_data(conversation, proto_http);
  510. if(!conv_data) {
  511. /* Setup the conversation structure itself */
  512. conv_data = (http_conv_t *)wmem_alloc0(wmem_file_scope(), sizeof(http_conv_t));
  513. conversation_add_proto_data(conversation, proto_http,
  514. conv_data);
  515. }
  516. return conv_data;
  517. }
  518. /**
  519. * create a new http_req_res_t and add it to the conversation.
  520. * @return the new allocated object which is already added to the linked list
  521. */
  522. static http_req_res_t* push_req_res(http_conv_t *conv_data)
  523. {
  524. http_req_res_t *req_res = (http_req_res_t *)wmem_alloc0(wmem_file_scope(), sizeof(http_req_res_t));
  525. nstime_set_unset(&(req_res->req_ts));
  526. req_res->number = ++conv_data->req_res_num;
  527. if (! conv_data->req_res_tail) {
  528. conv_data->req_res_tail = req_res;
  529. } else {
  530. req_res->prev = conv_data->req_res_tail;
  531. conv_data->req_res_tail->next = req_res;
  532. conv_data->req_res_tail = req_res;
  533. }
  534. return req_res;
  535. }
  536. /**
  537. * push a request frame number and its time stamp to the conversation data.
  538. */
  539. static void push_req(http_conv_t *conv_data, packet_info *pinfo)
  540. {
  541. /* a request will always create a new http_req_res_t object */
  542. http_req_res_t *req_res = push_req_res(conv_data);
  543. req_res->req_framenum = pinfo->fd->num;
  544. req_res->req_ts = pinfo->fd->abs_ts;
  545. p_add_proto_data(pinfo->fd, proto_http, 0, req_res);
  546. }
  547. /**
  548. * push a response frame number to the conversation data.
  549. */
  550. static void push_res(http_conv_t *conv_data, packet_info *pinfo)
  551. {
  552. /* a response will create a new http_req_res_t object: if no
  553. object exists, or if one exists for another response. In
  554. both cases the corresponding request was not
  555. detected/included in the conversation. In all other cases
  556. the http_req_res_t object created by the request is
  557. used. */
  558. http_req_res_t *req_res = conv_data->req_res_tail;
  559. if (!req_res || req_res->res_framenum > 0) {
  560. req_res = push_req_res(conv_data);
  561. }
  562. req_res->res_framenum = pinfo->fd->num;
  563. p_add_proto_data(pinfo->fd, proto_http, 0, req_res);
  564. }
  565. /*
  566. * TODO: remove this ugly global variable.
  567. * XXX: do we really want to have to pass this from one function to another?
  568. */
  569. static http_info_value_t *stat_info;
  570. static int
  571. dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo,
  572. proto_tree *tree, http_conv_t *conv_data)
  573. {
  574. const char *proto_tag;
  575. proto_tree *http_tree = NULL;
  576. proto_item *ti = NULL;
  577. proto_item *hidden_item;
  578. const guchar *line;
  579. gint next_offset;
  580. const guchar *linep, *lineend;
  581. int orig_offset;
  582. int first_linelen, linelen;
  583. gboolean is_request_or_reply;
  584. gboolean saw_req_resp_or_header;
  585. guchar c;
  586. http_type_t http_type;
  587. proto_item *hdr_item = NULL;
  588. ReqRespDissector reqresp_dissector;
  589. proto_tree *req_tree;
  590. int colon_offset;
  591. headers_t headers;
  592. int datalen;
  593. int reported_datalen = -1;
  594. dissector_handle_t handle;
  595. gboolean dissected = FALSE;
  596. /*guint i;*/
  597. /*http_info_value_t *si;*/
  598. http_eo_t *eo_info;
  599. /*
  600. * Is this a request or response?
  601. *
  602. * Note that "tvb_find_line_end()" will return a value that
  603. * is not longer than what's in the buffer, so the
  604. * "tvb_get_ptr()" call won't throw an exception.
  605. */
  606. first_linelen = tvb_find_line_end(tvb, offset,
  607. tvb_ensure_length_remaining(tvb, offset), &next_offset,
  608. TRUE);
  609. if (first_linelen == -1) {
  610. /* No complete line was found in this segment, do
  611. * desegmentation if we're told to.
  612. */
  613. if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
  614. http_desegment_headers, http_desegment_body)) {
  615. /*
  616. * More data needed for desegmentation.
  617. */
  618. return -1;
  619. }
  620. }
  621. /*
  622. * Is the first line a request or response?
  623. */
  624. line = tvb_get_ptr(tvb, offset, first_linelen);
  625. http_type = HTTP_OTHERS; /* type not known yet */
  626. is_request_or_reply = is_http_request_or_reply((const gchar *)line,
  627. first_linelen, &http_type, NULL, conv_data);
  628. if (is_request_or_reply) {
  629. /*
  630. * Yes, it's a request or response.
  631. * Do header desegmentation if we've been told to,
  632. * and do body desegmentation if we've been told to and
  633. * we find a Content-Length header.
  634. */
  635. if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
  636. http_desegment_headers, http_desegment_body)) {
  637. /*
  638. * More data needed for desegmentation.
  639. */
  640. return -1;
  641. }
  642. }
  643. stat_info = ep_new(http_info_value_t);
  644. stat_info->framenum = pinfo->fd->num;
  645. stat_info->response_code = 0;
  646. stat_info->request_method = NULL;
  647. stat_info->request_uri = NULL;
  648. stat_info->http_host = NULL;
  649. switch (pinfo->match_uint) {
  650. case TCP_PORT_SSDP: /* TCP_PORT_SSDP = UDP_PORT_SSDP */
  651. proto_tag = "SSDP";
  652. break;
  653. default:
  654. proto_tag = "HTTP";
  655. break;
  656. }
  657. col_set_str(pinfo->cinfo, COL_PROTOCOL, proto_tag);
  658. /*
  659. * Put the first line from the buffer into the summary
  660. * if it's an HTTP request or reply (but leave out the
  661. * line terminator).
  662. * Otherwise, just call it a continuation.
  663. *
  664. * Note that "tvb_find_line_end()" will return a value that
  665. * is not longer than what's in the buffer, so the
  666. * "tvb_get_ptr()" call won't throw an exception.
  667. */
  668. if (is_request_or_reply) {
  669. line = tvb_get_ptr(tvb, offset, first_linelen);
  670. col_add_fstr(pinfo->cinfo, COL_INFO, "%s ", format_text(line, first_linelen));
  671. }
  672. else
  673. col_set_str(pinfo->cinfo, COL_INFO, "Continuation or non-HTTP traffic");
  674. orig_offset = offset;
  675. if (tree) {
  676. ti = proto_tree_add_item(tree, proto_http, tvb, offset, -1,
  677. ENC_NA);
  678. http_tree = proto_item_add_subtree(ti, ett_http);
  679. }
  680. /*
  681. * Process the packet data, a line at a time.
  682. */
  683. http_type = HTTP_OTHERS; /* type not known yet */
  684. headers.content_type = NULL; /* content type not known yet */
  685. headers.content_type_parameters = NULL; /* content type parameters too */
  686. headers.have_content_length = FALSE; /* content length not known yet */
  687. headers.content_length = 0; /* content length set to 0 (avoid a gcc warning) */
  688. headers.content_encoding = NULL; /* content encoding not known yet */
  689. headers.transfer_encoding = NULL; /* transfer encoding not known yet */
  690. headers.upgrade = 0; /* assume we're not upgrading */
  691. saw_req_resp_or_header = FALSE; /* haven't seen anything yet */
  692. while (tvb_reported_length_remaining(tvb, offset) != 0) {
  693. /*
  694. * Find the end of the line.
  695. * XXX - what if we don't find it because the packet
  696. * is cut short by a snapshot length or the header is
  697. * split across TCP segments? How much dissection should
  698. * we do on it?
  699. */
  700. linelen = tvb_find_line_end(tvb, offset,
  701. tvb_ensure_length_remaining(tvb, offset), &next_offset,
  702. FALSE);
  703. if (linelen < 0)
  704. return -1;
  705. /*
  706. * Get a buffer that refers to the line.
  707. */
  708. line = tvb_get_ptr(tvb, offset, linelen);
  709. lineend = line + linelen;
  710. colon_offset = -1;
  711. /*
  712. * OK, does it look like an HTTP request or response?
  713. */
  714. reqresp_dissector = NULL;
  715. is_request_or_reply =
  716. is_http_request_or_reply((const gchar *)line,
  717. linelen, &http_type, &reqresp_dissector, conv_data);
  718. if (is_request_or_reply)
  719. goto is_http;
  720. /*
  721. * No. Does it look like a blank line (as would appear
  722. * at the end of an HTTP request)?
  723. */
  724. if (linelen == 0)
  725. goto is_http; /* Yes. */
  726. /*
  727. * No. Does it look like a header?
  728. */
  729. linep = line;
  730. colon_offset = offset;
  731. while (linep < lineend) {
  732. c = *linep++;
  733. /*
  734. * This must be a CHAR to be part of a token; that
  735. * means it must be ASCII.
  736. */
  737. if (!isascii(c))
  738. break; /* not ASCII, thus not a CHAR */
  739. /*
  740. * This mustn't be a CTL to be part of a token.
  741. *
  742. * XXX - what about leading LWS on continuation
  743. * lines of a header?
  744. */
  745. if (iscntrl(c))
  746. break; /* CTL, not part of a header */
  747. /*
  748. * This mustn't be a SEP to be part of a token;
  749. * a ':' ends the token, everything else is an
  750. * indication that this isn't a header.
  751. */
  752. switch (c) {
  753. case '(':
  754. case ')':
  755. case '<':
  756. case '>':
  757. case '@':
  758. case ',':
  759. case ';':
  760. case '\\':
  761. case '"':
  762. case '/':
  763. case '[':
  764. case ']':
  765. case '?':
  766. case '=':
  767. case '{':
  768. case '}':
  769. case ' ':
  770. /*
  771. * It's a separator, so it's not part of a
  772. * token, so it's not a field name for the
  773. * beginning of a header.
  774. *
  775. * (We don't have to check for HT; that's
  776. * already been ruled out by "iscntrl()".)
  777. */
  778. goto not_http;
  779. case ':':
  780. /*
  781. * This ends the token; we consider this
  782. * to be a header.
  783. */
  784. goto is_http;
  785. default:
  786. colon_offset++;
  787. break;
  788. }
  789. }
  790. /*
  791. * We haven't seen the colon, but everything else looks
  792. * OK for a header line.
  793. *
  794. * If we've already seen an HTTP request or response
  795. * line, or a header line, and we're at the end of
  796. * the tvbuff, we assume this is an incomplete header
  797. * line. (We quit this loop after seeing a blank line,
  798. * so if we've seen a request or response line, or a
  799. * header line, this is probably more of the request
  800. * or response we're presumably seeing. There is some
  801. * risk of false positives, but the same applies for
  802. * full request or response lines or header lines,
  803. * although that's less likely.)
  804. *
  805. * We throw an exception in that case, by checking for
  806. * the existence of the next byte after the last one
  807. * in the line. If it exists, "tvb_ensure_bytes_exist()"
  808. * throws no exception, and we fall through to the
  809. * "not HTTP" case. If it doesn't exist,
  810. * "tvb_ensure_bytes_exist()" will throw the appropriate
  811. * exception.
  812. */
  813. if (saw_req_resp_or_header)
  814. tvb_ensure_bytes_exist(tvb, offset, linelen + 1);
  815. not_http:
  816. /*
  817. * We don't consider this part of an HTTP request or
  818. * reply, so we don't display it.
  819. * (Yeah, that means we don't display, say, a text/http
  820. * page, but you can get that from the data pane.)
  821. */
  822. break;
  823. is_http:
  824. /*
  825. * Process this line.
  826. */
  827. if (linelen == 0) {
  828. /*
  829. * This is a blank line, which means that
  830. * whatever follows it isn't part of this
  831. * request or reply.
  832. */
  833. proto_tree_add_text(http_tree, tvb, offset,
  834. next_offset - offset, "%s",
  835. tvb_format_text(tvb, offset, next_offset - offset));
  836. offset = next_offset;
  837. break;
  838. }
  839. /*
  840. * Not a blank line - either a request, a reply, or a header
  841. * line.
  842. */
  843. saw_req_resp_or_header = TRUE;
  844. if (is_request_or_reply) {
  845. char *text = tvb_format_text(tvb, offset, next_offset - offset);
  846. if (tree) {
  847. hdr_item = proto_tree_add_text(http_tree, tvb,
  848. offset, next_offset - offset, "%s", text);
  849. }
  850. expert_add_info_format_text(pinfo, hdr_item, &ei_http_chat, "%s", text);
  851. if (reqresp_dissector) {
  852. if (tree) req_tree = proto_item_add_subtree(hdr_item, ett_http_request);
  853. else req_tree = NULL;
  854. reqresp_dissector(tvb, req_tree, offset, line,
  855. lineend, conv_data);
  856. }
  857. } else {
  858. /*
  859. * Header.
  860. */
  861. process_header(tvb, offset, next_offset, line, linelen,
  862. colon_offset, pinfo, http_tree, &headers, conv_data);
  863. }
  864. offset = next_offset;
  865. }
  866. if (tree && stat_info->http_host && stat_info->request_uri) {
  867. proto_item *e_ti;
  868. gchar *uri = ep_strdup_printf("%s://%s%s",
  869. "http", /* XXX, https? */
  870. g_strstrip(ep_strdup(stat_info->http_host)), stat_info->request_uri);
  871. e_ti = proto_tree_add_string(http_tree,
  872. hf_http_request_full_uri, tvb, 0,
  873. 0, uri);
  874. PROTO_ITEM_SET_URL(e_ti);
  875. PROTO_ITEM_SET_GENERATED(e_ti);
  876. }
  877. if (!PINFO_FD_VISITED(pinfo)) {
  878. if (http_type == HTTP_REQUEST) {
  879. push_req(conv_data, pinfo);
  880. } else if (http_type == HTTP_RESPONSE) {
  881. push_res(conv_data, pinfo);
  882. }
  883. }
  884. if (tree) {
  885. proto_item *pi;
  886. http_req_res_t *curr = (http_req_res_t *)p_get_proto_data(pinfo->fd, proto_http, 0);
  887. http_req_res_t *prev = curr ? curr->prev : NULL;
  888. http_req_res_t *next = curr ? curr->next : NULL;
  889. switch (http_type) {
  890. case HTTP_NOTIFICATION:
  891. hidden_item = proto_tree_add_boolean(http_tree,
  892. hf_http_notification, tvb, 0, 0, 1);
  893. PROTO_ITEM_SET_HIDDEN(hidden_item);
  894. break;
  895. case HTTP_RESPONSE:
  896. hidden_item = proto_tree_add_boolean(http_tree,
  897. hf_http_response, tvb, 0, 0, 1);
  898. PROTO_ITEM_SET_HIDDEN(hidden_item);
  899. if (curr) {
  900. nstime_t delta;
  901. pi = proto_tree_add_text(http_tree, tvb, 0, 0, "HTTP response %u/%u", curr->number, conv_data->req_res_num);
  902. PROTO_ITEM_SET_GENERATED(pi);
  903. if (! nstime_is_unset(&(curr->req_ts))) {
  904. nstime_delta(&delta, &pinfo->fd->abs_ts, &(curr->req_ts));
  905. pi = proto_tree_add_time(http_tree, hf_http_time, tvb, 0, 0, &delta);
  906. PROTO_ITEM_SET_GENERATED(pi);
  907. }
  908. }
  909. if (prev && prev->req_framenum) {
  910. pi = proto_tree_add_uint(http_tree, hf_http_prev_request_in, tvb, 0, 0, prev->req_framenum);
  911. PROTO_ITEM_SET_GENERATED(pi);
  912. }
  913. if (prev && prev->res_framenum) {
  914. pi = proto_tree_add_uint(http_tree, hf_http_prev_response_in, tvb, 0, 0, prev->res_framenum);
  915. PROTO_ITEM_SET_GENERATED(pi);
  916. }
  917. if (curr && curr->req_framenum) {
  918. pi = proto_tree_add_uint(http_tree, hf_http_request_in, tvb, 0, 0, curr->req_framenum);
  919. PROTO_ITEM_SET_GENERATED(pi);
  920. }
  921. if (next && next->req_framenum) {
  922. pi = proto_tree_add_uint(http_tree, hf_http_next_request_in, tvb, 0, 0, next->req_framenum);
  923. PROTO_ITEM_SET_GENERATED(pi);
  924. }
  925. if (next && next->res_framenum) {
  926. pi = proto_tree_add_uint(http_tree, hf_http_next_response_in, tvb, 0, 0, next->res_framenum);
  927. PROTO_ITEM_SET_GENERATED(pi);
  928. }
  929. break;
  930. case HTTP_REQUEST:
  931. hidden_item = proto_tree_add_boolean(http_tree,
  932. hf_http_request, tvb, 0, 0, 1);
  933. PROTO_ITEM_SET_HIDDEN(hidden_item);
  934. if (curr) {
  935. pi = proto_tree_add_text(http_tree, tvb, 0, 0, "HTTP request %u/%u", curr->number, conv_data->req_res_num);
  936. PROTO_ITEM_SET_GENERATED(pi);
  937. }
  938. if (prev && prev->req_framenum) {
  939. pi = proto_tree_add_uint(http_tree, hf_http_prev_request_in, tvb, 0, 0, prev->req_framenum);
  940. PROTO_ITEM_SET_GENERATED(pi);
  941. }
  942. if (curr && curr->res_framenum) {
  943. pi = proto_tree_add_uint(http_tree, hf_http_response_in, tvb, 0, 0, curr->res_framenum);
  944. PROTO_ITEM_SET_GENERATED(pi);
  945. }
  946. if (next && next->req_framenum) {
  947. pi = proto_tree_add_uint(http_tree, hf_http_next_request_in, tvb, 0, 0, next->req_framenum);
  948. PROTO_ITEM_SET_GENERATED(pi);
  949. }
  950. break;
  951. case HTTP_OTHERS:
  952. default:
  953. break;
  954. }
  955. }
  956. reported_datalen = tvb_reported_length_remaining(tvb, offset);
  957. datalen = tvb_length_remaining(tvb, offset);
  958. /*
  959. * If a content length was supplied, the amount of data to be
  960. * processed as HTTP payload is the minimum of the content
  961. * length and the amount of data remaining in the frame.
  962. *
  963. * If a message is received with both a Transfer-Encoding
  964. * header field and a Content-Length header field, the latter
  965. * MUST be ignored.
  966. *
  967. * If no content length was supplied (or if a bad content length
  968. * was supplied), the amount of data to be processed is the amount
  969. * of data remaining in the frame.
  970. *
  971. * If there was no Content-Length entity header, we should
  972. * accumulate all data until the end of the connection.
  973. * That'd require that the TCP dissector call subdissectors
  974. * for all frames with FIN, even if they contain no data,
  975. * which would require subdissectors to deal intelligently
  976. * with empty segments.
  977. *
  978. * According to RFC 2616, however, 1xx responses, 204 responses,
  979. * and 304 responses MUST NOT include a message body; if no
  980. * content length is specified for them, we don't attempt to
  981. * dissect the body.
  982. *
  983. * XXX - it says the same about responses to HEAD requests;
  984. * unless there's a way to determine from the response
  985. * whether it's a response to a HEAD request, we have to
  986. * keep information about the request and associate that with
  987. * the response in order to handle that.
  988. */
  989. if (headers.have_content_length &&
  990. headers.content_length != -1 &&
  991. headers.transfer_encoding == NULL) {
  992. if (datalen > headers.content_length)
  993. datalen = (int)headers.content_length;
  994. /*
  995. * XXX - limit the reported length in the tvbuff we'll
  996. * hand to a subdissector to be no greater than the
  997. * content length.
  998. *
  999. * We really need both unreassembled and "how long it'd
  1000. * be if it were reassembled" lengths for tvbuffs, so
  1001. * that we throw the appropriate exceptions for
  1002. * "not enough data captured" (running past the length),
  1003. * "packet needed reassembly" (within the length but
  1004. * running past the unreassembled length), and
  1005. * "packet is malformed" (running past the reassembled
  1006. * length).
  1007. */
  1008. if (reported_datalen > headers.content_length)
  1009. reported_datalen = (int)headers.content_length;
  1010. } else {
  1011. switch (http_type) {
  1012. case HTTP_REQUEST:
  1013. /*
  1014. * Requests have no content if there's no
  1015. * Content-Length header and no Transfer-Encoding
  1016. * header.
  1017. */
  1018. if (headers.transfer_encoding == NULL)
  1019. datalen = 0;
  1020. else
  1021. reported_datalen = -1;
  1022. break;
  1023. case HTTP_RESPONSE:
  1024. if ((stat_info->response_code/100) == 1 ||
  1025. stat_info->response_code == 204 ||
  1026. stat_info->response_code == 304)
  1027. datalen = 0; /* no content! */
  1028. else {
  1029. /*
  1030. * XXX - responses to HEAD requests,
  1031. * and possibly other responses,
  1032. * "MUST NOT" include a
  1033. * message-body.
  1034. */
  1035. reported_datalen = -1;
  1036. }
  1037. break;
  1038. default:
  1039. /*
  1040. * XXX - what about HTTP_NOTIFICATION?
  1041. */
  1042. reported_datalen = -1;
  1043. break;
  1044. }
  1045. }
  1046. if (datalen > 0) {
  1047. /*
  1048. * There's stuff left over; process it.
  1049. */
  1050. tvbuff_t *next_tvb;
  1051. void *save_private_data = NULL;
  1052. gboolean private_data_changed = FALSE;
  1053. gint chunks_decoded = 0;
  1054. /*
  1055. * Create a tvbuff for the payload.
  1056. *
  1057. * The amount of data to be processed that's
  1058. * available in the tvbuff is "datalen", which
  1059. * is the minimum of the amount of data left in
  1060. * the tvbuff and any specified content length.
  1061. *
  1062. * The amount of data to be processed that's in
  1063. * this frame, regardless of whether it was
  1064. * captured or not, is "reported_datalen",
  1065. * which, if no content length was specified,
  1066. * is -1, i.e. "to the end of the frame.
  1067. */
  1068. next_tvb = tvb_new_subset(tvb, offset, datalen,
  1069. reported_datalen);
  1070. /*
  1071. * Handle *transfer* encodings other than "identity".
  1072. */
  1073. if (headers.transfer_encoding != NULL &&
  1074. g_ascii_strcasecmp(headers.transfer_encoding, "identity") != 0) {
  1075. if (http_dechunk_body &&
  1076. (g_ascii_strncasecmp(headers.transfer_encoding, "chunked", 7)
  1077. == 0)) {
  1078. chunks_decoded = chunked_encoding_dissector(
  1079. &next_tvb, pinfo, http_tree, 0);
  1080. if (chunks_decoded <= 0) {
  1081. /*
  1082. * The chunks weren't reassembled,
  1083. * or there was a single zero
  1084. * length chunk.
  1085. */
  1086. goto body_dissected;
  1087. } else {
  1088. /*
  1089. * Add a new data source for the
  1090. * de-chunked data.
  1091. */
  1092. #if 0 /* Handled in chunked_encoding_dissector() */
  1093. tvb_set_child_real_data_tvbuff(tvb,
  1094. next_tvb);
  1095. #endif
  1096. add_new_data_source(pinfo, next_tvb,
  1097. "De-chunked entity body");
  1098. }
  1099. } else {
  1100. /*
  1101. * We currently can't handle, for example,
  1102. * "gzip", "compress", or "deflate" as
  1103. * *transfer* encodings; just handle them
  1104. * as data for now.
  1105. */
  1106. call_dissector(data_handle, next_tvb, pinfo,
  1107. http_tree);
  1108. goto body_dissected;
  1109. }
  1110. }
  1111. /*
  1112. * At this point, any chunked *transfer* coding has been removed
  1113. * (the entity body has been dechunked) so it can be presented
  1114. * for the following operation (*content* encoding), or it has
  1115. * been been handed off to the data dissector.
  1116. *
  1117. * Handle *content* encodings other than "identity" (which
  1118. * shouldn't appear in a Content-Encoding header, but
  1119. * we handle it in any case).
  1120. */
  1121. if (headers.content_encoding != NULL &&
  1122. g_ascii_strcasecmp(headers.content_encoding, "identity") != 0) {
  1123. /*
  1124. * We currently can't handle, for example, "compress";
  1125. * just handle them as data for now.
  1126. *
  1127. * After July 7, 2004 the LZW patent expires, so support
  1128. * might be added then. However, I don't think that
  1129. * anybody ever really implemented "compress", due to
  1130. * the aforementioned patent.
  1131. */
  1132. tvbuff_t *uncomp_tvb = NULL;
  1133. proto_item *e_ti = NULL;
  1134. proto_tree *e_tree = NULL;
  1135. if (http_decompress_body &&
  1136. (g_ascii_strcasecmp(headers.content_encoding, "gzip") == 0 ||
  1137. g_ascii_strcasecmp(headers.content_encoding, "deflate") == 0 ||
  1138. g_ascii_strcasecmp(headers.content_encoding, "x-gzip") == 0 ||
  1139. g_ascii_strcasecmp(headers.content_encoding, "x-deflate") == 0))
  1140. {
  1141. uncomp_tvb = tvb_child_uncompress(tvb, next_tvb, 0,
  1142. tvb_length(next_tvb));
  1143. }
  1144. /*
  1145. * Add the encoded entity to the protocol tree
  1146. */
  1147. e_ti = proto_tree_add_text(http_tree, next_tvb,
  1148. 0, tvb_length(next_tvb),
  1149. "Content-encoded entity body (%s): %u bytes",
  1150. headers.content_encoding,
  1151. tvb_length(next_tvb));
  1152. e_tree = proto_item_add_subtree(e_ti,
  1153. ett_http_encoded_entity);
  1154. if (uncomp_tvb != NULL) {
  1155. /*
  1156. * Decompression worked
  1157. */
  1158. /* XXX - Don't free this, since it's possible
  1159. * that the data was only partially
  1160. * decompressed, such as when desegmentation
  1161. * isn't enabled.
  1162. *
  1163. tvb_free(next_tvb);
  1164. */
  1165. proto_item_append_text(e_ti, " -> %u bytes", tvb_length(uncomp_tvb));
  1166. next_tvb = uncomp_tvb;
  1167. add_new_data_source(pinfo, next_tvb,
  1168. "Uncompressed entity body");
  1169. } else {
  1170. proto_item_append_text(e_ti, " [Error: Decompression failed]");
  1171. call_dissector(data_handle, next_tvb, pinfo,
  1172. e_tree);
  1173. goto body_dissected;
  1174. }
  1175. }
  1176. /*
  1177. * Note that a new data source is added for the entity body
  1178. * only if it was content-encoded and/or transfer-encoded.
  1179. */
  1180. /* Save values for the Export Object GUI feature if we have
  1181. * an active listener to process it (which happens when
  1182. * the export object window is open). */
  1183. if(have_tap_listener(http_eo_tap)) {
  1184. eo_info = ep_new(http_eo_t);
  1185. eo_info->hostname = conv_data->http_host;
  1186. eo_info->filename = conv_data->request_uri;
  1187. eo_info->content_type = headers.content_type;
  1188. eo_info->payload_len = tvb_length(next_tvb);
  1189. eo_info->payload_data = tvb_get_ptr(next_tvb, 0, eo_info->payload_len);
  1190. tap_queue_packet(http_eo_tap, pinfo, eo_info);
  1191. }
  1192. /*
  1193. * Do subdissector checks.
  1194. *
  1195. * First, if we have a Content-Type value, check whether
  1196. * there's a subdissector for that media type.
  1197. */
  1198. handle = NULL;
  1199. if (headers.content_type != NULL) {
  1200. /*
  1201. * We didn't find any subdissector that
  1202. * registered for the port, and we have a
  1203. * Content-Type value. Is there any subdissector
  1204. * for that content type?
  1205. */
  1206. save_private_data = pinfo->private_data;
  1207. private_data_changed = TRUE;
  1208. if (headers.content_type_parameters)
  1209. pinfo->private_data = ep_strdup(headers.content_type_parameters);
  1210. else
  1211. pinfo->private_data = NULL;
  1212. /*
  1213. * Calling the string handle for the media type
  1214. * dissector table will set pinfo->match_string
  1215. * to headers.content_type for us.
  1216. */
  1217. pinfo->match_string = headers.content_type;
  1218. handle = dissector_get_string_handle(
  1219. media_type_subdissector_table,
  1220. headers.content_type);
  1221. if (handle == NULL &&
  1222. strncmp(headers.content_type, "multipart/", sizeof("multipart/")-1) == 0) {
  1223. /* Try to decode the unknown multipart subtype anyway */
  1224. handle = dissector_get_string_handle(
  1225. media_type_subdissector_table,
  1226. "multipart/");
  1227. }
  1228. }
  1229. /*
  1230. * Now, if we didn't find such a subdissector, check
  1231. * whether some subdissector asked that they be called
  1232. * if HTTP traffic was on some particular port. This
  1233. * handles protocols that use HTTP syntax but don't have
  1234. * a media type and instead use a specified port.
  1235. */
  1236. if (handle == NULL) {
  1237. handle = dissector_get_uint_handle(port_subdissector_table,
  1238. pinfo->match_uint);
  1239. }
  1240. if (handle != NULL) {
  1241. /*
  1242. * We have a subdissector - call it.
  1243. */
  1244. dissected = call_dissector_only(handle, next_tvb, pinfo, tree, NULL);
  1245. if (!dissected)
  1246. expert_add_info(pinfo, http_tree, &ei_http_subdissector_failed);
  1247. }
  1248. if (!dissected) {
  1249. /*
  1250. * We don't have a subdissector or we have one and it did not
  1251. * dissect the payload - try the heuristic subdissectors.
  1252. */
  1253. dissected = dissector_try_heuristic(heur_subdissector_list,
  1254. next_tvb, pinfo, tree, NULL);
  1255. }
  1256. if (dissected) {
  1257. /*
  1258. * The subdissector dissected the body.
  1259. * Fix up the top-level item so that it doesn't
  1260. * include the stuff for that protocol.
  1261. */
  1262. if (ti != NULL)
  1263. proto_item_set_len(ti, offset);
  1264. } else {
  1265. if (headers.content_type != NULL) {
  1266. /*
  1267. * Calling the default media handle if there is a content-type that
  1268. * wasn't handled above.
  1269. */
  1270. call_dissector(media_handle, next_tvb, pinfo, tree);
  1271. } else {
  1272. /* Call the default data dissector */
  1273. call_dissector(data_handle, next_tvb, pinfo, http_tree);
  1274. }
  1275. }
  1276. body_dissected:
  1277. /*
  1278. * Do *not* attempt at freeing the private data;
  1279. * it may be in use by subdissectors.
  1280. */
  1281. if (private_data_changed) /*restore even NULL value*/
  1282. pinfo->private_data = save_private_data;
  1283. /*
  1284. * We've processed "datalen" bytes worth of data
  1285. * (which may be no data at all); advance the
  1286. * offset past whatever data we've processed.
  1287. */
  1288. offset += datalen;
  1289. }
  1290. if (http_type == HTTP_RESPONSE && pinfo->desegment_offset<=0 && pinfo->desegment_len<=0) {
  1291. conv_data->upgrade = headers.upgrade;
  1292. conv_data->startframe = pinfo->fd->num + 1;
  1293. }
  1294. tap_queue_packet(http_tap, pinfo, stat_info);
  1295. return offset - orig_offset;
  1296. }
  1297. /* This can be used to dissect an HTTP request until such time
  1298. * that a more complete dissector is written for that HTTP request.
  1299. * This simple dissector only puts the request method, URI, and
  1300. * protocol version into a sub-tree.
  1301. */
  1302. static void
  1303. basic_request_dissector(tvbuff_t *tvb, proto_tree *tree, int offset,
  1304. const guchar *line, const guchar *lineend,
  1305. http_conv_t *conv_data)
  1306. {
  1307. const guchar *next_token;
  1308. const gchar *request_uri;
  1309. int tokenlen;
  1310. /* The first token is the method. */
  1311. tokenlen = get_token_len(line, lineend, &next_token);
  1312. if (tokenlen == 0)
  1313. return;
  1314. proto_tree_add_item(tree, hf_http_request_method, tvb, offset, tokenlen,
  1315. ENC_ASCII|ENC_NA);
  1316. if ((next_token - line) > 2 && next_token[-1] == ' ' && next_token[-2] == ' ') {
  1317. /* Two spaces in a now indicates empty URI, so roll back one here */
  1318. next_token--;
  1319. }
  1320. offset += (int) (next_token - line);
  1321. line = next_token;
  1322. /* The next token is the URI. */
  1323. tokenlen = get_token_len(line, lineend, &next_token);
  1324. /* Save the request URI for various later uses */
  1325. request_uri = tvb_get_ephemeral_string(tvb, offset, tokenlen);
  1326. stat_info->request_uri = ep_strdup(request_uri);
  1327. conv_data->request_uri = se_strdup(request_uri);
  1328. proto_tree_add_string(tree, hf_http_request_uri, tvb, offset, tokenlen,
  1329. request_uri);
  1330. offset += (int) (next_token - line);
  1331. line = next_token;
  1332. /* Everything to the end of the line is the version. */
  1333. tokenlen = (int) (lineend - line);
  1334. proto_tree_add_item(tree, hf_http_version, tvb, offset, tokenlen,
  1335. ENC_ASCII|ENC_NA);
  1336. }
  1337. static void
  1338. basic_response_dissector(tvbuff_t *tvb, proto_tree *tree, int offset,
  1339. const guchar *line, const guchar *lineend,
  1340. http_conv_t *conv_data _U_)
  1341. {
  1342. const guchar *next_token;
  1343. int tokenlen;
  1344. gchar response_code_chars[4];
  1345. /*
  1346. * The first token is the HTTP Version.
  1347. */
  1348. tokenlen = get_token_len(line, lineend, &next_token);
  1349. if (tokenlen == 0)
  1350. return;
  1351. proto_tree_add_item(tree, hf_http_version, tvb, offset, tokenlen,
  1352. ENC_ASCII|ENC_NA);
  1353. /* Advance to the start of the next token. */
  1354. offset += (int) (next_token - line);
  1355. line = next_token;
  1356. /*
  1357. * The second token is the Status Code.
  1358. */
  1359. tokenlen = get_token_len(line, lineend, &next_token);
  1360. if (tokenlen < 3)
  1361. return;
  1362. /* The Status Code characters must be copied into a null-terminated
  1363. * buffer for strtoul() to parse them into an unsigned integer value.
  1364. */
  1365. memcpy(response_code_chars, line, 3);
  1366. response_code_chars[3] = '\0';
  1367. stat_info->response_code = conv_data->response_code =
  1368. (guint)strtoul(response_code_chars, NULL, 10);
  1369. proto_tree_add_uint(tree, hf_http_response_code, tvb, offset, 3,
  1370. stat_info->response_code);
  1371. /* Advance to the start of the next token. */
  1372. offset += (int) (next_token - line);
  1373. line = next_token;
  1374. /*
  1375. * The remaining tokens in the line comprise the Reason Phrase.
  1376. */
  1377. tokenlen = (int) (lineend - line);
  1378. if (tokenlen < 1)
  1379. return;
  1380. proto_tree_add_item(tree, hf_http_response_phrase, tvb, offset,
  1381. tokenlen, ENC_ASCII|ENC_NA);
  1382. }
  1383. #if 0 /* XXX: Replaced by code creating the "Dechunked" tvb O(N) rather tan O(N^2) */
  1384. /*
  1385. * Dissect the http data chunks and add them to the tree.
  1386. */
  1387. static int
  1388. chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
  1389. proto_tree *tree, int offset)
  1390. {
  1391. guint8 *chunk_string = NULL;
  1392. guint32 chunk_size = 0;
  1393. gint chunk_offset = 0;
  1394. guint32 datalen = 0;
  1395. gint linelen = 0;
  1396. gint chunks_decoded = 0;
  1397. tvbuff_t *tvb = NULL;
  1398. tvbuff_t *new_tvb = NULL;
  1399. gint chunked_data_size = 0;
  1400. proto_tree *subtree = NULL;
  1401. proto_item *ti = NULL;
  1402. if (tvb_ptr == NULL || *tvb_ptr == NULL) {
  1403. return 0;
  1404. }
  1405. tvb = *tvb_ptr;
  1406. datalen = tvb_reported_length_remaining(tvb, offset);
  1407. if (tree) {
  1408. ti = proto_tree_add_text(tree, tvb, offset, datalen,
  1409. "HTTP chunked response");
  1410. subtree = proto_item_add_subtree(ti, ett_http_chunked_response);
  1411. }
  1412. while (datalen != 0) {
  1413. proto_item *chunk_ti = NULL;
  1414. proto_tree *chunk_subtree = NULL;
  1415. tvbuff_t *data_tvb = NULL; /* */
  1416. gchar *c = NULL;
  1417. guint8 *raw_data;
  1418. gint raw_len = 0;
  1419. linelen = tvb_find_line_end(tvb, offset, -1, &chunk_offset, TRUE);
  1420. if (linelen <= 0) {
  1421. /* Can't get the chunk size line */
  1422. break;
  1423. }
  1424. chunk_string = tvb_get_ephemeral_string(tvb, offset, linelen);
  1425. if (chunk_string == NULL) {
  1426. /* Can't get the chunk size line */
  1427. break;
  1428. }
  1429. c = (gchar*) chunk_string;
  1430. /*
  1431. * We don't care about the extensions.
  1432. */
  1433. if ((c = strchr(c, ';'))) {
  1434. *c = '\0';
  1435. }
  1436. chunk_size = strtol((gchar*)chunk_string, NULL, 16);
  1437. if (chunk_size > datalen) {
  1438. /*
  1439. * The chunk size is more than what's in the tvbuff,
  1440. * so either the user hasn't enabled decoding, or all
  1441. * of the segments weren't captured.
  1442. */
  1443. chunk_size = datalen;
  1444. }
  1445. #if 0
  1446. else if (new_tvb == NULL) {
  1447. new_tvb = tvb_new_composite();
  1448. }
  1449. if (new_tvb != NULL && chunk_size != 0) {
  1450. tvbuff_t *chunk_tvb = NULL;
  1451. chunk_tvb = tvb_new_subset(tvb, chunk_offset,
  1452. chunk_size, datalen);
  1453. tvb_composite_append(new_tvb, chunk_tvb);
  1454. }
  1455. #endif
  1456. chunked_data_size += chunk_size;
  1457. raw_data = g_malloc(chunked_data_size);
  1458. raw_len = 0;
  1459. if (new_tvb != NULL) {
  1460. raw_len = tvb_length_remaining(new_tvb, 0);
  1461. tvb_memcpy(new_tvb, raw_data, 0, raw_len);
  1462. tvb_free(new_tvb);
  1463. }
  1464. tvb_memcpy(tvb, (guint8 *)(raw_data + raw_len),
  1465. chunk_offset, chunk_size);
  1466. /* Don't create a new tvb if we have a single chunk with
  1467. * a size of zero (meaning it is the end of the chunks). */
  1468. if(chunked_data_size > 0) {
  1469. new_tvb = tvb_new_real_data(raw_data,

Large files files are truncated, but you can click here to view the full file