Exemplo n.º 1
0
/*
 * 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);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
  }
}