示例#1
0
static int
dissect_btsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    int          offset = 0;
    proto_item  *ti;
    proto_tree  *st;
    guint8      opcode;
    guint32     interface_id;
    guint32     adapter_id;
    gint        previous_proto;

    interface_id = HCI_INTERFACE_DEFAULT;
    adapter_id = HCI_ADAPTER_DEFAULT;
    previous_proto = (GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))));
    if (data && previous_proto == proto_btl2cap) {
        btl2cap_data_t *l2cap_data;

        l2cap_data = (btl2cap_data_t *) data;
        if (l2cap_data) {
            interface_id = l2cap_data->interface_id;
            adapter_id = l2cap_data->adapter_id;
        }
    }

    ti = proto_tree_add_item(tree, proto_btsmp, tvb, 0, tvb_captured_length(tvb), ENC_NA);
    st = proto_item_add_subtree(ti, ett_btsmp);

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMP");

    switch (pinfo->p2p_dir) {
        case P2P_DIR_SENT:
            col_set_str(pinfo->cinfo, COL_INFO, "Sent ");
            break;
        case P2P_DIR_RECV:
            col_set_str(pinfo->cinfo, COL_INFO, "Rcvd ");
            break;
        default:
            col_set_str(pinfo->cinfo, COL_INFO, "UnknownDirection ");
            break;
    }

    if (tvb_reported_length(tvb) < 1)
        return FALSE;

    proto_tree_add_item(st, hf_btsmp_opcode, tvb, 0, 1, ENC_LITTLE_ENDIAN);
    opcode = tvb_get_guint8(tvb, 0);
    offset++;

    col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(opcode, opcode_vals, "<unknown>"));

    switch (opcode) {
    case 0x01: /* Pairing Request */
    case 0x02: /* Pairing Response */
    {
        col_append_str(pinfo->cinfo, COL_INFO, ": ");

        proto_tree_add_item(st, hf_btsmp_io_capabilities, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;
        proto_tree_add_item(st, hf_btsmp_oob_data_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;

        offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st);

        proto_tree_add_item(st, hf_btsmp_max_enc_key_size, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        offset++;

        offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, TRUE);
        offset = dissect_btsmp_key_dist(tvb, offset, pinfo, st, FALSE);
        break;
    }

    case 0x03: /* Pairing Confirm */
        proto_tree_add_item(st, hf_btsmp_cfm_value, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x04: /* Pairing Random */
        proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x05: /* Pairing Failed */
        proto_tree_add_item(st, hf_btsmp_reason, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(tvb_get_guint8(tvb, offset), reason_vals, "<unknown>"));
        offset++;
        break;

    case 0x06: /* Encryption Information */
        proto_tree_add_item(st, hf_btsmp_long_term_key, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x07: /* Master Identification */
        proto_tree_add_item(st, hf_btsmp_ediv, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;
        proto_tree_add_item(st, hf_btsmp_random, tvb, offset, 8, ENC_NA);
        offset += 8;
        break;

    case 0x08: /* Identity Information */
        proto_tree_add_item(st, hf_btsmp_id_resolving_key, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

    case 0x09: /* Identity Address Information */
        proto_tree_add_item(st, hf_address_type, tvb, offset, 1, ENC_NA);
        offset += 1;

        offset = dissect_bd_addr(hf_bd_addr, pinfo, st, tvb, offset, FALSE, interface_id, adapter_id, NULL);
        break;

    case 0x0A: /* Signing Information */
        proto_tree_add_item(st, hf_btsmp_signature_key, tvb, offset, 16, ENC_NA);
        offset += 16;
        break;

     case 0x0B: /* Security Request */
        col_append_str(pinfo->cinfo, COL_INFO, ": ");
        offset = dissect_btsmp_auth_req(tvb, offset, pinfo, st);
        break;

    case 0x0C: /* Pairing Public Key */ {
        proto_item  *sub_item;

        sub_item = proto_tree_add_item(st, hf_btsmp_public_key_x, tvb, offset, 32, ENC_NA);
        if (tvb_memeql(tvb, offset, debug_public_key_x, 32) == 0)
            proto_item_append_text(sub_item, " (Debug Key)");
        offset += 32;

        sub_item = proto_tree_add_item(st, hf_btsmp_public_key_y, tvb, offset, 32, ENC_NA);
        if (tvb_memeql(tvb, offset, debug_public_key_y, 32) == 0)
            proto_item_append_text(sub_item, " (Debug Key)");
        offset += 32;

        break;}
    case 0x0D: /* Pairing DHKey Check" */
        proto_tree_add_item(st, hf_btsmp_dhkey_check, tvb, offset, 16, ENC_NA);
        offset += 16;

        break;
    case 0x0E: /* Pairing Keypress Notification */
        proto_tree_add_item(st, hf_btsmp_notification_type, tvb, offset, 1, ENC_NA);
        col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", val_to_str_const(tvb_get_guint8(tvb, offset), notification_type_vals, "<unknown>"));
        offset += 1;

        break;
    default:
        break;
    }

    return offset;
}
static void dissect_ipsictl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

  proto_tree   *ipsictl_tree = NULL;
  proto_tree   *pdu_tree = NULL;
  proto_item   *ti;
  int           offset = 0;
  int           loffset = 0;
  int           llength = 0;
  int		remaining_length;
  guint16       magic;
  guint16       length;
  guint16       type=0;
  guint16       sequence=0;
  int		first_sequence=-1;
  int		last_sequence=-1;
  guint16       field1=0;
  guint16       pdu=0;
  int		haspdus=0;

  remaining_length=tvb_reported_length_remaining(tvb, offset);

  if (tree) {

      ti = proto_tree_add_item(tree, proto_ipsictl, tvb, offset, remaining_length, ENC_NA);
      ipsictl_tree = proto_item_add_subtree(ti, ett_ipsictl);

  }

  magic = tvb_get_ntohs(tvb, offset);
  if (magic == IPSICTL_PDU_MAGIC)
  {
    haspdus=1;
  }

  while (haspdus &&
    ((remaining_length=tvb_reported_length_remaining(tvb, offset)) > 6))
  {
    loffset = offset;

    magic = tvb_get_ntohs(tvb, loffset); loffset+=2;
    length = tvb_get_ntohs(tvb, loffset); loffset+=2;
    llength=length;
    remaining_length-=4;
    if (remaining_length>=2)
    {
      type = tvb_get_ntohs(tvb, loffset); loffset+=2;
      remaining_length-=2;
      llength-=2;
    }
    if (remaining_length>=2)
    {
      sequence = tvb_get_ntohs(tvb, loffset); loffset+=2;
      remaining_length-=2;
      llength-=2;
      if (first_sequence==-1)
      {
        first_sequence=sequence;
      }else{
        last_sequence=sequence;
      }
    }
    if (remaining_length>=2)
    {
      field1 = tvb_get_ntohs(tvb, loffset); 
      llength-=2;
    }

    if (tree) {

      ti = proto_tree_add_uint_format(ipsictl_tree, hf_ipsictl_pdu, tvb,
           offset, (length+4), pdu,
           "PDU: %d", pdu);

      pdu_tree = proto_item_add_subtree(ti, ett_ipsictl_pdu);
    }

    loffset=offset;
    remaining_length=tvb_reported_length_remaining(tvb, offset);

    if (tree) {
      proto_tree_add_uint(pdu_tree, hf_ipsictl_magic, tvb, loffset, 2, magic);
    }
    loffset+=2; remaining_length-=2;
    if (tree) {
      proto_tree_add_uint(pdu_tree, hf_ipsictl_length, tvb, loffset, 2, length);
    }
    loffset+=2; remaining_length-=2;

    if (remaining_length>=2)
    {
      if (tree) {
        proto_tree_add_uint(pdu_tree, hf_ipsictl_type, tvb, loffset, 2, type);
      }
      loffset+=2; remaining_length-=2;
    }
    if (remaining_length>=2)
    {
      if (tree) {
        proto_tree_add_uint(pdu_tree, hf_ipsictl_sequence, tvb, loffset, 2, sequence);
      }
      loffset+=2; remaining_length-=2;
    }
    if (remaining_length>=2)
    {
      if (tree) {
        proto_tree_add_uint(pdu_tree, hf_ipsictl_field1, tvb, loffset, 2, field1);
      }
      loffset+=2; remaining_length-=2;
    }
    if (remaining_length>=2)
    {
      if (tree) {
        proto_tree_add_item(pdu_tree, hf_ipsictl_data, tvb, loffset, llength, ENC_NA);
      }
      loffset+=llength;
    }

    offset=loffset;
    pdu++;
  }

  if (!haspdus)
  {
    if (tree) {
      proto_tree_add_item(ipsictl_tree, hf_ipsictl_data, tvb, offset, -1, ENC_NA);
    }
  }

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPSICTL");

  if (haspdus)
  {
    if (last_sequence==-1)
    {
      col_add_fstr(pinfo->cinfo, COL_INFO, "PDUS=%d, Seq=0x%04x",
        pdu,first_sequence);
    }else{
      col_add_fstr(pinfo->cinfo, COL_INFO, "PDUS=%d, Seq=0x%04x-0x%04x",
        pdu,first_sequence,last_sequence);
    }
  }else{
    col_set_str(pinfo->cinfo, COL_INFO, "Initialization");
  }


} /* dissect_ipsictl */
示例#3
0
static void
dissect_rmi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_tree *rmi_tree;

    tvbuff_t   *next_tvb;

    gint       offset;
    gint       next_offset;
    int        datalen;

    guint16    version, len, port;
    guint8     message, proto;

    rmi_type   rmitype;

    const char *epid_hostname;
    guint epid_len;

    offset     = 0;
    rmitype    = 0;

/* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "RMI");

    datalen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);

    rmitype = get_rmi_type(tvb, offset, datalen);

    if (check_col(pinfo->cinfo, COL_INFO)) {
	switch(rmitype) {
	case RMI_OUTPUTSTREAM:
	    version = tvb_get_ntohs(tvb,4);
	    col_add_fstr(pinfo->cinfo, COL_INFO,
			 "JRMI, Version: %d, ", version);

	    proto   = tvb_get_guint8(tvb, 6);
	    col_append_str(pinfo->cinfo, COL_INFO,
			   val_to_str(proto, rmi_protocol_str,
				      "Unknown protocol"));
	    break;
	case RMI_OUTPUTMESSAGE:
	    message = tvb_get_guint8(tvb,0);
	    col_set_str(pinfo->cinfo, COL_INFO,
			"JRMI, ");
	    col_append_str(pinfo->cinfo, COL_INFO,
			   val_to_str(message, rmi_output_message_str,
				      "Unknown message"));
	    break;
	case RMI_INPUTSTREAM:
	    message = tvb_get_guint8(tvb,0);
	    col_set_str(pinfo->cinfo, COL_INFO,
			"JRMI, ");
	    col_append_str(pinfo->cinfo, COL_INFO,
			   val_to_str(message, rmi_input_message_str,
				      "Unknown message"));
	    break;
	case SERIALIZATION_DATA:
	    version = tvb_get_ntohs(tvb,2);
	    col_add_fstr(pinfo->cinfo, COL_INFO,
			 "Serialization data, Version: %d", version);
	    break;
	default:
	    col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
	    break;
	}
    }

    if (tree) {
	ti = proto_tree_add_item(tree, proto_rmi, tvb, 0, -1, ENC_NA);
	rmi_tree = proto_item_add_subtree(ti, ett_rmi);
	switch(rmitype) {
	case RMI_OUTPUTSTREAM:
	    /* XXX - uint, or string? */
	    proto_tree_add_uint(rmi_tree, hf_rmi_magic,
				tvb, offset,     4, tvb_get_ntohl(tvb,0));
	    proto_tree_add_item(rmi_tree, hf_rmi_version,
				tvb, offset + 4, 2, ENC_BIG_ENDIAN);
	    proto_tree_add_item(rmi_tree, hf_rmi_protocol,
				  tvb, offset + 6, 1, ENC_BIG_ENDIAN);
	    break;
	case RMI_INPUTSTREAM:
	    message = tvb_get_guint8(tvb, 0);
	    proto_tree_add_uint(rmi_tree, hf_rmi_inputmessage,
				  tvb, offset, 1, message);
	    if(message == RMI_INPUTSTREAM_MESSAGE_ACK) {
		proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
				    "EndPointIdentifier");
		/* MESSAGE_ACK should include EndpointIdentifier */
		len = tvb_get_ntohs(tvb, 1);
		proto_tree_add_uint(rmi_tree, hf_rmi_epid_length,
				       tvb, offset + 1, 2, len);
		epid_len = len < ITEM_LABEL_LENGTH ? len : ITEM_LABEL_LENGTH;
		if (epid_len > 0) {
			epid_hostname = tvb_format_text(tvb, offset + 3, epid_len);
		} else {
			epid_hostname = "[Empty]";
		}
		proto_tree_add_string(rmi_tree, hf_rmi_epid_hostname,
				      tvb, offset + 3, len, epid_hostname);

		port = tvb_get_ntohs(tvb, offset + len + 5);
  		proto_tree_add_uint(rmi_tree, hf_rmi_epid_port,
  				    tvb, offset + len + 5, 2, port);
	    }
	    if(message == RMI_INPUTSTREAM_MESSAGE_RETURNDATA) {
		proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
				    "Serialization Data");
		next_tvb = tvb_new_subset_remaining(tvb, offset + 1);
		dissect_ser(next_tvb, tree);
	    }
	    break;
	case RMI_OUTPUTMESSAGE:
	    message = tvb_get_guint8(tvb, 0);
	    proto_tree_add_uint(rmi_tree, hf_rmi_outputmessage,
				  tvb, offset, 1, message);
	    if(message == RMI_OUTPUTSTREAM_MESSAGE_CALL) {
		proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
				    "Serialization Data");
		/* XXX */
		next_tvb = tvb_new_subset_remaining(tvb, offset + 1);
		dissect_ser(next_tvb, tree);
	    }
	    if(message == RMI_OUTPUTSTREAM_MESSAGE_DGCACK) {
		proto_tree_add_text(rmi_tree, tvb, offset + 1, -1,
				    "UniqueIdentifier");
	    }
	    break;
	case SERIALIZATION_DATA:
	    dissect_ser(tvb, tree);
	    break;
	default:
	    break;
	}
    }
}
示例#4
0
static void
dissect_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	proto_item  *volatile ti = NULL, *comment_item;
	guint	     cap_len = 0, frame_len = 0;
	proto_tree  *volatile tree;
	proto_tree  *comments_tree;
	proto_item  *item;
	const gchar *cap_plurality, *frame_plurality;

	tree=parent_tree;

	pinfo->current_proto = "Frame";

	if (pinfo->pseudo_header != NULL) {
		switch (pinfo->fd->lnk_t) {

		case WTAP_ENCAP_WFLEET_HDLC:
		case WTAP_ENCAP_CHDLC_WITH_PHDR:
		case WTAP_ENCAP_PPP_WITH_PHDR:
		case WTAP_ENCAP_SDLC:
		case WTAP_ENCAP_BLUETOOTH_H4_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->p2p.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_BLUETOOTH_HCI:
			pinfo->p2p_dir = pinfo->pseudo_header->bthci.sent;
			break;

		case WTAP_ENCAP_LAPB:
		case WTAP_ENCAP_FRELAY_WITH_PHDR:
			pinfo->p2p_dir =
			    (pinfo->pseudo_header->x25.flags & FROM_DCE) ?
			    P2P_DIR_RECV : P2P_DIR_SENT;
			break;

		case WTAP_ENCAP_ISDN:
		case WTAP_ENCAP_V5_EF:
		case WTAP_ENCAP_DPNSS:
		case WTAP_ENCAP_BACNET_MS_TP_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->isdn.uton ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_LINUX_LAPD:
			pinfo->p2p_dir = (pinfo->pseudo_header->lapd.pkttype == 3 ||
				pinfo->pseudo_header->lapd.pkttype == 4) ?
				P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		case WTAP_ENCAP_MTP2_WITH_PHDR:
			pinfo->p2p_dir = pinfo->pseudo_header->mtp2.sent ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			pinfo->link_number  = pinfo->pseudo_header->mtp2.link_number;
			pinfo->annex_a_used = pinfo->pseudo_header->mtp2.annex_a_used;
			break;

		case WTAP_ENCAP_GSM_UM:
			pinfo->p2p_dir = pinfo->pseudo_header->gsm_um.uplink ?
			    P2P_DIR_SENT : P2P_DIR_RECV;
			break;

		}
	}

	if(pinfo->pkt_comment){
		item = proto_tree_add_item(tree, proto_pkt_comment, tvb, 0, -1, ENC_NA);
		comments_tree = proto_item_add_subtree(item, ett_comments);
		comment_item = proto_tree_add_string_format(comments_tree, hf_comments_text, tvb, 0, -1,
							                   pinfo->pkt_comment, "%s",
							                   pinfo->pkt_comment);
		expert_add_info_format(pinfo, comment_item, &ei_comments_text,
					                       "%s",  pinfo->pkt_comment);


	}

	/* if FRAME is not referenced from any filters we dont need to worry about
	   generating any tree items.  */
	if(!proto_field_is_referenced(tree, proto_frame)) {
		tree=NULL;
		if(pinfo->fd->flags.has_ts) {
			if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000)
				expert_add_info(pinfo, NULL, &ei_arrive_time_out_of_range);
		}
	} else {
		proto_tree *fh_tree;
		gboolean old_visible;

		/* Put in frame header information. */
		cap_len = tvb_length(tvb);
		frame_len = tvb_reported_length(tvb);

		cap_plurality = plurality(cap_len, "", "s");
		frame_plurality = plurality(frame_len, "", "s");

		ti = proto_tree_add_protocol_format(tree, proto_frame, tvb, 0, -1,
		    "Frame %u: %u byte%s on wire",
		    pinfo->fd->num, frame_len, frame_plurality);
		if (generate_bits_field)
			proto_item_append_text(ti, " (%u bits)", frame_len * 8);
		proto_item_append_text(ti, ", %u byte%s captured",
		    cap_len, cap_plurality);
		if (generate_bits_field) {
			proto_item_append_text(ti, " (%u bits)",
			    cap_len * 8);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) {
			proto_item_append_text(ti, " on interface %u",
			    pinfo->phdr->interface_id);
		}
		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			if (pinfo->phdr->pack_flags & 0x00000001) {
				proto_item_append_text(ti, " (inbound)");
				pinfo->p2p_dir = P2P_DIR_RECV;
			}
			if (pinfo->phdr->pack_flags & 0x00000002) {
				proto_item_append_text(ti, " (outbound)");
				pinfo->p2p_dir = P2P_DIR_SENT;
			}
		}

		fh_tree = proto_item_add_subtree(ti, ett_frame);

		if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID && proto_field_is_referenced(tree, hf_frame_interface_id)) {
			const char *interface_name = epan_get_interface_name(pinfo->epan, pinfo->phdr->interface_id);

			if (interface_name)
				proto_tree_add_uint_format_value(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id, "%u (%s)", pinfo->phdr->interface_id, interface_name);
			else
				proto_tree_add_uint(fh_tree, hf_frame_interface_id, tvb, 0, 0, pinfo->phdr->interface_id);
		}

		if (pinfo->phdr->presence_flags & WTAP_HAS_PACK_FLAGS) {
			proto_tree *flags_tree;
			proto_item *flags_item;

			flags_item = proto_tree_add_uint(fh_tree, hf_frame_pack_flags, tvb, 0, 0, pinfo->phdr->pack_flags);
			flags_tree = proto_item_add_subtree(flags_item, ett_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_direction, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reception_type, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_fcs_length, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_uint(flags_tree, hf_frame_pack_reserved, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_crc_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_long_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_packet_too_short_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_wrong_inter_frame_gap_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_unaligned_frame_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_start_frame_delimiter_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_preamble_error, tvb, 0, 0, pinfo->phdr->pack_flags);
			proto_tree_add_boolean(flags_tree, hf_frame_pack_symbol_error, tvb, 0, 0, pinfo->phdr->pack_flags);
		}

		proto_tree_add_int(fh_tree, hf_frame_wtap_encap, tvb, 0, 0, pinfo->fd->lnk_t);

		if (pinfo->fd->flags.has_ts) {
			proto_tree_add_time(fh_tree, hf_frame_arrival_time, tvb,
					    0, 0, &(pinfo->fd->abs_ts));
			if(pinfo->fd->abs_ts.nsecs < 0 || pinfo->fd->abs_ts.nsecs >= 1000000000) {
				expert_add_info_format(pinfo, ti, &ei_arrive_time_out_of_range,
								  "Arrival Time: Fractional second %09ld is invalid,"
								  " the valid range is 0-1000000000",
								  (long) pinfo->fd->abs_ts.nsecs);
			}
			item = proto_tree_add_time(fh_tree, hf_frame_shift_offset, tvb,
					    0, 0, &(pinfo->fd->shift_offset));
			PROTO_ITEM_SET_GENERATED(item);

			if(generate_epoch_time) {
				proto_tree_add_time(fh_tree, hf_frame_arrival_time_epoch, tvb,
						    0, 0, &(pinfo->fd->abs_ts));
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta)) {
				nstime_t     del_cap_ts;

				frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->num - 1, &del_cap_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta, tvb,
							   0, 0, &(del_cap_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			if (proto_field_is_referenced(tree, hf_frame_time_delta_displayed)) {
				nstime_t del_dis_ts;

				frame_delta_abs_time(pinfo->epan, pinfo->fd, pinfo->fd->prev_dis_num, &del_dis_ts);

				item = proto_tree_add_time(fh_tree, hf_frame_time_delta_displayed, tvb,
							   0, 0, &(del_dis_ts));
				PROTO_ITEM_SET_GENERATED(item);
			}

			item = proto_tree_add_time(fh_tree, hf_frame_time_relative, tvb,
						   0, 0, &(pinfo->rel_ts));
			PROTO_ITEM_SET_GENERATED(item);

			if(pinfo->fd->flags.ref_time){
				ti = proto_tree_add_item(fh_tree, hf_frame_time_reference, tvb, 0, 0, ENC_NA);
				PROTO_ITEM_SET_GENERATED(ti);
			}
		}

		proto_tree_add_uint(fh_tree, hf_frame_number, tvb,
				    0, 0, pinfo->fd->num);

		proto_tree_add_uint_format(fh_tree, hf_frame_len, tvb,
					   0, 0, frame_len, "Frame Length: %u byte%s (%u bits)",
					   frame_len, frame_plurality, frame_len * 8);

		proto_tree_add_uint_format(fh_tree, hf_frame_capture_len, tvb,
					   0, 0, cap_len, "Capture Length: %u byte%s (%u bits)",
					   cap_len, cap_plurality, cap_len * 8);

		if (generate_md5_hash) {
			const guint8 *cp;
			md5_state_t   md_ctx;
			md5_byte_t    digest[16];
			const gchar  *digest_string;

			cp = tvb_get_ptr(tvb, 0, cap_len);

			md5_init(&md_ctx);
			md5_append(&md_ctx, cp, cap_len);
			md5_finish(&md_ctx, digest);

			digest_string = bytestring_to_str(digest, 16, '\0');
			ti = proto_tree_add_string(fh_tree, hf_frame_md5_hash, tvb, 0, 0, digest_string);
			PROTO_ITEM_SET_GENERATED(ti);
		}

		ti = proto_tree_add_boolean(fh_tree, hf_frame_marked, tvb, 0, 0,pinfo->fd->flags.marked);
		PROTO_ITEM_SET_GENERATED(ti);

		ti = proto_tree_add_boolean(fh_tree, hf_frame_ignored, tvb, 0, 0,pinfo->fd->flags.ignored);
		PROTO_ITEM_SET_GENERATED(ti);

		if(proto_field_is_referenced(tree, hf_frame_protocols)) {
			/* we are going to be using proto_item_append_string() on
			 * hf_frame_protocols, and we must therefore disable the
			 * TRY_TO_FAKE_THIS_ITEM() optimisation for the tree by
			 * setting it as visible.
			 *
			 * See proto.h for details.
			 */
			old_visible = proto_tree_set_visible(fh_tree, TRUE);
			ti = proto_tree_add_string(fh_tree, hf_frame_protocols, tvb, 0, 0, "");
			PROTO_ITEM_SET_GENERATED(ti);
			proto_tree_set_visible(fh_tree, old_visible);
		}

		if(pinfo->fd->pfd != 0){
			proto_item *ppd_item;
			guint num_entries = g_slist_length(pinfo->fd->pfd);
			guint i;
			ppd_item = proto_tree_add_uint(fh_tree, hf_frame_num_p_prot_data, tvb, 0, 0, num_entries);
			PROTO_ITEM_SET_GENERATED(ppd_item);
			for(i=0; i<num_entries; i++){
				proto_tree_add_text (fh_tree, tvb, 0, 0, "%s",p_get_proto_name_and_key(pinfo->fd, i));
			}
		}
		/* Check for existences of P2P pseudo header */
		if (pinfo->p2p_dir != P2P_DIR_UNKNOWN) {
			proto_tree_add_int(fh_tree, hf_frame_p2p_dir, tvb,
					   0, 0, pinfo->p2p_dir);
		}

		/* Check for existences of MTP2 link number */
		if ((pinfo->pseudo_header != NULL ) && (pinfo->fd->lnk_t == WTAP_ENCAP_MTP2_WITH_PHDR)) {
			proto_tree_add_uint(fh_tree, hf_link_number, tvb,
					    0, 0, pinfo->link_number);
		}

		if (show_file_off) {
			proto_tree_add_int64_format_value(fh_tree, hf_frame_file_off, tvb,
						    0, 0, pinfo->fd->file_off,
						    "%" G_GINT64_MODIFIER "d (0x%" G_GINT64_MODIFIER "x)",
						    pinfo->fd->file_off, pinfo->fd->file_off);
		}

		if(pinfo->fd->color_filter != NULL) {
			const color_filter_t *color_filter = (const color_filter_t *)pinfo->fd->color_filter;
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_name, tvb,
						     0, 0, color_filter->filter_name);
			PROTO_ITEM_SET_GENERATED(item);
			item = proto_tree_add_string(fh_tree, hf_frame_color_filter_text, tvb,
						     0, 0, color_filter->filter_text);
			PROTO_ITEM_SET_GENERATED(item);
		}
	}

	if (pinfo->fd->flags.ignored) {
		/* Ignored package, stop handling here */
		col_set_str(pinfo->cinfo, COL_INFO, "<Ignored>");
		proto_tree_add_text (tree, tvb, 0, -1, "This frame is marked as ignored");
		return;
	}

	/* Portable Exception Handling to trap Wireshark specific exceptions like BoundsError exceptions */
	TRY {
#ifdef _MSC_VER
		/* Win32: Visual-C Structured Exception Handling (SEH) to trap hardware exceptions
		   like memory access violations.
		   (a running debugger will be called before the except part below) */
                /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                   stack in an inconsistent state thus causing a crash at some point in the
                   handling of the exception.
                   See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                */
		__try {
#endif
			if ((force_docsis_encap) && (docsis_handle)) {
				call_dissector(docsis_handle, tvb, pinfo, parent_tree);
			} else {
				if (!dissector_try_uint(wtap_encap_dissector_table, pinfo->fd->lnk_t,
							tvb, pinfo, parent_tree)) {

					col_set_str(pinfo->cinfo, COL_PROTOCOL, "UNKNOWN");
					col_add_fstr(pinfo->cinfo, COL_INFO, "WTAP_ENCAP = %d",
						     pinfo->fd->lnk_t);
					call_dissector(data_handle,tvb, pinfo, parent_tree);
				}
			}
#ifdef _MSC_VER
		} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
			switch(GetExceptionCode()) {
			case(STATUS_ACCESS_VIOLATION):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
				break;
			case(STATUS_INTEGER_DIVIDE_BY_ZERO):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
				break;
			case(STATUS_STACK_OVERFLOW):
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
				/* XXX - this will have probably corrupted the stack,
				   which makes problems later in the exception code */
				break;
				/* XXX - add other hardware exception codes as required */
			default:
				show_exception(tvb, pinfo, parent_tree, DissectorError,
					       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
			}
		}
#endif
	}
	CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
		show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
	}
	ENDTRY;

        if(proto_field_is_referenced(tree, hf_frame_protocols)) {
		wmem_strbuf_t *val = wmem_strbuf_new(wmem_packet_scope(), "");
		wmem_list_frame_t *frame;
		/* skip the first entry, it's always the "frame" protocol */
		frame = wmem_list_frame_next(wmem_list_head(pinfo->layers));
		if (frame) {
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		while (frame) {
			wmem_strbuf_append_c(val, ':');
			wmem_strbuf_append(val, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(frame))));
			frame = wmem_list_frame_next(frame);
		}
		proto_item_append_string(ti, wmem_strbuf_get_str(val));
	}

	/*  Call postdissectors if we have any (while trying to avoid another
	 *  TRY/CATCH)
	 */
	if (have_postdissector()) {
		TRY {
#ifdef _MSC_VER
			/* Win32: Visual-C Structured Exception Handling (SEH)
			   to trap hardware exceptions like memory access violations */
			/* (a running debugger will be called before the except part below) */
                        /* Note: A Windows "exceptional exception" may leave the kazlib's (Portable Exception Handling)
                           stack in an inconsistent state thus causing a crash at some point in the
                           handling of the exception.
                           See: https://www.wireshark.org/lists/wireshark-dev/200704/msg00243.html
                        */
			__try {
#endif
				call_all_postdissectors(tvb, pinfo, parent_tree);
#ifdef _MSC_VER
			} __except(EXCEPTION_EXECUTE_HANDLER /* handle all exceptions */) {
				switch(GetExceptionCode()) {
				case(STATUS_ACCESS_VIOLATION):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_ACCESS_VIOLATION: dissector accessed an invalid memory address");
					break;
				case(STATUS_INTEGER_DIVIDE_BY_ZERO):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_INTEGER_DIVIDE_BY_ZERO: dissector tried an integer division by zero");
					break;
				case(STATUS_STACK_OVERFLOW):
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       "STATUS_STACK_OVERFLOW: dissector overflowed the stack (e.g. endless loop)");
					/* XXX - this will have probably corrupted the stack,
					   which makes problems later in the exception code */
					break;
					/* XXX - add other hardware exception codes as required */
				default:
					show_exception(tvb, pinfo, parent_tree, DissectorError,
						       g_strdup_printf("dissector caused an unknown exception: 0x%x", GetExceptionCode()));
				}
			}
#endif
		}
		CATCH_BOUNDS_AND_DISSECTOR_ERRORS {
			show_exception(tvb, pinfo, parent_tree, EXCEPT_CODE, GET_MESSAGE);
		}
		ENDTRY;
	}

	tap_queue_packet(frame_tap, pinfo, NULL);


	if (pinfo->frame_end_routines) {
		g_slist_foreach(pinfo->frame_end_routines, &call_frame_end_routine, NULL);
		g_slist_free(pinfo->frame_end_routines);
		pinfo->frame_end_routines = NULL;
	}
}
示例#5
0
static int
dissect_l1_events(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	proto_tree	*subtree;
	proto_item	*ti;
	gint		offset = 0, next_offset;
	gint		len;
	const char	*data_name;

	data_name = pinfo->match_string;
	if (! (data_name && data_name[0])) {
		/*
		 * No information from "match_string"
		 */
		data_name = (char *)data;
		if (! (data_name && data_name[0])) {
			/*
			 * No information from dissector data
			 */
			data_name = (char *)(pinfo->private_data);
			if (! (data_name && data_name[0])) {
				/*
				 * No information from "private_data"
				 */
				data_name = NULL;
			}
		}
	}

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "Layer1");
	col_set_str(pinfo->cinfo, COL_DEF_SRC,
			    pinfo->pseudo_header->l1event.uton? "TE" : "NT");
	len = tvb_find_line_end(tvb, 0, tvb_ensure_length_remaining(tvb, 0),
					&next_offset, FALSE);
	if(len>0)
		col_add_str(pinfo->cinfo, COL_INFO, tvb_format_text(tvb, 0, len));

	if (tree) {
		ti = proto_tree_add_item(tree, proto_l1_events,
				tvb, 0, -1, ENC_NA);
		if (data_name)
			proto_item_append_text(ti, ": %s", data_name);
		subtree = proto_item_add_subtree(ti, ett_l1_events);
		/* Read the media line by line */
		while (tvb_offset_exists(tvb, offset)) {
			/*
			 * XXX - we need to be passed the parameters
			 * of the content type via "pinfo->private_data",
			 * so that we know the character set.  We'd
			 * have to handle that character set, which
			 * might be a multibyte character set such
			 * as "iso-10646-ucs-2", or might require other
			 * special processing.
			 */
			len = tvb_find_line_end(tvb, offset,
					tvb_ensure_length_remaining(tvb, offset),
					&next_offset, FALSE);
			if (len == -1)
				break;

			/* We use next_offset - offset instead of len in the
			 * call to proto_tree_add_format_text() so it will include the
			 * line terminator(s) (\r and/or \n) in the display.
			 */
			proto_tree_add_format_text(subtree, tvb, offset, next_offset - offset);
			offset = next_offset;
		}
	}

	return tvb_length(tvb);
}
示例#6
0
/* Code to actually dissect the packets */
static void
dissect_mip( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  /* Set up structures we will need to add the protocol subtree and manage it */
  proto_item	*ti;
  proto_tree	*mip_tree=NULL;
  proto_item    *tf;
  proto_tree    *flags_tree;
  guint8         type;
  guint16        flags;
  gint           offset=0;
  const guint8  *reftime;
  tvbuff_t      *next_tvb;

  /* Make entries in Protocol column and Info column on summary display */

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "MobileIP");
  col_clear(pinfo->cinfo, COL_INFO);

  type = tvb_get_guint8(tvb, offset);
  switch (type) {
  case MIP_REGISTRATION_REQUEST:
	col_add_fstr(pinfo->cinfo, COL_INFO,
		       "Reg Request: HoA=%s HA=%s CoA=%s",
		       ip_to_str(tvb_get_ptr(tvb,4,4)),
		       ip_to_str(tvb_get_ptr(tvb,8,4)),
		       ip_to_str(tvb_get_ptr(tvb,12,4)));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* type */
	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* flags */
	  flags = tvb_get_guint8(tvb, offset);
	  tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 1, flags);
	  flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_s, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_b, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_d, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_m, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_g, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_v, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_t, tvb, offset, 1, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_x, tvb, offset, 1, flags);
	  offset++;

	  /* lifetime */
	  proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, FALSE);
	  offset += 2;

	  /* home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* home agent address */
	  proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Care of Address */
	  proto_tree_add_item(mip_tree, hf_mip_coa, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Identifier - assumed to be an NTP time here */
	  reftime = tvb_get_ptr(tvb, offset, 8);
	  proto_tree_add_bytes_format(mip_tree, hf_mip_ident, tvb, offset, 8,
				      reftime,
				      "Identification: %s",
				      ntp_fmt_ts(reftime));
	  offset += 8;

	} /* if tree */
	break;
  case MIP_REGISTRATION_REPLY:
	col_add_fstr(pinfo->cinfo, COL_INFO,
		       "Reg Reply: HoA=%s HA=%s, Code=%u",
		       ip_to_str(tvb_get_ptr(tvb,4,4)), 
		       ip_to_str(tvb_get_ptr(tvb,8,4)), 
		       tvb_get_guint8(tvb,1));

	if (tree) {
	  /* Add Subtree */
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* Type */
  	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* Reply Code */
	  proto_tree_add_item(mip_tree, hf_mip_code, tvb, offset, 1, FALSE);
	  offset++;

	  /* Registration Lifetime */
	  proto_tree_add_item(mip_tree, hf_mip_life, tvb, offset, 2, FALSE);
	  offset += 2;

	  /* Home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Home Agent Address */
	  proto_tree_add_item(mip_tree, hf_mip_haaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* Identifier - assumed to be an NTP time here */
	  reftime = tvb_get_ptr(tvb, offset, 8);
	  proto_tree_add_bytes_format(mip_tree, hf_mip_ident, tvb, offset, 8,
				      reftime,
				      "Identification: %s",
				      ntp_fmt_ts(reftime));
	  offset += 8;
	} /* if tree */
	break;
  case MIP_NATT_TUNNEL_DATA:
	col_add_fstr(pinfo->cinfo, COL_INFO, "Tunnel Data: Next Header=%u",
		       tvb_get_guint8(tvb,1));

	if (tree) {
	  /* Add Subtree */
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* Type */
  	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* Next Header */
	  proto_tree_add_item(mip_tree, hf_mip_nattt_nexthdr, tvb, offset, 1, FALSE);
	  offset++;

	  /* reserved */
	  proto_tree_add_item(mip_tree, hf_mip_nattt_reserved, tvb, offset, 2, FALSE);
	  offset += 2;
	} /* if tree */
	else {
	  offset += 4;
	}
	/* encapsulated payload */
	next_tvb = tvb_new_subset_remaining(tvb, 4);
	call_dissector(ip_handle, next_tvb, pinfo, mip_tree);
	offset += tvb_reported_length_remaining(tvb, offset);
	break;
  case MIP_REGISTRATION_REVOCATION:
	col_add_fstr(pinfo->cinfo, COL_INFO,
		       "Reg Revocation: HoA=%s HDA=%s FDA=%s",
		       ip_to_str(tvb_get_ptr(tvb,4,4)),
		       ip_to_str(tvb_get_ptr(tvb,8,4)),
		       ip_to_str(tvb_get_ptr(tvb,12,4)));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* type */
	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* reserved */
	  proto_tree_add_item(mip_tree, hf_mip_rev_reserved, tvb, offset, 1, FALSE);
	  offset++;

	  /* flags */
	  flags = tvb_get_ntohs(tvb, offset);
	  tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
	  flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_rev_a, tvb, offset, 2, flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_rev_i, tvb, offset, 2, flags);

	  /* reserved */
	  proto_tree_add_uint(flags_tree, hf_mip_rev_reserved, tvb, offset, 2, flags);
	  offset += 2;

	  /* home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* home domain address */
	  proto_tree_add_item(mip_tree, hf_mip_hda, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* foreign domain address */
	  proto_tree_add_item(mip_tree, hf_mip_fda, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* revocation identifier */
	  proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, FALSE);
	  offset += 4;
	} /* if tree */
	break;
  case MIP_REGISTRATION_REVOCATION_ACK:
	  col_add_fstr(pinfo->cinfo, COL_INFO, "Reg Revocation Ack: HoA=%s",
		       ip_to_str(tvb_get_ptr(tvb,4,4)));

	if (tree) {
	  ti = proto_tree_add_item(tree, proto_mip, tvb, offset, -1, FALSE);
	  mip_tree = proto_item_add_subtree(ti, ett_mip);

	  /* type */
	  proto_tree_add_uint(mip_tree, hf_mip_type, tvb, offset, 1, type);
	  offset++;

	  /* reserved */
	  proto_tree_add_item(mip_tree, hf_mip_ack_reserved, tvb, offset, 1, FALSE);
	  offset++;

	  /* flags */
	  flags = tvb_get_ntohs(tvb, offset);
	  tf = proto_tree_add_uint(mip_tree, hf_mip_flags, tvb, offset, 2, flags);
	  flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
	  proto_tree_add_boolean(flags_tree, hf_mip_ack_i, tvb, offset, 2, flags);

	  /* reserved */
	  proto_tree_add_uint(flags_tree, hf_mip_ack_reserved, tvb, offset, 2, flags);
	  offset += 2;

	  /* home address */
	  proto_tree_add_item(mip_tree, hf_mip_homeaddr, tvb, offset, 4, FALSE);
	  offset += 4;

	  /* revocation identifier */
	  proto_tree_add_item(mip_tree, hf_mip_revid, tvb, offset, 4, FALSE);
	  offset += 4;
	} /* if tree */
	break;
  } /* End switch */

  if (tree) {
	if (tvb_reported_length_remaining(tvb, offset) > 0)
	  dissect_mip_extensions(tvb, offset, mip_tree);
  }
} /* dissect_mip */
示例#7
0
static void
dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_item *ct;
    proto_tree *bacnet_tree;
    proto_tree *control_tree;

    gint offset;
    guint8 bacnet_version;
    guint8 bacnet_control;
    guint8 bacnet_dlen;
    guint8 bacnet_slen;
    guint8 bacnet_mesgtyp;
    guint8 bacnet_rejectreason;
    guint8 bacnet_rportnum;
    guint8 bacnet_pinfolen;
    guint8 i;
    tvbuff_t *next_tvb;
    guint32 vendor_id;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "BACnet-NPDU");

    col_set_str(pinfo->cinfo, COL_INFO, "Building Automation and Control Network NPDU");

    offset = 0;
    bacnet_version = tvb_get_guint8(tvb, offset);
    bacnet_control = tvb_get_guint8(tvb, offset+1);

    /* I don't know the length of the NPDU yet; Setting the length after dissection */
    ti = proto_tree_add_item(tree, proto_bacnet, tvb, 0, -1, ENC_NA);

    bacnet_tree = proto_item_add_subtree(ti, ett_bacnet);

    proto_tree_add_uint_format_value(bacnet_tree, hf_bacnet_version, tvb,
                                     offset, 1,
                                     bacnet_version,"0x%02x (%s)",bacnet_version,
                                     (bacnet_version == 0x01)?"ASHRAE 135-1995":"unknown");
    offset ++;
    ct = proto_tree_add_uint(bacnet_tree, hf_bacnet_control,
                             tvb, offset, 1, bacnet_control);
    control_tree = proto_item_add_subtree(ct, ett_bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_net,
                           tvb, offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_res1, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_dest, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_res2, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_src, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_expect, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_high,
                           tvb, offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_low,
                           tvb, offset, 1, bacnet_control);
    offset ++;
    if (bacnet_control & BAC_CONTROL_DEST) { /* DNET, DLEN, DADR */
        proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                            tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;
        bacnet_dlen = tvb_get_guint8(tvb, offset);
        /* DLEN = 0 is broadcast on dest.network */
        if( bacnet_dlen == 0) {
            /* append to hf_bacnet_dlen: broadcast */
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
                                             "%d indicates Broadcast on Destination Network",
                                             bacnet_dlen);
            offset ++;
            /* going to SNET */
        } else if (bacnet_dlen==6) {
            proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
                                tvb, offset, 1, bacnet_dlen);
            offset ++;
            /* Ethernet MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_dadr_eth, tvb, offset,
                                bacnet_dlen, ENC_NA);
            offset += bacnet_dlen;
        } else if (bacnet_dlen==1) {
            proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
                                tvb, offset, 1, bacnet_dlen);
            offset ++;
            /* MS/TP or ARCNET MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_dadr_mstp, tvb, offset,
                                bacnet_dlen, ENC_BIG_ENDIAN);
            offset += bacnet_dlen;
        } else if (bacnet_dlen<7) {
            proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
                                tvb, offset, 1, bacnet_dlen);
            offset ++;
            /* Other MAC formats should be included here */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_dadr_tmp, tvb, offset,
                                bacnet_dlen, ENC_NA);
            offset += bacnet_dlen;
        } else {
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
                                             "%d invalid!",
                                             bacnet_dlen);
        }
    }
    if (bacnet_control & BAC_CONTROL_SRC) { /* SNET, SLEN, SADR */
        /* SNET */
        proto_tree_add_uint(bacnet_tree, hf_bacnet_snet,
                            tvb, offset, 2, tvb_get_ntohs(tvb, offset));
        offset += 2;
        bacnet_slen = tvb_get_guint8(tvb, offset);
        if( bacnet_slen == 0) { /* SLEN = 0 invalid */
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
                                             "%d invalid!",
                                             bacnet_slen);
            offset ++;
        } else if (bacnet_slen==6) {
            /* SLEN */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
                                tvb, offset, 1, bacnet_slen);
            offset ++;
            /* Ethernet MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_sadr_eth, tvb, offset,
                                bacnet_slen, ENC_NA);
            offset += bacnet_slen;
        } else if (bacnet_slen==1) {
            /* SLEN */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
                                tvb, offset, 1, bacnet_slen);
            offset ++;
            /* MS/TP or ARCNET MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_sadr_mstp, tvb, offset,
                                bacnet_slen, ENC_BIG_ENDIAN);
            offset += bacnet_slen;
        } else if (bacnet_slen<6) { /* LON MAC */
            /* SLEN */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
                                tvb, offset, 1, bacnet_slen);
            offset ++;
            /* Other MAC formats should be included here */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_sadr_tmp, tvb, offset,
                                bacnet_slen, ENC_NA);
            offset += bacnet_slen;
        } else {
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
                                             "%d invalid!",
                                             bacnet_slen);
            offset ++;
        }
    }
    if (bacnet_control & BAC_CONTROL_DEST) { /* Hopcount */
        proto_tree_add_item(bacnet_tree, hf_bacnet_hopc,
                            tvb, offset, 1, ENC_BIG_ENDIAN);
        offset ++;
    }
    /* Network Layer Message Type */
    if (bacnet_control & BAC_CONTROL_NET) {
        bacnet_mesgtyp =  tvb_get_guint8(tvb, offset);
        proto_tree_add_uint_format_value(bacnet_tree,
                                         hf_bacnet_mesgtyp, tvb, offset, 1, bacnet_mesgtyp,
                                         "%02x (%s)", bacnet_mesgtyp,
                                         bacnet_mesgtyp_name(bacnet_mesgtyp));
        /* Put the NPDU Type in the info column */
        col_add_str(pinfo->cinfo, COL_INFO,
                    bacnet_mesgtyp_name(bacnet_mesgtyp));
        offset ++;
        /* Vendor ID
        * The standard says: "If Bit 7 of the control octet is 1 and
        * the Message Type field contains a value in the range
        * X'80' - X'FF', then a Vendor ID field shall be present (...)."
        * We should not go any further in dissecting the packet if it's
        * not present, but we don't know about that: No length field...
        */
        if (bacnet_mesgtyp > 0x7f) {
            /* Note: our next_tvb includes message type and vendor id! */
            next_tvb = tvb_new_subset_remaining(tvb, offset-1);
            vendor_id = tvb_get_ntohs(tvb, offset);
            proto_tree_add_uint(bacnet_tree, hf_bacnet_vendor, tvb,
                                offset, 2, vendor_id);
            offset += 2;	/* vendor_id */
            if (dissector_try_uint(bacnet_dissector_table,
                                   vendor_id, next_tvb, pinfo, bacnet_tree)) {
                /* we parsed it so skip over length and we are done */
                /* Note: offset has now been bumped for message type and vendor id so we take that out of our next_tvb size */
                offset += tvb_length(next_tvb) -3;
            }
        }
        /* Performance Index (in I-Could-Be-Router-To-Network) */
        if (bacnet_mesgtyp == BAC_NET_ICB_R) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
            proto_tree_add_item(bacnet_tree, hf_bacnet_perf,
                                tvb, offset, 1, ENC_BIG_ENDIAN);
            offset ++;
        }
        /* Reason, DNET (in Reject-Message-To-Network) */
        if (bacnet_mesgtyp == BAC_NET_REJ) {
            bacnet_rejectreason = tvb_get_guint8(tvb, offset);
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_rejectreason,
                                             tvb, offset, 1,
                                             bacnet_rejectreason, "%d (%s)",
                                             bacnet_rejectreason,
                                             bacnet_rejectreason_name(bacnet_rejectreason));
            offset ++;
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
        }
        /* N*DNET (in Router-Busy-To-Network,Router-Available-To-Network) */
        if ((bacnet_mesgtyp == BAC_NET_R_BUSY) ||
                (bacnet_mesgtyp == BAC_NET_WHO_R) ||
                (bacnet_mesgtyp == BAC_NET_R_AVA) ||
                (bacnet_mesgtyp == BAC_NET_IAM_R) ) {
            while(tvb_reported_length_remaining(tvb, offset) > 1 ) {
                proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                    tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
            }
        }
        /* Initialize-Routing-Table */
        if ( (bacnet_mesgtyp == BAC_NET_INIT_RTAB) ||
                (bacnet_mesgtyp == BAC_NET_INIT_RTAB_ACK) ) {
            bacnet_rportnum = tvb_get_guint8(tvb, offset);
            /* number of ports */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_rportnum,
                                tvb, offset, 1, bacnet_rportnum);
            offset ++;
            for(i=0; i<bacnet_rportnum; i++) {
                /* Connected DNET */
                proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                    tvb, offset, 2, ENC_BIG_ENDIAN);
                offset += 2;
                /* Port ID */
                proto_tree_add_item(bacnet_tree, hf_bacnet_portid,
                                    tvb, offset, 1, ENC_BIG_ENDIAN);
                offset ++;
                /* Port Info Length */
                bacnet_pinfolen = tvb_get_guint8(tvb, offset);
                proto_tree_add_uint(bacnet_tree, hf_bacnet_pinfolen,
                                    tvb, offset, 1, bacnet_pinfolen);
                offset ++;
                proto_tree_add_item(bacnet_tree, hf_bacnet_pinfo, tvb, offset,
                                    bacnet_pinfolen, ENC_NA);
                offset += bacnet_pinfolen;
            }
        }
        /* Establish-Connection-To-Network */
        if (bacnet_mesgtyp == BAC_NET_EST_CON) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
            proto_tree_add_item(bacnet_tree, hf_bacnet_term_time_value,
                                tvb, offset, 1, ENC_BIG_ENDIAN);
            offset ++;
        }
        /* Disconnect-Connection-To-Network */
        if (bacnet_mesgtyp == BAC_NET_DISC_CON) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, ENC_BIG_ENDIAN);
            offset += 2;
        }
    }
    /* Now set NPDU length */
    proto_item_set_len(ti, offset);

    /* dissect BACnet APDU */
    next_tvb = tvb_new_subset_remaining(tvb,offset);
    if (bacnet_control & BAC_CONTROL_NET) {
        /* Unknown function - dissect the payload as data */
        call_dissector(data_handle, next_tvb, pinfo, tree);
    } else {
        /* APDU - call the APDU dissector */
        call_dissector(bacapp_handle, next_tvb, pinfo, tree);
    }
}
示例#8
0
static void
dissect_nmpi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree	*nmpi_tree = NULL;
    proto_item	*ti;
    int		offset = 0;
    guint8		opcode;
    guint8		nmpi_name_type;
    char		name[(NETBIOS_NAME_LEN - 1)*4 + 1];
    int		name_type;
    char		node_name[(NETBIOS_NAME_LEN - 1)*4 + 1];
    /*int		node_name_type = 0;*/
    tvbuff_t	*next_tvb;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "NMPI");
    col_clear(pinfo->cinfo, COL_INFO);

    if (tree) {
        ti = proto_tree_add_item(tree, proto_nmpi, tvb, offset, 68,
                                 ENC_NA);
        nmpi_tree = proto_item_add_subtree(ti, ett_nmpi);

        add_routers(nmpi_tree, tvb, offset);
    }
    offset += 32;

    /*
     * XXX - we don't use "node_name" or "node_name_type".
     */
    opcode = tvb_get_guint8(tvb, offset);
    nmpi_name_type = tvb_get_guint8(tvb, offset+1);
    name_type = get_netbios_name(tvb, offset+4, name, (NETBIOS_NAME_LEN - 1)*4 + 1);
    /*node_name_type = */get_netbios_name(tvb, offset+20, node_name, (NETBIOS_NAME_LEN - 1)*4 + 1);

    switch (opcode) {

    case INAME_CLAIM:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Claim name %s<%02x>",
                     name, name_type);
        break;

    case INAME_DELETE:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Delete name %s<%02x>",
                     name, name_type);
        break;

    case INAME_QUERY:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Query name %s<%02x>",
                     name, name_type);
        break;

    case INAME_FOUND:
        col_add_fstr(pinfo->cinfo, COL_INFO, "Name %s<%02x> found",
                     name, name_type);
        break;

    case IMSG_HANGUP:
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Messenger hangup on %s<%02x>", name, name_type);
        break;

    case IMSLOT_SEND:
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Mailslot write to %s<%02x>", name, name_type);
        break;

    case IMSLOT_FIND:
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Find mailslot name %s<%02x>", name, name_type);
        break;

    case IMSLOT_NAME:
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Mailslot name %s<%02x> found", name, name_type);
        break;

    default:
        col_add_fstr(pinfo->cinfo, COL_INFO,
                     "Unknown NMPI op 0x%02x: name %s<%02x>",
                     opcode, name, name_type);
        break;
    }

    if (tree) {
        proto_tree_add_text(nmpi_tree, tvb, offset, 1,
                            "Opcode: %s (0x%02x)",
                            val_to_str_const(opcode, nmpi_opcode_vals, "Unknown"),
                            opcode);
        proto_tree_add_text(nmpi_tree, tvb, offset+1, 1,
                            "Name Type: %s (0x%02x)",
                            val_to_str_const(nmpi_name_type, nmpi_name_type_vals, "Unknown"),
                            nmpi_name_type);
        proto_tree_add_text(nmpi_tree, tvb, offset+2, 2,
                            "Message ID: 0x%04x",
                            tvb_get_letohs(tvb, offset+2));
        netbios_add_name("Requested name", tvb, offset+4, nmpi_tree);
        netbios_add_name("Source name", tvb, offset+20, nmpi_tree);
    }

    offset += 1 + 1 + 2 + NETBIOS_NAME_LEN + NETBIOS_NAME_LEN;

    if (opcode == IMSLOT_SEND && tvb_offset_exists(tvb, offset)) {
        next_tvb = tvb_new_subset_remaining(tvb, offset);
        dissect_netbios_payload(next_tvb, pinfo, tree);
    }
}
示例#9
0
static void
dissect_icap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree   *icap_tree = NULL;
    proto_item   *ti        = NULL;
    proto_item   *hidden_item;
    tvbuff_t     *new_tvb;
    gint          offset    = 0;
    const guchar *line;
    gint          next_offset;
    const guchar *linep, *lineend;
    int           linelen;
    guchar        c;
    icap_type_t   icap_type;
    int           datalen;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "ICAP");

    /*
     * Put the first line from the buffer into the summary
     * if it's an ICAP header (but leave out the
     * line terminator).
     * Otherwise, just call it a continuation.
     *
     * Note that "tvb_find_line_end()" will return a value that
     * is not longer than what's in the buffer, so the
     * "tvb_get_ptr()" call won't throw an exception.
     */
    linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
    line = tvb_get_ptr(tvb, offset, linelen);
    icap_type = ICAP_OTHER; /* type not known yet */
    if (is_icap_message(line, linelen, &icap_type))
        col_add_str(pinfo->cinfo, COL_INFO,
            format_text(line, linelen));
    else
        col_set_str(pinfo->cinfo, COL_INFO, "Continuation");

    if (tree) {
        ti = proto_tree_add_item(tree, proto_icap, tvb, offset, -1,
            ENC_NA);
        icap_tree = proto_item_add_subtree(ti, ett_icap);
    }

    /*
     * Process the packet data, a line at a time.
     */
    icap_type = ICAP_OTHER; /* type not known yet */
    while (tvb_offset_exists(tvb, offset)) {
        gboolean is_icap = FALSE;
        gboolean loop_done = FALSE;
        /*
         * Find the end of the line.
         */
        linelen = tvb_find_line_end(tvb, offset, -1, &next_offset,
            FALSE);

        /*
         * Get a buffer that refers to the line.
         */
        line = tvb_get_ptr(tvb, offset, linelen);
        lineend = line + linelen;

        /*
         * find header format
         */
        if (is_icap_message(line, linelen, &icap_type)) {
            goto is_icap_header;
        }

        /*
         * if it looks like a blank line, end of header perhaps?
         */
        if (linelen == 0) {
            goto is_icap_header;
        }

        /*
         * No.  Does it look like a header?
         */
        linep = line;
        loop_done = FALSE;
        while (linep < lineend && (!loop_done)) {
            c = *linep++;

            /*
             * This must be a CHAR, and must not be a CTL, to be part
             * of a token; that means it must be printable ASCII.
             *
             * XXX - what about leading LWS on continuation
             * lines of a header?
             */
            if (!g_ascii_isprint(c)) {
                is_icap = FALSE;
                break;
            }

            switch (c) {

            case '(':
            case ')':
            case '<':
            case '>':
            case '@':
            case ',':
            case ';':
            case '\\':
            case '"':
            case '/':
            case '[':
            case ']':
            case '?':
            case '=':
            case '{':
            case '}':
                /*
                 * It's a separator, so it's not part of a
                 * token, so it's not a field name for the
                 * beginning of a header.
                 *
                 * (We don't have to check for HT; that's
                 * already been ruled out by "iscntrl()".)
                 *
                 * XXX - what about ' '?  HTTP's checks
                 * check for that.
                 */
                is_icap = FALSE;
                loop_done = TRUE;
                break;

            case ':':
                /*
                 * This ends the token; we consider this
                 * to be a header.
                 */
                goto is_icap_header;
            }
        }

        /*
         * We don't consider this part of an ICAP message,
         * so we don't display it.
         * (Yeah, that means we don't display, say, a text/icap
         * page, but you can get that from the data pane.)
         */
        if (!is_icap)
            break;
is_icap_header:
        proto_tree_add_format_text(icap_tree, tvb, offset, next_offset - offset);
        offset = next_offset;
    }

    if (tree) {
        switch (icap_type) {

        case ICAP_OPTIONS:
            hidden_item = proto_tree_add_boolean(icap_tree,
                        hf_icap_options, tvb, 0, 0, 1);
                        PROTO_ITEM_SET_HIDDEN(hidden_item);
            break;

        case ICAP_REQMOD:
            hidden_item = proto_tree_add_boolean(icap_tree,
                        hf_icap_reqmod, tvb, 0, 0, 1);
                        PROTO_ITEM_SET_HIDDEN(hidden_item);
            break;

        case ICAP_RESPMOD:
            hidden_item = proto_tree_add_boolean(icap_tree,
                        hf_icap_respmod, tvb, 0, 0, 1);
                        PROTO_ITEM_SET_HIDDEN(hidden_item);
            break;

        case ICAP_RESPONSE:
            hidden_item = proto_tree_add_boolean(icap_tree,
                        hf_icap_response, tvb, 0, 0, 1);
                        PROTO_ITEM_SET_HIDDEN(hidden_item);
            break;

        case ICAP_OTHER:
        default:
            break;
        }
    }

    datalen = tvb_reported_length_remaining(tvb, offset);
    if (datalen > 0) {
        if(http_handle){
            new_tvb = tvb_new_subset_remaining(tvb, offset);
            call_dissector(http_handle, new_tvb, pinfo, icap_tree);
        }
    }
}
示例#10
0
/* Code to actually dissect the PAGP packets */
static void
dissect_pagp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
      guint32 raw_word;
      guint16 raw_half_word;
      guint16 num_tlvs;
      guint16 tlv;
      guint16 len;
      guint16 ii;
      guint16 offset = PAGP_FIRST_TLV;
      guint8  raw_octet;

      guint8  flags;

      guchar *ch;

      proto_tree *pagp_tree = NULL;
      proto_item *pagp_item;
      proto_tree *flags_tree;
      proto_item *flags_item;
      proto_tree *tlv_tree;
      proto_item *tlv_item;


      const char *sep;


      col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAGP"); /* PAGP Protocol */

      col_clear(pinfo->cinfo, COL_INFO);

      pinfo->current_proto = "PAGP";

      raw_octet = tvb_get_guint8(tvb, PAGP_VERSION_NUMBER);
      if (tree) {
	    pagp_item = proto_tree_add_protocol_format(tree, proto_pagp, tvb,
				0, -1, "Port Aggregation Protocol");
	    pagp_tree = proto_item_add_subtree(pagp_item, ett_pagp);
	    proto_tree_add_uint(pagp_tree, hf_pagp_version_number, tvb,
				PAGP_VERSION_NUMBER, 1, raw_octet);
      }
      col_append_str(pinfo->cinfo, COL_INFO,
           val_to_str_const(raw_octet, pdu_vers, "Unknown PDU version"));

      if (raw_octet == PAGP_FLUSH_PDU) {

         col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s",
               tvb_ether_to_str(tvb, PAGP_FLUSH_LOCAL_DEVICE_ID));

         proto_tree_add_item(pagp_tree, hf_pagp_flush_local_device_id, tvb,
            PAGP_FLUSH_LOCAL_DEVICE_ID, 6, ENC_NA);

         col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s",
               tvb_ether_to_str(tvb, PAGP_FLUSH_PARTNER_DEVICE_ID));

         proto_tree_add_item(pagp_tree, hf_pagp_flush_partner_device_id, tvb,
            PAGP_FLUSH_PARTNER_DEVICE_ID, 6, ENC_NA);

         raw_word = tvb_get_ntohl(tvb, PAGP_FLUSH_TRANSACTION_ID);
         col_append_fstr(pinfo->cinfo, COL_INFO, "; Transaction ID: 0x%x ", raw_word);

         proto_tree_add_uint(pagp_tree, hf_pagp_flush_transaction_id, tvb,
            PAGP_FLUSH_TRANSACTION_ID, 4, raw_word);
         return;
      }

      /* Info PDU */

      flags = tvb_get_guint8(tvb, PAGP_FLAGS);
      col_append_fstr(pinfo->cinfo, COL_INFO, "; Flags 0x%x", flags);

      if (tree) {
         flags_item = proto_tree_add_uint(pagp_tree, hf_pagp_flags, tvb,
			PAGP_FLAGS, 1, flags);
         flags_tree = proto_item_add_subtree(flags_item, ett_pagp_flags);

	 sep = initial_sep;

	 APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_SLOW_HELLO, flags_item, "%sSlow Hello");
	 proto_tree_add_boolean(flags_tree, hf_pagp_flags_slow_hello, tvb,
			PAGP_FLAGS, 1, flags);

	 APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_AUTO_MODE, flags_item, "%sAuto Mode");
	 proto_tree_add_boolean(flags_tree, hf_pagp_flags_auto_mode, tvb,
			PAGP_FLAGS, 1, flags);

	 APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_CONSISTENT_STATE, flags_item,
			"%sConsistent State");
	 proto_tree_add_boolean(flags_tree, hf_pagp_flags_consistent_state, tvb,
				PAGP_FLAGS, 1, flags);

	 sep = cont_sep;
	 if (sep != initial_sep) {
            /* We put something in; put in the terminating ")" */
            proto_item_append_text(flags_item, ")");
	 }
      }

      col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s",
            tvb_ether_to_str(tvb, PAGP_LOCAL_DEVICE_ID));

      proto_tree_add_item(pagp_tree, hf_pagp_local_device_id, tvb,
				PAGP_LOCAL_DEVICE_ID, 6, ENC_NA);

      if (tree) {
	    raw_octet = tvb_get_guint8(tvb, PAGP_LOCAL_LEARN_CAP);
	    proto_tree_add_uint(pagp_tree, hf_pagp_local_learn_cap, tvb,
				PAGP_LOCAL_LEARN_CAP, 1, raw_octet);

	    raw_octet = tvb_get_guint8(tvb, PAGP_LOCAL_PORT_PRIORITY);
	    proto_tree_add_uint(pagp_tree, hf_pagp_local_port_priority, tvb,
				PAGP_LOCAL_PORT_PRIORITY, 1, raw_octet);

	    raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_SENT_PORT_IFINDEX);
	    proto_tree_add_uint(pagp_tree, hf_pagp_local_sent_port_ifindex, tvb,
				PAGP_LOCAL_SENT_PORT_IFINDEX, 4, raw_word);

	    raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_GROUP_CAPABILITY);
	    proto_tree_add_uint(pagp_tree, hf_pagp_local_group_capability, tvb,
				PAGP_LOCAL_GROUP_CAPABILITY, 4, raw_word);

	    raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_GROUP_IFINDEX);
	    proto_tree_add_uint(pagp_tree, hf_pagp_local_group_ifindex, tvb,
				PAGP_LOCAL_GROUP_IFINDEX, 4, raw_word);
      }

      col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s",
  	       tvb_ether_to_str(tvb, PAGP_PARTNER_DEVICE_ID));

      proto_tree_add_item(pagp_tree, hf_pagp_partner_device_id, tvb,
				PAGP_PARTNER_DEVICE_ID, 6, ENC_NA);

      if (tree) {
	    raw_octet = tvb_get_guint8(tvb, PAGP_PARTNER_LEARN_CAP);
	    proto_tree_add_uint(pagp_tree, hf_pagp_partner_learn_cap, tvb,
				PAGP_PARTNER_LEARN_CAP, 1, raw_octet);

	    raw_octet = tvb_get_guint8(tvb, PAGP_PARTNER_PORT_PRIORITY);
	    proto_tree_add_uint(pagp_tree, hf_pagp_partner_port_priority, tvb,
				PAGP_PARTNER_PORT_PRIORITY, 1, raw_octet);

	    raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_SENT_PORT_IFINDEX);
	    proto_tree_add_uint(pagp_tree, hf_pagp_partner_sent_port_ifindex, tvb,
				PAGP_PARTNER_SENT_PORT_IFINDEX, 4, raw_word);

	    raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_GROUP_CAPABILITY);
	    proto_tree_add_uint(pagp_tree, hf_pagp_partner_group_capability, tvb,
				PAGP_PARTNER_GROUP_CAPABILITY, 4, raw_word);

	    raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_GROUP_IFINDEX);
	    proto_tree_add_uint(pagp_tree, hf_pagp_partner_group_ifindex, tvb,
				PAGP_PARTNER_GROUP_IFINDEX, 4, raw_word);

	    raw_half_word = tvb_get_ntohs(tvb, PAGP_PARTNER_COUNT);
	    proto_tree_add_uint(pagp_tree, hf_pagp_partner_count, tvb,
				PAGP_PARTNER_COUNT, 2, raw_half_word);

	    num_tlvs = tvb_get_ntohs(tvb, PAGP_NUM_TLVS);
	    proto_tree_add_uint(pagp_tree, hf_pagp_num_tlvs, tvb,
				PAGP_NUM_TLVS, 2, num_tlvs);

	    /* dump TLV entries */

	    for ( ii = 0; ii < num_tlvs; ii++ ) {

		tlv = tvb_get_ntohs(tvb, offset);
		len = tvb_get_ntohs(tvb, offset + 2);
		if ( len == 0 ) {
		   proto_tree_add_text(pagp_tree, tvb, offset, -1,
			               "Unknown data - TLV len=0");
		   return;
		}

		tlv_item = proto_tree_add_text (pagp_tree, tvb, offset, len,
			   "TLV Entry #%d", ii+1);

		tlv_tree = proto_item_add_subtree (tlv_item, ett_pagp_tlvs);
		proto_tree_add_uint_format (tlv_tree, hf_pagp_tlv, tvb,
			offset,2,tlv,"Type = %d (%s)", tlv,
			val_to_str_const(tlv,tlv_types, "Unknown")) ;
		proto_tree_add_text (tlv_tree, tvb, offset+2, 2,
			"Length = %u bytes (includes Type and Length)", len) ;
		if ( tvb_reported_length_remaining(tvb, offset) < len ) {
		   proto_tree_add_text(tlv_tree, tvb, offset, -1,
			               "TLV length too large");
		   return;
		}

		switch (tlv) {
		   case PAGP_TLV_DEVICE_NAME:
			ch = tvb_get_string(wmem_packet_scope(), tvb, offset+4, len-4);
			proto_tree_add_string(tlv_tree, hf_pagp_tlv_device_name,
			   tvb, offset+4, len-4, ch);
			break;
		   case PAGP_TLV_PORT_NAME:
			ch = tvb_get_string(wmem_packet_scope(), tvb, offset+4, len-4);
			proto_tree_add_string(tlv_tree, hf_pagp_tlv_port_name,
			   tvb, offset+4, len-4, ch);
			break;
		   case PAGP_TLV_AGPORT_MAC:
			proto_tree_add_item(tlv_tree, hf_pagp_tlv_agport_mac,
			   tvb, offset+4, 6, ENC_NA);
			break;
		   case PAGP_TLV_RESERVED:
			break;
		}

		offset += len;

	    }
      }
}
示例#11
0
static int
dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
    gboolean	has_routes;
    proto_tree	*nbipx_tree = NULL;
    proto_item	*ti = NULL;
    int		offset = 0;
    guint8		packet_type;
    proto_tree	*name_type_flag_tree;
    proto_item	*tf;
    char		name[(NETBIOS_NAME_LEN - 1)*4 + 1];
    int		name_type;
    gboolean	has_payload;
    tvbuff_t	*next_tvb;
    ipxhdr_t *ipxh;

    /* Reject the packet if data is NULL */
    if (data == NULL)
        return 0;
    ipxh = (ipxhdr_t*)data;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBIPX");
    col_clear(pinfo->cinfo, COL_INFO);

    if (ipxh->ipx_type == IPX_PACKET_TYPE_WANBCAST) {
        /*
         * This is a WAN Broadcast packet; we assume it will have
         * 8 IPX addresses at the beginning.
         */
        has_routes = TRUE;
    } else {
        /*
         * This isn't a WAN Broadcast packet, but it still might
         * have the 8 addresses.
         *
         * If it's the right length for a name operation,
         * and, if we assume it has routes, the packet type
         * is a name operation, assume it has routes.
         *
         * NOTE: this will throw an exception if the byte that
         * would be the packet type byte if this has the 8
         * addresses isn't present; if that's the case, we don't
         * know how to interpret this packet, so we can't dissect
         * it anyway.
         */
        has_routes = FALSE;	/* start out assuming it doesn't */
        if (tvb_reported_length(tvb) == 50) {
            packet_type = tvb_get_guint8(tvb, offset + 32 + 1);
            switch (packet_type) {

            case NBIPX_FIND_NAME:
            case NBIPX_NAME_RECOGNIZED:
            case NBIPX_CHECK_NAME:
            case NBIPX_NAME_IN_USE:
            case NBIPX_DEREGISTER_NAME:
                has_routes = TRUE;
                break;
            }
        }
    }

    if (tree) {
        ti = proto_tree_add_item(tree, proto_nbipx, tvb, 0,
                                 -1, ENC_NA);
        nbipx_tree = proto_item_add_subtree(ti, ett_nbipx);
    }

    if (has_routes) {
        if (tree)
            add_routers(nbipx_tree, tvb, 0);
        offset += 32;
    }

    packet_type = tvb_get_guint8(tvb, offset + 1);

    switch (packet_type) {

    case NBIPX_FIND_NAME:
    case NBIPX_NAME_RECOGNIZED:
    case NBIPX_CHECK_NAME:
    case NBIPX_NAME_IN_USE:
    case NBIPX_DEREGISTER_NAME:
        name_type = get_netbios_name(tvb, offset+2, name, (NETBIOS_NAME_LEN - 1)*4 + 1);
        col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s<%02x>",
                     val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"),
                     name, name_type);

        if (nbipx_tree) {
            tf = proto_tree_add_item(nbipx_tree, hf_nbipx_name_flags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            name_type_flag_tree = proto_item_add_subtree(tf, ett_nbipx_name_type_flags);

            proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_group, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_in_use, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_registered, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_duplicated, tvb, offset, 1, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(name_type_flag_tree, hf_nbipx_name_flags_deregistered, tvb, offset, 1, ENC_LITTLE_ENDIAN);
        }
        offset += 1;

        proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
        offset += 1;

        if (nbipx_tree)
            netbios_add_name("Name", tvb, offset, nbipx_tree);
        offset += NETBIOS_NAME_LEN;

        /*
         * No payload to be interpreted by another protocol.
         */
        has_payload = FALSE;
        break;

    case NBIPX_SESSION_DATA:
    case NBIPX_SESSION_END:
    case NBIPX_SESSION_END_ACK:
        col_set_str(pinfo->cinfo, COL_INFO,
                    val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"));

        dissect_conn_control(tvb, offset, nbipx_tree);
        offset += 1;

        proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
        offset += 1;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_src_conn_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_dest_conn_id, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_send_seq_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_total_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_offset, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_data_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_recv_seq_number, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        proto_tree_add_item(nbipx_tree, hf_nbipx_session_bytes_received, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        offset += 2;

        /*
         * We may have payload to dissect.
         */
        has_payload = TRUE;
        break;

    case NBIPX_DIRECTED_DATAGRAM:
        col_set_str(pinfo->cinfo, COL_INFO,
                    val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"));

        dissect_conn_control(tvb, offset, nbipx_tree);
        offset += 1;

        proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
        offset += 1;

        if (nbipx_tree)
            netbios_add_name("Receiver's Name", tvb, offset,
                             nbipx_tree);
        offset += NETBIOS_NAME_LEN;

        if (nbipx_tree)
            netbios_add_name("Sender's Name", tvb, offset,
                             nbipx_tree);
        offset += NETBIOS_NAME_LEN;

        /*
         * We may have payload to dissect.
         */
        has_payload = TRUE;
        break;

    default:
        col_set_str(pinfo->cinfo, COL_INFO,
                    val_to_str_const(packet_type, nbipx_data_stream_type_vals, "Unknown"));

        /*
         * We don't know what the first byte is.
         */
        offset += 1;

        /*
         * The second byte is a data stream type byte.
         */
        proto_tree_add_uint(nbipx_tree, hf_nbipx_packettype, tvb, offset, 1, packet_type);
        offset += 1;

        /*
         * We don't know what the rest of the packet is.
         */
        has_payload = FALSE;
    }

    /*
     * Set the length of the NBIPX tree item.
     */
    if (ti != NULL)
        proto_item_set_len(ti, offset);

    if (has_payload && tvb_offset_exists(tvb, offset)) {
        next_tvb = tvb_new_subset_remaining(tvb, offset);
        dissect_netbios_payload(next_tvb, pinfo, tree);
    }

    return tvb_length(tvb);
}
示例#12
0
/* Code to actually dissect the packets */
static void
dissect_nsrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item  *ti;
    proto_tree  *nsrp_tree = NULL;
    gint        offset = 0;
    guint8      msgtype = 0;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSRP");

    if (check_col(pinfo->cinfo, COL_INFO))
    {
			col_clear(pinfo->cinfo, COL_INFO);
			col_set_str(pinfo->cinfo, COL_INFO, "NSRP Protocol");
		}

    if (tree) {
			ti = proto_tree_add_item(tree, proto_nsrp, tvb, 0, -1, FALSE);
			nsrp_tree = proto_item_add_subtree(ti, ett_nsrp);
			
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_version, tvb, offset, 1, FALSE);
			offset += 1;

			msgtype = tvb_get_guint8(tvb, offset);
			proto_tree_add_item(nsrp_tree, hf_nsrp_msg_type, tvb, offset, 1, FALSE);
			offset += 1;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_clust_id, tvb, offset, 1, FALSE);
			offset += 1;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_msg_flag, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_len, tvb, offset, 2, FALSE);
			offset += 2;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_ha_port, tvb, offset, 1, FALSE);
			offset += 1;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_not_used, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_dst_unit, tvb, offset, 4, FALSE);
			offset += 4;

			proto_tree_add_item(nsrp_tree, hf_nsrp_src_unit, tvb, offset, 4, FALSE);
			offset += 4;
		}
		
/*
 *
 *
 *    NSRP HA Packet is defined as follow:
 * 
 *       1         2       3        4        5         6       7        8 
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   | Type   |WstGroup|HstGroup|MSG Flag|     Length      |Enc Flag|Not Used|
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   |            Total Size             |        NS       |        NR       |
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   |     No Used     |    Checksum     |              Data                 |
 *   +--------+--------+--------+--------+-----------------------------------+
 *
 *
 */

		if ( msgtype == 0x00 ) {
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_msgtype, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_wst_group, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_hst_group, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_msgflag, tvb, offset, 1, FALSE);
			offset += 1;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_msglen, tvb, offset, 2, FALSE);
			offset += 2;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_encflag, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_not_used, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_total_size, tvb, offset, 4, FALSE);
			offset += 4;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_ns, tvb, offset, 2, FALSE);
			offset += 2;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_nr, tvb, offset, 2, FALSE);
			offset += 2;

			proto_tree_add_item(nsrp_tree, hf_nsrp_no_used, tvb, offset, 2, FALSE);
			offset += 2;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_checksum, tvb, offset, 2, FALSE);
			offset += 2;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_data, tvb, offset, -1, FALSE);
			
    }
    
/*
 *  
 *    NSRP MNG Packet is defined as follow:
 * 
 *       1         2       3        4        5         6       7        8 
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   | Type   |WstGroup|HstGroup|MSG Flag|     Length      |AuthFlag|Not Used|
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   |Priority+ Dummy  +   Auth CheckSum +                Data               |
 *   +--------+--------+--------+--------+-----------------------------------+
 *  
 *
 */

		if ( msgtype == 0x02 ) {
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_msgtype, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_wst_group, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_hst_group, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_msgflag, tvb, offset, 1, FALSE);
			offset += 1;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_msglen, tvb, offset, 2, FALSE);
			offset += 2;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_authflag, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_not_used, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_priority, tvb, offset, 1, FALSE);
			offset += 1;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_dummy, tvb, offset, 1, FALSE);
			offset += 1;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_authchecksum, tvb, offset, 2, FALSE);
			offset += 2;

			proto_tree_add_item(nsrp_tree, hf_nsrp_data, tvb, offset, -1, FALSE);
			
    }
    
        
    
    
/*   
 *    NSRP DATA Packet is defined as follow:
 * 
 *       1         2       3        4        5         6       7        8 
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   | Type   |WstGroup|HstGroup|MSG Flag|     Length      | Ifnum  |Not Used|
 *   +--------+--------+--------+--------+--------+--------+--------+--------+
 *   |            Total Size             |                Data               |
 *   +--------+--------+--------+--------+-----------------------------------+
 *
 *
 */
   if ( msgtype == 0x03 ) {
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_msgtype, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_wst_group, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_hst_group, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_msgflag, tvb, offset, 1, FALSE);
			offset += 1;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_msglen, tvb, offset, 2, FALSE);
			offset += 2;
			
			proto_tree_add_item(nsrp_tree, hf_nsrp_ifnum, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_not_used, tvb, offset, 1, FALSE);
			offset += 1;

			proto_tree_add_item(nsrp_tree, hf_nsrp_total_size, tvb, offset, 4, FALSE);
			offset += 4;
		
			proto_tree_add_item(nsrp_tree, hf_nsrp_data, tvb, offset, -1, FALSE);
			
    }

}
示例#13
0
static int dissect_packetlogger(tvbuff_t *tvb, packet_info *pinfo,
        proto_tree *tree, void *data)
{
  proto_tree        *packetlogger_tree = NULL;
  tvbuff_t          *next_tvb;
  proto_item        *ti = NULL;
  guint8             pl_type;
  gint               len;
  bluetooth_data_t  *bluetooth_data;
  struct bthci_phdr  bthci;

  bluetooth_data = (bluetooth_data_t *) data;

  col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
  col_clear (pinfo->cinfo, COL_INFO);

  ti = proto_tree_add_item (tree, proto_packetlogger, tvb, 0, -1, ENC_NA);
  packetlogger_tree = proto_item_add_subtree (ti, ett_packetlogger);

  pl_type = tvb_get_guint8 (tvb, 0);
  proto_tree_add_item (packetlogger_tree, hf_type, tvb, 0, 1, ENC_BIG_ENDIAN);
  proto_item_append_text (ti, " %s", val_to_str (pl_type, type_vals, "Unknown 0x%02x"));

  len = tvb_reported_length_remaining (tvb, 1);
  next_tvb = tvb_new_subset_remaining (tvb, 1);

  if (pl_type <= PKT_RECV_ACL_DATA) {
    /* HCI H1 packages */
    switch (pl_type) {
    case PKT_HCI_COMMAND:
      bthci.channel = BTHCI_CHANNEL_COMMAND;
      bthci.sent = P2P_DIR_SENT;
      pinfo->p2p_dir = P2P_DIR_SENT;
      break;
    case PKT_HCI_EVENT:
      bthci.channel = BTHCI_CHANNEL_EVENT;
      bthci.sent = P2P_DIR_RECV;
      pinfo->p2p_dir = P2P_DIR_RECV;
      break;
    case PKT_SENT_ACL_DATA:
      bthci.channel = BTHCI_CHANNEL_ACL;
      bthci.sent = P2P_DIR_SENT;
      pinfo->p2p_dir = P2P_DIR_SENT;
      break;
    case PKT_RECV_ACL_DATA:
      bthci.channel = BTHCI_CHANNEL_ACL;
      bthci.sent = P2P_DIR_RECV;
      pinfo->p2p_dir = P2P_DIR_RECV;
      break;
    default:
      bthci.channel = pl_type;
      bthci.sent = P2P_DIR_UNKNOWN;
      pinfo->p2p_dir = P2P_DIR_UNKNOWN;
      break;
    }
    bluetooth_data->previous_protocol_data.bthci = &bthci;
    proto_item_set_len (ti, 1);

    col_add_fstr (pinfo->cinfo, COL_INFO, "%s", val_to_str(pl_type, type_vals, "Unknown 0x%02x"));
    if (!dissector_try_uint_new(hci_h1_table, bthci.channel,
            next_tvb, pinfo, tree, TRUE, bluetooth_data)) {
      call_dissector (data_handle, next_tvb, pinfo, tree);
    }
  } else {
    /* PacketLogger data */
    switch (pl_type) {
    case PKT_POWER:
    case PKT_NOTE:
    case PKT_NEW_CONTROLLER:
      proto_tree_add_item (packetlogger_tree, hf_info, next_tvb, 0, len, ENC_ASCII|ENC_NA);
      col_add_fstr (pinfo->cinfo, COL_INFO, "%s", tvb_format_stringzpad_wsp (next_tvb, 0, len));
      break;
    default:
      call_dissector (data_handle, next_tvb, pinfo, tree);
      col_add_fstr (pinfo->cinfo, COL_INFO, "Unknown 0x%02x", pl_type);
      break;
    }
  }

  return tvb_captured_length(tvb);
}
示例#14
0
static void
dissect_applemidi_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 command ) {

	guint16		 seq_num;
	guint8		 count;
	guint8		*name;
	gint		 offset			= 0;
	gint		 len;
	gint		 string_size;
	proto_tree	*applemidi_tree;
	proto_tree	*applemidi_tree_seq_num;


	col_set_str( pinfo->cinfo, COL_PROTOCOL, APPLEMIDI_DISSECTOR_SHORTNAME );

	/* Clear out stuff in the info column */
	col_clear( pinfo->cinfo, COL_INFO );

	col_add_fstr( pinfo->cinfo, COL_INFO, "%s", val_to_str( command, applemidi_commands, applemidi_unknown_command ) );

	if ( tree ) {
		proto_item *ti;
		ti = proto_tree_add_item( tree, proto_applemidi, tvb, 0, -1, ENC_NA  );
		applemidi_tree = proto_item_add_subtree( ti, ett_applemidi );

		proto_tree_add_item( applemidi_tree, hf_applemidi_signature, tvb, offset, 2, ENC_BIG_ENDIAN  );
		offset += 2;

		proto_tree_add_item( applemidi_tree, hf_applemidi_command, tvb, offset, 2, ENC_BIG_ENDIAN  );
		offset += 2;

		/* the format of packets for "IN", "NO", "OK" and "BY" is identical and contains
		 * the protocol version, a random number generated by the initiator of the session,
		 * the SSRC that is used by the respective sides RTP-entity and optionally the
		 * name of the participant */
		if ( ( APPLEMIDI_COMMAND_INVITATION == command ) ||
		     ( APPLEMIDI_COMMAND_INVITATION_REJECTED == command ) ||
		     ( APLLEMIDI_COMMAND_INVITATION_ACCEPTED == command ) ||
		     ( APPLEMIDI_COMMAND_ENDSESSION == command ) ) {

			proto_tree_add_item( applemidi_tree, hf_applemidi_protocol_version, tvb, offset, 4, ENC_BIG_ENDIAN  );
			offset += 4;

			proto_tree_add_item( applemidi_tree, hf_applemidi_token, tvb, offset, 4, ENC_BIG_ENDIAN  );
			offset += 4;

			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN  );
			offset += 4;

			len = tvb_reported_length(tvb) - offset;

			/* Name is optional */
			if ( len > 0 ) {
				name = tvb_get_string( wmem_packet_scope(), tvb, offset, len );
				string_size = (gint)( strlen( name ) + 1 );
				proto_tree_add_item( applemidi_tree, hf_applemidi_name, tvb, offset, string_size, ENC_UTF_8|ENC_NA );
				col_append_fstr( pinfo->cinfo, COL_INFO, ": peer = \"%s\"", name );
				offset += string_size;
			}

		/* the synchronization packet contains three 64bit timestamps,  and a value to define how
		 * many of the timestamps transmitted are valid */
		} else if ( APPLEMIDI_COMMAND_SYNCHRONIZATION == command ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;

			count = tvb_get_guint8( tvb, offset );
			proto_tree_add_item( applemidi_tree, hf_applemidi_count, tvb, offset, 1, ENC_BIG_ENDIAN );
			col_append_fstr( pinfo->cinfo, COL_INFO, ": count = %u", count );
			offset += 1;

			proto_tree_add_item( applemidi_tree, hf_applemidi_padding, tvb, offset, 3, ENC_BIG_ENDIAN );
			offset += 3;

			proto_tree_add_item( applemidi_tree, hf_applemidi_timestamp1, tvb, offset, 8, ENC_BIG_ENDIAN );
			offset += 8;

			proto_tree_add_item( applemidi_tree, hf_applemidi_timestamp2, tvb, offset, 8, ENC_BIG_ENDIAN );
			offset += 8;

			proto_tree_add_item( applemidi_tree, hf_applemidi_timestamp3, tvb, offset, 8, ENC_BIG_ENDIAN );
			offset += 8;
		/* With the receiver feedback packet, the recipient can tell the sender up to what sequence
		 * number in the RTP-stream the packets have been received; this can be used to shorten the
		 * recovery-journal-section in the RTP-session */
		} else if ( APPLEMIDI_COMMAND_RECEIVER_FEEDBACK == command ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;

			ti = proto_tree_add_item( applemidi_tree, hf_applemidi_sequence_num, tvb, offset, 4, ENC_BIG_ENDIAN );
			/* Apple includes a 32bit sequence-number, but the RTP-packet only specifies 16bit.
			 * this subtree and subitem are added to be able to associate the sequence-number
			 * here easier with the one specified in the corresponding RTP-packet */
			applemidi_tree_seq_num = proto_item_add_subtree( ti, ett_applemidi_seq_num );
			seq_num = tvb_get_ntohs( tvb, offset );
			proto_tree_add_uint( applemidi_tree_seq_num, hf_applemidi_rtp_sequence_num, tvb, offset, 2, seq_num );
			offset += 4;

			col_append_fstr( pinfo->cinfo, COL_INFO, ": seq = %u", seq_num );
		/* With the bitrate receive limit packet, the recipient can tell the sender to limit
		   the transmission to a certain bitrate.  This is important if the peer is a gateway
		   to a hardware-device that only supports a certain speed.  Like the MIDI 1.0 DIN-cable
		   MIDI-implementation which is limited to 31250.  */
		} else if ( APPLEMIDI_COMMAND_BITRATE_RECEIVE_LIMIT == command ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_ssrc, tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;

			proto_tree_add_item( applemidi_tree, hf_applemidi_rtp_bitrate_limit,
					     tvb, offset, 4, ENC_BIG_ENDIAN );
			offset += 4;
		}
		/* If there is any remaining data (possibly because an unknown command was encountered),
		 * we just dump it here */
		len = tvb_length_remaining( tvb, offset );
		if ( len > 0 ) {
			proto_tree_add_item( applemidi_tree, hf_applemidi_unknown_data, tvb, offset, len, ENC_NA );
		}
	}
}
示例#15
0
/* Code to actually dissect the PAGP packets */
static void
dissect_pagp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint32 raw_word;
    guint16 num_tlvs;
    guint16 tlv;
    guint16 len;
    guint16 ii;
    guint16 offset = PAGP_FIRST_TLV;
    guint8  raw_octet;

    guint8  flags;

    proto_tree *pagp_tree = NULL;
    proto_item *pagp_item, *len_item;
    proto_tree *tlv_tree;
    static const int * pagp_flags[] = {
        &hf_pagp_flags_slow_hello,
        &hf_pagp_flags_auto_mode,
        &hf_pagp_flags_consistent_state,
        NULL,
    };


    col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAGP"); /* PAGP Protocol */

    col_clear(pinfo->cinfo, COL_INFO);

    pinfo->current_proto = "PAGP";

    raw_octet = tvb_get_guint8(tvb, PAGP_VERSION_NUMBER);
    if (tree) {
        pagp_item = proto_tree_add_protocol_format(tree, proto_pagp, tvb,
                                                   0, -1, "Port Aggregation Protocol");
        pagp_tree = proto_item_add_subtree(pagp_item, ett_pagp);
        proto_tree_add_uint(pagp_tree, hf_pagp_version_number, tvb,
                            PAGP_VERSION_NUMBER, 1, raw_octet);
    }
    col_append_str(pinfo->cinfo, COL_INFO,
                   val_to_str_const(raw_octet, pdu_vers, "Unknown PDU version"));

    if (raw_octet == PAGP_FLUSH_PDU) {

        col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s",
                        tvb_ether_to_str(tvb, PAGP_FLUSH_LOCAL_DEVICE_ID));

        proto_tree_add_item(pagp_tree, hf_pagp_flush_local_device_id, tvb,
                            PAGP_FLUSH_LOCAL_DEVICE_ID, 6, ENC_NA);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s",
                        tvb_ether_to_str(tvb, PAGP_FLUSH_PARTNER_DEVICE_ID));

        proto_tree_add_item(pagp_tree, hf_pagp_flush_partner_device_id, tvb,
                            PAGP_FLUSH_PARTNER_DEVICE_ID, 6, ENC_NA);

        raw_word = tvb_get_ntohl(tvb, PAGP_FLUSH_TRANSACTION_ID);
        col_append_fstr(pinfo->cinfo, COL_INFO, "; Transaction ID: 0x%x ", raw_word);

        proto_tree_add_uint(pagp_tree, hf_pagp_flush_transaction_id, tvb,
                            PAGP_FLUSH_TRANSACTION_ID, 4, raw_word);
        return;
    }

    /* Info PDU */

    flags = tvb_get_guint8(tvb, PAGP_FLAGS);
    col_append_fstr(pinfo->cinfo, COL_INFO, "; Flags 0x%x", flags);

    proto_tree_add_bitmask(pagp_tree, tvb, PAGP_FLAGS, hf_pagp_flags, ett_pagp_flags, pagp_flags, ENC_NA);

    col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s",
                    tvb_ether_to_str(tvb, PAGP_LOCAL_DEVICE_ID));

    proto_tree_add_item(pagp_tree, hf_pagp_local_device_id, tvb,
                        PAGP_LOCAL_DEVICE_ID, 6, ENC_NA);

    if (tree) {
        proto_tree_add_item(pagp_tree, hf_pagp_local_learn_cap, tvb,
                            PAGP_LOCAL_LEARN_CAP, 1, ENC_NA);

        proto_tree_add_item(pagp_tree, hf_pagp_local_port_priority, tvb,
                            PAGP_LOCAL_PORT_PRIORITY, 1, ENC_NA);

        proto_tree_add_item(pagp_tree, hf_pagp_local_sent_port_ifindex, tvb,
                            PAGP_LOCAL_SENT_PORT_IFINDEX, 4, ENC_BIG_ENDIAN);

        proto_tree_add_item(pagp_tree, hf_pagp_local_group_capability, tvb,
                            PAGP_LOCAL_GROUP_CAPABILITY, 4, ENC_BIG_ENDIAN);

        proto_tree_add_item(pagp_tree, hf_pagp_local_group_ifindex, tvb,
                            PAGP_LOCAL_GROUP_IFINDEX, 4, ENC_BIG_ENDIAN);
    }

    col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s",
                    tvb_ether_to_str(tvb, PAGP_PARTNER_DEVICE_ID));

    proto_tree_add_item(pagp_tree, hf_pagp_partner_device_id, tvb,
                        PAGP_PARTNER_DEVICE_ID, 6, ENC_NA);

    proto_tree_add_item(pagp_tree, hf_pagp_partner_learn_cap, tvb,
                        PAGP_PARTNER_LEARN_CAP, 1, ENC_NA);

    proto_tree_add_item(pagp_tree, hf_pagp_partner_port_priority, tvb,
                        PAGP_PARTNER_PORT_PRIORITY, 1, ENC_NA);

    proto_tree_add_item(pagp_tree, hf_pagp_partner_sent_port_ifindex, tvb,
                        PAGP_PARTNER_SENT_PORT_IFINDEX, 4, ENC_BIG_ENDIAN);

    proto_tree_add_item(pagp_tree, hf_pagp_partner_group_capability, tvb,
                        PAGP_PARTNER_GROUP_CAPABILITY, 4, ENC_BIG_ENDIAN);

    proto_tree_add_item(pagp_tree, hf_pagp_partner_group_ifindex, tvb,
                        PAGP_PARTNER_GROUP_IFINDEX, 4, ENC_BIG_ENDIAN);

    proto_tree_add_item(pagp_tree, hf_pagp_partner_count, tvb,
                        PAGP_PARTNER_COUNT, 2, ENC_BIG_ENDIAN);

    num_tlvs = tvb_get_ntohs(tvb, PAGP_NUM_TLVS);
    proto_tree_add_uint(pagp_tree, hf_pagp_num_tlvs, tvb,
                        PAGP_NUM_TLVS, 2, num_tlvs);

    /* dump TLV entries */

    for ( ii = 0; ii < num_tlvs; ii++ ) {

        tlv = tvb_get_ntohs(tvb, offset);
        len = tvb_get_ntohs(tvb, offset + 2);

        tlv_tree = proto_tree_add_subtree_format(pagp_tree, tvb, offset, len,
                                                 ett_pagp_tlvs, NULL, "TLV Entry #%d", ii+1);

        proto_tree_add_uint(tlv_tree, hf_pagp_tlv, tvb, offset, 2, tlv);
        len_item = proto_tree_add_uint(tlv_tree, hf_pagp_tlv_length, tvb, offset+2, 2, len);
        if ( len == 0 ) {
            expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length,
                                   "Unknown data - TLV len=0");
            return;
        }
        if ( tvb_reported_length_remaining(tvb, offset) < len ) {
            expert_add_info_format(pinfo, len_item, &ei_pagp_tlv_length,
                                   "TLV length too large");
            return;
        }

        switch (tlv) {
            case PAGP_TLV_DEVICE_NAME:
                proto_tree_add_item(tlv_tree, hf_pagp_tlv_device_name,
                                      tvb, offset+4, len-4, ENC_NA|ENC_ASCII);
                break;
            case PAGP_TLV_PORT_NAME:
                proto_tree_add_item(tlv_tree, hf_pagp_tlv_port_name,
                                      tvb, offset+4, len-4, ENC_NA|ENC_ASCII);
                break;
            case PAGP_TLV_AGPORT_MAC:
                proto_tree_add_item(tlv_tree, hf_pagp_tlv_agport_mac,
                                    tvb, offset+4, 6, ENC_NA);
                break;
            case PAGP_TLV_RESERVED:
                break;
        }

        offset += len;

    }
}
示例#16
0
static void
dissect_smtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    struct smtp_proto_data    *frame_data;
    proto_tree                *smtp_tree = NULL;
    proto_tree                *cmdresp_tree;
    proto_item                *ti, *hidden_item;
    int                       offset = 0;
    int                       request = 0;
    conversation_t            *conversation;
    struct smtp_session_state *session_state;
    const guchar              *line, *linep, *lineend;
    guchar                    c;
    guint32                   code;
    int                       linelen = 0;
    gint                      length_remaining;
    gboolean                  eom_seen = FALSE;
    gint                      next_offset;
    gint                      loffset = 0;
    gboolean                  is_continuation_line;
    int                       cmdlen;
    fragment_data             *frag_msg = NULL;
    tvbuff_t                  *next_tvb;

    /* As there is no guarantee that we will only see frames in the
     * the SMTP conversation once, and that we will see them in
     * order - in Wireshark, the user could randomly click on frames
     * in the conversation in any order in which they choose - we
     * have to store information with each frame indicating whether
     * it contains commands or data or an EOM indication.
     *
     * XXX - what about frames that contain *both*?  TCP is a
     * byte-stream protocol, and there are no guarantees that
     * TCP segment boundaries will correspond to SMTP commands
     * or EOM indications.
     *
     * We only need that for the client->server stream; responses
     * are easy to manage.
     *
     * If we have per frame data, use that, else, we must be on the first
     * pass, so we figure it out on the first pass.
     */

    /*
     * Find the conversation for this.
     */
    conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                                     pinfo->srcport, pinfo->destport, 0);
    if (conversation == NULL) { /* No conversation, create one */
      conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
                                      pinfo->srcport, pinfo->destport, 0);
    }

    /*
     * Is there a request structure attached to this conversation?
     */
    session_state = conversation_get_proto_data(conversation, proto_smtp);
    if (!session_state) {
      /*
       * No - create one and attach it.
       */
      session_state = se_alloc(sizeof(struct smtp_session_state));
      session_state->smtp_state = READING_CMDS;
      session_state->crlf_seen = FALSE;
      session_state->data_seen = FALSE;
      session_state->msg_read_len = 0;
      session_state->msg_tot_len = 0;
      session_state->msg_last = TRUE;
      session_state->last_nontls_frame = 0;

      conversation_add_proto_data(conversation, proto_smtp, session_state);
    }

    /* Are we doing TLS? 
     * FIXME In my understanding of RFC 2487 client and server can send SMTP cmds 
     * after a rejected TLS negotiation
    */
    if (session_state->last_nontls_frame != 0 && pinfo->fd->num > session_state->last_nontls_frame) {
      guint16 save_can_desegment;
      /* This is TLS, not raw SMTP. TLS can desegment */
      save_can_desegment = pinfo->can_desegment;
      pinfo->can_desegment = pinfo->saved_can_desegment;
      call_dissector(ssl_handle, tvb, pinfo, tree);
      pinfo->can_desegment = save_can_desegment;
      return;
    }

    /* Is this a request or a response? */
    request = pinfo->destport == pinfo->match_port;

    /*
     * Is there any data attached to this frame?
     */
    frame_data = p_get_proto_data(pinfo->fd, proto_smtp);

    if (!frame_data) {

      /*
       * No frame data.
       */
      if(request) {

        /*
         * Create a frame data structure and attach it to the packet.
         */
        frame_data = se_alloc0(sizeof(struct smtp_proto_data));

        frame_data->conversation_id = conversation->index;
        frame_data->more_frags = TRUE;

        p_add_proto_data(pinfo->fd, proto_smtp, frame_data);        

      }

      /*
       * Get the first line from the buffer.
       *
       * Note that "tvb_find_line_end()" will, if it doesn't return
       * -1, return a value that is not longer than what's in the buffer,
       * and "tvb_find_line_end()" will always return a value that is not
       * longer than what's in the buffer, so the "tvb_get_ptr()" call
       * won't throw an exception.
       */
      loffset = offset;
      while (tvb_offset_exists(tvb, loffset)) {
        linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset,
                                    smtp_desegment && pinfo->can_desegment);
        if (linelen == -1) {
          if (offset == loffset) {
            /*
             * We didn't find a line ending, and we're doing desegmentation;
             * tell the TCP dissector where the data for this message starts
             * in the data it handed us, and tell it we need more bytes
             */
            pinfo->desegment_offset = loffset;
            pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
            return;
          } else {
            linelen = tvb_length_remaining(tvb, loffset);
            next_offset = loffset + linelen;
          }
        }
        line = tvb_get_ptr(tvb, loffset, linelen);

        /*
         * Check whether or not this packet is an end of message packet
         * We should look for CRLF.CRLF and they may be split.
         * We have to keep in mind that we may see what we want on
         * two passes through here ...
         */
        if (session_state->smtp_state == READING_DATA) {
          /*
           * The order of these is important ... We want to avoid
           * cases where there is a CRLF at the end of a packet and a
           * .CRLF at the begining of the same packet.
           */
          if ((session_state->crlf_seen && tvb_strneql(tvb, loffset, ".\r\n", 3) == 0) ||
               tvb_strneql(tvb, loffset, "\r\n.\r\n", 5) == 0)
            eom_seen = TRUE;

          length_remaining = tvb_length_remaining(tvb, loffset);
          if (length_remaining == tvb_reported_length_remaining(tvb, loffset) &&
              tvb_strneql(tvb, loffset + length_remaining - 2, "\r\n", 2) == 0)
            session_state->crlf_seen = TRUE;
          else
            session_state->crlf_seen = FALSE;
        }

        /*
         * OK, Check if we have seen a DATA request. We do it here for
         * simplicity, but we have to be careful below.
         */
        if (request) {
          if (session_state->smtp_state == READING_DATA) {
            /*
             * This is message data.
             */
            if (eom_seen) { /* Seen the EOM */
              /*
               * EOM.
               * Everything that comes after it is commands.
               */
              frame_data->pdu_type = SMTP_PDU_EOM;
              session_state->smtp_state = READING_CMDS;
              break;
            } else {
              /*
               * Message data with no EOM.
               */
              frame_data->pdu_type = SMTP_PDU_MESSAGE;

              if (session_state->msg_tot_len > 0) {
                /* 
                 * We are handling a BDAT message.
                 * Check if we have reached end of the data chunk.
                 */
                session_state->msg_read_len += tvb_length_remaining(tvb, loffset);

                if (session_state->msg_read_len == session_state->msg_tot_len) {
                  /* 
                   * We have reached end of BDAT data chunk.
                   * Everything that comes after this is commands.
                   */
                  session_state->smtp_state = READING_CMDS;

                  if (session_state->msg_last) {
                    /* 
                     * We have found the LAST data chunk.
                     * The message can now be reassembled.
                     */
                    frame_data->more_frags = FALSE;
                  }
                
                  break; /* no need to go through the remaining lines */
                }
              }
            }
          } else {
            /*
             * This is commands - unless the capture started in the
             * middle of a session, and we're in the middle of data.
             *
             * Commands are not necessarily 4 characters; look
             * for a space or the end of the line to see where
             * the putative command ends.
             */
            linep = line;
            lineend = line + linelen;
            while (linep < lineend && (c = *linep) != ' ')
              linep++;
            cmdlen = (int)(linep - line);
            if (line_is_smtp_command(line, cmdlen)) {
              if (g_ascii_strncasecmp(line, "DATA", 4) == 0) {
                /*
                 * DATA command.
                 * This is a command, but everything that comes after it,
                 * until an EOM, is data.
                 */
                frame_data->pdu_type = SMTP_PDU_CMD;
                session_state->smtp_state = READING_DATA;
                session_state->data_seen = TRUE;
              } else if (g_ascii_strncasecmp(line, "BDAT", 4) == 0) {
                /*
                 * BDAT command.
                 * This is a command, but everything that comes after it,
                 * until given length is received, is data.
                 */
                guint32 msg_len;

                msg_len = strtoul (line+5, NULL, 10);

                frame_data->pdu_type = SMTP_PDU_CMD;
                session_state->data_seen = TRUE;
                session_state->msg_tot_len += msg_len;

                if (msg_len == 0) {
                  /* No data to read, next will be a command */
                  session_state->smtp_state = READING_CMDS;
                } else {
                  session_state->smtp_state = READING_DATA;
                }

                if (g_ascii_strncasecmp(line+linelen-4, "LAST", 4) == 0) {
                  /*
                   * This is the last data chunk.
                   */
                  session_state->msg_last = TRUE;

                  if (msg_len == 0) {
                    /* 
                     * No more data to expect.
                     * The message can now be reassembled.
                     */
                    frame_data->more_frags = FALSE;
                  }
                } else {
                  session_state->msg_last = FALSE;
                }
              } else if (g_ascii_strncasecmp(line, "STARTTLS", 8) == 0) {
                /*
                 * STARTTLS command.
                 * This is a command, but if the response is 220,
                 * everything after the response is TLS.
                 */
                session_state->smtp_state = AWAITING_STARTTLS_RESPONSE;
                frame_data->pdu_type = SMTP_PDU_CMD;
              } else {
                /*
                 * Regular command.
                 */
                frame_data->pdu_type = SMTP_PDU_CMD;
              }
            } else {
              /*
               * Assume it's message data.
               */
              frame_data->pdu_type = session_state->data_seen ? SMTP_PDU_MESSAGE : SMTP_PDU_CMD;
            }
          }
        }

        /*
         * Step past this line.
         */
        loffset = next_offset;
      }
    }


    /*
     * From here, we simply add items to the tree and info to the info
     * fields ...
     */

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMTP");

    if (check_col(pinfo->cinfo, COL_INFO)) {  /* Add the appropriate type here */
      col_clear(pinfo->cinfo, COL_INFO);

      /*
       * If it is a request, we have to look things up, otherwise, just
       * display the right things
       */

      if (request) {
        /* We must have frame_data here ... */
        switch (frame_data->pdu_type) {
        case SMTP_PDU_MESSAGE:

          length_remaining = tvb_length_remaining(tvb, offset);
          col_set_str(pinfo->cinfo, COL_INFO, smtp_data_desegment ? "C: DATA fragment" : "C: Message Body");
          col_append_fstr(pinfo->cinfo, COL_INFO, ", %d byte%s", length_remaining,
                          plurality (length_remaining, "", "s"));
          break;

        case SMTP_PDU_EOM:
          col_set_str(pinfo->cinfo, COL_INFO, "C: .");
          break;

        case SMTP_PDU_CMD:
          loffset = offset;
          while (tvb_offset_exists(tvb, loffset)) {
            /*
             * Find the end of the line.
             */
            linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset, FALSE);
            line = tvb_get_ptr(tvb, loffset, linelen);

            if(loffset == offset) 
              col_append_fstr(pinfo->cinfo, COL_INFO, "C: %s",
                           format_text(line, linelen));
            else {
              col_append_fstr(pinfo->cinfo, COL_INFO, " | %s",
                           format_text(line, linelen));
            }

            loffset = next_offset;
          }
          break;
        }
      } else {
        loffset = offset;
        while (tvb_offset_exists(tvb, loffset)) {
          /*
           * Find the end of the line.
           */
          linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset, FALSE);
          line = tvb_get_ptr(tvb, loffset, linelen);

          if (loffset == offset) 
            col_append_fstr(pinfo->cinfo, COL_INFO, "S: %s",
                            format_text(line, linelen));
          else {
            col_append_fstr(pinfo->cinfo, COL_INFO, " | %s",
                            format_text(line, linelen));
          }

          loffset = next_offset;
        }
      }
    }

    if (tree) { /* Build the tree info ... */
      ti = proto_tree_add_item(tree, proto_smtp, tvb, offset, -1, FALSE);
      smtp_tree = proto_item_add_subtree(ti, ett_smtp);
    }

    if (request) {
        /*
         * Check out whether or not we can see a command in there ...
         * What we are looking for is not data_seen and the word DATA
         * and not eom_seen.
         *
         * We will see DATA and session_state->data_seen when we process the
         * tree view after we have seen a DATA packet when processing
         * the packet list pane.
         *
         * On the first pass, we will not have any info on the packets
         * On second and subsequent passes, we will.
         */
        switch (frame_data->pdu_type) {

        case SMTP_PDU_MESSAGE:
          if (smtp_data_desegment) {
            frag_msg = fragment_add_seq_next(tvb, 0, pinfo, frame_data->conversation_id, 
                                             smtp_data_segment_table, smtp_data_reassembled_table, 
                                             tvb_length(tvb), frame_data->more_frags);
          } else {
            /*
             * Message body.
             * Put its lines into the protocol tree, a line at a time.
             */
            dissect_smtp_data(tvb, offset, smtp_tree);
          }
          break;

        case SMTP_PDU_EOM:
          /*
           * End-of-message-body indicator.
           *
           * XXX - what about stuff after the first line?
           * Unlikely, as the client should wait for a response to the
           * DATA command this terminates before sending another
           * request, but we should probably handle it.
           */
          proto_tree_add_text(smtp_tree, tvb, offset, linelen, "C: .");

          if (smtp_data_desegment) {
            /* add final data segment */
            if (loffset)
              fragment_add_seq_next(tvb, 0, pinfo, frame_data->conversation_id,
                                    smtp_data_segment_table, smtp_data_reassembled_table,
                                    loffset, frame_data->more_frags);

            /* terminate the desegmentation */
            frag_msg = fragment_end_seq_next (pinfo, frame_data->conversation_id, smtp_data_segment_table,
                                              smtp_data_reassembled_table);
          }
          break;

        case SMTP_PDU_CMD:
          /*
           * Command.
           *
           * XXX - what about stuff after the first line?
           * Unlikely, as the client should wait for a response to the
           * previous command before sending another request, but we
           * should probably handle it.
           */

          loffset = offset;
          while (tvb_offset_exists(tvb, loffset)) {
            /*
             * Find the end of the line.
             */
            linelen = tvb_find_line_end(tvb, loffset, -1, &next_offset, FALSE);

            if (linelen >= 4)
              cmdlen = 4;
            else
              cmdlen = linelen;
            hidden_item = proto_tree_add_boolean(smtp_tree, hf_smtp_req, tvb,
                                                 0, 0, TRUE);
            PROTO_ITEM_SET_HIDDEN(hidden_item);

            /*
             * Put the command line into the protocol tree.
             */
            ti = proto_tree_add_text(smtp_tree, tvb, loffset, next_offset - loffset,
                "Command: %s",
                tvb_format_text(tvb, loffset, next_offset - loffset));
            cmdresp_tree = proto_item_add_subtree(ti, ett_smtp_cmdresp);

            proto_tree_add_item(cmdresp_tree, hf_smtp_req_command, tvb,
                                loffset, cmdlen, FALSE);
            if (linelen > 5) {
              proto_tree_add_item(cmdresp_tree, hf_smtp_req_parameter, tvb,
                                  loffset + 5, linelen - 5, FALSE);
            }

            if (smtp_data_desegment && !frame_data->more_frags) {
              /* terminate the desegmentation */
              frag_msg = fragment_end_seq_next (pinfo, frame_data->conversation_id, smtp_data_segment_table,
                                                smtp_data_reassembled_table);
            }

            /*
             * Step past this line.
             */
            loffset = next_offset;
          }
        }

        if (smtp_data_desegment) {
          next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled DATA",
                                              frag_msg, &smtp_data_frag_items, NULL, smtp_tree);
          if (next_tvb) {
            /* XXX: this is presumptious - we may have negotiated something else */
            if (imf_handle) {
              call_dissector(imf_handle, next_tvb, pinfo, tree);
            } else {
              /*
               * Message body.
               * Put its lines into the protocol tree, a line at a time.
               */
              dissect_smtp_data(tvb, offset, smtp_tree);
            }
            
            pinfo->fragmented = FALSE;
          } else {
            pinfo->fragmented = TRUE;
          }
        }
    } else {
      /*
       * Process the response, a line at a time, until we hit a line
       * that doesn't have a continuation indication on it.
       */
      if (tree) {
        hidden_item = proto_tree_add_boolean(smtp_tree, hf_smtp_rsp, tvb,
                                             0, 0, TRUE);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
      }

      while (tvb_offset_exists(tvb, offset)) {
        /*
         * Find the end of the line.
         */
        linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);

	if (tree) {
          /*
           * Put it into the protocol tree.
           */
          ti = proto_tree_add_text(smtp_tree, tvb, offset,
                                   next_offset - offset, "Response: %s",
                                   tvb_format_text(tvb, offset,
                                                   next_offset - offset));
          cmdresp_tree = proto_item_add_subtree(ti, ett_smtp_cmdresp);
        } else
          cmdresp_tree = NULL;

        /*
         * Is it a continuation line?
         */
        is_continuation_line =
            (linelen >= 4 && tvb_get_guint8(tvb, offset + 3) == '-');

        line = tvb_get_ptr(tvb, offset, linelen);
        if (linelen >= 3 && isdigit(line[0]) && isdigit(line[1])
                         && isdigit(line[2])) {
          /*
           * We have a 3-digit response code.
           */
          code = (line[0] - '0')*100 + (line[1] - '0')*10 + (line[2] - '0');

          /*
           * If we're awaiting the response to a STARTTLS code, this
           * is it - if it's 220, all subsequent traffic will
           * be TLS, otherwise we're back to boring old SMTP.
           */
          if (session_state->smtp_state == AWAITING_STARTTLS_RESPONSE) {
            if (code == 220) {
              /* This is the last non-TLS frame. */
              session_state->last_nontls_frame = pinfo->fd->num;
              session_state->smtp_state = READING_DATA;
            } else
              session_state->smtp_state = READING_CMDS;
          }

	  if (tree) {
            /*
             * Put the response code and parameters into the protocol tree.
             */
            proto_tree_add_uint(cmdresp_tree, hf_smtp_rsp_code, tvb, offset, 3,
                                code);

            if (linelen >= 4) {
              proto_tree_add_item(cmdresp_tree, hf_smtp_rsp_parameter, tvb,
                                  offset + 4, linelen - 4, FALSE);
            }
          }
        }

        /*
         * Step past this line.
         */
        offset = next_offset;

        /*
         * If it's not a continuation line, quit.
         */
        /* if (!is_continuation_line)
           break; */
      }
    }
}
static void dissect_packetlogger (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_tree *packetlogger_tree = NULL;
  tvbuff_t   *next_tvb;
  proto_item *ti = NULL;
  guint8      pl_type;
  gint        len;

  col_set_str (pinfo->cinfo, COL_PROTOCOL, PSNAME);
  col_clear (pinfo->cinfo, COL_INFO);

  ti = proto_tree_add_item (tree, proto_packetlogger, tvb, 0, -1, FALSE);
  packetlogger_tree = proto_item_add_subtree (ti, ett_packetlogger);

  pl_type = tvb_get_guint8 (tvb, 0);
  proto_tree_add_item (packetlogger_tree, hf_type, tvb, 0, 1, FALSE);
  proto_item_append_text (ti, " %s", val_to_str (pl_type, type_vals, "Unknown 0x%02x"));

  len = tvb_length_remaining (tvb, 1);
  next_tvb = tvb_new_subset (tvb, 1, len, len);

  if (pl_type <= PKT_RECV_ACL_DATA) {
    /* HCI H1 packages */
    switch (pl_type) {
    case PKT_HCI_COMMAND:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_COMMAND;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT;
      pinfo->p2p_dir = P2P_DIR_SENT;
      break;
    case PKT_HCI_EVENT:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_EVENT;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV;
      pinfo->p2p_dir = P2P_DIR_RECV;
      break;
    case PKT_SENT_ACL_DATA:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_SENT;
      pinfo->p2p_dir = P2P_DIR_SENT;
      break;
    case PKT_RECV_ACL_DATA:
      pinfo->pseudo_header->bthci.channel = BTHCI_CHANNEL_ACL;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_RECV;
      pinfo->p2p_dir = P2P_DIR_RECV;
      break;
    default:
      pinfo->pseudo_header->bthci.channel = pl_type;
      pinfo->pseudo_header->bthci.sent = P2P_DIR_UNKNOWN;
      pinfo->p2p_dir = P2P_DIR_UNKNOWN;
      break;
    }
    proto_item_set_len (ti, 1);

    col_add_fstr (pinfo->cinfo, COL_INFO, "%s", val_to_str(pl_type, type_vals, "Unknown 0x%02x"));
    if (!dissector_try_port (hci_h1_table, pinfo->pseudo_header->bthci.channel, next_tvb, pinfo, tree)) {
      call_dissector (data_handle, next_tvb, pinfo, tree);
    }
  } else {
    /* PacketLogger data */
    switch (pl_type) {
    case PKT_INFO:
    case PKT_NEW_CONTROLLER:
      proto_tree_add_item (packetlogger_tree, hf_info, next_tvb, 0, len, FALSE);
      col_set_str (pinfo->cinfo, COL_INFO, tvb_format_stringzpad_wsp (next_tvb, 0, len));
      break;
    default:
      call_dissector (data_handle, next_tvb, pinfo, tree);
      col_add_fstr (pinfo->cinfo, COL_INFO, "Unknown 0x%02x", pl_type);
      break;
    }
  }
}
示例#18
0
// content format
static void dissect_radiohead_router(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  // your variable definitions go here
  int offset = 0;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "rhrouter");
  col_add_fstr(pinfo->cinfo, COL_PACKET_LENGTH, "%d", tvb_length(tvb) );
  
  // Clear out stuff in the info column
  col_clear(pinfo->cinfo, COL_INFO);
  if (tree)
  {
    // in case that someone wants to know some details of our protocol
    // spawn a subtree and cut the sequence in readable parts
    proto_item *ti = NULL;
    proto_item *pi = NULL;
    proto_tree *radiohead_tree = NULL;
    guint8 dest, source, hops, id, flags;
    guint length;
    gchar* info;

    ti = proto_tree_add_item(tree, proto_radiohead_router, tvb, 0 /*start*/, -1 /*end*/, encoding);
    radiohead_tree = proto_item_add_subtree(ti, ett_radiohead_router);

    length = tvb_length(tvb);

    proto_tree_add_item(radiohead_tree, hf_radiohead_router_dest, tvb, offset, 1, encoding);
    dest = tvb_get_guint8(tvb, offset);
    offset++;
    proto_tree_add_item(radiohead_tree, hf_radiohead_router_source, tvb, offset, 1, encoding);
    source = tvb_get_guint8(tvb, offset);
    offset++;
    proto_tree_add_item(radiohead_tree, hf_radiohead_router_hops, tvb, offset, 1, encoding);
    hops = tvb_get_guint8(tvb, offset);
    offset++;
    proto_tree_add_item(radiohead_tree, hf_radiohead_router_id, tvb, offset, 1, encoding);
    id = tvb_get_guint8(tvb, offset);
    offset++;
    proto_tree_add_item(radiohead_tree, hf_radiohead_router_flags, tvb, offset, 1, encoding);
    flags = tvb_get_guint8(tvb, offset);
    offset++;

    info = radiohead_router_buildColInfo( pinfo, hops, id, flags);
    col_add_str(pinfo->cinfo, COL_INFO, info);
    proto_item_append_text(ti, " - %s", info);
    col_add_fstr(pinfo->cinfo, COL_DEF_SRC, "%d", source);
    col_add_fstr(pinfo->cinfo, COL_DEF_DST, "%d", dest);

    if (tvb_length_remaining(tvb, offset /*TODO: bits or bytes?*/) > 0)
    {
      tvbuff_t* tvb_next;
      tvb_next = tvb_new_subset(tvb, offset/*start*/, -1 /*to end*/, -1/*reported length*/ );

      add_new_data_source(pinfo, tvb_next, "RadioHead Router Payload Data");
      // The radiohead header contains no indication of the payload type. Therefore we
      // pass it on to a list of heuristic dissectors for radiohead payloads, or display
      // it as data when none found.
      if (!dissector_try_heuristic(heur_subdissector_list, tvb_next, pinfo, tree, NULL))
      {
        call_dissector(data_handle, tvb_next, pinfo, tree);
      }
    }
  }
}
示例#19
0
static void
dissect_jpeg( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
	proto_item *ti = NULL;
	proto_tree *jpeg_tree = NULL;
	proto_tree *main_hdr_tree = NULL;
	proto_tree *restart_hdr_tree = NULL;
	proto_tree *qtable_hdr_tree = NULL;
	guint32 fragment_offset = 0;
	guint16 len = 0;
	guint8 type = 0;
	guint8 q = 0;
	gint h = 0;
	gint w = 0;

	unsigned int offset       = 0;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "JPEG");

	col_set_str(pinfo->cinfo, COL_INFO, "JPEG message");

	if ( tree ) {
		ti = proto_tree_add_item( tree, proto_jpeg, tvb, offset, -1, FALSE );
		jpeg_tree = proto_item_add_subtree( ti, ett_jpeg );

		ti = proto_tree_add_item(jpeg_tree, hf_rtp_jpeg_main_hdr, tvb, offset, 8, FALSE);
		main_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);

		proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_ts, tvb, offset, 1, FALSE);
		offset += 1;
		proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_offs, tvb, offset, 3, FALSE);
		fragment_offset = tvb_get_ntoh24(tvb, offset);
		offset += 3;
		proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_type, tvb, offset, 1, FALSE);
		type = tvb_get_guint8(tvb, offset);
		offset += 1;
		proto_tree_add_item(main_hdr_tree, hf_rtp_jpeg_main_hdr_q, tvb, offset, 1, FALSE);
		q = tvb_get_guint8(tvb, offset);
		offset += 1;
		w = tvb_get_guint8(tvb, offset) * 8;
		proto_tree_add_uint(main_hdr_tree, hf_rtp_jpeg_main_hdr_width, tvb, offset, 1, w);
		offset += 1;
		h = tvb_get_guint8(tvb, offset) * 8;
		proto_tree_add_uint(main_hdr_tree, hf_rtp_jpeg_main_hdr_height, tvb, offset, 1, h);
		offset += 1;

		if (type >= 64 && type <= 127) {
			ti = proto_tree_add_item(jpeg_tree, hf_rtp_jpeg_restart_hdr, tvb, offset, 4, FALSE);
			restart_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
			proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_interval, tvb, offset, 2, FALSE);
			offset += 2;
			proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_f, tvb, offset, 2, FALSE);
			proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_l, tvb, offset, 2, FALSE);
			proto_tree_add_item(restart_hdr_tree, hf_rtp_jpeg_restart_hdr_count, tvb, offset, 2, FALSE);
			offset += 2;
		}

		if (q >= 128 && fragment_offset == 0) {
			ti = proto_tree_add_item(jpeg_tree, hf_rtp_jpeg_qtable_hdr, tvb, offset, -1, FALSE);
			qtable_hdr_tree = proto_item_add_subtree(ti, ett_jpeg);
			proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_mbz, tvb, offset, 1, FALSE);
			offset += 1;
			proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_prec, tvb, offset, 1, FALSE);
			offset += 1;
			proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_length, tvb, offset, 2, FALSE);
			len = tvb_get_ntohs(tvb, offset);
			offset += 2;
			if (len > 0) {
				proto_tree_add_item(qtable_hdr_tree, hf_rtp_jpeg_qtable_hdr_data, tvb, offset, len, FALSE);
				offset += len;
			}
			proto_item_set_len(ti, len + 4);
		}

		/* The rest of the packet is the JPEG data */
		proto_tree_add_item( jpeg_tree, hf_rtp_jpeg_payload, tvb, offset, -1, FALSE );
	}
}
示例#20
0
static void
dissect_nntp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
        const gchar     *type;
	proto_tree	*nntp_tree;
	proto_item	*ti;
	gint		offset = 0;
	gint		next_offset;
	int		linelen;

        if (pinfo->match_uint == pinfo->destport)
        	type = "Request";
        else
        	type = "Response";

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "NNTP");

	if (check_col(pinfo->cinfo, COL_INFO)) {
		/*
		 * Put the first line from the buffer into the summary
		 * (but leave out the line terminator).
		 *
		 * Note that "tvb_find_line_end()" will return a value that
		 * is not longer than what's in the buffer, so the
		 * "tvb_get_ptr()" call won't throw an exception.
		 */
		linelen = tvb_find_line_end(tvb, offset, -1, &next_offset,
		    FALSE);
		col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s", type,
		    tvb_format_text(tvb, offset, linelen));
	}

	if (tree) {
		ti = proto_tree_add_item(tree, proto_nntp, tvb, offset, -1,
		    ENC_NA);
		nntp_tree = proto_item_add_subtree(ti, ett_nntp);

		if (pinfo->match_uint == pinfo->destport) {
			ti = proto_tree_add_boolean(nntp_tree,
			    hf_nntp_request, tvb, 0, 0, TRUE);
		} else {
			ti = proto_tree_add_boolean(nntp_tree,
			    hf_nntp_response, tvb, 0, 0, TRUE);
		}
		PROTO_ITEM_SET_HIDDEN(ti);

		/*
		 * Show the request or response as text, a line at a time.
		 * XXX - for requests, we could display the stuff after the
		 * first line, if any, based on what the request was, and
		 * for responses, we could display it based on what the
		 * matching request was, although the latter requires us to
		 * know what the matching request was....
		 */
		while (tvb_offset_exists(tvb, offset)) {
			/*
			 * Find the end of the line.
			 */
			tvb_find_line_end(tvb, offset, -1, &next_offset,
			    FALSE);

			/*
			 * Put this line.
			 */
			proto_tree_add_text(nntp_tree, tvb, offset,
			    next_offset - offset, "%s",
			    tvb_format_text(tvb, offset, next_offset - offset));
			offset = next_offset;
		}
	}
}
示例#21
0
static void
dissect_swift(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "swift");
    /* Clear out stuff in the info column */
    col_clear(pinfo->cinfo,COL_INFO);

    if (tree) { /* we are being asked for details */
        proto_item *ti;
		ti = proto_tree_add_item(tree, proto_swift, tvb, 0, -1, FALSE);

		proto_tree *swift_tree;
		swift_tree = proto_item_add_subtree(ti, ett_swift);

		/* All messages start with the receiving channel, so we can pull it out here */
		proto_tree_add_item(swift_tree, hf_swift_receiving_channel, tvb, offset, 4, FALSE); offset += 4;

		/* Loop until there is nothing left to read in the packet */
		while(tvb_bytes_exist(tvb, offset, 1)) {
			guint8 message_type;
			guint dat_len;
		    message_type = tvb_get_guint8(tvb, offset);
			proto_tree_add_item(swift_tree, hf_swift_message_type, tvb, offset, 1, FALSE); 
			offset += 1;

			/* Add message type to the info column */
			if(offset > 5) {
				col_append_fstr(pinfo->cinfo, COL_INFO, ", ");
			}
			col_append_fstr(pinfo->cinfo, COL_INFO, "%s",
				val_to_str(message_type, message_type_names, "Unknown (0x%02x)"));

			/* Add it to the dissection window as well */
			proto_item_append_text(ti, ", %s",
				val_to_str(message_type, message_type_names, "Unknown (0x%02x)"));

			switch(message_type) {
				case 0: /* Handshake */
					proto_tree_add_item(swift_tree, hf_swift_handshake_channel, tvb, offset, 4, FALSE); 
					offset += 4;
					break;
				case 1: /* Data */
					proto_tree_add_item(swift_tree, hf_swift_data_bin_id, tvb, offset, 4, FALSE); 
					offset += 4;
					/* We assume that the data field comprises the rest of this packet */
					dat_len = tvb_length(tvb) - offset;
					proto_tree_add_item(swift_tree, hf_swift_data_payload, tvb, offset, dat_len, FALSE); 
					offset += dat_len;
					break;
				case 2: /* Ack */
					proto_tree_add_item(swift_tree, hf_swift_ack_bin_id, tvb, offset, 4, FALSE); 
					offset += 4;
					proto_tree_add_item(swift_tree, hf_swift_ack_timestamp, tvb, offset, 8, FALSE); 
					offset += 8;
					break;
				case 3: /* Have */
					proto_tree_add_item(swift_tree, hf_swift_have_bin_id, tvb, offset, 4, FALSE); 
					offset += 4;
					break;
				case 4: /* Hash */
					proto_tree_add_item(swift_tree, hf_swift_hash_bin_id, tvb, offset, 4, FALSE); 
					offset += 4;
					proto_tree_add_item(swift_tree, hf_swift_hash_value, tvb, offset, 20, FALSE); 
					offset += 20;
					break;
				case 5: /* PEX+ */
					proto_tree_add_item(swift_tree, hf_swift_pexplus_ip, tvb, offset, 4, FALSE); 
					offset += 4;
					proto_tree_add_item(swift_tree, hf_swift_pexplus_port, tvb, offset, 2, FALSE); 
					offset += 2;
					break;
				case 6: /* PEX- */
					proto_tree_add_item(swift_tree, hf_swift_pexminus_ip, tvb, offset, 4, FALSE); 
					offset += 4;
					proto_tree_add_item(swift_tree, hf_swift_pexminus_port, tvb, offset, 2, FALSE); 
					offset += 2;
					break;
				case 7: /* Signed Hash */
					proto_tree_add_item(swift_tree, hf_swift_signed_hash_bin_id, tvb, offset, 4, FALSE); 
					offset += 4;
					proto_tree_add_item(swift_tree, hf_swift_signed_hash_value, tvb, offset, 20, FALSE); 
					offset += 20;
					/* It is not entirely clear what size the public key will be, so we allow any size
					   For this to work, we must assume there aren't any more messages in the packet */
					dat_len = tvb_length(tvb) - offset;
					proto_tree_add_item(swift_tree, hf_swift_signed_hash_signature, tvb, offset, dat_len, FALSE); 
					offset += dat_len;
					break;
				case 8: /* Hint */
					proto_tree_add_item(swift_tree, hf_swift_hint_bin_id, tvb, offset, 4, FALSE); 
					offset += 4;
					break;
				case 9: /* SWIFT_MSGTYPE_RCVD */
					break;
				case 10: /* SWIFT_MESSAGE_COUNT */
					break;
				default:
					break;
			}
   		}
		/* If the offset is still 4 here, the message is a keep-alive */
		if(offset == 4) {
			col_append_fstr(pinfo->cinfo, COL_INFO, "Keep-Alive");
			proto_item_append_text(ti, ", Keep-Alive");
		}
	}
}
示例#22
0
static int dissect_cmp_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	tvbuff_t   *next_tvb;
	guint32    pdu_len;
	guint8     pdu_type;
	nstime_t   ts;
	proto_item *item=NULL;
	proto_item *ti=NULL;
	proto_tree *tree=NULL;
	proto_tree *tcptrans_tree=NULL;
	asn1_ctx_t asn1_ctx;
	int offset=0;

	asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "CMP");

	col_set_str(pinfo->cinfo, COL_INFO, "PKIXCMP");

	if(parent_tree){
		item=proto_tree_add_item(parent_tree, proto_cmp, tvb, 0, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_cmp);
	}

	pdu_len=tvb_get_ntohl(tvb, 0);
	pdu_type=tvb_get_guint8(tvb, 4);

	if (pdu_type < 10) {
		/* RFC2510 TCP transport */
		ti = proto_tree_add_item(tree, proto_cmp, tvb, offset, 5, ENC_NA);
		tcptrans_tree = proto_item_add_subtree(ti, ett_cmp);
		proto_tree_add_item(tree, hf_cmp_tcptrans_len, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		proto_tree_add_item(tree, hf_cmp_tcptrans_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
	} else {
		/* post RFC2510 TCP transport - the former "type" field is now "version" */
		ti = proto_tree_add_text(tree, tvb, offset, 7, "TCP transport");
		tcptrans_tree = proto_item_add_subtree(ti, ett_cmp);
		pdu_type=tvb_get_guint8(tvb, 6);
		proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_len, tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans10_version, tvb, offset++, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans10_flags, tvb, offset++, 1, ENC_BIG_ENDIAN);
		proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_type, tvb, offset++, 1, ENC_BIG_ENDIAN);
	}

	col_add_str (pinfo->cinfo, COL_INFO, val_to_str (pdu_type, cmp_pdu_types, "0x%x"));

	switch(pdu_type){
		case CMP_TYPE_PKIMSG:
			next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), pdu_len);
			dissect_cmp_pdu(next_tvb, tree, &asn1_ctx);
			offset += tvb_length_remaining(tvb, offset);
			break;
		case CMP_TYPE_POLLREP:
			proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_poll_ref, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			ts.secs = tvb_get_ntohl(tvb, 4);
			ts.nsecs = 0;
			proto_tree_add_time(tcptrans_tree, hf_cmp_tcptrans_ttcb, tvb, offset, 4, &ts);
			offset += 4;
			break;
		case CMP_TYPE_POLLREQ:
			proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_poll_ref, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			break;
		case CMP_TYPE_NEGPOLLREP:
			break;
		case CMP_TYPE_PARTIALMSGREP:
			proto_tree_add_item(tcptrans_tree, hf_cmp_tcptrans_next_poll_ref, tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;

			ts.secs = tvb_get_ntohl(tvb, 4);
			ts.nsecs = 0;
			proto_tree_add_time(tcptrans_tree, hf_cmp_tcptrans_ttcb, tvb, offset, 4, &ts);
			offset += 4;

			next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), pdu_len);
			dissect_cmp_pdu(next_tvb, tree, &asn1_ctx);
			offset += tvb_length_remaining(tvb, offset);
			break;
		case CMP_TYPE_FINALMSGREP:
			next_tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), pdu_len);
			dissect_cmp_pdu(next_tvb, tree, &asn1_ctx);
			offset += tvb_length_remaining(tvb, offset);
			break;
		case CMP_TYPE_ERRORMSGREP:
			/*XXX to be added*/
			break;
	}

	return offset;
}
示例#23
0
static void
dissect_clnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  proto_tree     *clnp_tree = NULL;
  proto_item     *ti, *ti_len = NULL, *ti_pdu_len = NULL, *ti_tot_len = NULL;
  guint8          cnf_proto_id;
  guint8          cnf_hdr_len;
  guint8          cnf_vers;
  guint8          cnf_ttl;
  guint8          cnf_type;
  char            flag_string[6+1];
  const char     *pdu_type_string;
  proto_tree     *type_tree;
  guint16         segment_length;
  guint16         du_id = 0;
  guint16         segment_offset = 0;
  guint16         total_length;
  guint16         cnf_cksum;
  cksum_status_t  cksum_status;
  int             offset;
  guchar          src_len, dst_len, nsel, opt_len = 0;
  const guint8   *dst_addr, *src_addr;
  guint           next_length;
  proto_tree     *discpdu_tree;
  gboolean        save_in_error_pkt;
  fragment_data  *fd_head;
  tvbuff_t       *next_tvb;
  gboolean        update_col_info = TRUE;
  gboolean        save_fragmented;

  col_set_str(pinfo->cinfo, COL_PROTOCOL, "CLNP");
  col_clear(pinfo->cinfo, COL_INFO);

  cnf_proto_id = tvb_get_guint8(tvb, P_CLNP_PROTO_ID);
  if (cnf_proto_id == NLPID_NULL) {
    col_set_str(pinfo->cinfo, COL_INFO, "Inactive subset");
    if (tree) {
      ti = proto_tree_add_item(tree, proto_clnp, tvb, P_CLNP_PROTO_ID, 1, ENC_NA);
      clnp_tree = proto_item_add_subtree(ti, ett_clnp);
      proto_tree_add_uint_format(clnp_tree, hf_clnp_id, tvb, P_CLNP_PROTO_ID, 1,
                                 cnf_proto_id,
                                 "Inactive subset");
    }
    next_tvb = tvb_new_subset_remaining(tvb, 1);
    if (call_dissector(ositp_inactive_handle, next_tvb, pinfo, tree) == 0)
      call_dissector(data_handle,tvb, pinfo, tree);
    return;
  }

  /* return if version not known */
  cnf_vers = tvb_get_guint8(tvb, P_CLNP_VERS);
  if (cnf_vers != ISO8473_V1) {
    call_dissector(data_handle,tvb, pinfo, tree);
    return;
  }

  /* fixed part decoding */
  cnf_hdr_len = tvb_get_guint8(tvb, P_CLNP_HDR_LEN);
	
  if (tree) {
    ti = proto_tree_add_item(tree, proto_clnp, tvb, 0, cnf_hdr_len, ENC_NA);
    clnp_tree = proto_item_add_subtree(ti, ett_clnp);
    proto_tree_add_uint(clnp_tree, hf_clnp_id, tvb, P_CLNP_PROTO_ID, 1,
                        cnf_proto_id);
    ti_len = proto_tree_add_uint(clnp_tree, hf_clnp_length, tvb, P_CLNP_HDR_LEN, 1,
                                 cnf_hdr_len);
  }
  if (cnf_hdr_len < FIXED_PART_LEN) {
    /* Header length is less than the length of the fixed part of
       the header. */
    expert_add_info_format(pinfo, ti_len, PI_MALFORMED, PI_ERROR,
                           "Header length value < minimum length %u",
                           FIXED_PART_LEN);
    return;
  }
  if (tree) {                   
    proto_tree_add_uint(clnp_tree, hf_clnp_version, tvb, P_CLNP_VERS, 1,
                        cnf_vers);
    cnf_ttl = tvb_get_guint8(tvb, P_CLNP_TTL);
    proto_tree_add_uint_format(clnp_tree, hf_clnp_ttl, tvb, P_CLNP_TTL, 1,
                               cnf_ttl,
                               "Holding Time : %u (%u.%u secs)",
                               cnf_ttl, cnf_ttl / 2, (cnf_ttl % 2) * 5);
  }

  cnf_type = tvb_get_guint8(tvb, P_CLNP_TYPE);
  pdu_type_string = val_to_str(cnf_type & CNF_TYPE, npdu_type_abbrev_vals,
                               "Unknown (0x%02x)");
  flag_string[0] = '\0';
  if (cnf_type & CNF_SEG_OK)
    g_strlcat(flag_string, "S ", 7);
  if (cnf_type & CNF_MORE_SEGS)
    g_strlcat(flag_string, "M ", 7);
  if (cnf_type & CNF_ERR_OK)
    g_strlcat(flag_string, "E ", 7);
  if (tree) {
    ti = proto_tree_add_uint_format(clnp_tree, hf_clnp_type, tvb, P_CLNP_TYPE, 1,
                                    cnf_type,
                                    "PDU Type     : 0x%02x (%s%s)",
                                    cnf_type,
                                    flag_string,
                                    pdu_type_string);
    type_tree = proto_item_add_subtree(ti, ett_clnp_type);
    proto_tree_add_item(type_tree, hf_clnp_cnf_segmentation, tvb, P_CLNP_TYPE, 1, ENC_NA);
    proto_tree_add_item(type_tree, hf_clnp_cnf_more_segments, tvb, P_CLNP_TYPE, 1, ENC_NA);
    proto_tree_add_item(type_tree, hf_clnp_cnf_report_error, tvb, P_CLNP_TYPE, 1, ENC_NA);
    proto_tree_add_item(type_tree, hf_clnp_cnf_type, tvb, P_CLNP_TYPE, 1, ENC_NA);
  }

  /* If we don't have the full header - i.e., not enough to see the
     segmentation part and determine whether this datagram is segmented
     or not - set the Info column now; we'll get an exception before
     we set it otherwise. */

  if (tvb_length(tvb) < cnf_hdr_len) {
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
  }

  segment_length = tvb_get_ntohs(tvb, P_CLNP_SEGLEN);
  if (tree) {
    ti_pdu_len = proto_tree_add_uint(clnp_tree, hf_clnp_pdu_length, tvb, P_CLNP_SEGLEN, 2,
                                     segment_length);
  }
  if (segment_length < cnf_hdr_len) {
    /* Segment length is less than the header length. */
    expert_add_info_format(pinfo, ti_pdu_len, PI_MALFORMED, PI_ERROR,
                           "PDU length < header length %u", cnf_hdr_len);
    return;
  }
  cnf_cksum = tvb_get_ntohs(tvb, P_CLNP_CKSUM);
  cksum_status = calc_checksum(tvb, 0, cnf_hdr_len, cnf_cksum);
  if (tree) {
    switch (cksum_status) {

    default:
      /*
       * No checksum present, or not enough of the header present to
       * checksum it.
       */
      proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, tvb,
                                 P_CLNP_CKSUM, 2,
                                 cnf_cksum,
                                 "Checksum     : 0x%04x",
                                 cnf_cksum);
      break;

    case CKSUM_OK:
      /*
       * Checksum is correct.
       */
      proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, tvb,
                                 P_CLNP_CKSUM, 2,
                                 cnf_cksum,
                                 "Checksum     : 0x%04x (correct)",
                                 cnf_cksum);
      break;

    case CKSUM_NOT_OK:
      /*
       * Checksum is not correct.
       */
      proto_tree_add_uint_format(clnp_tree, hf_clnp_checksum, tvb,
                                 P_CLNP_CKSUM, 2,
                                 cnf_cksum,
                                 "Checksum     : 0x%04x (incorrect)",
                                 cnf_cksum);
      break;
    }
  } /* tree */

  opt_len = cnf_hdr_len;
  opt_len -= FIXED_PART_LEN; /* Fixed part of Header */

  /* address part */

  offset = P_CLNP_ADDRESS_PART;
  if (opt_len < 1) {
    /* Header length is less than the minimum value in CLNP,
       including the destination address length. */
    expert_add_info_format(pinfo, ti_len, PI_MALFORMED, PI_ERROR,
                           "Header length value < %u",
                           FIXED_PART_LEN + 1);
    return;
  }
  dst_len  = tvb_get_guint8(tvb, offset);
  if (tree) {
    proto_tree_add_uint(clnp_tree, hf_clnp_dest_length, tvb, offset, 1,
                        dst_len);
  }
  offset += 1;
  opt_len -= 1;

  if (opt_len < dst_len) {
    /* Header length is less than the minimum value,
       including the destination address length and the
       destination address. */
    expert_add_info_format(pinfo, ti_len, PI_MALFORMED, PI_ERROR,
                           "Header length value < %u",
                           FIXED_PART_LEN + 1 + dst_len);
    return;
  }
  dst_addr = tvb_get_ptr(tvb, offset, dst_len);
  nsel     = tvb_get_guint8(tvb, offset + dst_len - 1);
  SET_ADDRESS(&pinfo->net_dst, AT_OSI, dst_len, dst_addr);
  SET_ADDRESS(&pinfo->dst, AT_OSI, dst_len, dst_addr);
  if (tree) {
    proto_tree_add_bytes_format(clnp_tree, hf_clnp_dest, tvb, offset, dst_len,
                                dst_addr,
                                " DA : %s",
                                print_nsap_net(dst_addr, dst_len));
  }
  offset += dst_len;
  opt_len -= dst_len;

  if (opt_len < 1) {
    /* Header length is less than the minimum value,
       including the destination address length, the
       destination address, and the source address length. */
    expert_add_info_format(pinfo, ti_len, PI_MALFORMED, PI_ERROR,
                           "Header length value < %u",
                           FIXED_PART_LEN + 1 + dst_len + 1);
    return;
  }
  src_len  = tvb_get_guint8(tvb, offset);
  if (tree) {
    proto_tree_add_uint(clnp_tree, hf_clnp_src_length, tvb,
                        offset, 1, src_len);
  }
  offset += 1;
  opt_len -= 1;

  if (opt_len < src_len) {
    /* Header length is less than the minimum value,
       including the destination address length, the
       destination address, the source address length,
       and the source address. */
    expert_add_info_format(pinfo, ti_len, PI_MALFORMED, PI_ERROR,
                           "Header length value < %u",
                           FIXED_PART_LEN + 1 + dst_len + 1 + src_len);
    return;
  }
  src_addr = tvb_get_ptr(tvb, offset, src_len);
  SET_ADDRESS(&pinfo->net_src, AT_OSI, src_len, src_addr);
  SET_ADDRESS(&pinfo->src, AT_OSI, src_len, src_addr);
  if (tree) {
    proto_tree_add_bytes_format(clnp_tree, hf_clnp_src, tvb,
                                offset, src_len,
                                src_addr,
                                " SA : %s",
                                print_nsap_net(src_addr, src_len));

  }
  offset += src_len;
  opt_len -= src_len;

  /* Segmentation Part */

  if (cnf_type & CNF_SEG_OK) {
    if (opt_len < SEGMENTATION_PART_LEN) {
      /* Header length is less than the minimum value,
         including the destination address length, the
         destination address, the source address length,
         the source address, and the segmentation part. */
      expert_add_info_format(pinfo, ti_len, PI_MALFORMED, PI_ERROR,
                             "Header length value < %u",
                             FIXED_PART_LEN + 1 + dst_len + 1 + SEGMENTATION_PART_LEN);
      return;
    }
    du_id = tvb_get_ntohs(tvb, offset);
    if (tree) {
      proto_tree_add_text(clnp_tree, tvb, offset, 2,
                          "Data unit identifier: %06u",
                          du_id);
    }
    segment_offset = tvb_get_ntohs(tvb, offset + 2);
    if (tree) {
      proto_tree_add_text(clnp_tree, tvb, offset + 2 , 2,
                          "Segment offset      : %6u",
                          segment_offset);
    }
    total_length = tvb_get_ntohs(tvb, offset + 4);
    if (tree) {
      ti_tot_len = proto_tree_add_text(clnp_tree, tvb, offset + 4 , 2,
                                       "Total length        : %6u",
                                       total_length);
    }
    if (total_length < segment_length) {
      /* Reassembled length is less than the length of this segment. */
      expert_add_info_format(pinfo, ti_tot_len, PI_MALFORMED, PI_ERROR,
                             "Total length < segment length %u", segment_length);
      return;
    }
    offset  += SEGMENTATION_PART_LEN;
    opt_len -= SEGMENTATION_PART_LEN;
  }

  if (tree) {
    dissect_osi_options(opt_len, tvb, offset, clnp_tree);
  }

  offset += opt_len;

  /* If clnp_reassemble is on, this is a segment, we have all the
   * data in the segment, and the checksum is valid, then just add the
   * segment to the hashtable.
   */
  save_fragmented = pinfo->fragmented;
  if (clnp_reassemble && (cnf_type & CNF_SEG_OK) &&
      ((cnf_type & CNF_MORE_SEGS) || segment_offset != 0) &&
      tvb_bytes_exist(tvb, offset, segment_length - cnf_hdr_len) &&
      segment_length > cnf_hdr_len &&
      cksum_status != CKSUM_NOT_OK) {
    fd_head = fragment_add_check(&clnp_reassembly_table,
                                 tvb, offset, pinfo, du_id, NULL,
                                 segment_offset, segment_length - cnf_hdr_len,
                                 cnf_type & CNF_MORE_SEGS);

    next_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled CLNP",
                                        fd_head, &clnp_frag_items, &update_col_info, clnp_tree);
  } else {
    /* If this is the first segment, dissect its contents, otherwise
       just show it as a segment.

       XXX - if we eventually don't save the reassembled contents of all
       segmented datagrams, we may want to always reassemble. */
    if ((cnf_type & CNF_SEG_OK) && segment_offset != 0) {
      /* Not the first segment - don't dissect it. */
      next_tvb = NULL;
    } else {
      /* First segment, or not segmented.  Dissect what we have here. */

      /* Get a tvbuff for the payload.  Set its length to the segment
         length, and flag it as a fragment, so going past the end
         reports FragmentBoundsError, i.e. "there's data missing
         because this isn't reassembled", not ReportedBoundsError,
         i.e. "the dissector ran past the end of the packet, so the
         packet must not have been constructed properly". */
      next_tvb = tvb_new_subset_length(tvb, offset, segment_length - cnf_hdr_len);
      tvb_set_fragment(next_tvb);

      /*
       * If this is the first segment, but not the only segment,
       * tell the next protocol that.
       */
      if ((cnf_type & (CNF_SEG_OK|CNF_MORE_SEGS)) == (CNF_SEG_OK|CNF_MORE_SEGS))
        pinfo->fragmented = TRUE;
      else
        pinfo->fragmented = FALSE;
    }
  }

  if (next_tvb == NULL) {
    /* Just show this as a segment. */
    col_add_fstr(pinfo->cinfo, COL_INFO, "Fragmented %s NPDU %s(off=%u)",
                 pdu_type_string, flag_string, segment_offset);

    /* As we haven't reassembled anything, we haven't changed "pi", so
       we don't have to restore it. */
    call_dissector(data_handle, tvb_new_subset_remaining(tvb, offset), pinfo,
                   tree);
    pinfo->fragmented = save_fragmented;
    return;
  }

  if (tvb_offset_exists(tvb, offset)) {
    switch (cnf_type & CNF_TYPE) {

    case DT_NPDU:
    case MD_NPDU:
      /* Continue with COTP if any data.
         XXX - if this isn't the first Derived PDU of a segmented Initial
         PDU, skip that? */

      if (nsel == (guchar)tp_nsap_selector || always_decode_transport) {
        if (call_dissector(ositp_handle, next_tvb, pinfo, tree) != 0) {
          pinfo->fragmented = save_fragmented;
          return;       /* yes, it appears to be COTP or CLTP */
        }
      }
      if (dissector_try_heuristic(clnp_heur_subdissector_list, next_tvb,
                                  pinfo, tree, NULL)) {
          pinfo->fragmented = save_fragmented;
          return;       /* yes, it appears to be one of the protocols in the heuristic list */
      }

      break;

    case ER_NPDU:
      /* The payload is the header and "none, some, or all of the data
         part of the discarded PDU", i.e. it's like an ICMP error;
         dissect it as a CLNP PDU. */

      col_add_fstr(pinfo->cinfo, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
      next_length = tvb_length_remaining(tvb, offset);
      if (next_length != 0) {
          /* We have payload; dissect it. */
          ti = proto_tree_add_text(clnp_tree, tvb, offset, next_length,
            "Discarded PDU");
          discpdu_tree = proto_item_add_subtree(ti, ett_clnp_disc_pdu);

          /* Save the current value of the "we're inside an error packet"
             flag, and set that flag; subdissectors may treat packets
             that are the payload of error packets differently from
             "real" packets. */
          save_in_error_pkt = pinfo->flags.in_error_pkt;
          pinfo->flags.in_error_pkt = TRUE;

          call_dissector(clnp_handle, next_tvb, pinfo, discpdu_tree);

          /* Restore the "we're inside an error packet" flag. */
          pinfo->flags.in_error_pkt = save_in_error_pkt;
      }
      pinfo->fragmented = save_fragmented;
      return;   /* we're done with this PDU */

    case ERQ_NPDU:
    case ERP_NPDU:
      /* XXX - dissect this */
      break;
    }
  }
  col_add_fstr(pinfo->cinfo, COL_INFO, "%s NPDU %s", pdu_type_string, flag_string);
  call_dissector(data_handle,next_tvb, pinfo, tree);
  pinfo->fragmented = save_fragmented;
} /* dissect_clnp */
示例#24
0
static void
dissect_nflog(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	const int start_tlv_offset = 4;

	proto_tree *nflog_tree = NULL;
	proto_item *ti;

	int offset = 0;

	tvbuff_t *next_tvb = NULL;
	int aftype;

	int enc;
	guint16 (*val16_get)(tvbuff_t *, int);

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "NFLOG");
	col_clear(pinfo->cinfo, COL_INFO);

	aftype = tvb_get_guint8(tvb, 0);
	enc = nflog_tvb_byte_order(tvb, start_tlv_offset);
	switch (enc) {
		case ENC_LITTLE_ENDIAN:
			val16_get = tvb_get_letohs;
			break;

		case ENC_BIG_ENDIAN:
		default:
			val16_get = tvb_get_ntohs;
			break;
	}

	/* Header */
	if (proto_field_is_referenced(tree, proto_nflog)) {
		ti = proto_tree_add_item(tree, proto_nflog, tvb, 0, -1, ENC_NA);
		nflog_tree = proto_item_add_subtree(ti, ett_nflog);

		proto_tree_add_item(nflog_tree, hf_nflog_family, tvb, offset, 1, ENC_NA);
		offset += 1;

		proto_tree_add_item(nflog_tree, hf_nflog_version, tvb, offset, 1, ENC_NA);
		offset += 1;

		proto_tree_add_item(nflog_tree, hf_nflog_resid, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		ti = proto_tree_add_uint(nflog_tree, hf_nflog_encoding,
					 tvb, offset, tvb_length_remaining(tvb, offset), enc);
		PROTO_ITEM_SET_GENERATED(ti);
	}

	offset = start_tlv_offset;
	/* TLVs */
	while (tvb_length_remaining(tvb, offset) >= 4) {
		guint16 tlv_len = val16_get(tvb, offset + 0);
		guint16 tlv_type;
		guint16 value_len;

		proto_tree *tlv_tree;

		/* malformed */
		if (tlv_len < 4)
			return;

		value_len = tlv_len - 4;
		tlv_type = (val16_get(tvb, offset + 2) & 0x7fff);

		if (nflog_tree) {
			gboolean handled = FALSE;

			ti = proto_tree_add_bytes_format(nflog_tree, hf_nflog_tlv,
							 tvb, offset, tlv_len, NULL,
							 "TLV Type: %s (%u), Length: %u",
							 val_to_str_const(tlv_type, nflog_tlv_vals, "Unknown"),
							 tlv_type, tlv_len);
			tlv_tree = proto_item_add_subtree(ti, ett_nflog_tlv);

			proto_tree_add_item(tlv_tree, hf_nflog_tlv_length, tvb, offset + 0, 2, enc);
			proto_tree_add_item(tlv_tree, hf_nflog_tlv_type, tvb, offset + 2, 2, enc);
			switch (tlv_type) {
				case WS_NFULA_PAYLOAD:
					handled = TRUE;
					break;

				case WS_NFULA_PREFIX:
					if (value_len >= 1) {
						proto_tree_add_item(tlv_tree, hf_nflog_tlv_prefix,
								    tvb, offset + 4, value_len, ENC_NA);
						handled = TRUE;
					}
					break;

				case WS_NFULA_UID:
					if (value_len == 4) {
						proto_tree_add_item(tlv_tree, hf_nflog_tlv_uid,
								    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
						handled = TRUE;
					}
					break;

				case WS_NFULA_GID:
					if (value_len == 4) {
						proto_tree_add_item(tlv_tree, hf_nflog_tlv_gid,
								    tvb, offset + 4, value_len, ENC_BIG_ENDIAN);
						handled = TRUE;
					}
					break;

				case WS_NFULA_TIMESTAMP:
					if (value_len == 16) {
						nstime_t ts;

						ts.secs  = tvb_get_ntoh64(tvb, offset + 4);
						/* XXX - add an "expert info" warning if this is >= 10^9? */
						ts.nsecs = (int)tvb_get_ntoh64(tvb, offset + 12);
						proto_tree_add_time(tlv_tree, hf_nflog_tlv_timestamp,
									tvb, offset + 4, value_len, &ts);
						handled = TRUE;
					}
					break;
			}

			if (!handled)
					proto_tree_add_item(tlv_tree, hf_nflog_tlv_unknown,
							    tvb, offset + 4, value_len, ENC_NA);
		}

		if (tlv_type == WS_NFULA_PAYLOAD)
			next_tvb = tvb_new_subset(tvb, offset + 4, value_len, value_len);

		offset += ((tlv_len + 3) & ~3);	/* next TLV aligned to 4B */
	}

	if (next_tvb) {
		switch (aftype) {
			case LINUX_AF_INET:
				call_dissector(ip_handle, next_tvb, pinfo, tree);
				break;
			case LINUX_AF_INET6:
				call_dissector(ip6_handle, next_tvb, pinfo, tree);
				break;
			default:
				call_dissector(data_handle, next_tvb, pinfo, tree);
				break;
		}
	}
}
static void
dissect_prism(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *prism_tree = NULL, *prism_did_tree = NULL;
    proto_item *ti = NULL, *ti_did = NULL;
    tvbuff_t *next_tvb;
    int offset;
    guint32 msgcode, msglen, did;
    guint16 status;
    guint8 *devname_p;

    offset = 0;
    did = 0;

    /* handle the AVS header */
    msgcode = tvb_get_ntohl(tvb, offset);
    if ((msgcode == WLANCAP_MAGIC_COOKIE_V1) ||
        (msgcode == WLANCAP_MAGIC_COOKIE_V2)) {
      call_dissector(wlancap_handle, tvb, pinfo, tree);
      return;
    }

    /*
     * If we don't see a valid message type, assume the Prism or AVS
     * header was omitted and just hand off to the 802.11 dissector;
     * at least one capture has AVS headers on some packets and no
     * radio headers on others (incoming vs. outgoing?).
     *
     * XXX - check for both byte orders and use that to determine
     * the byte order of the fields in the Prism header?
     */
    msgcode = tvb_get_letohl(tvb, offset);
    if ((msgcode != PRISM_TYPE1_MSGCODE) &&
        (msgcode != PRISM_TYPE2_MSGCODE)) {
        call_dissector(ieee80211_handle, tvb, pinfo, tree);
        return;
    }

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Prism");
    col_clear(pinfo->cinfo, COL_INFO);

    if(tree) {
        ti = proto_tree_add_item(tree, proto_prism, tvb, 0, 144, ENC_NA);
        prism_tree = proto_item_add_subtree(ti, ett_prism);
    }

    /* Message Code */
    if(tree) {
        proto_tree_add_item(prism_tree, hf_ieee80211_prism_msgcode, tvb, offset, 4, ENC_LITTLE_ENDIAN);
    }
    msgcode = tvb_get_letohl(tvb, offset);
    offset += 4;

    /* Message Length */
    if(tree) {
        proto_tree_add_item(prism_tree, hf_ieee80211_prism_msglen, tvb, offset, 4, ENC_LITTLE_ENDIAN);
    }
    msglen = tvb_get_letohl(tvb, offset);
    offset += 4;

    /* Device Name */
    if(tree) {
       proto_tree_add_item(prism_tree, hf_ieee80211_prism_devname, tvb, offset, 16, ENC_ASCII|ENC_NA);
    }
    devname_p = tvb_get_ephemeral_string(tvb, offset, 16);
    offset += 16;

    col_add_fstr(pinfo->cinfo, COL_INFO, "Device: %s, Message 0x%x, Length %d", devname_p, msgcode, msglen);


    while(offset < PRISM_HEADER_LENGTH)
    {
        /* DID */
        if(tree) {
            ti_did = proto_tree_add_item(prism_tree, hf_ieee80211_prism_did, tvb, offset, 12, ENC_NA);
            prism_did_tree = proto_item_add_subtree(ti_did, ett_prism_did);

            proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
            did = tvb_get_letohl(tvb, offset);
            proto_item_append_text(ti_did, " %s", val_to_str(did, prism_did_vals, "Unknown %x") );
        }
        offset += 4;


        /* Status */
        status = tvb_get_letohs(tvb, offset);
        if(tree) {
            proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_status, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        }
        offset += 2;

        /* Length */
        if(tree) {
            proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_length, tvb, offset, 2, ENC_LITTLE_ENDIAN);
        }
        offset += 2;

        /* Data, if present... */
        if (status == 0) {
            switch(did){
              case PRISM_TYPE1_HOSTTIME:
              case PRISM_TYPE2_HOSTTIME:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_hosttime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) );
                }
              break;

              case PRISM_TYPE1_MACTIME:
              case PRISM_TYPE2_MACTIME:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_mactime, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) );
                }
              break;

              case PRISM_TYPE1_CHANNEL:
              case PRISM_TYPE2_CHANNEL:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) );
                }
                col_add_fstr(pinfo->cinfo, COL_FREQ_CHAN, "%u", tvb_get_letohl(tvb, offset));
              break;

              case PRISM_TYPE1_RSSI:
              case PRISM_TYPE2_RSSI:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_rssi, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) );
                }
                col_add_fstr(pinfo->cinfo, COL_RSSI, "%d", tvb_get_letohl(tvb, offset));
              break;

              case PRISM_TYPE1_SQ:
              case PRISM_TYPE2_SQ:
                 if(tree){
                      proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_sq, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                      proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) );
                }
              break;

              case PRISM_TYPE1_SIGNAL:
              case PRISM_TYPE2_SIGNAL:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_signal, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) );
                }
              break;

              case PRISM_TYPE1_NOISE:
              case PRISM_TYPE2_NOISE:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_noise, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) );
                }
              break;

              case PRISM_TYPE1_RATE:
              case PRISM_TYPE2_RATE:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_rate, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " %s Mb/s", prism_rate_return(tvb_get_letohl(tvb, offset)) );
                }
                col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%s", prism_rate_return(tvb_get_letohl(tvb, offset)) );
              break;

              case PRISM_TYPE1_ISTX:
              case PRISM_TYPE2_ISTX:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_istx, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " 0x%x", tvb_get_letohl(tvb, offset) );
                }
              break;

              case PRISM_TYPE1_FRMLEN:
              case PRISM_TYPE2_FRMLEN:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_frmlen, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                    proto_item_append_text(ti_did, " %d", tvb_get_letohl(tvb, offset) );
                }
              break;

              default:
                if(tree){
                    proto_tree_add_item(prism_did_tree, hf_ieee80211_prism_did_unknown, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                }
              break;
            }
        }
        offset += 4;
    }

    /* dissect the 802.11 header next */
    next_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector(ieee80211_handle, next_tvb, pinfo, tree);
}
示例#26
0
/* Code to actually dissect the packets */
static void
dissect_brdwlk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

/* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti, *hidden_item;
    proto_tree *brdwlk_tree = NULL;
    tvbuff_t *next_tvb;
    guint8 error, eof, sof;
    int hdrlen = 2,
        offset = 0;
    gint len, reported_len, plen;
    guint16 pkt_cnt;
    gboolean dropped_packets;
    fc_data_t fc_data;

    /* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Boardwalk");

    col_clear(pinfo->cinfo, COL_INFO);

    sof = (tvb_get_guint8(tvb, offset) & 0xF0) >> 4;

    fc_data.sof_eof = 0;
    if ((sof == FCM_DELIM_SOFI3) || (sof == FCM_DELIM_SOFI2) || (sof == FCM_DELIM_SOFI1)
        || (sof == FCM_DELIM_SOFI4)) {
        fc_data.sof_eof = FC_DATA_SOF_FIRST_FRAME;
    }
    else if (sof == FCM_DELIM_SOFF) {
        fc_data.sof_eof = FC_DATA_SOF_SOFF;
    }

    if (tree) {
        ti = proto_tree_add_protocol_format(tree, proto_brdwlk, tvb, 0,
                                            hdrlen, "Boardwalk");

        brdwlk_tree = proto_item_add_subtree(ti, ett_brdwlk);

        proto_tree_add_item(brdwlk_tree, hf_brdwlk_sof, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(brdwlk_tree, hf_brdwlk_vsan, tvb, offset, 2, ENC_BIG_ENDIAN);

    }

    /* Locate EOF which is the last 4 bytes of the frame */
    len = tvb_length_remaining(tvb, hdrlen);
    reported_len = tvb_reported_length_remaining(tvb, hdrlen);
    if (reported_len < 4) {
        /*
         * This packet is claimed not to even have enough data for
         * a 4-byte EOF.
         * Don't try to process the EOF.
         */
        ;
    }
    else if (len < reported_len) {
        /*
         * This packet is claimed to have enough data for a 4-byte EOF,
         * but we didn't capture all of the packet.
         * Slice off the 4-byte EOF from the reported length, and trim
         * the captured length so it's no more than the reported length;
         * that will slice off what of the EOF, if any, is in the
         * captured length.
         */
        reported_len -= 4;
        if (len > reported_len)
            len = reported_len;
    }
    else {
        /*
         * We have the entire packet, and it includes a 4-byte EOF.
         * Slice it off, and put it into the tree if we're building
         * a tree.
         */
        len -= 4;
        reported_len -= 4;
        offset = tvb_reported_length(tvb) - 4;
        pkt_cnt = tvb_get_ntohs(tvb, offset);
        if (tree) {
            proto_tree_add_uint(brdwlk_tree, hf_brdwlk_pktcnt, tvb, offset,
                                2, pkt_cnt);
        }
        dropped_packets = FALSE;
        if (pinfo->fd->flags.visited) {
            /*
             * This isn't the first pass, so we can't use the global
             * "packet_count" variable to determine whether there were
             * any dropped frames or not.
             * We therefore attach a non-null pointer as frame data to
             * any frame preceded by dropped packets.
             */
            if (p_get_proto_data(wmem_file_scope(), pinfo, proto_brdwlk, 0) != NULL)
                dropped_packets = TRUE;
        } else {
            /*
             * This is the first pass, so we have to use the global
             * "packet_count" variable to determine whether there were
             * any dropped frames or not.
             *
             * XXX - can there be more than one stream of packets, so that
             * we can't just use a global variable?
             */
            if (pkt_cnt != packet_count + 1) {
                if (!first_pkt &&
                    (pkt_cnt != 0 || (packet_count != BRDWLK_MAX_PACKET_CNT))) {
                    dropped_packets = TRUE;

                    /*
                     * Mark this frame as having been preceded by dropped
                     * packets.  (The data we use as the frame data doesn't
                     * matter - it just matters that it's non-null.)
                     */
                    p_add_proto_data(wmem_file_scope(), pinfo, proto_brdwlk, 0, &packet_count);
                }
            }
        }
        if (tree) {
            hidden_item = proto_tree_add_boolean(brdwlk_tree, hf_brdwlk_drop,
                                                     tvb, offset, 0, dropped_packets);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
        }

        packet_count = pkt_cnt;

        error=tvb_get_guint8(tvb, offset+2);
        dissect_brdwlk_err(brdwlk_tree, tvb, offset+2);

        eof = tvb_get_guint8(tvb, offset+3);
        if (eof != FCM_DELIM_EOFN) {
            fc_data.sof_eof |= FC_DATA_EOF_LAST_FRAME;
        }
        else if (eof != FCM_DELIM_EOFT) {
            fc_data.sof_eof |= FC_DATA_EOF_INVALID;
        }

        if (tree) {
            proto_tree_add_item(brdwlk_tree, hf_brdwlk_eof, tvb, offset+3,
                                1, ENC_BIG_ENDIAN);
        }

        if ((error & BRDWLK_HAS_PLEN) && tree) {
            /* In newer Boardwalks, if this bit is set, the actual frame length
             * is also provided. This length is the size between SOF & EOF
             * including FC CRC.
             */
            plen = tvb_get_ntohl(tvb, offset-4);
            plen *= 4;
            proto_tree_add_uint(brdwlk_tree, hf_brdwlk_plen, tvb, offset-4,
                                4, plen);

#if 0
            /* XXX - this would throw an exception if it would increase
             * the reported length.
             */
            if (error & BRDWLK_TRUNCATED_BIT) {
                tvb_set_reported_length(tvb, plen);
            }
#endif
        }
    }

    fc_data.ethertype = ETHERTYPE_BRDWALK;
    next_tvb = tvb_new_subset(tvb, 2, len, reported_len);
    call_dissector_with_data(fc_dissector_handle, next_tvb, pinfo, tree, &fc_data);
}
示例#27
0
static void
dissect_ax25_nol3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree )
{
    proto_item *ti;
    proto_tree *ax25_nol3_tree;
    char       *info_buffer;
    int         offset;
    tvbuff_t   *next_tvb = NULL;
    guint8      dti      = 0;
    gboolean    dissected;

    info_buffer = (char *)wmem_alloc( wmem_packet_scope(), STRLEN );
    info_buffer[0] = '\0';

    col_set_str( pinfo->cinfo, COL_PROTOCOL, "AX.25-NoL3");

    col_clear( pinfo->cinfo, COL_INFO);

    offset = 0;
    g_snprintf( info_buffer, STRLEN, "Text" );

    if ( gPREF_APRS )
    {
        dti = tvb_get_guint8( tvb, offset );
        if ( isaprs( dti ) )
            g_snprintf( info_buffer, STRLEN, "APRS" );
    }
    if ( gPREF_DX )
    {
        if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' )
            g_snprintf( info_buffer, STRLEN, "DX cluster" );
    }

    col_add_str( pinfo->cinfo, COL_INFO, info_buffer );

    /* Call sub-dissectors here */

    if ( parent_tree )
    {
        /* create display subtree for the protocol */
        ti = proto_tree_add_protocol_format( parent_tree,
                                             proto_ax25_nol3,
                                             tvb,
                                             0,
                                             -1,
                                             "AX.25 No Layer 3 - (%s)", info_buffer );
        ax25_nol3_tree = proto_item_add_subtree( ti, ett_ax25_nol3 );

        next_tvb = tvb_new_subset_remaining(tvb, offset);
        dissected = FALSE;
        if ( gPREF_APRS )
        {
            if ( isaprs( dti ) )
            {
                dissected = TRUE;
                call_dissector( aprs_handle , next_tvb, pinfo, ax25_nol3_tree );
            }
        }
        if ( gPREF_DX )
        {
            if ( tvb_get_guint8( tvb, offset ) == 'D' && tvb_get_guint8( tvb, offset + 1 ) == 'X' )
            {
                dissected = TRUE;
                dissect_dx( next_tvb, pinfo, ax25_nol3_tree );
            }
        }
        if ( ! dissected )
            call_dissector( default_handle , next_tvb, pinfo, ax25_nol3_tree );

    }
}
示例#28
0
/* dissect_main
 *
 * main dissect function that calls the other functions listed above as necessary
 */
static void
dissect_mvrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* Set up structures needed to add the protocol subtrees and manage them */
    proto_item *ti, *msg_ti, *attr_list_ti, *vect_attr_ti, *first_value_ti;
    proto_tree *mvrp_tree, *msg_tree, *attr_list_tree, *vect_attr_tree, *first_value_tree;

    /* Make entries in Protocol column and Info column on summary display */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "MRP-MVRP");

    col_set_str(pinfo->cinfo, COL_INFO, "Multiple VLAN Registration Protocol");

    if (tree) {
        guint8 attribute_type;
        guint8 attribute_length;
        guint16 number_of_values;
        guint offset = 0;
        int vect_attr_len;
        int msg_offset;  /* Use when handling multiple messages.  This points to current msg being decoded. */
        int vect_offset; /* Use when handling multiple vector attributes.  This points to the current vector attribute being decoded. */

        ti = proto_tree_add_item(tree, proto_mvrp, tvb, 0, -1, ENC_NA);
        mvrp_tree = proto_item_add_subtree(ti, ett_mvrp);

        proto_tree_add_item(mvrp_tree, hf_mvrp_proto_id, tvb, MVRP_PROTOCOL_VERSION_OFFSET, 1, ENC_BIG_ENDIAN);

        /* MVRP supports multiple MRP Messages per frame.  Handle those Messages in
         * the following while() loop. You will know you are at the end of the list
         * of messages when the EndMark (0x0000) is encountered instead of an
         * Attribute Type and Attribute Length (guaranteed to not be 0x0000).
         */
        msg_offset = 0;
        while (tvb_get_ntohs(tvb, MVRP_ATTRIBUTE_TYPE_OFFSET + msg_offset) != MVRP_END_MARK) {

            attribute_type = tvb_get_guint8(tvb, MVRP_ATTRIBUTE_TYPE_OFFSET + msg_offset);
            attribute_length = tvb_get_guint8(tvb, MVRP_ATTRIBUTE_LENGTH_OFFSET + msg_offset);

            /* MVRP Message is a group of fields
             *
             * Contains AttributeType (1 byte)
             *        + AttributeLength (1 byte)
             *        + AttributeList (AttributeListLength bytes)
            *        bytes of data
            */
            msg_ti = proto_tree_add_item(mvrp_tree, hf_mvrp_message, tvb,
                                         MVRP_MESSAGE_GROUP_OFFSET + msg_offset,
                                         -1, ENC_NA);
            msg_tree = proto_item_add_subtree(msg_ti, ett_msg);

            /* Append AttributeType description to the end of the "Message" heading */
            proto_item_append_text(msg_tree, ": %s (%d)",
                                   val_to_str_const(attribute_type, attribute_type_vals, "<Unknown>"),
                                   attribute_type);

            dissect_mvrp_common1(msg_tree, tvb, msg_offset);

            /* MVRP AttributeList is a group of fields
             *
             * Contains AttributeListLength bytes of data NOT
             */
            attr_list_ti = proto_tree_add_item(msg_tree, hf_mvrp_attribute_list, tvb,
                                               MVRP_ATTRIBUTE_LIST_GROUP_OFFSET + msg_offset,
                                               -1, ENC_NA);
            attr_list_tree = proto_item_add_subtree(attr_list_ti, ett_attr_list);


            /* MVRP supports multiple MRP Vector Attributes per Attribute List.  Handle those
             * Vector Attributes in the following while() loop. You will know you are at the
             * end of the list of Vector Attributes when the EndMark (0x0000) is encountered
             * instead of a Vector Header (guaranteed to not be 0x0000).
             */
            vect_offset = 0;
            while (tvb_get_ntohs(tvb, MVRP_VECTOR_HEADER_OFFSET + msg_offset + vect_offset) != MVRP_END_MARK) {
                /* MVRP VectorAttribute is a group of fields
                 *
                 * Contains VectorHeader (2 bytes)
                 *        + FirstValue (AttributeLength bytes)
                 *        + VectorThreePacked (NumberOfValues @ 3/vector bytes)
                 *        + VectorFourPacked (NumberOfValues @ 4/vector bytes only for Listener attributes)
                 *        bytes of data
                 */
                number_of_values = tvb_get_ntohs(tvb, MVRP_NUMBER_OF_VALUES_OFFSET + msg_offset + vect_offset)
                                   & MVRP_NUMBER_OF_VALUES_MASK;

                vect_attr_len = 2 + attribute_length + (number_of_values + 2)/3; /* stores 3 values per byte */

                vect_attr_ti = proto_tree_add_item(attr_list_tree, hf_mvrp_vector_attribute, tvb,
                                                   MVRP_VECTOR_ATTRIBUTE_GROUP_OFFSET + msg_offset + vect_offset,
                                                   vect_attr_len, ENC_NA);

                vect_attr_tree = proto_item_add_subtree(vect_attr_ti, ett_vect_attr);

                dissect_mvrp_common2(vect_attr_tree, tvb, msg_offset + vect_offset);

                if (attribute_type == MVRP_ATTRIBUTE_TYPE_VID) {
                    /* MVRP VLAN ID FirstValue is a group of fields
                     *
                     * Contains VID (2 bytes)
                     *        bytes of data
                     */
                    first_value_ti = proto_tree_add_item(vect_attr_tree, hf_mvrp_first_value, tvb,
                                                         MVRP_FIRST_VALUE_GROUP_OFFSET + msg_offset + vect_offset,
                                                         attribute_length, ENC_NA);
                    first_value_tree = proto_item_add_subtree(first_value_ti, ett_first_value);

                    /* Add VLAN components to First Value tree */
                    proto_tree_add_item(first_value_tree, hf_mvrp_vid, tvb,
                                        MVRP_FIRST_VALUE_GROUP_OFFSET + msg_offset + vect_offset, 2, ENC_BIG_ENDIAN);

                    /* Decode three packed events. */
                    offset = dissect_mvrp_three_packed_event(vect_attr_tree, tvb,
                                                             MVRP_VID_THREE_PACKED_OFFSET + msg_offset + vect_offset,
                                                             number_of_values);

                }

                vect_offset += vect_attr_len; /* Move to next Vector Attribute, if there is one */
            } /* Multiple VectorAttribute while() */

            proto_tree_add_item(attr_list_tree, hf_mvrp_end_mark, tvb, offset, 2, ENC_NA); /* VectorAttribute EndMark */

            proto_item_set_len(attr_list_ti, vect_offset); /*without an endmark*/
            msg_offset += vect_offset + 2; /*  + endmark; Move to next Message, if there is one */
            proto_item_set_len(msg_ti, vect_offset + 2); /*length of message*/

        } /* Multiple Message while() */

        proto_tree_add_item(mvrp_tree, hf_mvrp_end_mark, tvb, offset+2, 2, ENC_NA); /* Message EndMark */
    }
}
示例#29
0
/*
 * Dissect ASCII TPKT-encapsulated data in a TCP stream.
 */
void
dissect_asciitpkt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
          dissector_handle_t subdissector_handle)
{
    proto_item *ti = NULL;
    proto_tree *tpkt_tree = NULL;
    volatile int offset = 0;
    int length_remaining;
    int data_len;
    volatile int mgcp_packet_len = 0;
    int mgcp_version = 0;
    int mgcp_reserved = 0;
    volatile int length;
    tvbuff_t *volatile next_tvb;
    const char *saved_proto;
    guint8 string[4];

    /*
     * If we're reassembling segmented TPKT PDUs, empty the COL_INFO
     * column, so subdissectors can append information
     * without having to worry about emptying the column.
     *
     * We use "col_add_str()" because the subdissector
     * might be appending information to the column, in
     * which case we'd have to zero the buffer out explicitly
     * anyway.
     */
    if (tpkt_desegment)
        col_set_str(pinfo->cinfo, COL_INFO, "");

    while (tvb_reported_length_remaining(tvb, offset) != 0) {
        /*
         * Is the first byte of this putative TPKT header
         * a valid TPKT version number, i.e. 3?
         */
        if (tvb_get_guint8(tvb, offset) != 48) {
            /*
             * No, so don't assume this is a TPKT header;
             * we might be in the middle of TPKT data,
             * so don't get the length and don't try to
             * do reassembly.
             */
            col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
            col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
            if (tree) {
                ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                             offset, -1, ENC_NA);
                tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);

                proto_tree_add_item(tpkt_tree, hf_tpkt_continuation_data, tvb, offset, -1, ENC_NA);
            }
            return;
        }

        length_remaining = tvb_length_remaining(tvb, offset);

        /*
         * Get the length from the TPKT header.
         */

        tvb_memcpy(tvb, (guint8 *)string, offset, 2);
        mgcp_version = parseVersionText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset +2, 2);
        mgcp_reserved = parseReservedText(string);
        tvb_memcpy(tvb, (guint8 *)string, offset + 4, 4);
        mgcp_packet_len = parseLengthText(string);
        data_len = mgcp_packet_len;

        /*
         * Dissect the TPKT header.
         * Save and restore "pinfo->current_proto".
         */
        saved_proto = pinfo->current_proto;
        pinfo->current_proto = "TPKT";

        col_set_str(pinfo->cinfo, COL_PROTOCOL, "TPKT");
        /*
         * Don't add the TPKT header information if we're
         * reassembling segmented TPKT PDUs or if this
         * PDU isn't reassembled.
         *
         * XXX - the first is so that subdissectors can append
         * information without getting TPKT stuff in the middle;
         * why the second?
         */
        if (!tpkt_desegment && !pinfo->fragmented) {
            col_add_fstr(pinfo->cinfo, COL_INFO,
                     "TPKT Data length = %u", data_len);
        }

        if (tree) {
            ti = proto_tree_add_item(tree, proto_tpkt, tvb,
                         offset, 8, ENC_NA);
            tpkt_tree = proto_item_add_subtree(ti, ett_tpkt);
            proto_item_set_text(ti, "TPKT");

            /* Version */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_version, tvb,
                        offset, 2, mgcp_version);

            /* Reserved octet*/
            proto_tree_add_uint(tpkt_tree, hf_tpkt_reserved, tvb,
                        offset + 2, 2, mgcp_reserved);

            /* Length */
            proto_tree_add_uint(tpkt_tree, hf_tpkt_length, tvb,
                        offset + 4, 4, mgcp_packet_len);
        }
        pinfo->current_proto = saved_proto;

        /* Skip the TPKT header. */
        offset += TEXT_LAYER_LENGTH;
        length = length_remaining - TEXT_LAYER_LENGTH;
        if (length > data_len)
            length = data_len;

        next_tvb = tvb_new_subset(tvb, offset,length, data_len);

        /*
         * Call the subdissector.
         *
         * If it gets an error that means there's no point in
         * dissecting any more TPKT messages, rethrow the
         * exception in question.
         *
         * If it gets any other error, report it and continue, as that
         * means that TPKT message got an error, but that doesn't mean
         * we should stop dissecting TPKT messages within this frame
         * or chunk of reassembled data.
         */
        TRY {
            call_dissector(subdissector_handle, next_tvb, pinfo,
                       tree);
        }
        CATCH_NONFATAL_ERRORS {

            show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
        }
        ENDTRY;

        /*
         * Skip the payload.
         */
        offset += data_len;
    }
}
static void dissect_1722(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti = NULL;
    proto_tree *ieee1722_tree = NULL;
    proto_tree *audio_tree = NULL;
    proto_tree *sample_tree = NULL;
    gint offset = 0;
    guint16 datalen = 0;
    guint8 dbs = 0;
    guint8 subtype = 0;
    int i, j;

    col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE1722");

    col_set_str(pinfo->cinfo, COL_INFO, "AVB Transportation Protocol");

    if (tree) {
        ti = proto_tree_add_item(tree, proto_1722, tvb, 0, -1, FALSE);

        ieee1722_tree = proto_item_add_subtree(ti, ett_1722);

        /* Add the CD and Subtype fields 
         * CD field is 1 bit
         * Subtype field is 7 bits
         */
        proto_tree_add_item(ieee1722_tree, hf_1722_cdfield, tvb, IEEE_1722_CD_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_subtype, tvb, IEEE_1722_CD_OFFSET, 1, FALSE);
        
        proto_tree_add_item(ieee1722_tree, hf_1722_svfield, tvb, IEEE_1722_VERSION_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_verfield, tvb, IEEE_1722_VERSION_OFFSET, 1, FALSE);
        
        /* Version field ends the common AVTPDU. Now parse the specfic packet type */
        subtype = tvb_get_guint8(tvb, IEEE_1722_CD_OFFSET);
        subtype &= 0x7F;
        
        // fprintf(stderr, "subtype: %d\n", subtype);
        
        switch (subtype)
        {
            case 0x7A:
            {
                if (dissector_try_uint(avb_dissector_table, 0x7A, tvb, pinfo, tree))
                {
                    return;
                }
            }
            case 0x7B:
            {
                if (dissector_try_uint(avb_dissector_table, 0x7B, tvb, pinfo, tree))
                {
                    return;
                }
            }
            case 0x7C:
            {
                if (dissector_try_uint(avb_dissector_table, 0x7C, tvb, pinfo, tree))
                {
                    return;
                }
            }
            default:
                break;
        }
        
        proto_tree_add_item(ieee1722_tree, hf_1722_mrfield, tvb, IEEE_1722_VERSION_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_gvfield, tvb, IEEE_1722_VERSION_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_tvfield, tvb, IEEE_1722_VERSION_OFFSET, 1, FALSE);

        /* Add the rest of the packet fields */
        proto_tree_add_item(ieee1722_tree, hf_1722_seqnum, tvb,
                            IEEE_1722_SEQ_NUM_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_tufield, tvb,
                            IEEE_1722_TU_FIELD_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_stream_id, tvb, 
                            IEEE_1722_STREAM_ID_OFFSET, 8, FALSE);
                            

        proto_tree_add_item(ieee1722_tree, hf_1722_avbtp_timestamp, tvb,
                            IEEE_1722_TIMESTAMP_OFFSET, 4, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_gateway_info, tvb,
                            IEEE_1722_GW_INFO_OFFSET, 4, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_packet_data_length, tvb,
                            IEEE_1722_PKT_DATA_LENGTH_OFFSET, 2, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_tag, tvb,
                            IEEE_1722_TAG_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_channel, tvb, 
                            IEEE_1722_TAG_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_tcode, tvb, 
                            IEEE_1722_TCODE_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_sy, tvb,
                            IEEE_1722_TCODE_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_sid, tvb,
                            IEEE_1722_SID_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_dbs, tvb,
                            IEEE_1722_DBS_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_fn, tvb,
                            IEEE_1722_FN_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_qpc, tvb,
                            IEEE_1722_FN_OFFSET, 1, FALSE);
        proto_tree_add_item(ieee1722_tree, hf_1722_sph, tvb,
                            IEEE_1722_FN_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_dbc, tvb,
                            IEEE_1722_DBC_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_fmt, tvb,
                            IEEE_1722_FMT_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_fdf, tvb,
                            IEEE_1722_FDF_OFFSET, 1, FALSE);

        proto_tree_add_item(ieee1722_tree, hf_1722_syt, tvb,
                            IEEE_1722_SYT_OFFSET, 2, FALSE);

        /* Calculate the remaining size by subtracting the CIP header size 
           from the value in the packet data length field */
        datalen = tvb_get_ntohs(tvb, IEEE_1722_PKT_DATA_LENGTH_OFFSET);
        datalen -= IEEE_1722_CIP_HEADER_SIZE;

        /* Make the Audio sample tree. */
        ti = proto_tree_add_item(ieee1722_tree, hf_1722_data, tvb, 
                                 IEEE_1722_DATA_OFFSET, datalen, FALSE);

        audio_tree = proto_item_add_subtree(ti, ett_1722_audio);

        /* Need to get the offset of where the audio data starts */
        offset = IEEE_1722_DATA_OFFSET;
        dbs = tvb_get_guint8(tvb, IEEE_1722_DBS_OFFSET);

        /* If the DBS is ever 0 for whatever reason, then just add the rest of packet as unknown */
        if(dbs == 0)
            proto_tree_add_text(ieee1722_tree, tvb, IEEE_1722_DATA_OFFSET, datalen, "Incorrect DBS");

        else {
            /* Loop through all samples and add them to the audio tree. */
            for (j = 0; j < (datalen / (dbs*4)); j++) {
                ti = proto_tree_add_text(audio_tree, tvb, offset, 1, "Sample %d", j+1);
                sample_tree = proto_item_add_subtree(ti, ett_1722_sample);
                for (i = 0; i < dbs; i++) {
                    proto_tree_add_item(sample_tree, hf_1722_label, tvb, offset, 1, FALSE);
                    offset += 1;

                    proto_tree_add_item(sample_tree, hf_1722_sample, tvb, offset, 3, FALSE);
                    offset += 3;
                }
            }
        }
    }
}