PageRenderTime 58ms CodeModel.GetById 16ms 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
  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,
  1470. chunked_data_size, chunked_data_size);
  1471. tvb_set_free_cb(new_tvb, g_free);
  1472. }
  1473. if (subtree) {
  1474. if(chunk_size == 0) {
  1475. chunk_ti = proto_tree_add_text(subtree, tvb,
  1476. offset,
  1477. chunk_offset - offset + chunk_size + 2,
  1478. "End of chunked encoding");
  1479. } else {
  1480. chunk_ti = proto_tree_add_text(subtree, tvb,
  1481. offset,
  1482. chunk_offset - offset + chunk_size + 2,
  1483. "Data chunk (%u octets)", chunk_size);
  1484. }
  1485. chunk_subtree = proto_item_add_subtree(chunk_ti,
  1486. ett_http_chunk_data);
  1487. proto_tree_add_text(chunk_subtree, tvb, offset,
  1488. chunk_offset - offset, "Chunk size: %u octets",
  1489. chunk_size);
  1490. data_tvb = tvb_new_subset(tvb, chunk_offset, chunk_size, chunk_size);
  1491. /*
  1492. * XXX - just use "proto_tree_add_text()"?
  1493. * This means that, in TShark, you get
  1494. * the entire chunk dumped out in hex,
  1495. * in addition to whatever dissection is
  1496. * done on the reassembled data.
  1497. */
  1498. call_dissector(data_handle, data_tvb, pinfo,
  1499. chunk_subtree);
  1500. proto_tree_add_text(chunk_subtree, tvb, chunk_offset +
  1501. chunk_size, 2, "Chunk boundary");
  1502. }
  1503. chunks_decoded++;
  1504. offset = chunk_offset + chunk_size + 2;
  1505. datalen = tvb_reported_length_remaining(tvb, offset);
  1506. }
  1507. if (new_tvb != NULL) {
  1508. /* Placeholder for the day that composite tvbuffer's will work.
  1509. tvb_composite_finalize(new_tvb);
  1510. / * tvb_set_reported_length(new_tvb, chunked_data_size); * /
  1511. */
  1512. /*
  1513. * XXX - Don't free this, since the tvbuffer that was passed
  1514. * may be used if the data spans multiple frames and reassembly
  1515. * isn't enabled.
  1516. *
  1517. tvb_free(*tvb_ptr);
  1518. */
  1519. *tvb_ptr = new_tvb;
  1520. } else {
  1521. /*
  1522. * We didn't create a new tvb, so don't allow sub dissectors
  1523. * try to decode the non-existent entity body.
  1524. */
  1525. chunks_decoded = -1;
  1526. }
  1527. return chunks_decoded;
  1528. }
  1529. #else
  1530. /*
  1531. * Dissect the http data chunks and add them to the tree.
  1532. */
  1533. static int
  1534. chunked_encoding_dissector(tvbuff_t **tvb_ptr, packet_info *pinfo,
  1535. proto_tree *tree, int offset)
  1536. {
  1537. tvbuff_t *tvb;
  1538. guint32 datalen;
  1539. guint32 orig_datalen;
  1540. gint chunks_decoded;
  1541. gint chunked_data_size;
  1542. proto_tree *subtree;
  1543. guint8 *raw_data;
  1544. gint raw_len;
  1545. if ((tvb_ptr == NULL) || (*tvb_ptr == NULL)) {
  1546. return 0;
  1547. }
  1548. tvb = *tvb_ptr;
  1549. datalen = tvb_reported_length_remaining(tvb, offset);
  1550. subtree = NULL;
  1551. if (tree) {
  1552. proto_item *ti;
  1553. ti = proto_tree_add_text(tree, tvb, offset, datalen,
  1554. "HTTP chunked response");
  1555. subtree = proto_item_add_subtree(ti, ett_http_chunked_response);
  1556. }
  1557. /* Dechunk the "chunked response" to a new memory buffer */
  1558. orig_datalen = datalen;
  1559. raw_data = (guint8 *)wmem_alloc(pinfo->pool, datalen);
  1560. raw_len = 0;
  1561. chunks_decoded = 0;
  1562. chunked_data_size = 0;
  1563. while (datalen != 0) {
  1564. tvbuff_t *data_tvb;
  1565. guint32 chunk_size;
  1566. gint chunk_offset;
  1567. guint8 *chunk_string;
  1568. gint linelen;
  1569. gchar *c;
  1570. linelen = tvb_find_line_end(tvb, offset, -1, &chunk_offset, TRUE);
  1571. if (linelen <= 0) {
  1572. /* Can't get the chunk size line */
  1573. break;
  1574. }
  1575. chunk_string = tvb_get_ephemeral_string(tvb, offset, linelen);
  1576. if (chunk_string == NULL) {
  1577. /* Can't get the chunk size line */
  1578. break;
  1579. }
  1580. c = (gchar*)chunk_string;
  1581. /*
  1582. * We don't care about the extensions.
  1583. */
  1584. if ((c = strchr(c, ';'))) {
  1585. *c = '\0';
  1586. }
  1587. chunk_size = (guint32)strtol((gchar*)chunk_string, NULL, 16);
  1588. if (chunk_size > datalen) {
  1589. /*
  1590. * The chunk size is more than what's in the tvbuff,
  1591. * so either the user hasn't enabled decoding, or all
  1592. * of the segments weren't captured.
  1593. */
  1594. chunk_size = datalen;
  1595. }
  1596. chunked_data_size += chunk_size;
  1597. DISSECTOR_ASSERT((raw_len+chunk_size) <= orig_datalen);
  1598. tvb_memcpy(tvb, (guint8 *)(raw_data + raw_len), chunk_offset, chunk_size);
  1599. raw_len += chunk_size;
  1600. if (subtree) {
  1601. proto_item *chunk_ti;
  1602. proto_tree *chunk_subtree;
  1603. if(chunk_size == 0) {
  1604. chunk_ti = proto_tree_add_text(subtree, tvb,
  1605. offset,
  1606. chunk_offset - offset + chunk_size + 2,
  1607. "End of chunked encoding");
  1608. } else {
  1609. chunk_ti = proto_tree_add_text(subtree, tvb,
  1610. offset,
  1611. chunk_offset - offset + chunk_size + 2,
  1612. "Data chunk (%u octets)", chunk_size);
  1613. }
  1614. chunk_subtree = proto_item_add_subtree(chunk_ti,
  1615. ett_http_chunk_data);
  1616. proto_tree_add_text(chunk_subtree, tvb, offset,
  1617. chunk_offset - offset, "Chunk size: %u octets",
  1618. chunk_size);
  1619. data_tvb = tvb_new_subset(tvb, chunk_offset, chunk_size, datalen);
  1620. /*
  1621. * XXX - just use "proto_tree_add_text()"?
  1622. * This means that, in TShark, you get
  1623. * the entire chunk dumped out in hex,
  1624. * in addition to whatever dissection is
  1625. * done on the reassembled data.
  1626. */
  1627. call_dissector(data_handle, data_tvb, pinfo,
  1628. chunk_subtree);
  1629. proto_tree_add_text(chunk_subtree, tvb, chunk_offset +
  1630. chunk_size, 2, "Chunk boundary");
  1631. }
  1632. chunks_decoded++;
  1633. offset = chunk_offset + 2 + chunk_size; /* beginning of next chunk */
  1634. datalen = tvb_reported_length_remaining(tvb, offset);
  1635. }
  1636. if (chunked_data_size > 0) {
  1637. tvbuff_t *new_tvb;
  1638. new_tvb = tvb_new_child_real_data(tvb, raw_data, chunked_data_size, chunked_data_size);
  1639. *tvb_ptr = new_tvb;
  1640. } else {
  1641. /*
  1642. * There was no actual chunk data, so don't allow sub dissectors
  1643. * try to decode the non-existent entity body.
  1644. */
  1645. chunks_decoded = -1;
  1646. }
  1647. return chunks_decoded;
  1648. }
  1649. #endif
  1650. /* Call a subdissector to handle HTTP CONNECT's traffic */
  1651. static void
  1652. http_payload_subdissector(tvbuff_t *tvb, proto_tree *tree,
  1653. packet_info *pinfo, http_conv_t *conv_data)
  1654. {
  1655. guint32 *ptr = NULL;
  1656. guint32 uri_port, saved_port, srcport, destport;
  1657. gchar **strings; /* An array for splitting the request URI into hostname and port */
  1658. proto_item *item;
  1659. proto_tree *proxy_tree;
  1660. conversation_t *conv;
  1661. /* Grab the destination port number from the request URI to find the right subdissector */
  1662. strings = g_strsplit(conv_data->request_uri, ":", 2);
  1663. if(strings[0] != NULL && strings[1] != NULL) {
  1664. /*
  1665. * The string was successfully split in two
  1666. * Create a proxy-connect subtree
  1667. */
  1668. if(tree) {
  1669. item = proto_tree_add_item(tree, proto_http, tvb, 0, -1, ENC_NA);
  1670. proxy_tree = proto_item_add_subtree(item, ett_http);
  1671. item = proto_tree_add_string(proxy_tree, hf_http_proxy_connect_host,
  1672. tvb, 0, 0, strings[0]);
  1673. PROTO_ITEM_SET_GENERATED(item);
  1674. item = proto_tree_add_uint(proxy_tree, hf_http_proxy_connect_port,
  1675. tvb, 0, 0, (guint32)strtol(strings[1], NULL, 10) );
  1676. PROTO_ITEM_SET_GENERATED(item);
  1677. }
  1678. uri_port = (int)strtol(strings[1], NULL, 10); /* Convert string to a base-10 integer */
  1679. if (value_is_in_range(http_tcp_range, pinfo->destport)) {
  1680. srcport = pinfo->srcport;
  1681. destport = uri_port;
  1682. } else {
  1683. srcport = uri_port;
  1684. destport = pinfo->destport;
  1685. }
  1686. conv = find_conversation(PINFO_FD_NUM(pinfo), &pinfo->src, &pinfo->dst, PT_TCP, srcport, destport, 0);
  1687. /* We may get stuck in a recursion loop if we let process_tcp_payload() call us.
  1688. * So, if the port in the URI is one we're registered for or we have set up a
  1689. * conversation (e.g., one we detected heuristically or via Decode-As) call the data
  1690. * dissector directly.
  1691. */
  1692. if (value_is_in_range(http_tcp_range, uri_port) || (conv && conv->dissector_handle == http_handle)) {
  1693. call_dissector(data_handle, tvb, pinfo, tree);
  1694. } else {
  1695. /* set pinfo->{src/dst port} and call the TCP sub-dissector lookup */
  1696. if (value_is_in_range(http_tcp_range, pinfo->destport))
  1697. ptr = &pinfo->destport;
  1698. else
  1699. ptr = &pinfo->srcport;
  1700. /* Increase pinfo->can_desegment because we are traversing
  1701. * http and want to preserve desegmentation functionality for
  1702. * the proxied protocol
  1703. */
  1704. if( pinfo->can_desegment>0 )
  1705. pinfo->can_desegment++;
  1706. saved_port = *ptr;
  1707. *ptr = uri_port;
  1708. decode_tcp_ports(tvb, 0, pinfo, tree,
  1709. pinfo->srcport, pinfo->destport, NULL);
  1710. *ptr = saved_port;
  1711. }
  1712. }
  1713. g_strfreev(strings); /* Free the result of g_strsplit() above */
  1714. }
  1715. /*
  1716. * XXX - this won't handle HTTP 0.9 replies, but they're all data
  1717. * anyway.
  1718. */
  1719. static int
  1720. is_http_request_or_reply(const gchar *data, int linelen, http_type_t *type,
  1721. ReqRespDissector *reqresp_dissector,
  1722. http_conv_t *conv_data)
  1723. {
  1724. int isHttpRequestOrReply = FALSE;
  1725. /*
  1726. * From RFC 2774 - An HTTP Extension Framework
  1727. *
  1728. * Support the command prefix that identifies the presence of
  1729. * a "mandatory" header.
  1730. */
  1731. if (linelen >= 2 && strncmp(data, "M-", 2) == 0) {
  1732. data += 2;
  1733. linelen -= 2;
  1734. }
  1735. /*
  1736. * From draft-cohen-gena-client-01.txt, available from the uPnP forum:
  1737. * NOTIFY, SUBSCRIBE, UNSUBSCRIBE
  1738. *
  1739. * From draft-ietf-dasl-protocol-00.txt, a now vanished Microsoft draft:
  1740. * SEARCH
  1741. */
  1742. if (linelen >= 5 && strncmp(data, "HTTP/", 5) == 0) {
  1743. *type = HTTP_RESPONSE;
  1744. isHttpRequestOrReply = TRUE; /* response */
  1745. if (reqresp_dissector)
  1746. *reqresp_dissector = basic_response_dissector;
  1747. } else {
  1748. const guchar * ptr = (const guchar *)data;
  1749. int indx = 0;
  1750. /* Look for the space following the Method */
  1751. while (indx < linelen) {
  1752. if (*ptr == ' ')
  1753. break;
  1754. else {
  1755. ptr++;
  1756. indx++;
  1757. }
  1758. }
  1759. /* Check the methods that have same length */
  1760. switch (indx) {
  1761. case 3:
  1762. if (strncmp(data, "GET", indx) == 0 ||
  1763. strncmp(data, "PUT", indx) == 0) {
  1764. *type = HTTP_REQUEST;
  1765. isHttpRequestOrReply = TRUE;
  1766. }
  1767. else if (strncmp(data, "ICY", indx) == 0) {
  1768. *type = HTTP_RESPONSE;
  1769. isHttpRequestOrReply = TRUE;
  1770. }
  1771. break;
  1772. case 4:
  1773. if (strncmp(data, "COPY", indx) == 0 ||
  1774. strncmp(data, "HEAD", indx) == 0 ||
  1775. strncmp(data, "LOCK", indx) == 0 ||
  1776. strncmp(data, "MOVE", indx) == 0 ||
  1777. strncmp(data, "POLL", indx) == 0 ||
  1778. strncmp(data, "POST", indx) == 0) {
  1779. *type = HTTP_REQUEST;
  1780. isHttpRequestOrReply = TRUE;
  1781. }
  1782. break;
  1783. case 5:
  1784. if (strncmp(data, "BCOPY", indx) == 0 ||
  1785. strncmp(data, "BMOVE", indx) == 0 ||
  1786. strncmp(data, "MKCOL", indx) == 0 ||
  1787. strncmp(data, "TRACE", indx) == 0 ||
  1788. strncmp(data, "LABEL", indx) == 0 || /* RFC 3253 8.2 */
  1789. strncmp(data, "MERGE", indx) == 0) { /* RFC 3253 11.2 */
  1790. *type = HTTP_REQUEST;
  1791. isHttpRequestOrReply = TRUE;
  1792. }
  1793. break;
  1794. case 6:
  1795. if (strncmp(data, "DELETE", indx) == 0 ||
  1796. strncmp(data, "SEARCH", indx) == 0 ||
  1797. strncmp(data, "UNLOCK", indx) == 0 ||
  1798. strncmp(data, "REPORT", indx) == 0 || /* RFC 3253 3.6 */
  1799. strncmp(data, "UPDATE", indx) == 0) { /* RFC 3253 7.1 */
  1800. *type = HTTP_REQUEST;
  1801. isHttpRequestOrReply = TRUE;
  1802. }
  1803. else if (strncmp(data, "NOTIFY", indx) == 0) {
  1804. *type = HTTP_NOTIFICATION;
  1805. isHttpRequestOrReply = TRUE;
  1806. }
  1807. break;
  1808. case 7:
  1809. if (strncmp(data, "BDELETE", indx) == 0 ||
  1810. strncmp(data, "CONNECT", indx) == 0 ||
  1811. strncmp(data, "OPTIONS", indx) == 0 ||
  1812. strncmp(data, "CHECKIN", indx) == 0) { /* RFC 3253 4.4, 9.4 */
  1813. *type = HTTP_REQUEST;
  1814. isHttpRequestOrReply = TRUE;
  1815. }
  1816. break;
  1817. case 8:
  1818. if (strncmp(data, "PROPFIND", indx) == 0 ||
  1819. strncmp(data, "CHECKOUT", indx) == 0 || /* RFC 3253 4.3, 9.3 */
  1820. strncmp(data, "CCM_POST", indx) == 0) {
  1821. *type = HTTP_REQUEST;
  1822. isHttpRequestOrReply = TRUE;
  1823. }
  1824. break;
  1825. case 9:
  1826. if (strncmp(data, "SUBSCRIBE", indx) == 0) {
  1827. *type = HTTP_NOTIFICATION;
  1828. isHttpRequestOrReply = TRUE;
  1829. } else if (strncmp(data, "PROPPATCH", indx) == 0 ||
  1830. strncmp(data, "BPROPFIND", indx) == 0) {
  1831. *type = HTTP_REQUEST;
  1832. isHttpRequestOrReply = TRUE;
  1833. }
  1834. break;
  1835. case 10:
  1836. if (strncmp(data, "BPROPPATCH", indx) == 0 ||
  1837. strncmp(data, "UNCHECKOUT", indx) == 0 || /* RFC 3253 4.5 */
  1838. strncmp(data, "MKACTIVITY", indx) == 0) { /* RFC 3253 13.5 */
  1839. *type = HTTP_REQUEST;
  1840. isHttpRequestOrReply = TRUE;
  1841. }
  1842. break;
  1843. case 11:
  1844. if (strncmp(data, "MKWORKSPACE", indx) == 0 || /* RFC 3253 6.3 */
  1845. strncmp(data, "RPC_CONNECT", indx) == 0 || /* [MS-RPCH] 2.1.1.1.1 */
  1846. strncmp(data, "RPC_IN_DATA", indx) == 0) { /* [MS-RPCH] 2.1.2.1.1 */
  1847. *type = HTTP_REQUEST;
  1848. isHttpRequestOrReply = TRUE;
  1849. } else if (strncmp(data, "UNSUBSCRIBE", indx) == 0) {
  1850. *type = HTTP_NOTIFICATION;
  1851. isHttpRequestOrReply = TRUE;
  1852. }
  1853. break;
  1854. case 12:
  1855. if (strncmp(data, "RPC_OUT_DATA", indx) == 0) { /* [MS-RPCH] 2.1.2.1.2 */
  1856. *type = HTTP_REQUEST;
  1857. isHttpRequestOrReply = TRUE;
  1858. }
  1859. break;
  1860. case 15:
  1861. if (strncmp(data, "VERSION-CONTROL", indx) == 0) { /* RFC 3253 3.5 */
  1862. *type = HTTP_REQUEST;
  1863. isHttpRequestOrReply = TRUE;
  1864. }
  1865. break;
  1866. case 16:
  1867. if (strncmp(data, "BASELINE-CONTROL", indx) == 0) { /* RFC 3253 12.6 */
  1868. *type = HTTP_REQUEST;
  1869. isHttpRequestOrReply = TRUE;
  1870. }
  1871. break;
  1872. default:
  1873. break;
  1874. }
  1875. if (isHttpRequestOrReply && reqresp_dissector) {
  1876. *reqresp_dissector = basic_request_dissector;
  1877. stat_info->request_method = ep_strndup(data, indx+1);
  1878. conv_data->request_method = se_strndup(data, indx+1);
  1879. }
  1880. }
  1881. return isHttpRequestOrReply;
  1882. }
  1883. /*
  1884. * Process headers.
  1885. */
  1886. typedef struct {
  1887. const char *name;
  1888. gint *hf;
  1889. int special;
  1890. } header_info;
  1891. #define HDR_NO_SPECIAL 0
  1892. #define HDR_AUTHORIZATION 1
  1893. #define HDR_AUTHENTICATE 2
  1894. #define HDR_CONTENT_TYPE 3
  1895. #define HDR_CONTENT_LENGTH 4
  1896. #define HDR_CONTENT_ENCODING 5
  1897. #define HDR_TRANSFER_ENCODING 6
  1898. #define HDR_HOST 7
  1899. #define HDR_UPGRADE 8
  1900. static const header_info headers[] = {
  1901. { "Authorization", &hf_http_authorization, HDR_AUTHORIZATION },
  1902. { "Proxy-Authorization", &hf_http_proxy_authorization, HDR_AUTHORIZATION },
  1903. { "Proxy-Authenticate", &hf_http_proxy_authenticate, HDR_AUTHENTICATE },
  1904. { "WWW-Authenticate", &hf_http_www_authenticate, HDR_AUTHENTICATE },
  1905. { "Content-Type", &hf_http_content_type, HDR_CONTENT_TYPE },
  1906. { "Content-Length", &hf_http_content_length_header, HDR_CONTENT_LENGTH },
  1907. { "Content-Encoding", &hf_http_content_encoding, HDR_CONTENT_ENCODING },
  1908. { "Transfer-Encoding", &hf_http_transfer_encoding, HDR_TRANSFER_ENCODING },
  1909. { "Upgrade", &hf_http_upgrade, HDR_UPGRADE },
  1910. { "User-Agent", &hf_http_user_agent, HDR_NO_SPECIAL },
  1911. { "Host", &hf_http_host, HDR_HOST },
  1912. { "Connection", &hf_http_connection, HDR_NO_SPECIAL },
  1913. { "Cookie", &hf_http_cookie, HDR_NO_SPECIAL },
  1914. { "Accept", &hf_http_accept, HDR_NO_SPECIAL },
  1915. { "Referer", &hf_http_referer, HDR_NO_SPECIAL },
  1916. { "Accept-Language", &hf_http_accept_language, HDR_NO_SPECIAL },
  1917. { "Accept-Encoding", &hf_http_accept_encoding, HDR_NO_SPECIAL },
  1918. { "Date", &hf_http_date, HDR_NO_SPECIAL },
  1919. { "Cache-Control", &hf_http_cache_control, HDR_NO_SPECIAL },
  1920. { "Server", &hf_http_server, HDR_NO_SPECIAL },
  1921. { "Location", &hf_http_location, HDR_NO_SPECIAL },
  1922. { "Sec-WebSocket-Accept", &hf_http_sec_websocket_accept, HDR_NO_SPECIAL },
  1923. { "Sec-WebSocket-Extensions", &hf_http_sec_websocket_extensions, HDR_NO_SPECIAL },
  1924. { "Sec-WebSocket-Key", &hf_http_sec_websocket_key, HDR_NO_SPECIAL },
  1925. { "Sec-WebSocket-Protocol", &hf_http_sec_websocket_protocol, HDR_NO_SPECIAL },
  1926. { "Sec-WebSocket-Version", &hf_http_sec_websocket_version, HDR_NO_SPECIAL },
  1927. { "Set-Cookie", &hf_http_set_cookie, HDR_NO_SPECIAL },
  1928. { "Last-Modified", &hf_http_last_modified, HDR_NO_SPECIAL },
  1929. { "X-Forwarded-For", &hf_http_x_forwarded_for, HDR_NO_SPECIAL },
  1930. };
  1931. /*
  1932. *
  1933. */
  1934. static gint*
  1935. get_hf_for_header(char* header_name)
  1936. {
  1937. gint* hf_id = NULL;
  1938. if (header_fields_hash) {
  1939. hf_id = (gint*) g_hash_table_lookup(header_fields_hash, header_name);
  1940. } else {
  1941. hf_id = NULL;
  1942. }
  1943. return hf_id;
  1944. }
  1945. /*
  1946. *
  1947. */
  1948. static void
  1949. header_fields_initialize_cb(void)
  1950. {
  1951. static hf_register_info* hf;
  1952. gint* hf_id;
  1953. guint i;
  1954. gchar* header_name;
  1955. if (header_fields_hash && hf) {
  1956. guint hf_size = g_hash_table_size (header_fields_hash);
  1957. /* Unregister all fields */
  1958. for (i = 0; i < hf_size; i++) {
  1959. proto_unregister_field (proto_http, *(hf[i].p_id));
  1960. g_free (hf[i].p_id);
  1961. g_free ((char *) hf[i].hfinfo.name);
  1962. g_free ((char *) hf[i].hfinfo.abbrev);
  1963. g_free ((char *) hf[i].hfinfo.blurb);
  1964. }
  1965. g_hash_table_destroy (header_fields_hash);
  1966. g_free (hf);
  1967. header_fields_hash = NULL;
  1968. }
  1969. if (num_header_fields) {
  1970. header_fields_hash = g_hash_table_new(g_str_hash, g_str_equal);
  1971. hf = g_new0(hf_register_info, num_header_fields);
  1972. for (i = 0; i < num_header_fields; i++) {
  1973. hf_id = g_new(gint,1);
  1974. *hf_id = -1;
  1975. header_name = g_strdup(header_fields[i].header_name);
  1976. hf[i].p_id = hf_id;
  1977. hf[i].hfinfo.name = header_name;
  1978. hf[i].hfinfo.abbrev = g_strdup_printf("http.header.%s", header_name);
  1979. hf[i].hfinfo.type = FT_STRING;
  1980. hf[i].hfinfo.display = BASE_NONE;
  1981. hf[i].hfinfo.strings = NULL;
  1982. hf[i].hfinfo.blurb = g_strdup(header_fields[i].header_desc);
  1983. hf[i].hfinfo.same_name_prev_id = -1;
  1984. hf[i].hfinfo.same_name_next = NULL;
  1985. g_hash_table_insert(header_fields_hash, header_name, hf_id);
  1986. }
  1987. proto_register_field_array(proto_http, hf, num_header_fields);
  1988. }
  1989. }
  1990. static void
  1991. process_header(tvbuff_t *tvb, int offset, int next_offset,
  1992. const guchar *line, int linelen, int colon_offset,
  1993. packet_info *pinfo, proto_tree *tree, headers_t *eh_ptr,
  1994. http_conv_t *conv_data)
  1995. {
  1996. int len;
  1997. int line_end_offset;
  1998. int header_len;
  1999. gint hf_index;
  2000. guchar c;
  2001. int value_offset;
  2002. int value_len;
  2003. char *value;
  2004. char *header_name;
  2005. char *p;
  2006. guchar *up;
  2007. proto_item *hdr_item;
  2008. int i;
  2009. int* hf_id;
  2010. len = next_offset - offset;
  2011. line_end_offset = offset + linelen;
  2012. header_len = colon_offset - offset;
  2013. header_name = se_strndup(&line[0], header_len);
  2014. hf_index = find_header_hf_value(tvb, offset, header_len);
  2015. /*
  2016. * Skip whitespace after the colon.
  2017. */
  2018. value_offset = colon_offset + 1;
  2019. while (value_offset < line_end_offset
  2020. && ((c = line[value_offset - offset]) == ' ' || c == '\t'))
  2021. value_offset++;
  2022. /*
  2023. * Fetch the value.
  2024. *
  2025. * XXX - the line may well have a NUL in it. Wireshark should
  2026. * really treat strings extracted from packets as counted
  2027. * strings, so that NUL isn't any different from any other
  2028. * character. For now, we just allocate a buffer that's
  2029. * value_len+1 bytes long, copy value_len bytes, and stick
  2030. * in a NUL terminator, so that the buffer for value actually
  2031. * has value_len bytes in it.
  2032. */
  2033. value_len = line_end_offset - value_offset;
  2034. value = (char *)ep_alloc(value_len+1);
  2035. memcpy(value, &line[value_offset - offset], value_len);
  2036. value[value_len] = '\0';
  2037. if (hf_index == -1) {
  2038. /*
  2039. * Not a header we know anything about.
  2040. * Check if a HF generated from UAT information exists.
  2041. */
  2042. hf_id = get_hf_for_header(header_name);
  2043. if (tree) {
  2044. if (!hf_id) {
  2045. proto_tree_add_text(tree, tvb, offset, len,
  2046. "%s", format_text(line, len));
  2047. } else {
  2048. proto_tree_add_string_format(tree,
  2049. *hf_id, tvb, offset, len,
  2050. value, "%s", format_text(line, len));
  2051. }
  2052. }
  2053. } else {
  2054. /*
  2055. * Add it to the protocol tree as a particular field,
  2056. * but display the line as is.
  2057. */
  2058. if (tree) {
  2059. header_field_info *hfinfo;
  2060. guint32 tmp;
  2061. hfinfo = proto_registrar_get_nth(*headers[hf_index].hf);
  2062. switch(hfinfo->type){
  2063. case FT_UINT8:
  2064. case FT_UINT16:
  2065. case FT_UINT24:
  2066. case FT_UINT32:
  2067. case FT_INT8:
  2068. case FT_INT16:
  2069. case FT_INT24:
  2070. case FT_INT32:
  2071. tmp=(guint32)strtol(value, NULL, 10);
  2072. hdr_item = proto_tree_add_uint(tree, *headers[hf_index].hf, tvb, offset, len, tmp);
  2073. break;
  2074. default:
  2075. hdr_item = proto_tree_add_string_format(tree,
  2076. *headers[hf_index].hf, tvb, offset, len,
  2077. value, "%s", format_text(line, len));
  2078. }
  2079. } else
  2080. hdr_item = NULL;
  2081. /*
  2082. * Do any special processing that particular headers
  2083. * require.
  2084. */
  2085. switch (headers[hf_index].special) {
  2086. case HDR_AUTHORIZATION:
  2087. if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
  2088. break; /* dissected NTLMSSP */
  2089. if (check_auth_basic(hdr_item, tvb, value))
  2090. break; /* dissected basic auth */
  2091. check_auth_kerberos(hdr_item, tvb, pinfo, value);
  2092. break;
  2093. case HDR_AUTHENTICATE:
  2094. if (check_auth_ntlmssp(hdr_item, tvb, pinfo, value))
  2095. break; /* dissected NTLMSSP */
  2096. check_auth_kerberos(hdr_item, tvb, pinfo, value);
  2097. break;
  2098. case HDR_CONTENT_TYPE:
  2099. eh_ptr->content_type = (gchar*) ep_memdup((guint8*)value,value_len + 1);
  2100. for (i = 0; i < value_len; i++) {
  2101. c = value[i];
  2102. if (c == ';' || g_ascii_isspace(c)) {
  2103. /*
  2104. * End of subtype - either
  2105. * white space or a ";"
  2106. * separating the subtype from
  2107. * a parameter.
  2108. */
  2109. break;
  2110. }
  2111. /*
  2112. * Map the character to lower case;
  2113. * content types are case-insensitive.
  2114. */
  2115. eh_ptr->content_type[i] = g_ascii_tolower(eh_ptr->content_type[i]);
  2116. }
  2117. eh_ptr->content_type[i] = '\0';
  2118. /*
  2119. * Now find the start of the optional parameters;
  2120. * skip the optional white space and the semicolon
  2121. * if this has not been done before.
  2122. */
  2123. i++;
  2124. while (i < value_len) {
  2125. c = eh_ptr->content_type[i];
  2126. if (c == ';' || g_ascii_isspace(c))
  2127. /* Skip till start of parameters */
  2128. i++;
  2129. else
  2130. break;
  2131. }
  2132. if (i < value_len)
  2133. eh_ptr->content_type_parameters = eh_ptr->content_type + i;
  2134. else
  2135. eh_ptr->content_type_parameters = NULL;
  2136. break;
  2137. case HDR_CONTENT_LENGTH:
  2138. errno = 0;
  2139. eh_ptr->content_length = g_ascii_strtoll(value, &p, 10);
  2140. up = (guchar *)p;
  2141. if (eh_ptr->content_length < 0 ||
  2142. p == value ||
  2143. errno == ERANGE ||
  2144. (*up != '\0' && !isspace(*up))) {
  2145. /*
  2146. * Content length not valid; pretend
  2147. * we don't have it.
  2148. */
  2149. eh_ptr->have_content_length = FALSE;
  2150. } else {
  2151. proto_tree *header_tree;
  2152. proto_item *tree_item;
  2153. /*
  2154. * We do have a valid content length.
  2155. */
  2156. eh_ptr->have_content_length = TRUE;
  2157. header_tree = proto_item_add_subtree(hdr_item, ett_http_header_item);
  2158. tree_item = proto_tree_add_uint64(header_tree, hf_http_content_length,
  2159. tvb, offset, len, eh_ptr->content_length);
  2160. PROTO_ITEM_SET_GENERATED(tree_item);
  2161. }
  2162. break;
  2163. case HDR_CONTENT_ENCODING:
  2164. eh_ptr->content_encoding = ep_strndup(value, value_len);
  2165. break;
  2166. case HDR_TRANSFER_ENCODING:
  2167. eh_ptr->transfer_encoding = ep_strndup(value, value_len);
  2168. break;
  2169. case HDR_HOST:
  2170. stat_info->http_host = ep_strndup(value, value_len);
  2171. conv_data->http_host = se_strndup(value, value_len);
  2172. break;
  2173. case HDR_UPGRADE:
  2174. if (g_ascii_strncasecmp(value, "WebSocket", value_len) == 0)
  2175. eh_ptr->upgrade = UPGRADE_WEBSOCKET;
  2176. break;
  2177. }
  2178. }
  2179. }
  2180. /* Returns index of header tag in headers */
  2181. static gint
  2182. find_header_hf_value(tvbuff_t *tvb, int offset, guint header_len)
  2183. {
  2184. guint i;
  2185. for (i = 0; i < array_length(headers); i++) {
  2186. if (header_len == strlen(headers[i].name) &&
  2187. tvb_strncaseeql(tvb, offset,
  2188. headers[i].name, header_len) == 0)
  2189. return i;
  2190. }
  2191. return -1;
  2192. }
  2193. /*
  2194. * Dissect Microsoft's abomination called NTLMSSP over HTTP.
  2195. */
  2196. static gboolean
  2197. check_auth_ntlmssp(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo,
  2198. gchar *value)
  2199. {
  2200. static const char *ntlm_headers[] = {
  2201. "NTLM ",
  2202. "Negotiate ",
  2203. NULL
  2204. };
  2205. const char **header;
  2206. size_t hdrlen;
  2207. proto_tree *hdr_tree;
  2208. /*
  2209. * Check for NTLM credentials and challenge; those can
  2210. * occur with WWW-Authenticate.
  2211. */
  2212. for (header = &ntlm_headers[0]; *header != NULL; header++) {
  2213. hdrlen = strlen(*header);
  2214. if (strncmp(value, *header, hdrlen) == 0) {
  2215. if (hdr_item != NULL) {
  2216. hdr_tree = proto_item_add_subtree(hdr_item,
  2217. ett_http_ntlmssp);
  2218. } else
  2219. hdr_tree = NULL;
  2220. value += hdrlen;
  2221. dissect_http_ntlmssp(tvb, pinfo, hdr_tree, value);
  2222. return TRUE;
  2223. }
  2224. }
  2225. return FALSE;
  2226. }
  2227. /*
  2228. * Dissect HTTP Basic authorization.
  2229. */
  2230. static gboolean
  2231. check_auth_basic(proto_item *hdr_item, tvbuff_t *tvb, gchar *value)
  2232. {
  2233. static const char *basic_headers[] = {
  2234. "Basic ",
  2235. NULL
  2236. };
  2237. const char **header;
  2238. size_t hdrlen;
  2239. proto_tree *hdr_tree;
  2240. for (header = &basic_headers[0]; *header != NULL; header++) {
  2241. hdrlen = strlen(*header);
  2242. if (strncmp(value, *header, hdrlen) == 0) {
  2243. if (hdr_item != NULL) {
  2244. hdr_tree = proto_item_add_subtree(hdr_item,
  2245. ett_http_ntlmssp);
  2246. } else
  2247. hdr_tree = NULL;
  2248. value += hdrlen;
  2249. epan_base64_decode(value);
  2250. proto_tree_add_string(hdr_tree, hf_http_basic, tvb,
  2251. 0, 0, value);
  2252. return TRUE;
  2253. }
  2254. }
  2255. return FALSE;
  2256. }
  2257. static gboolean
  2258. check_auth_kerberos(proto_item *hdr_item, tvbuff_t *tvb, packet_info *pinfo,
  2259. const gchar *value)
  2260. {
  2261. proto_tree *hdr_tree;
  2262. if (strncmp(value, "Kerberos ", 9) == 0) {
  2263. if (hdr_item != NULL) {
  2264. hdr_tree = proto_item_add_subtree(hdr_item, ett_http_kerberos);
  2265. } else
  2266. hdr_tree = NULL;
  2267. dissect_http_kerberos(tvb, pinfo, hdr_tree, value);
  2268. return TRUE;
  2269. }
  2270. return FALSE;
  2271. }
  2272. static void
  2273. dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  2274. {
  2275. http_conv_t *conv_data;
  2276. int offset = 0;
  2277. int len;
  2278. /*
  2279. * Check if this is proxied connection and if so, hand of dissection to the
  2280. * payload-dissector.
  2281. * Response code 200 means "OK" and strncmp() == 0 means the strings match exactly */
  2282. conv_data = get_http_conversation_data(pinfo);
  2283. if(pinfo->fd->num >= conv_data->startframe &&
  2284. conv_data->response_code == 200 &&
  2285. conv_data->request_method &&
  2286. strncmp(conv_data->request_method, "CONNECT", 7) == 0 &&
  2287. conv_data->request_uri) {
  2288. if(conv_data->startframe == 0 && !pinfo->fd->flags.visited)
  2289. conv_data->startframe = pinfo->fd->num;
  2290. http_payload_subdissector(tvb, tree, pinfo, conv_data);
  2291. } else {
  2292. while (tvb_reported_length_remaining(tvb, offset) != 0) {
  2293. if (conv_data->upgrade == UPGRADE_WEBSOCKET && pinfo->fd->num >= conv_data->startframe) {
  2294. call_dissector_only(websocket_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree, NULL);
  2295. break;
  2296. }
  2297. len = dissect_http_message(tvb, offset, pinfo, tree, conv_data);
  2298. if (len == -1)
  2299. break;
  2300. offset += len;
  2301. /*
  2302. * OK, we've set the Protocol and Info columns for the
  2303. * first HTTP message; set a fence so that subsequent
  2304. * HTTP messages don't overwrite the Info column.
  2305. */
  2306. col_set_fence(pinfo->cinfo, COL_INFO);
  2307. }
  2308. }
  2309. }
  2310. static gboolean
  2311. dissect_http_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
  2312. {
  2313. gint offset = 0, next_offset, linelen;
  2314. conversation_t *conversation;
  2315. /* Check if we have a line terminated by CRLF
  2316. * Return the length of the line (not counting the line terminator at
  2317. * the end), or, if we don't find a line terminator:
  2318. *
  2319. * if "deseg" is true, return -1;
  2320. */
  2321. linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, TRUE);
  2322. if((linelen == -1)||(linelen == 8)){
  2323. return FALSE;
  2324. }
  2325. /* Check if the line start or ends with the HTTP token */
  2326. if((tvb_strncaseeql(tvb, linelen-8, "HTTP/1.1", 8) == 0)||(tvb_strncaseeql(tvb, 0, "HTTP/1.1", 8) == 0)){
  2327. conversation = find_or_create_conversation(pinfo);
  2328. conversation_set_dissector(conversation,http_handle);
  2329. dissect_http(tvb, pinfo, tree);
  2330. return TRUE;
  2331. }
  2332. return FALSE;
  2333. }
  2334. static void
  2335. dissect_http_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  2336. {
  2337. http_conv_t *conv_data;
  2338. conv_data = get_http_conversation_data(pinfo);
  2339. dissect_http_message(tvb, 0, pinfo, tree, conv_data);
  2340. }
  2341. static void
  2342. range_delete_http_tcp_callback(guint32 port) {
  2343. dissector_delete_uint("tcp.port", port, http_handle);
  2344. }
  2345. static void
  2346. range_add_http_tcp_callback(guint32 port) {
  2347. dissector_add_uint("tcp.port", port, http_handle);
  2348. }
  2349. static void
  2350. range_delete_http_ssl_callback(guint32 port) {
  2351. ssl_dissector_delete(port, "http", TRUE);
  2352. }
  2353. static void
  2354. range_add_http_ssl_callback(guint32 port) {
  2355. ssl_dissector_add(port, "http", TRUE);
  2356. }
  2357. static void reinit_http(void) {
  2358. range_foreach(http_tcp_range, range_delete_http_tcp_callback);
  2359. g_free(http_tcp_range);
  2360. http_tcp_range = range_copy(global_http_tcp_range);
  2361. range_foreach(http_tcp_range, range_add_http_tcp_callback);
  2362. range_foreach(http_ssl_range, range_delete_http_ssl_callback);
  2363. g_free(http_ssl_range);
  2364. http_ssl_range = range_copy(global_http_ssl_range);
  2365. range_foreach(http_ssl_range, range_add_http_ssl_callback);
  2366. }
  2367. void
  2368. proto_register_http(void)
  2369. {
  2370. static hf_register_info hf[] = {
  2371. { &hf_http_notification,
  2372. { "Notification", "http.notification",
  2373. FT_BOOLEAN, BASE_NONE, NULL, 0x0,
  2374. "TRUE if HTTP notification", HFILL }},
  2375. { &hf_http_response,
  2376. { "Response", "http.response",
  2377. FT_BOOLEAN, BASE_NONE, NULL, 0x0,
  2378. "TRUE if HTTP response", HFILL }},
  2379. { &hf_http_request,
  2380. { "Request", "http.request",
  2381. FT_BOOLEAN, BASE_NONE, NULL, 0x0,
  2382. "TRUE if HTTP request", HFILL }},
  2383. { &hf_http_basic,
  2384. { "Credentials", "http.authbasic",
  2385. FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
  2386. { &hf_http_request_method,
  2387. { "Request Method", "http.request.method",
  2388. FT_STRING, BASE_NONE, NULL, 0x0,
  2389. "HTTP Request Method", HFILL }},
  2390. { &hf_http_request_uri,
  2391. { "Request URI", "http.request.uri",
  2392. FT_STRING, BASE_NONE, NULL, 0x0,
  2393. "HTTP Request-URI", HFILL }},
  2394. { &hf_http_version,
  2395. { "Request Version", "http.request.version",
  2396. FT_STRING, BASE_NONE, NULL, 0x0,
  2397. "HTTP Request HTTP-Version", HFILL }},
  2398. { &hf_http_request_full_uri,
  2399. { "Full request URI", "http.request.full_uri",
  2400. FT_STRING, BASE_NONE, NULL, 0x0,
  2401. "The full requested URI (including host name)", HFILL }},
  2402. { &hf_http_response_code,
  2403. { "Status Code", "http.response.code",
  2404. FT_UINT16, BASE_DEC, NULL, 0x0,
  2405. "HTTP Response Status Code", HFILL }},
  2406. { &hf_http_response_phrase,
  2407. { "Response Phrase", "http.response.phrase",
  2408. FT_STRING, BASE_NONE, NULL, 0x0,
  2409. "HTTP Response Reason Phrase", HFILL }},
  2410. { &hf_http_authorization,
  2411. { "Authorization", "http.authorization",
  2412. FT_STRING, BASE_NONE, NULL, 0x0,
  2413. "HTTP Authorization header", HFILL }},
  2414. { &hf_http_proxy_authenticate,
  2415. { "Proxy-Authenticate", "http.proxy_authenticate",
  2416. FT_STRING, BASE_NONE, NULL, 0x0,
  2417. "HTTP Proxy-Authenticate header", HFILL }},
  2418. { &hf_http_proxy_authorization,
  2419. { "Proxy-Authorization", "http.proxy_authorization",
  2420. FT_STRING, BASE_NONE, NULL, 0x0,
  2421. "HTTP Proxy-Authorization header", HFILL }},
  2422. { &hf_http_proxy_connect_host,
  2423. { "Proxy-Connect-Hostname", "http.proxy_connect_host",
  2424. FT_STRING, BASE_NONE, NULL, 0x0,
  2425. "HTTP Proxy Connect Hostname", HFILL }},
  2426. { &hf_http_proxy_connect_port,
  2427. { "Proxy-Connect-Port", "http.proxy_connect_port",
  2428. FT_UINT16, BASE_DEC, NULL, 0x0,
  2429. "HTTP Proxy Connect Port", HFILL }},
  2430. { &hf_http_www_authenticate,
  2431. { "WWW-Authenticate", "http.www_authenticate",
  2432. FT_STRING, BASE_NONE, NULL, 0x0,
  2433. "HTTP WWW-Authenticate header", HFILL }},
  2434. { &hf_http_content_type,
  2435. { "Content-Type", "http.content_type",
  2436. FT_STRING, BASE_NONE, NULL, 0x0,
  2437. "HTTP Content-Type header", HFILL }},
  2438. { &hf_http_content_length_header,
  2439. { "Content-Length", "http.content_length_header",
  2440. FT_STRING, BASE_NONE, NULL, 0x0,
  2441. "HTTP Content-Length header", HFILL }},
  2442. { &hf_http_content_length,
  2443. { "Content length", "http.content_length",
  2444. FT_UINT64, BASE_DEC, NULL, 0x0,
  2445. NULL, HFILL }},
  2446. { &hf_http_content_encoding,
  2447. { "Content-Encoding", "http.content_encoding",
  2448. FT_STRING, BASE_NONE, NULL, 0x0,
  2449. "HTTP Content-Encoding header", HFILL }},
  2450. { &hf_http_transfer_encoding,
  2451. { "Transfer-Encoding", "http.transfer_encoding",
  2452. FT_STRING, BASE_NONE, NULL, 0x0,
  2453. "HTTP Transfer-Encoding header", HFILL }},
  2454. { &hf_http_upgrade,
  2455. { "Upgrade", "http.upgrade",
  2456. FT_STRING, BASE_NONE, NULL, 0x0,
  2457. "HTTP Upgrade header", HFILL }},
  2458. { &hf_http_user_agent,
  2459. { "User-Agent", "http.user_agent",
  2460. FT_STRING, BASE_NONE, NULL, 0x0,
  2461. "HTTP User-Agent header", HFILL }},
  2462. { &hf_http_host,
  2463. { "Host", "http.host",
  2464. FT_STRING, BASE_NONE, NULL, 0x0,
  2465. "HTTP Host", HFILL }},
  2466. { &hf_http_connection,
  2467. { "Connection", "http.connection",
  2468. FT_STRING, BASE_NONE, NULL, 0x0,
  2469. "HTTP Connection", HFILL }},
  2470. { &hf_http_cookie,
  2471. { "Cookie", "http.cookie",
  2472. FT_STRING, BASE_NONE, NULL, 0x0,
  2473. "HTTP Cookie", HFILL }},
  2474. { &hf_http_accept,
  2475. { "Accept", "http.accept",
  2476. FT_STRING, BASE_NONE, NULL, 0x0,
  2477. "HTTP Accept", HFILL }},
  2478. { &hf_http_referer,
  2479. { "Referer", "http.referer",
  2480. FT_STRING, BASE_NONE, NULL, 0x0,
  2481. "HTTP Referer", HFILL }},
  2482. { &hf_http_accept_language,
  2483. { "Accept-Language", "http.accept_language",
  2484. FT_STRING, BASE_NONE, NULL, 0x0,
  2485. "HTTP Accept Language", HFILL }},
  2486. { &hf_http_accept_encoding,
  2487. { "Accept Encoding", "http.accept_encoding",
  2488. FT_STRING, BASE_NONE, NULL, 0x0,
  2489. "HTTP Accept Encoding", HFILL }},
  2490. { &hf_http_date,
  2491. { "Date", "http.date",
  2492. FT_STRING, BASE_NONE, NULL, 0x0,
  2493. "HTTP Date", HFILL }},
  2494. { &hf_http_cache_control,
  2495. { "Cache-Control", "http.cache_control",
  2496. FT_STRING, BASE_NONE, NULL, 0x0,
  2497. "HTTP Cache Control", HFILL }},
  2498. { &hf_http_server,
  2499. { "Server", "http.server",
  2500. FT_STRING, BASE_NONE, NULL, 0x0,
  2501. "HTTP Server", HFILL }},
  2502. { &hf_http_location,
  2503. { "Location", "http.location",
  2504. FT_STRING, BASE_NONE, NULL, 0x0,
  2505. "HTTP Location", HFILL }},
  2506. { &hf_http_sec_websocket_accept,
  2507. { "Sec-WebSocket-Accept", "http.sec_websocket_accept",
  2508. FT_STRING, BASE_NONE, NULL, 0x0,
  2509. NULL, HFILL }},
  2510. { &hf_http_sec_websocket_extensions,
  2511. { "Sec-WebSocket-Extensions", "http.sec_websocket_extensions",
  2512. FT_STRING, BASE_NONE, NULL, 0x0,
  2513. NULL, HFILL }},
  2514. { &hf_http_sec_websocket_key,
  2515. { "Sec-WebSocket-Key", "http.sec_websocket_key",
  2516. FT_STRING, BASE_NONE, NULL, 0x0,
  2517. NULL, HFILL }},
  2518. { &hf_http_sec_websocket_protocol,
  2519. { "Sec-WebSocket-Protocol", "http.sec_websocket_protocol",
  2520. FT_STRING, BASE_NONE, NULL, 0x0,
  2521. NULL, HFILL }},
  2522. { &hf_http_sec_websocket_version,
  2523. { "Sec-WebSocket-Version", "http.sec_websocket_version",
  2524. FT_STRING, BASE_NONE, NULL, 0x0,
  2525. NULL, HFILL }},
  2526. { &hf_http_set_cookie,
  2527. { "Set-Cookie", "http.set_cookie",
  2528. FT_STRING, BASE_NONE, NULL, 0x0,
  2529. "HTTP Set Cookie", HFILL }},
  2530. { &hf_http_last_modified,
  2531. { "Last-Modified", "http.last_modified",
  2532. FT_STRING, BASE_NONE, NULL, 0x0,
  2533. "HTTP Last Modified", HFILL }},
  2534. { &hf_http_x_forwarded_for,
  2535. { "X-Forwarded-For", "http.x_forwarded_for",
  2536. FT_STRING, BASE_NONE, NULL, 0x0,
  2537. "HTTP X-Forwarded-For", HFILL }},
  2538. { &hf_http_request_in,
  2539. { "Request in frame", "http.request_in",
  2540. FT_FRAMENUM, BASE_NONE, NULL, 0,
  2541. "This packet is a response to the packet with this number", HFILL }},
  2542. { &hf_http_response_in,
  2543. { "Response in frame","http.response_in",
  2544. FT_FRAMENUM, BASE_NONE, NULL, 0,
  2545. "This packet will be responded in the packet with this number", HFILL }},
  2546. { &hf_http_next_request_in,
  2547. { "Next request in frame", "http.next_request_in",
  2548. FT_FRAMENUM, BASE_NONE, NULL, 0,
  2549. "The next HTTP request starts in packet number", HFILL }},
  2550. { &hf_http_next_response_in,
  2551. { "Next response in frame","http.next_response_in",
  2552. FT_FRAMENUM, BASE_NONE, NULL, 0,
  2553. "The next HTTP response starts in packet number", HFILL }},
  2554. { &hf_http_prev_request_in,
  2555. { "Prev request in frame", "http.prev_request_in",
  2556. FT_FRAMENUM, BASE_NONE, NULL, 0,
  2557. "The previous HTTP request starts in packet number", HFILL }},
  2558. { &hf_http_prev_response_in,
  2559. { "Prev response in frame","http.prev_response_in",
  2560. FT_FRAMENUM, BASE_NONE, NULL, 0,
  2561. "The previous HTTP response starts in packet number", HFILL }},
  2562. { &hf_http_time,
  2563. { "Time since request", "http.time",
  2564. FT_RELATIVE_TIME, BASE_NONE, NULL, 0,
  2565. "Time since the request was send", HFILL }},
  2566. };
  2567. static gint *ett[] = {
  2568. &ett_http,
  2569. &ett_http_ntlmssp,
  2570. &ett_http_kerberos,
  2571. &ett_http_request,
  2572. &ett_http_chunked_response,
  2573. &ett_http_chunk_data,
  2574. &ett_http_encoded_entity,
  2575. &ett_http_header_item
  2576. };
  2577. static ei_register_info ei[] = {
  2578. { &ei_http_chat, { "http.chat", PI_SEQUENCE, PI_CHAT, "Formatted text", EXPFILL }},
  2579. { &ei_http_subdissector_failed, { "http.subdissector_failed", PI_MALFORMED, PI_NOTE, "HTTP body subdissector failed, trying heuristic subdissector", EXPFILL }},
  2580. };
  2581. /* UAT for header fields */
  2582. static uat_field_t custom_header_uat_fields[] = {
  2583. UAT_FLD_CSTRING(header_fields, header_name, "Header name", "HTTP header name"),
  2584. UAT_FLD_CSTRING(header_fields, header_desc, "Field desc", "Description of the value contained in the header"),
  2585. UAT_END_FIELDS
  2586. };
  2587. module_t *http_module;
  2588. expert_module_t* expert_http;
  2589. uat_t* headers_uat;
  2590. proto_http = proto_register_protocol("Hypertext Transfer Protocol",
  2591. "HTTP", "http");
  2592. proto_register_field_array(proto_http, hf, array_length(hf));
  2593. proto_register_subtree_array(ett, array_length(ett));
  2594. expert_http = expert_register_protocol(proto_http);
  2595. expert_register_field_array(expert_http, ei, array_length(ei));
  2596. http_handle = register_dissector("http", dissect_http, proto_http);
  2597. http_module = prefs_register_protocol(proto_http, reinit_http);
  2598. prefs_register_bool_preference(http_module, "desegment_headers",
  2599. "Reassemble HTTP headers spanning multiple TCP segments",
  2600. "Whether the HTTP dissector should reassemble headers "
  2601. "of a request spanning multiple TCP segments. "
  2602. "To use this option, you must also enable "
  2603. "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
  2604. &http_desegment_headers);
  2605. prefs_register_bool_preference(http_module, "desegment_body",
  2606. "Reassemble HTTP bodies spanning multiple TCP segments",
  2607. "Whether the HTTP dissector should use the "
  2608. "\"Content-length:\" value, if present, to reassemble "
  2609. "the body of a request spanning multiple TCP segments, "
  2610. "and reassemble chunked data spanning multiple TCP segments. "
  2611. "To use this option, you must also enable "
  2612. "\"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
  2613. &http_desegment_body);
  2614. prefs_register_bool_preference(http_module, "dechunk_body",
  2615. "Reassemble chunked transfer-coded bodies",
  2616. "Whether to reassemble bodies of entities that are transferred "
  2617. "using the \"Transfer-Encoding: chunked\" method",
  2618. &http_dechunk_body);
  2619. #ifdef HAVE_LIBZ
  2620. prefs_register_bool_preference(http_module, "decompress_body",
  2621. "Uncompress entity bodies",
  2622. "Whether to uncompress entity bodies that are compressed "
  2623. "using \"Content-Encoding: \"",
  2624. &http_decompress_body);
  2625. #endif
  2626. prefs_register_obsolete_preference(http_module, "tcp_alternate_port");
  2627. range_convert_str(&global_http_tcp_range, TCP_DEFAULT_RANGE, 65535);
  2628. http_tcp_range = range_empty();
  2629. prefs_register_range_preference(http_module, "tcp.port", "TCP Ports",
  2630. "TCP Ports range",
  2631. &global_http_tcp_range, 65535);
  2632. range_convert_str(&global_http_ssl_range, SSL_DEFAULT_RANGE, 65535);
  2633. http_ssl_range = range_empty();
  2634. prefs_register_range_preference(http_module, "ssl.port", "SSL/TLS Ports",
  2635. "SSL/TLS Ports range",
  2636. &global_http_ssl_range, 65535);
  2637. /* UAT */
  2638. headers_uat = uat_new("Custom HTTP headers fields Table",
  2639. sizeof(header_field_t),
  2640. "custom_http_header_fields",
  2641. TRUE,
  2642. (void**) &header_fields,
  2643. &num_header_fields,
  2644. /* specifies named fields, so affects dissection
  2645. and the set of named fields */
  2646. UAT_AFFECTS_DISSECTION|UAT_AFFECTS_FIELDS,
  2647. NULL,
  2648. header_fields_copy_cb,
  2649. header_fields_update_cb,
  2650. header_fields_free_cb,
  2651. header_fields_initialize_cb,
  2652. custom_header_uat_fields
  2653. );
  2654. prefs_register_uat_preference(http_module, "custom_http_header_fields", "Custom HTTP headers fields",
  2655. "A table to define custom HTTP header for which fields can be setup and used for filtering/data extraction etc.",
  2656. headers_uat);
  2657. /*
  2658. * Dissectors shouldn't register themselves in this table;
  2659. * instead, they should call "http_dissector_add()", and
  2660. * we'll register the port number they specify as a port
  2661. * for HTTP, and register them in our subdissector table.
  2662. *
  2663. * This only works for protocols such as IPP that run over
  2664. * HTTP on a specific non-HTTP port.
  2665. */
  2666. port_subdissector_table = register_dissector_table("http.port",
  2667. "TCP port for protocols using HTTP", FT_UINT16, BASE_DEC);
  2668. /*
  2669. * Dissectors can register themselves in this table.
  2670. * It's just "media_type", not "http.content_type", because
  2671. * it's an Internet media type, usable by other protocols as well.
  2672. */
  2673. media_type_subdissector_table =
  2674. register_dissector_table("media_type",
  2675. "Internet media type", FT_STRING, BASE_NONE);
  2676. /*
  2677. * Heuristic dissectors SHOULD register themselves in
  2678. * this table using the standard heur_dissector_add()
  2679. * function.
  2680. */
  2681. register_heur_dissector_list("http", &heur_subdissector_list);
  2682. /*
  2683. * Register for tapping
  2684. */
  2685. http_tap = register_tap("http"); /* HTTP statistics tap */
  2686. http_eo_tap = register_tap("http_eo"); /* HTTP Export Object tap */
  2687. }
  2688. /*
  2689. * Called by dissectors for protocols that run atop HTTP/TCP.
  2690. */
  2691. void
  2692. http_dissector_add(guint32 port, dissector_handle_t handle)
  2693. {
  2694. /*
  2695. * Register ourselves as the handler for that port number
  2696. * over TCP.
  2697. */
  2698. dissector_add_uint("tcp.port", port, http_handle);
  2699. /*
  2700. * And register them in *our* table for that port.
  2701. */
  2702. dissector_add_uint("http.port", port, handle);
  2703. }
  2704. void
  2705. http_port_add(guint32 port)
  2706. {
  2707. /*
  2708. * Register ourselves as the handler for that port number
  2709. * over TCP. We rely on our caller having registered
  2710. * themselves for the appropriate media type.
  2711. */
  2712. dissector_add_uint("tcp.port", port, http_handle);
  2713. }
  2714. void
  2715. proto_reg_handoff_http(void)
  2716. {
  2717. dissector_handle_t http_udp_handle;
  2718. data_handle = find_dissector("data");
  2719. media_handle = find_dissector("media");
  2720. websocket_handle = find_dissector("websocket");
  2721. /*
  2722. * XXX - is there anything to dissect in the body of an SSDP
  2723. * request or reply? I.e., should there be an SSDP dissector?
  2724. */
  2725. http_udp_handle = create_dissector_handle(dissect_http_udp, proto_http);
  2726. dissector_add_uint("udp.port", UDP_PORT_SSDP, http_udp_handle);
  2727. ntlmssp_handle = find_dissector("ntlmssp");
  2728. gssapi_handle = find_dissector("gssapi");
  2729. stats_tree_register("http", "http", "HTTP/Packet Counter", 0, http_stats_tree_packet, http_stats_tree_init, NULL );
  2730. stats_tree_register("http", "http_req", "HTTP/Requests", 0, http_req_stats_tree_packet, http_req_stats_tree_init, NULL );
  2731. stats_tree_register("http", "http_srv", "HTTP/Load Distribution",0, http_reqs_stats_tree_packet, http_reqs_stats_tree_init, NULL );
  2732. }
  2733. /*
  2734. * Content-Type: message/http
  2735. */
  2736. static gint proto_message_http = -1;
  2737. static gint ett_message_http = -1;
  2738. static void
  2739. dissect_message_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
  2740. {
  2741. proto_tree *subtree;
  2742. proto_item *ti;
  2743. gint offset = 0, next_offset;
  2744. gint len;
  2745. col_append_str(pinfo->cinfo, COL_INFO, " (message/http)");
  2746. if (tree) {
  2747. ti = proto_tree_add_item(tree, proto_message_http,
  2748. tvb, 0, -1, ENC_NA);
  2749. subtree = proto_item_add_subtree(ti, ett_message_http);
  2750. while (tvb_reported_length_remaining(tvb, offset) != 0) {
  2751. len = tvb_find_line_end(tvb, offset,
  2752. tvb_ensure_length_remaining(tvb, offset),
  2753. &next_offset, FALSE);
  2754. if (len == -1)
  2755. break;
  2756. proto_tree_add_text(subtree, tvb, offset, next_offset - offset,
  2757. "%s", tvb_format_text(tvb, offset, len));
  2758. offset = next_offset;
  2759. }
  2760. }
  2761. }
  2762. void
  2763. proto_register_message_http(void)
  2764. {
  2765. static gint *ett[] = {
  2766. &ett_message_http,
  2767. };
  2768. proto_message_http = proto_register_protocol(
  2769. "Media Type: message/http",
  2770. "message/http",
  2771. "message-http"
  2772. );
  2773. proto_register_subtree_array(ett, array_length(ett));
  2774. }
  2775. void
  2776. proto_reg_handoff_message_http(void)
  2777. {
  2778. dissector_handle_t message_http_handle;
  2779. message_http_handle = create_dissector_handle(dissect_message_http,
  2780. proto_message_http);
  2781. dissector_add_string("media_type", "message/http", message_http_handle);
  2782. heur_dissector_add("tcp", dissect_http_heur_tcp, proto_http);
  2783. reinit_http();
  2784. }
  2785. /*
  2786. * Editor modelines - http://www.wireshark.org/tools/modelines.html
  2787. *
  2788. * Local variables:
  2789. * c-basic-offset: 8
  2790. * tab-width: 8
  2791. * indent-tabs-mode: true
  2792. * End:
  2793. *
  2794. * vi: set shiftwidth=8 tabstop=8:
  2795. * :indentSize=8:tabSize=8:
  2796. */