/* * Given two address/port pairs for a packet, search for a matching * conversation and, if found and it has a conversation dissector, * call that dissector and return TRUE, otherwise return FALSE. * * This helper uses call_dissector_only which will NOT call the default * "data" dissector if the packet was rejected. * Our caller is responsible to call the data dissector explicitely in case * this function returns FALSE. */ gboolean try_conversation_dissector(const address *addr_a, const address *addr_b, const port_type ptype, const guint32 port_a, const guint32 port_b, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { conversation_t *conversation; conversation = find_conversation(pinfo->fd->num, addr_a, addr_b, ptype, port_a, port_b, 0); if (conversation != NULL) { int ret; if (conversation->dissector_handle == NULL) return FALSE; ret=call_dissector_only(conversation->dissector_handle, tvb, pinfo, tree); if(!ret) { /* this packet was rejected by the dissector * so return FALSE in case our caller wants * to do some cleaning up. */ return FALSE; } return TRUE; } return FALSE; }
/* Main dissection function. */ static void dissect_mac_lte_framed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; struct mac_lte_info *p_mac_lte_info; tvbuff_t *mac_tvb; gboolean infoAlreadySet = FALSE; /* Need to find enabled mac-lte dissector */ dissector_handle_t mac_lte_handle = find_dissector("mac-lte"); if (!mac_lte_handle) { return; } /* Do this again on re-dissection to re-discover offset of actual PDU */ /* Needs to be at least as long as: - fixed header bytes - tag for data - at least one byte of MAC PDU payload */ if ((size_t)tvb_length_remaining(tvb, offset) < (3+2)) { return; } /* If redissecting, use previous info struct (if available) */ p_mac_lte_info = (struct mac_lte_info*)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0); if (p_mac_lte_info == NULL) { /* Allocate new info struct for this frame */ p_mac_lte_info = (struct mac_lte_info*)wmem_alloc0(wmem_file_scope(), sizeof(struct mac_lte_info)); infoAlreadySet = FALSE; } else { infoAlreadySet = TRUE; } /* Dissect the fields to populate p_mac_lte */ if (!dissect_mac_lte_context_fields(p_mac_lte_info, tvb, &offset)) { return; } /* Store info in packet (first time) */ if (!infoAlreadySet) { p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info); } /**************************************/ /* OK, now dissect as MAC LTE */ /* Create tvb that starts at actual MAC PDU */ mac_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_only(mac_lte_handle, mac_tvb, pinfo, tree, NULL); }
static int dissect_websocket_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *ws_tree, guint8 opcode, guint payload_length, guint8 mask, const guint8* masking_key) { guint offset = 0; proto_item *ti_unmask, *ti; dissector_handle_t handle; proto_tree *pl_tree, *mask_tree = NULL; tvbuff_t *payload_tvb = NULL; /* Payload */ ti = proto_tree_add_item(ws_tree, hf_ws_payload, tvb, offset, payload_length, ENC_NA); pl_tree = proto_item_add_subtree(ti, ett_ws_pl); if(mask){ payload_tvb = tvb_unmasked(tvb, offset, payload_length, masking_key); tvb_set_child_real_data_tvbuff(tvb, payload_tvb); add_new_data_source(pinfo, payload_tvb, payload_length > tvb_length(payload_tvb) ? "Unmasked Data (truncated)" : "Unmasked Data"); ti = proto_tree_add_item(ws_tree, hf_ws_payload_unmask, payload_tvb, offset, payload_length, ENC_NA); mask_tree = proto_item_add_subtree(ti, ett_ws_mask); }else{ payload_tvb = tvb_new_subset(tvb, offset, payload_length, -1); } handle = dissector_get_uint_handle(port_subdissector_table, pinfo->match_uint); if(handle != NULL){ call_dissector_only(handle, payload_tvb, pinfo, tree, NULL); }else{ dissector_try_heuristic(heur_subdissector_list, payload_tvb, pinfo, tree, NULL); } /* Extension Data */ /* TODO: Add dissector of Extension (not extension available for the moment...) */ /* Application Data */ switch(opcode){ case WS_CONTINUE: /* Continue */ proto_tree_add_item(pl_tree, hf_ws_payload_continue, tvb, offset, payload_length, ENC_NA); /* TODO: Add Fragmentation support... */ break; case WS_TEXT: /* Text */ if(mask){ proto_tree_add_item(pl_tree, hf_ws_payload_text_mask, tvb, offset, payload_length, ENC_NA); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_text_unmask, payload_tvb, offset, payload_length, ENC_UTF_8|ENC_NA); PROTO_ITEM_SET_GENERATED(ti_unmask); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_text, payload_tvb, offset, payload_length, ENC_UTF_8|ENC_NA); PROTO_ITEM_SET_HIDDEN(ti_unmask); }else{ const gchar *saved_match_string = pinfo->match_string; void *save_private_data = pinfo->private_data; pinfo->match_string = NULL; pinfo->private_data = NULL; switch(pref_text_type){ case WEBSOCKET_TEXT: call_dissector(text_lines_handle, payload_tvb, pinfo, pl_tree); break; case WEBSOCKET_JSON: call_dissector(json_handle, payload_tvb, pinfo, pl_tree); break; case WEBSOCKET_NONE: /* falltrough */ default: proto_tree_add_item(pl_tree, hf_ws_payload_text, tvb, offset, payload_length, ENC_UTF_8|ENC_NA); break; } pinfo->match_string = saved_match_string; pinfo->private_data = save_private_data; } offset += payload_length; break; case WS_BINARY: /* Binary */ if(mask){ proto_tree_add_item(pl_tree, hf_ws_payload_binary_mask, tvb, offset, payload_length, ENC_NA); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_binary_unmask, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_GENERATED(ti_unmask); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_binary, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_HIDDEN(ti_unmask); }else{ proto_tree_add_item(pl_tree, hf_ws_payload_binary, tvb, offset, payload_length, ENC_NA); } offset += payload_length; break; case WS_CLOSE: /* Close */ if(mask){ proto_tree_add_item(pl_tree, hf_ws_payload_close_mask, tvb, offset, payload_length, ENC_NA); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_close_unmask, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_GENERATED(ti_unmask); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_close, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_HIDDEN(ti_unmask); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_close_status_code, payload_tvb, offset, 2, ENC_BIG_ENDIAN); PROTO_ITEM_SET_GENERATED(ti_unmask); if(payload_length > 2){ ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_close_reason, payload_tvb, offset+2, payload_length-2, ENC_ASCII|ENC_NA); PROTO_ITEM_SET_GENERATED(ti_unmask); } }else{ proto_tree_add_item(pl_tree, hf_ws_payload_close, tvb, offset, payload_length, ENC_NA); proto_tree_add_item(pl_tree, hf_ws_payload_close_status_code, tvb, offset, 2, ENC_BIG_ENDIAN); if(payload_length > 2){ proto_tree_add_item(pl_tree, hf_ws_payload_close_reason, tvb, offset+2, payload_length-2, ENC_ASCII|ENC_NA); } } offset += payload_length; break; case WS_PING: /* Ping */ if(mask){ proto_tree_add_item(pl_tree, hf_ws_payload_ping_mask, tvb, offset, payload_length, ENC_NA); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_ping_unmask, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_GENERATED(ti_unmask); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_ping, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_HIDDEN(ti_unmask); }else{ proto_tree_add_item(pl_tree, hf_ws_payload_ping, tvb, offset, payload_length, ENC_NA); } offset += payload_length; break; case WS_PONG: /* Pong */ if(mask){ proto_tree_add_item(pl_tree, hf_ws_payload_pong_mask, tvb, offset, payload_length, ENC_NA); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_pong_unmask, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_GENERATED(ti_unmask); ti_unmask = proto_tree_add_item(mask_tree, hf_ws_payload_pong, payload_tvb, offset, payload_length, ENC_NA); PROTO_ITEM_SET_HIDDEN(ti_unmask); }else{ proto_tree_add_item(pl_tree, hf_ws_payload_pong, tvb, offset, payload_length, ENC_NA); } offset += payload_length; break; default: /* Unknown */ ti = proto_tree_add_item(pl_tree, hf_ws_payload_unknown, tvb, offset, payload_length, ENC_NA); expert_add_info_format(pinfo, ti, &ei_ws_payload_unknown, "Dissector for Websocket Opcode (%d)" " code not implemented, Contact Wireshark developers" " if you want this supported", opcode); break; } return offset; }
static void dissect_websocket_data_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *pl_tree, guint8 opcode) { proto_item *ti; const guint offset = 0, length = tvb_reported_length(tvb); dissector_handle_t handle = NULL; heur_dtbl_entry_t *hdtbl_entry; conversation_t *conv; http_conv_t *http_conv = NULL; /* try to find a dissector which accepts the data. */ conv = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (conv) { http_conv = (http_conv_t *)conversation_get_proto_data(conv, proto_http); if (http_conv) handle = dissector_get_uint_handle(port_subdissector_table, http_conv->server_port); } if (handle) { call_dissector_only(handle, tvb, pinfo, tree, NULL); return; /* handle found, assume dissector took care of it. */ } else if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, NULL)) { return; /* heuristics dissector handled it. */ } /* no dissector wanted it, try to print something appropriate. */ switch (opcode) { case WS_TEXT: /* Text */ { const gchar *saved_match_string = pinfo->match_string; pinfo->match_string = NULL; switch (pref_text_type) { case WEBSOCKET_TEXT: case WEBSOCKET_NONE: default: /* Assume that most text protocols are line-based. */ call_dissector(text_lines_handle, tvb, pinfo, tree); break; case WEBSOCKET_JSON: call_dissector(json_handle, tvb, pinfo, tree); break; case WEBSOCKET_SIP: call_dissector(sip_handle, tvb, pinfo, tree); break; } pinfo->match_string = saved_match_string; } break; case WS_BINARY: /* Binary */ call_dissector(data_handle, tvb, pinfo, tree); break; default: /* Unknown */ ti = proto_tree_add_item(pl_tree, hf_ws_payload_unknown, tvb, offset, length, ENC_NA); expert_add_info_format(pinfo, ti, &ei_ws_payload_unknown, "Dissector for Websocket Opcode (%d)" " code not implemented, Contact Wireshark developers" " if you want this supported", opcode); break; } }