Ejemplo n.º 1
0
static void
dissect_who(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	int		offset = 0;
	proto_tree	*who_tree = NULL;
	proto_item	*who_ti = NULL;
	guint8		*server_name;
	double		loadav_5 = 0.0, loadav_10 = 0.0, loadav_15 = 0.0;
	nstime_t	ts;

	/* Summary information */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "WHO");
	col_clear(pinfo->cinfo, COL_INFO);

	ts.nsecs = 0;

	if (tree) {
		who_ti = proto_tree_add_item(tree, proto_who, tvb, offset, -1,
		    ENC_NA);
		who_tree = proto_item_add_subtree(who_ti, ett_who);
	}

	if (tree)
		proto_tree_add_item(who_tree, hf_who_vers, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	if (tree)
		proto_tree_add_item(who_tree, hf_who_type, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	/* 2 filler bytes */
	offset += 2;

	if (tree) {
		ts.secs = tvb_get_ntohl(tvb, offset);
		proto_tree_add_time(who_tree, hf_who_sendtime, tvb, offset, 4,
		    &ts);
	}
	offset += 4;

	if (tree) {
		ts.secs = tvb_get_ntohl(tvb, offset);
		proto_tree_add_time(who_tree, hf_who_recvtime, tvb, offset, 4,
		    &ts);
	}
	offset += 4;

	server_name = tvb_get_stringzpad(wmem_packet_scope(), tvb, offset, 32, ENC_ASCII|ENC_NA);
	if (tree)
		proto_tree_add_string(who_tree, hf_who_hostname, tvb, offset,
		    32, server_name);
	offset += 32;

	loadav_5  = (double) tvb_get_ntohl(tvb, offset) / 100.0;
	if (tree)
		proto_tree_add_double(who_tree, hf_who_loadav_5, tvb, offset,
		    4, loadav_5);
	offset += 4;

	loadav_10 = (double) tvb_get_ntohl(tvb, offset) / 100.0;
	if (tree)
		proto_tree_add_double(who_tree, hf_who_loadav_10, tvb, offset,
		    4, loadav_10);
	offset += 4;

	loadav_15 = (double) tvb_get_ntohl(tvb, offset) / 100.0;
	if (tree)
		proto_tree_add_double(who_tree, hf_who_loadav_15, tvb, offset,
		    4, loadav_15);
	offset += 4;

	/* Summary information */
	col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %.02f %.02f %.02f",
				server_name, loadav_5, loadav_10, loadav_15);

	if (tree) {
		ts.secs = tvb_get_ntohl(tvb, offset);
		proto_tree_add_time(who_tree, hf_who_boottime, tvb, offset, 4,
		    &ts);
		offset += 4;

		dissect_whoent(tvb, offset, who_tree);
	}
}
Ejemplo n.º 2
0
static void dissect_cimd_dcs(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
{
  /* Set up structures needed to add the param subtree and manage it */
  proto_item *param_item;
  proto_tree *param_tree;
  gint        offset;
  guint       dcs;
  guint       dcs_cg;           /* coding group */
  guint       dcs_cf;           /* compressed flag */
  guint       dcs_mcm;          /* message class meaning flag */
  guint       dcs_chs;          /* character set */
  guint       dcs_mc;           /* message class */
  guint       dcs_is;           /* indication sense */
  guint       dcs_it;           /* indication type */

  gchar* bigbuf = (gchar*)ep_alloc(1024);

  param_item = proto_tree_add_text(tree, tvb,
    startOffset + 1, endOffset - (startOffset + 1),
    "%s", cimd_vals_PC[pindex].strptr
  );
  param_tree = proto_item_add_subtree(param_item, (*vals_hdr_PC[pindex].ett_p));
  proto_tree_add_string(param_tree, hf_cimd_pcode_indicator, tvb,
    startOffset + 1, CIMD_PC_LENGTH,
    tvb_format_text(tvb, startOffset + 1, CIMD_PC_LENGTH)
  );

  offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
  dcs    = decimal_int_value(tvb, offset, endOffset - offset);
  proto_tree_add_uint(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, offset, endOffset - offset, dcs);

  dcs_cg = (dcs & 0xF0) >> 4;
  other_decode_bitfield_value(bigbuf, dcs, (dcs_cg <= 0x07 ? 0xC0 : 0xF0), 8);
  proto_tree_add_uint_format(param_tree, hf_cimd_dcs_coding_group_indicator, tvb, offset, 1,
    dcs_cg, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_coding_group_indicator)->name,
    val_to_str(dcs_cg, cimd_dcs_coding_groups, "Unknown (%d)"), dcs_cg
  );

  if (dcs_cg <= 0x07)
  {
    dcs_cf = (dcs & 0x20) >> 5;
    other_decode_bitfield_value(bigbuf, dcs, 0x20, 8);
    proto_tree_add_uint_format(param_tree, hf_cimd_dcs_compressed_indicator, tvb, offset, 1,
      dcs_cf, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_compressed_indicator)->name,
      val_to_str(dcs_cf, cimd_dcs_compressed, "Unknown (%d)"), dcs_cf
    );

    dcs_mcm = (dcs & 0x10) >> 4;
    other_decode_bitfield_value(bigbuf, dcs, 0x10, 8);
    proto_tree_add_uint_format(param_tree, hf_cimd_dcs_message_class_meaning_indicator, tvb, offset, 1,
      dcs_mcm, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_message_class_meaning_indicator)->name,
      val_to_str(dcs_mcm, cimd_dcs_message_class_meaning, "Unknown (%d)"), dcs_mcm
    );

    dcs_chs = (dcs & 0x0C) >> 2;
    other_decode_bitfield_value(bigbuf, dcs, 0x0C, 8);
    proto_tree_add_uint_format(param_tree, hf_cimd_dcs_character_set_indicator, tvb, offset, 1,
      dcs_chs, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_character_set_indicator)->name,
      val_to_str(dcs_chs, cimd_dcs_character_set, "Unknown (%d)"), dcs_chs
    );

    if (dcs_mcm)
    {
      dcs_mc = (dcs & 0x03);
      other_decode_bitfield_value(bigbuf, dcs, 0x03, 8);
      proto_tree_add_uint_format(param_tree, hf_cimd_dcs_message_class_indicator, tvb, offset, 1,
        dcs_mc, "%s = %s: %s (%d)", bigbuf, proto_registrar_get_nth(hf_cimd_dcs_message_class_indicator)->name,
        val_to_str(dcs_mc, cimd_dcs_message_class, "Unknown (%d)"), dcs_mc
      );
    }
  }
Ejemplo n.º 3
0
/* note that even if ajp13_tree is null on the first pass, we still
 * need to dissect the packet in order to determine if there is a
 * content-length, and thus if there is a subsequent automatic
 * request-body transmitted in the next request packet. if there is a
 * content-length, we record the fact in the conversation context.
 * ref the top of this file for comments explaining the multi-pass
 * thing.
*/
static void
display_req_forward(tvbuff_t *tvb, packet_info *pinfo,
                    proto_tree *ajp13_tree,
                    ajp13_conv_data* cd)
{
  int pos = 0;
  guint8 meth;
  guint8 cod;
  const gchar *ver;
  guint16 ver_len;
  const gchar *uri;
  guint16 uri_len;
  const gchar *raddr;
  guint16 raddr_len;
  const gchar *rhost;
  guint16 rhost_len;
  const gchar *srv;
  guint16 srv_len;
  guint nhdr;
  guint i;

  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, ENC_NA);
  pos+=2;

  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_len, tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;

  /* PACKET CODE
   */
  cod = tvb_get_guint8(tvb, 4);
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_code, tvb, pos, 1, ENC_BIG_ENDIAN);
  pos+=1;
  if ( cod == MTYPE_CPING ) {
    col_append_str(pinfo->cinfo, COL_INFO, "CPING" );
    return;
  }

  /* HTTP METHOD (ENCODED AS INTEGER)
   */
  meth = tvb_get_guint8(tvb, pos);
  col_append_str(pinfo->cinfo, COL_INFO, val_to_str(meth, http_method_codes, "Unknown method %u"));
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_method, tvb, pos, 1, ENC_BIG_ENDIAN);
  pos+=1;

  /* HTTP VERSION STRING
   */
  ver = ajp13_get_nstring(tvb, pos, &ver_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_ver, tvb, pos, ver_len+2, ver);
  pos=pos+ver_len+2;  /* skip over size + chars + trailing null */

  /* URI
   */
  uri = ajp13_get_nstring(tvb, pos, &uri_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_uri, tvb, pos, uri_len+2, uri);
  pos=pos+uri_len+2;  /* skip over size + chars + trailing null */


  col_append_fstr(pinfo->cinfo, COL_INFO, " %s %s", uri, ver);


  /* REMOTE ADDRESS
   */
  raddr = ajp13_get_nstring(tvb, pos, &raddr_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_raddr, tvb, pos, raddr_len+2, raddr);
  pos=pos+raddr_len+2;  /* skip over size + chars + trailing null */

  /* REMOTE HOST
   */
  rhost = ajp13_get_nstring(tvb, pos, &rhost_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_rhost, tvb, pos, rhost_len+2, rhost);
  pos=pos+rhost_len+2;  /* skip over size + chars + trailing null */

  /* SERVER NAME
   */
  srv = ajp13_get_nstring(tvb, pos, &srv_len);
  if (ajp13_tree)
    proto_tree_add_string(ajp13_tree, hf_ajp13_srv, tvb, pos, srv_len+2, srv);
  pos=pos+srv_len+2;  /* skip over size + chars + trailing null */

  /* SERVER PORT
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_port, tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;

  /* IS SSL?
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_sslp, tvb, pos, 1, ENC_NA);
  pos+=1;

  /* NUM HEADERS
   */
  nhdr = tvb_get_ntohs(tvb, pos);

  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;
  cd->content_length = 0;

  /* HEADERS
   */
  for(i=0; i<nhdr; i++) {

    guint8 hcd;
    guint8 hid;
    const gchar* hname = NULL;
    int hpos = pos;
    int cl = 0;
    const gchar *hval;
    guint16 hval_len, hname_len;

    /* HEADER CODE/NAME
     */
    hcd = tvb_get_guint8(tvb, pos);

    if (hcd == 0xA0) {
      pos+=1;
      hid = tvb_get_guint8(tvb, pos);
      pos+=1;

      if (hid >= array_length(req_headers))
        hid = 0;

      hval = ajp13_get_nstring(tvb, pos, &hval_len);

      proto_tree_add_string_format(ajp13_tree, *req_headers[hid],
                                     tvb, hpos, 2+hval_len+2, hval,
                                     "%s", hval);
      pos+=hval_len+2;

      if (hid == 0x08)
        cl = 1;
    } else {
      hname = ajp13_get_nstring(tvb, pos, &hname_len);
      pos+=hname_len+2;

      hval = ajp13_get_nstring(tvb, pos, &hval_len);

      proto_tree_add_string_format(ajp13_tree, hf_ajp13_additional_header,
                                     tvb, hpos, hname_len+2+hval_len+2,
                                     wmem_strdup_printf(wmem_packet_scope(), "%s: %s", hname, hval),
                                     "%s: %s", hname, hval);
      pos+=hval_len+2;
    }

    if (cl) {
      cl = atoi(hval);
      cd->content_length = cl;
    }
  }

  /* ATTRIBUTES
   */
  while(tvb_reported_length_remaining(tvb, pos) > 0) {
    guint8 aid;
    const gchar* aname = NULL;
    const gchar* aval;
    guint16 aval_len, aname_len;

    int apos = pos;

    /* ATTRIBUTE CODE/NAME
     */
    aid = tvb_get_guint8(tvb, pos);
    pos+=1;

    if (aid == 0xFF) {
      /* request terminator */
      break;
    }
    if (aid == 0x0A) {
      /* req_attribute - name and value follow */

      aname = ajp13_get_nstring(tvb, pos, &aname_len);
      pos+=aname_len+2;

      aval = ajp13_get_nstring(tvb, pos, &aval_len);
      pos+=aval_len+2;

      proto_tree_add_string_format(ajp13_tree, hf_ajp13_req_attribute,
                                     tvb, apos, 1+aname_len+2+aval_len+2,
                                     wmem_strdup_printf(wmem_packet_scope(), "%s: %s", aname, aval),
                                     "%s: %s", aname, aval);
    } else if (aid == 0x0B ) {
      /* ssl_key_length */
      if (ajp13_tree) {
        proto_tree_add_uint(ajp13_tree, hf_ajp13_ssl_key_size,
                            tvb, apos, 1+2, tvb_get_ntohs(tvb, pos));
      }
      pos+=2;
    } else {

      if (aid >= array_length(req_attributes))
        aid = 0;

      aval = ajp13_get_nstring(tvb, pos, &aval_len);
      pos+=aval_len+2;

      proto_tree_add_string_format(ajp13_tree, *req_attributes[aid],
                                     tvb, apos, 1+aval_len+2, aval,
                                     "%s", aval);
    }
  }
}
Ejemplo n.º 4
0
static void
dissect_gift(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_item	*ti, *hidden_item;
	proto_tree	*gift_tree, *cmd_tree;
	gboolean	is_request;
	gint            offset = 0;
	const guchar    *line;
	gint            next_offset;
	int             linelen;
	int             tokenlen;
	const guchar    *next_token;

	/* set "Protocol" column text */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "giFT");

	/* determine whether it is a request to or response from the server */
	if (pinfo->match_uint == pinfo->destport)
		is_request = TRUE;
	else
		is_request = FALSE;

	linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
	line = tvb_get_ptr(tvb, offset, linelen);

	/* set "Info" column text */
	col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s",
			     is_request ? "Request" : "Response",
			     format_text(line, linelen));

	/* if tree != NULL, build protocol tree */
	if (tree) {
		ti = proto_tree_add_item(tree, proto_gift, tvb, 0, -1, ENC_NA);
		gift_tree = proto_item_add_subtree(ti, ett_gift);

		if (is_request) {
			hidden_item = proto_tree_add_boolean(gift_tree, hf_gift_request, tvb, 0, 0, TRUE);
		} else {
			hidden_item = proto_tree_add_boolean(gift_tree, hf_gift_response, tvb, 0, 0, TRUE);
		}
		PROTO_ITEM_SET_HIDDEN(hidden_item);

		ti = proto_tree_add_format_text(gift_tree, tvb, offset, next_offset - offset);
		cmd_tree = proto_item_add_subtree(ti, ett_gift_cmd);

		tokenlen = get_token_len(line, line + linelen, &next_token);
		if (tokenlen != 0) {
			if (is_request) {
				proto_tree_add_string(cmd_tree, hf_gift_request_cmd, tvb, offset,
						    tokenlen, format_text(line, tokenlen));
			} else {
				proto_tree_add_string(cmd_tree, hf_gift_response_cmd, tvb, offset,
						    tokenlen, format_text(line, tokenlen));
			}
			offset += (gint) (next_token - line);
			linelen -= (int) (next_token - line);
			line = next_token;
		}

		if (linelen != 0) {
			if (is_request) {
				proto_tree_add_string(cmd_tree, hf_gift_request_arg, tvb, offset,
						    linelen, format_text(line, linelen));
			} else {
				proto_tree_add_string(cmd_tree, hf_gift_response_arg, tvb, offset,
						    linelen, format_text(line, linelen));
			}
		}
	}
}
Ejemplo n.º 5
0
static void
dissect_ppi_gps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
    /* These are locals used for processing the current tvb */
    guint length;
    gint  length_remaining;
    int offset = 0;

    proto_tree *ppi_gps_tree = NULL;
    proto_tree *my_pt, *gpsflags_flags_tree = NULL; /* used for DeviceType bitmask stuff */

    proto_item *ti = NULL, *pt;
    proto_item *gps_line = NULL;

    static const int * ppi_gps_present_flags[] = {
        &hf_ppi_gps_present_gpsflags_flags,
        &hf_ppi_gps_present_lat,
        &hf_ppi_gps_present_lon,
        &hf_ppi_gps_present_alt,
        &hf_ppi_gps_present_alt_gnd,
        &hf_ppi_gps_present_gpstime,
        &hf_ppi_gps_present_fractime,
        &hf_ppi_gps_present_eph,
        &hf_ppi_gps_present_epv,
        &hf_ppi_gps_present_ept,
        &hf_ppi_gps_present_descr,
        &hf_ppi_gps_present_appspecific_num,
        &hf_ppi_gps_present_appspecific_data,
        &hf_ppi_gps_present_ext,
        NULL
    };

    /* bits */
    int bit;
    guint32 present, next_present;
    /* values actually read out, for displaying */
    guint32 version, gpsflags_flags;
    gdouble lat, lon, alt, alt_gnd;
    nstime_t gps_timestamp;
    int gps_time_size, already_processed_fractime; /* we use this internally to track if this is a 4 or 8 byte wide timestamp */
    gdouble eph, epv, ept;
    gchar *curr_str;


    /* these are temporary intermediate values, used in the individual cases below */
    guint32 t_lat, t_lon, t_alt, t_alt_gnd;
    guint32 t_herr, t_verr, t_terr;
    guint32 t_appspecific_num;
    /* initialize the timestamp value(s) */
    gps_timestamp.secs = gps_timestamp.nsecs = already_processed_fractime = 0;

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

    /* pull out the first three fields of the BASE-GEOTAG-HEADER */
    version = tvb_get_guint8(tvb, offset);
    length  = tvb_get_letohs(tvb, offset+2);
    present = tvb_get_letohl(tvb, offset+4);

    /* Setup basic column info */
    col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_GPS Capture v%u, Length %u", version, length);

    /* Create the basic dissection tree*/
    if (tree) {
        ti = proto_tree_add_protocol_format(tree, proto_ppi_gps, tvb, 0, length, "GPS:");
        gps_line = ti; /*we will make this more useful if we hit lon/lat later */
        ppi_gps_tree= proto_item_add_subtree(ti, ett_ppi_gps);
        proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_version, tvb, offset, 1, version);
        proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_pad, tvb, offset + 1, 1, ENC_NA);
        ti = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_length, tvb, offset + 2, 2, length);
    }

    /* We support v1 and v2 of GPS tags (identical) */
    if (! (version == 1 || version == 2) ) {
        if (tree)
            proto_item_append_text(ti, "invalid version (got %d,  expected 1 or 2)", version);
        return;
    }

    /* initialize the length of the actual tag contents */
    length_remaining = length;
    /* minimum length check, should atleast be a fixed-size geotagging-base header*/
    if (length_remaining < PPI_GEOBASE_MIN_HEADER_LEN) {
        /*
         * Base-geotag-header (Radiotap lookalike) is shorter than the fixed-length portion
         * plus one "present" bitset.
         */
        if (tree)
            proto_item_append_text(ti, " (invalid - minimum length is 8)");
        return;
    }

    /* perform tag-specific max length sanity checking */
    if (length > PPI_GPS_MAXTAGLEN ) {
        if (tree)
            proto_item_append_text(ti, "Invalid PPI-GPS length  (got %d, %d max\n)", length, PPI_GPS_MAXTAGLEN);
        return;
    }

    /* Subtree for the "present flags" bitfield. */
    pt = proto_tree_add_bitmask(ppi_gps_tree, tvb, offset + 4, hf_ppi_gps_present, ett_ppi_gps_present, ppi_gps_present_flags, ENC_LITTLE_ENDIAN);

    offset += PPI_GEOBASE_MIN_HEADER_LEN;
    length_remaining -= PPI_GEOBASE_MIN_HEADER_LEN;

    /* The fixed BASE-GEOTAG-HEADER has been handled at this point. move on to the individual fields */
    for (; present; present = next_present) {
        /* clear the least significant bit that is set */
        next_present = present & (present - 1);
        /* extract the least significant bit that is set */
        bit = BITNO_32(present ^ next_present);
        switch (bit) {
        case PPI_GEOTAG_GPSFLAGS:
            if (length_remaining < 4)
                break;
            gpsflags_flags =   tvb_get_letohl(tvb, offset); /* retrieve 32-bit gpsflags bitmask (-not- present bitmask) */
            if (tree) {
                /* first we add the hex flags line */
                my_pt = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_gpsflags_flags, tvb, offset , 4, gpsflags_flags);
                /* then we add a subtree */
                gpsflags_flags_tree = proto_item_add_subtree(my_pt, ett_ppi_gps_gpsflags_flags);
                /* to pin the individual bits on */
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag0_nofix, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag1_gpsfix, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag2_diffgps, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag3_PPS, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag4_RTK, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag5_floatRTK, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag6_dead_reck, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag7_manual, tvb, offset, 4, ENC_LITTLE_ENDIAN);
                proto_tree_add_item(gpsflags_flags_tree, hf_ppi_gps_gpsflags_flag8_sim, tvb, offset, 4, ENC_LITTLE_ENDIAN);
            }
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_LAT:
            if (length_remaining < 4)
                break;
            t_lat = tvb_get_letohl(tvb, offset);
            lat =  ppi_fixed3_7_to_gdouble(t_lat);
            if (tree)
            {
                proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lat, tvb, offset, 4, lat);
                proto_item_append_text(gps_line, " Lat:%f ", lat);
            }
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_LON:
            if (length_remaining < 4)
                break;
            t_lon = tvb_get_letohl(tvb, offset);
            lon =  ppi_fixed3_7_to_gdouble(t_lon);
            if (tree)
            {
                proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_lon, tvb, offset, 4, lon);
                proto_item_append_text(gps_line, " Lon:%f ", lon);
            }
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_ALT:
            if (length_remaining < 4)
                break;
            t_alt = tvb_get_letohl(tvb, offset);
            alt = ppi_fixed6_4_to_gdouble(t_alt);
            if (tree)
            {
                proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt, tvb, offset, 4, alt);
                proto_item_append_text(gps_line, " Alt:%f ", alt);
            }
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_ALT_G:
            if (length_remaining < 4)
                break;
            t_alt_gnd = tvb_get_letohl(tvb, offset);
            alt_gnd = ppi_fixed6_4_to_gdouble(t_alt_gnd);
            if (tree)
            {
                proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_alt_gnd, tvb, offset, 4, alt_gnd);
                proto_item_append_text(gps_line, " Alt_g:%f ", alt_gnd);
            }
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_GPSTIME:
            if (length_remaining < 4)
                break;
            gps_timestamp.secs =    tvb_get_letohl(tvb, offset);
            gps_timestamp.nsecs = 0;
            gps_time_size = 4;
            /* This is somewhat tricky, inside the GPSTIME case we test if the optional fractional time */
            /* is present. If so, we pull it out, and combine it with GPSTime. */
            /* If we do this, we set already_processed_fractime to avoid hitting it below */
            if (length_remaining < 4 && (present & PPI_GPS_MASK_FRACTIME))
                break;
            else if (present & PPI_GPS_MASK_FRACTIME) {
                gps_timestamp.nsecs =  tvb_get_letohl(tvb, offset + 4); /* manually offset seconds */
                already_processed_fractime = 1;
                gps_time_size = 8;
            }
            proto_tree_add_time(ppi_gps_tree, hf_ppi_gps_gpstime, tvb, offset, gps_time_size, &gps_timestamp);
            offset += gps_time_size;
            length_remaining -= gps_time_size;
            break;
        case  PPI_GEOTAG_FRACTIONALTIME:
            if (length_remaining < 4)
                break;
            if (already_processed_fractime)
                break;
            break;
        case  PPI_GEOTAG_EPH:
            if (length_remaining < 4)
                break;
            t_herr = tvb_get_letohl(tvb, offset);
            eph  =  ppi_fixed3_6_to_gdouble(t_herr);
            proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_eph, tvb, offset, 4, eph);
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_EPV:
            if (length_remaining < 4)
                break;
            t_verr = tvb_get_letohl(tvb, offset);
            epv  =  ppi_fixed3_6_to_gdouble(t_verr);
            proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_epv, tvb, offset, 4, epv);
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_EPT:
            if (length_remaining < 4)
                break;
            t_terr = tvb_get_letohl(tvb, offset);
            ept  =  ppi_ns_counter_to_gdouble(t_terr);
            proto_tree_add_double(ppi_gps_tree, hf_ppi_gps_ept, tvb, offset, 4, ept);
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_DESCRIPTIONSTR:
            if (length_remaining < 32)
                break;
            if (tree)
            {
                /* proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32,  ENC_ASCII|ENC_NA); */
                curr_str = tvb_format_stringzpad(tvb, offset, 32); /* need to append_text this */
                proto_tree_add_string(ppi_gps_tree, hf_ppi_gps_descstr, tvb, offset, 32, curr_str);
                proto_item_append_text(gps_line, " (%s)", curr_str);
            }
            offset+=32;
            length_remaining-=32;
            break;
        case  PPI_GEOTAG_APPID:
            if (length_remaining < 4)
                break;
            t_appspecific_num  = tvb_get_letohl(tvb, offset); /* application specific parsers may switch on this later */
            proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_appspecific_num, tvb, offset, 4, t_appspecific_num);
            offset+=4;
            length_remaining-=4;
            break;
        case  PPI_GEOTAG_APPDATA:
            if (length_remaining < 60)
                break;
            proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_appspecific_data, tvb, offset, 60,  ENC_NA);
            offset+=60;
            length_remaining-=60;
            break;

            /*
             * This indicates a field whose size we do not know, so we cannot proceed.
             */
        default:
            next_present = 0; /* this will terminate the loop */
            expert_add_info_format(pinfo, pt, &ei_ppi_gps_present_bit,
                 "Error: PPI-GEOLOCATION-GPS: unknown bit (%d) set in present field.", bit);
            continue;
        } /* switch (bit) */

    } /* (for present..)*/

    /* If there was any post processing of the elements, it could happen here. */
    return;
}
Ejemplo n.º 6
0
static void
expert_set_info_vformat(packet_info *pinfo, proto_item *pi, int group, int severity, int hf_index, gboolean use_vaformat,
			const char *format, va_list ap)
{
	char           formatted[ITEM_LABEL_LENGTH];
	int            tap;
	expert_info_t *ei;
	proto_tree    *tree;
	proto_item    *ti;

	if (pinfo == NULL && pi && pi->tree_data) {
		pinfo = PTREE_DATA(pi)->pinfo;
	}

	/* if this packet isn't loaded because of a read filter, don't output anything */
	if (pinfo == NULL || pinfo->num == 0) {
		return;
	}

	if (severity > highest_severity) {
		highest_severity = severity;
	}

	/* XXX: can we get rid of these checks and make them programming errors instead now? */
	if (pi != NULL && PITEM_FINFO(pi) != NULL) {
		expert_set_item_flags(pi, group, severity);
	}

	if ((pi == NULL) || (PITEM_FINFO(pi) == NULL) ||
		((guint)severity >= FI_GET_FLAG(PITEM_FINFO(pi), PI_SEVERITY_MASK))) {
		col_add_str(pinfo->cinfo, COL_EXPERT, val_to_str(severity, expert_severity_vals, "Unknown (%u)"));
	}

	if (use_vaformat) {
		ws_vsnprintf(formatted, ITEM_LABEL_LENGTH, format, ap);
	} else {
		g_strlcpy(formatted, format, ITEM_LABEL_LENGTH);
	}

	tree = expert_create_tree(pi, group, severity, formatted);

	if (hf_index == -1) {
		/* If no filterable expert info, just add the message */
		ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted);
		PROTO_ITEM_SET_GENERATED(ti);
	} else {
		/* If filterable expert info, hide the "generic" form of the message,
		   and generate the formatted filterable expert info */
		ti = proto_tree_add_none_format(tree, hf_index, NULL, 0, 0, "%s", formatted);
		PROTO_ITEM_SET_GENERATED(ti);
		ti = proto_tree_add_string(tree, hf_expert_msg, NULL, 0, 0, formatted);
		PROTO_ITEM_SET_HIDDEN(ti);
	}

	ti = proto_tree_add_uint_format_value(tree, hf_expert_severity, NULL, 0, 0, severity,
					      "%s", val_to_str_const(severity, expert_severity_vals, "Unknown"));
	PROTO_ITEM_SET_GENERATED(ti);
	ti = proto_tree_add_uint_format_value(tree, hf_expert_group, NULL, 0, 0, group,
					      "%s", val_to_str_const(group, expert_group_vals, "Unknown"));
	PROTO_ITEM_SET_GENERATED(ti);

	tap = have_tap_listener(expert_tap);

	if (!tap)
		return;

	ei = wmem_new(wmem_packet_scope(), expert_info_t);

	ei->packet_num  = pinfo->num;
	ei->group       = group;
	ei->severity    = severity;
	ei->hf_index    = hf_index;
	ei->protocol    = pinfo->current_proto;
	ei->summary     = wmem_strdup(wmem_packet_scope(), formatted);

	/* if we have a proto_item (not a faked item), set expert attributes to it */
	if (pi != NULL && PITEM_FINFO(pi) != NULL) {
		ei->pitem = pi;
	}
	/* XXX: remove this because we don't have an internal-only function now? */
	else {
		ei->pitem = NULL;
	}

	tap_queue_packet(expert_tap, pinfo, ei);
}
Ejemplo n.º 7
0
static gint
dissect_adb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
    proto_item      *main_item;
    proto_tree      *main_tree;
    proto_item      *arg0_item;
    proto_tree      *arg0_tree;
    proto_item      *arg1_item;
    proto_tree      *arg1_tree;
    proto_item      *magic_item;
    proto_item      *crc_item;
    proto_tree      *crc_tree = NULL;
    proto_item      *sub_item;
    gint             offset = 0;
    guint32          command;
    guint32          arg0;
    guint32          arg1;
    guint32          data_length = 0;
    guint32          crc32 = 0;
    usb_conv_info_t *usb_conv_info = NULL;
    wmem_tree_key_t  key[5];
    guint32          interface_id;
    guint32          bus_id;
    guint32          device_address;
    guint32          side_id;
    guint32          frame_number;
    gboolean         is_command = TRUE;
    gboolean         is_next_fragment = FALSE;
    gboolean         is_service = FALSE;
    gint             proto;
    gint             direction = P2P_DIR_UNKNOWN;
    wmem_tree_t     *wmem_tree;
    command_data_t  *command_data = NULL;
    service_data_t  *service_data = NULL;

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

    main_item = proto_tree_add_item(tree, proto_adb, tvb, offset, -1, ENC_NA);
    main_tree = proto_item_add_subtree(main_item, ett_adb);

    frame_number       = pinfo->fd->num;

    /* XXX: Why? If interface is USB only first try is correct
     * (and seems strange...), in other cases standard check for
     * previous protocol is correct */
    proto = (gint) GPOINTER_TO_INT(wmem_list_frame_data(/*wmem_list_frame_prev*/(wmem_list_tail(pinfo->layers))));
    if (proto != proto_usb) {
        proto = (gint) GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers))));
    }

    if (proto == proto_usb) {
        usb_conv_info = (usb_conv_info_t *) data;
        DISSECTOR_ASSERT(usb_conv_info);

        direction = usb_conv_info->direction;
    } else if (proto == proto_tcp) {
        if (pinfo->destport == ADB_TCP_PORT)
            direction = P2P_DIR_SENT;
        else
            direction = P2P_DIR_RECV;
    } else {
        return offset;
    }

    if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID)
        interface_id = pinfo->phdr->interface_id;
    else
        interface_id = 0;

    if (proto == proto_usb) {
        bus_id             = usb_conv_info->bus_id;
        device_address     = usb_conv_info->device_address;

        key[0].length = 1;
        key[0].key = &interface_id;
        key[1].length = 1;
        key[1].key = &bus_id;
        key[2].length = 1;
        key[2].key = &device_address;
        key[3].length = 0;
        key[3].key = NULL;
    } else { /* tcp */
        key[0].length = 1;
        key[0].key = &interface_id;
        key[1].length = 1;
        key[2].length = 1;
        if (direction == P2P_DIR_SENT) {
            key[1].key = &pinfo->srcport;
            key[2].key = &pinfo->destport;
        } else {
            key[1].key = &pinfo->destport;
            key[2].key = &pinfo->srcport;
        }
        key[3].length = 0;
        key[3].key = NULL;
    }

    wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(command_info, key);
    if (wmem_tree) {
        command_data = (command_data_t *) wmem_tree_lookup32_le(wmem_tree, frame_number);
        if (command_data && command_data->completed_in_frame >= frame_number &&
                command_data->command_in_frame <= frame_number) {

            if (command_data->command_in_frame != frame_number) {
                is_command = FALSE;
                is_next_fragment = TRUE;
            }

            data_length = command_data->data_length;
            crc32 = command_data->crc32;

            if (direction == P2P_DIR_SENT)
                if (command_data->command == A_CLSE)
                    side_id = command_data->arg1; /* OUT: local id */
                else
                    side_id = command_data->arg0; /* OUT: local id */
            else
                if (command_data->command == A_OKAY) {
                    side_id = command_data->arg1; /* IN: remote id */
                } else
                    side_id = command_data->arg1; /* IN: remote id */

            key[3].length = 1;
            key[3].key = &side_id;
            key[4].length = 0;
            key[4].key = NULL;

            wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(service_info, key);
            if (wmem_tree) {
                service_data = (service_data_t *) wmem_tree_lookup32_le(wmem_tree, frame_number);
                if (service_data && command_data->command == A_OPEN) {
                    is_service = TRUE;
                }
            }
        }
    }

/* Simple heuristics to check if packet is command or data */
    if ((command_data && command_data->completed_in_frame <= frame_number) || !command_data) {
        if (tvb_reported_length(tvb) < 24) {
            is_command = FALSE;
        } else if (tvb_reported_length(tvb) >= 24) {
            command = tvb_get_letohl(tvb, offset);

            if (command != A_SYNC && command != A_CLSE && command != A_WRTE &&
                    command != A_AUTH && command != A_CNXN && command != A_OPEN && command != A_OKAY)
                is_command = FALSE;
            else if (command != (0xFFFFFFFF ^ tvb_get_letohl(tvb, offset + 20)))
                is_command = FALSE;

            if (is_command) {
                data_length = tvb_get_letohl(tvb, offset + 12);
                crc32 = tvb_get_letohl(tvb, offset + 16);
            }
            if (command == A_OPEN) is_service = TRUE;
        }
    }

    if (service_data && !(command_data->command == A_OPEN && is_next_fragment)) {
        sub_item = proto_tree_add_string(main_tree, hf_service, tvb, offset, 0, service_data->service);
        PROTO_ITEM_SET_GENERATED(sub_item);
    }

    if (service_data) {
        sub_item = proto_tree_add_uint(main_tree, hf_service_start_in_frame, tvb, offset, 0, service_data->start_in_frame);
        PROTO_ITEM_SET_GENERATED(sub_item);

        if (service_data->close_local_in_frame < max_in_frame) {
            sub_item = proto_tree_add_uint(main_tree, hf_close_local_in_frame, tvb, offset, 0, service_data->close_local_in_frame);
            PROTO_ITEM_SET_GENERATED(sub_item);
        }

        if (service_data->close_remote_in_frame < max_in_frame) {
            sub_item = proto_tree_add_uint(main_tree, hf_close_remote_in_frame, tvb, offset, 0, service_data->close_remote_in_frame);
            PROTO_ITEM_SET_GENERATED(sub_item);
        }
    }

    if (is_command) {
        proto_tree_add_item(main_tree, hf_command, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        command = tvb_get_letohl(tvb, offset);
        offset += 4;

        col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(command, command_vals, "Unknown command"));

        arg0_item = proto_tree_add_item(main_tree, hf_argument_0, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        arg0_tree = proto_item_add_subtree(arg0_item, ett_adb_arg0);
        arg0 = tvb_get_letohl(tvb, offset);
        offset += 4;

        arg1_item = proto_tree_add_item(main_tree, hf_argument_1, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        arg1_tree = proto_item_add_subtree(arg1_item, ett_adb_arg1);
        arg1 = tvb_get_letohl(tvb, offset);
        offset += 4;

        switch (command) {
        case A_CNXN:
            proto_tree_add_item(arg0_tree, hf_version, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_max_data, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(version=%u.%u.%u, max_data=%u)", tvb_get_guint8(tvb, offset - 5), tvb_get_guint8(tvb, offset - 6), tvb_get_letohs(tvb, offset - 7), tvb_get_letohl(tvb, offset - 4));
            break;
        case A_AUTH:
            proto_tree_add_item(arg0_tree, hf_auth_type, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_zero, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(type=%s, 0)", val_to_str_const(tvb_get_letohl(tvb, offset - 8), auth_type_vals, "Unknown"));
            break;
        case A_OPEN:
            proto_tree_add_item(arg0_tree, hf_local_id, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_zero, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(local=%u, 0)", tvb_get_letohl(tvb, offset - 8));
            break;
        case A_WRTE:
            proto_tree_add_item(arg0_tree, hf_zero, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_remote_id, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(0, remote=%u)", tvb_get_letohl(tvb, offset - 4));
            break;
        case A_CLSE:
        case A_OKAY:
            proto_tree_add_item(arg0_tree, hf_local_id, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_remote_id, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(local=%u, remote=%u)", tvb_get_letohl(tvb, offset - 8), tvb_get_letohl(tvb, offset - 4));
            break;
        case A_SYNC:
            proto_tree_add_item(arg0_tree, hf_online, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN);
            proto_tree_add_item(arg1_tree, hf_sequence, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN);

            col_append_fstr(pinfo->cinfo, COL_INFO, "(online=%s, sequence=%u)", tvb_get_letohl(tvb, offset - 8) ? "Yes": "No", tvb_get_letohl(tvb, offset - 4));
            break;
        }

        proto_tree_add_item(main_tree, hf_data_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        offset += 4;

        if (data_length > 0)
            col_append_fstr(pinfo->cinfo, COL_INFO, " length=%u ", data_length);

        crc_item = proto_tree_add_item(main_tree, hf_data_crc32, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        crc_tree = proto_item_add_subtree(crc_item, ett_adb_crc);
        crc32 = tvb_get_letohl(tvb, offset);
        offset += 4;

        magic_item = proto_tree_add_item(main_tree, hf_magic, tvb, offset, 4, ENC_LITTLE_ENDIAN);
        if ((tvb_get_letohl(tvb, offset) ^ 0xFFFFFFFF) != command) {
            proto_tree  *expert_tree;

            expert_tree = proto_item_add_subtree(magic_item, ett_adb_magic);
            proto_tree_add_expert(expert_tree, pinfo, &ei_invalid_magic, tvb, offset, 4);
        }

        if (!pinfo->fd->flags.visited)
            save_command(command, arg0, arg1, data_length, crc32, service_data, proto, data, pinfo, &service_data, &command_data);
        offset += 4;
    }

    if (!pinfo->fd->flags.visited && command_data) {
            if (command_data->command_in_frame != frame_number) {
                is_command = FALSE;
                is_next_fragment = TRUE;
            }

            data_length = command_data->data_length;
            crc32 = command_data->crc32;

            if ((command_data->command_in_frame != frame_number && tvb_captured_length(tvb) == data_length) ||
                (command_data->command_in_frame == frame_number && tvb_captured_length(tvb) == data_length + 24)
            ) {
                command_data->reassemble_data_length = command_data->data_length;
                command_data->completed_in_frame = frame_number;
            }
    }

    if (is_next_fragment && command_data) {
        sub_item = proto_tree_add_uint(main_tree, hf_command_in_frame, tvb, offset, 0, command_data->command_in_frame);
        PROTO_ITEM_SET_GENERATED(sub_item);

        sub_item = proto_tree_add_uint(main_tree, hf_command, tvb, offset, 0, command_data->command);
        PROTO_ITEM_SET_GENERATED(sub_item);

        sub_item = proto_tree_add_uint(main_tree, hf_data_length, tvb, offset, 0, command_data->data_length);
        PROTO_ITEM_SET_GENERATED(sub_item);

        crc_item = proto_tree_add_uint(main_tree, hf_data_crc32, tvb, offset, 0, command_data->crc32);
        crc_tree = proto_item_add_subtree(crc_item, ett_adb_crc);
        PROTO_ITEM_SET_GENERATED(crc_item);
    }

    if (command_data && command_data->completed_in_frame != frame_number) {
        sub_item = proto_tree_add_uint(main_tree, hf_completed_in_frame, tvb, offset, 0, command_data->completed_in_frame);
        PROTO_ITEM_SET_GENERATED(sub_item);
    }


    if (tvb_captured_length_remaining(tvb, offset) > 0 && (!is_command || data_length > 0)) {
        guint32 crc = 0;
        guint32 i_offset;

        if ((!pinfo->fd->flags.visited && command_data && command_data->reassemble_data_length < command_data->data_length) || data_length > (guint32) tvb_captured_length_remaining(tvb, offset)) { /* need reassemble */
            if (!pinfo->fd->flags.visited && command_data && command_data->reassemble_data_length < command_data->data_length) {
                tvb_memcpy(tvb, command_data->reassemble_data + command_data->reassemble_data_length, offset, tvb_captured_length_remaining(tvb, offset));
                command_data->reassemble_data_length += tvb_captured_length_remaining(tvb, offset);

                if (command_data->reassemble_data_length >= command_data->data_length)
                    command_data->completed_in_frame = frame_number;
            }

            proto_tree_add_item(main_tree, hf_data_fragment, tvb, offset, -1, ENC_NA);
            col_append_str(pinfo->cinfo, COL_INFO, "Data Fragment");
            offset = tvb_captured_length(tvb);

            if (service_data && command_data && command_data->reassemble_data_length >= command_data->data_length && frame_number == command_data->completed_in_frame) {
                tvbuff_t            *next_tvb;
                adb_service_data_t   adb_service_data;

                next_tvb = tvb_new_child_real_data(tvb, command_data->reassemble_data, command_data->reassemble_data_length, command_data->reassemble_data_length);
                add_new_data_source(pinfo, next_tvb, "ADB Reassembled Data");

                adb_service_data.service = service_data->service;
                adb_service_data.direction = direction;

                adb_service_data.session_key_length = 3;
                adb_service_data.session_key = (guint32 *) wmem_alloc(wmem_packet_scope(), adb_service_data.session_key_length * sizeof(guint32));
                adb_service_data.session_key[0] = interface_id;

                if (proto == proto_usb) {
                    adb_service_data.session_key[1] = usb_conv_info->bus_id;
                    adb_service_data.session_key[2] = usb_conv_info->device_address;
                } else { /* tcp */
                    if (direction == P2P_DIR_SENT) {
                        adb_service_data.session_key[1] = pinfo->srcport;
                        adb_service_data.session_key[2] = pinfo->destport;
                    } else {
                        adb_service_data.session_key[1] = pinfo->destport;
                        adb_service_data.session_key[2] = pinfo->srcport;
                    }
                }

                call_dissector_with_data(adb_service_handle, next_tvb, pinfo, tree, &adb_service_data);
            }
        } else { /* full message */
            for (i_offset = 0; i_offset < data_length; ++i_offset)
                crc += tvb_get_guint8(tvb, offset + i_offset);

            if (crc32 > 0 && crc32 != crc)
                proto_tree_add_expert(crc_tree, pinfo, &ei_invalid_crc, tvb, offset, -1);

            if (is_service) {
                proto_tree_add_item(main_tree, hf_service, tvb, offset, -1, ENC_ASCII | ENC_NA);
                if (!pinfo->fd->flags.visited && service_data) {
                    service_data->service = tvb_get_stringz_enc(wmem_file_scope(), tvb, offset, NULL, ENC_ASCII);
                }
                col_append_fstr(pinfo->cinfo, COL_INFO, "Service: %s", tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, NULL, ENC_ASCII));
                offset = tvb_captured_length(tvb);
            } else if (command_data && command_data->command == A_CNXN) {
                    gchar       *info;
                    gint         len;

                info = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII);
                col_append_fstr(pinfo->cinfo, COL_INFO, "Connection Info: %s", info);
                proto_tree_add_item(main_tree, hf_connection_info, tvb, offset, len, ENC_ASCII | ENC_NA);
                offset += len;
            } else {
                col_append_str(pinfo->cinfo, COL_INFO, "Data");

                /* Decode service payload */
                if (service_data) {
                    tvbuff_t           *next_tvb;
                    adb_service_data_t  adb_service_data;

                    adb_service_data.service = service_data->service;
                    adb_service_data.direction = direction;

                    adb_service_data.session_key_length = 3;
                    adb_service_data.session_key = (guint32 *) wmem_alloc(wmem_packet_scope(), adb_service_data.session_key_length * sizeof(guint32));
                    adb_service_data.session_key[0] = interface_id;

                    if (proto == proto_usb) {
                        adb_service_data.session_key[1] = usb_conv_info->bus_id;
                        adb_service_data.session_key[2] = usb_conv_info->device_address;
                    } else { /* tcp */
                        if (direction == P2P_DIR_SENT) {
                            adb_service_data.session_key[1] = pinfo->srcport;
                            adb_service_data.session_key[2] = pinfo->destport;
                        } else {
                            adb_service_data.session_key[1] = pinfo->destport;
                            adb_service_data.session_key[2] = pinfo->srcport;
                        }
                    }

                    next_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb, offset), tvb_captured_length_remaining(tvb, offset));
                    call_dissector_with_data(adb_service_handle, next_tvb, pinfo, tree, &adb_service_data);

                } else {
                    proto_item  *data_item;
                    gchar       *data_str;

                    data_item = proto_tree_add_item(main_tree, hf_data, tvb, offset, data_length, ENC_NA);
                    data_str = tvb_format_text(tvb, offset, data_length);
                    proto_item_append_text(data_item, ": %s", data_str);
                    col_append_fstr(pinfo->cinfo, COL_INFO, " Raw: %s", data_str);
                }

                offset = tvb_captured_length(tvb);
            }
        }
    }

    return offset;
}
Ejemplo n.º 8
0
/* Code to actually dissect the packets */
static void
dissect_fcfzs_zoneset(tvbuff_t *tvb, proto_tree *tree, int offset)
{
    int numzones, nummbrs, i, j, len;

    /* The zoneset structure has the following format */
    /* zoneset name (len[not including pad], name, pad),
     * number of zones,
     * for each zone,
     *     Zone name (len[not including pad], name, pad), num zone mbrs
     *     for each zone mbr,
     *         zone mbr id type, zone mbr id (len, name, pad)
     */
    if (tree) {

        /* Zoneset Name */
        len = tvb_get_guint8(tvb, offset);
        proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset,
                            1, ENC_BIG_ENDIAN);
        proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4,
                            len, ENC_ASCII|ENC_NA);
        offset += 4 + len + (4-(len % 4));


        /* Number of zones */
        numzones = tvb_get_ntohl(tvb, offset);
        proto_tree_add_item(tree, hf_fcfzs_numzones, tvb, offset, 4, ENC_BIG_ENDIAN);
        offset += 4;

        /* For each zone... */
        for (i = 0; i < numzones; i++) {
            len = tvb_get_guint8(tvb, offset);
            proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset,
                                1, ENC_BIG_ENDIAN);
            proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+4,
                                len, ENC_ASCII|ENC_NA);
            offset += 4 + len + (4-(len % 4));

            nummbrs = tvb_get_ntohl(tvb, offset);
            proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset,
                                4, ENC_BIG_ENDIAN);

            offset += 4;
            for (j = 0; j < nummbrs; j++) {
                proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN);

                switch (tvb_get_guint8(tvb, offset)) {
                case FC_FZS_ZONEMBR_PWWN:
                case FC_FZS_ZONEMBR_NWWN:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 8,
                                          tvb_fcwwn_to_str(tvb, offset+4));
                    break;
                case FC_FZS_ZONEMBR_DP:
                    proto_tree_add_string_format(tree,
                                                 hf_fcfzs_mbrid,
                                                 tvb, offset+4, 3, " ",
                                                 "0x%x",
                                                 tvb_get_ntoh24(tvb,
                                                         offset+4));
                    break;
                case FC_FZS_ZONEMBR_FCID:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 4,
                                          tvb_fc_to_str(tvb, offset+4));
                    break;
                case FC_FZS_ZONEMBR_PWWN_LUN:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 8,
                                          tvb_fcwwn_to_str(tvb, offset+4));
                    proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
                                        offset+8, 8, ENC_NA);
                    break;
                case FC_FZS_ZONEMBR_DP_LUN:
                    proto_tree_add_string_format(tree,
                                                 hf_fcfzs_mbrid,
                                                 tvb, offset+4, 3, " ",
                                                 "0x%x",
                                                 tvb_get_ntoh24(tvb,
                                                         offset+4));
                    proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
                                        offset+4, 8, ENC_NA);
                    break;
                case FC_FZS_ZONEMBR_FCID_LUN:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 4,
                                          tvb_fc_to_str(tvb, offset+4));
                    proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb,
                                        offset+4, 8, ENC_NA);
                    break;
                default:
                    proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb,
                                          offset+4, 8,
                                          "Unknown member type format");
                }
                offset += 12;
            }
        }
    }
}
Ejemplo n.º 9
0
static void
client_display_socks_v5(tvbuff_t *tvb, int offset, packet_info *pinfo,
	proto_tree *tree, socks_hash_entry_t *hash_info, sock_state_t* state_info) {

/* Display the protocol tree for the version. This routine uses the	*/
/* stored conversation information to decide what to do with the row.	*/
/* Per packet information would have been better to do this, but we	*/
/* didn't have that when I wrote this. And I didn't expect this to get	*/
/* so messy.								*/

	unsigned int i;
	const char *AuthMethodStr;
	sock_state_t new_state_info;

	/* Either there is an error, or we're done with the state machine
	  (so there's nothing to display) */
	if (state_info == NULL)
		return;

	proto_tree_add_item( tree, hf_socks_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
	++offset;

	if (state_info->client == clientStart)
	{
		proto_tree      *AuthTree;
		proto_item      *ti;
		guint8 num_auth_methods, auth;

		ti = proto_tree_add_text( tree, tvb, offset, -1, "Client Authentication Methods");
		AuthTree = proto_item_add_subtree(ti, ett_socks_auth);

		num_auth_methods = tvb_get_guint8(tvb, offset);
		proto_item_set_len(ti, num_auth_methods+1);

		proto_tree_add_item( AuthTree, hf_client_auth_method_count, tvb, offset, 1, ENC_NA);
		++offset;

		for( i = 0; i  < num_auth_methods; ++i) {
			auth = tvb_get_guint8( tvb, offset);
			AuthMethodStr = get_auth_method_name(auth);

			proto_tree_add_uint_format(AuthTree, hf_client_auth_method, tvb, offset, 1, auth,
										"Method[%u]: %u (%s)", i, auth, AuthMethodStr);
			++offset;
		}

		if ((num_auth_methods == 1) &&
			(tvb_bytes_exist(tvb, offset + 2, 1)) &&
			(tvb_get_guint8(tvb, offset + 2) == 0) &&
			(tvb_reported_length_remaining(tvb, offset + 2 + num_auth_methods) > 0)) {
				new_state_info.client = clientV5Command;
				client_display_socks_v5(tvb, offset, pinfo, tree, hash_info, &new_state_info);
		}
	}
	else if (state_info->client == clientV5Command) {

		proto_tree_add_item( tree, hf_socks_cmd, tvb, offset, 1, ENC_NA);
		++offset;

		proto_tree_add_item( tree, hf_socks_reserved, tvb, offset, 1, ENC_NA);
		++offset;

		offset = display_address(tvb, offset, tree);
		proto_tree_add_item( tree, hf_client_port, tvb, offset, 2, ENC_BIG_ENDIAN);
	}
	else if ((state_info->client == clientWaitForAuthReply) &&
			 (state_info->server == serverInitReply)) {
		guint16 len;
		gchar* str;

		switch(hash_info->authentication_method)
		{
		case NO_AUTHENTICATION:
			break;
		case USER_NAME_AUTHENTICATION:
			/* process user name */
			len = tvb_get_guint8(tvb, offset);
			str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len);
			proto_tree_add_string(tree, hf_socks_username, tvb, offset, len+1, str);
			offset += (len+1);

			len = tvb_get_guint8(tvb, offset);
			str = tvb_get_string(wmem_packet_scope(), tvb, offset+1, len);
			proto_tree_add_string(tree, hf_socks_password, tvb, offset, len+1, str);
			/* offset += (len+1); */
			break;
		case GSS_API_AUTHENTICATION:
			proto_tree_add_item( tree, hf_gssapi_command, tvb, offset, 1, ENC_BIG_ENDIAN);
			proto_tree_add_item( tree, hf_gssapi_length, tvb, offset+1, 2, ENC_BIG_ENDIAN);
			len = tvb_get_ntohs(tvb, offset+1);
			if (len > 0)
				proto_tree_add_item( tree, hf_gssapi_payload, tvb, offset+3, len, ENC_NA);
			break;
		default:
			break;
		}
	}
}
Ejemplo n.º 10
0
void gcp_analyze_msg(proto_tree* gcp_tree, tvbuff_t* gcp_tvb, gcp_msg_t* m, gcp_hf_ett_t* ids) {
    gcp_trx_msg_t* t;
    gcp_ctxs_t contexts = {NULL,NULL};
    gcp_ctxs_t* ctx_node;
    gcp_cmd_msg_t* c;


    for (t = m->trxs; t; t = t->next) {
        for (c = t->trx->cmds; c; c = c->next) {
            gcp_ctx_t* ctx = c->cmd->ctx;

            for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) {
                if (ctx_node->ctx->id == ctx->id) {
                    break;
                }
            }

            if (! ctx_node) {
                ctx_node = ep_new(gcp_ctxs_t);
                ctx_node->ctx = ctx;
                ctx_node->next = contexts.next;
                contexts.next = ctx_node;
            }
        }
    }

    for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) {
        gcp_ctx_t* ctx = ctx_node->ctx;
        proto_item* ctx_item = proto_tree_add_uint(gcp_tree,ids->hf.ctx,gcp_tvb,0,0,ctx->id);
        proto_tree* ctx_tree = proto_item_add_subtree(ctx_item,ids->ett.ctx);
        gcp_terms_t *ctx_term;

        PROTO_ITEM_SET_GENERATED(ctx_item);

        if (ctx->cmds) {
            proto_item* history_item = proto_tree_add_text(ctx_tree,gcp_tvb,0,0,"[ Command History ]");
            proto_tree* history_tree = proto_item_add_subtree(history_item,ids->ett.ctx_cmds);

            for (c = ctx->cmds; c; c = c->next) {
                proto_item* cmd_item = proto_tree_add_uint(history_tree,ids->hf.ctx_cmd,gcp_tvb,0,0,c->cmd->msg->framenum);
                if (c->cmd->str) proto_item_append_text(cmd_item,"  %s ",c->cmd->str);
                PROTO_ITEM_SET_GENERATED(cmd_item);
                if (c->cmd->error) {
                    proto_item_set_expert_flags(cmd_item, PI_RESPONSE_CODE, PI_WARN);
                }
            }
        }

        if (( ctx_term = ctx->terms.next )) {
            proto_item* terms_item = proto_tree_add_text(ctx_tree,gcp_tvb,0,0,"[ Terminations Used ]");
            proto_tree* terms_tree = proto_item_add_subtree(terms_item,ids->ett.ctx_terms);

            for (; ctx_term; ctx_term = ctx_term->next ) {
                if ( ctx_term->term && ctx_term->term->str) {
                    proto_item* pi = proto_tree_add_string(terms_tree,ids->hf.ctx_term,gcp_tvb,0,0,ctx_term->term->str);
                    proto_tree* term_tree = proto_item_add_subtree(pi,ids->ett.ctx_term);

                    PROTO_ITEM_SET_GENERATED(pi);

                    if (ctx_term->term->type) {
                        pi = proto_tree_add_uint(term_tree,ids->hf.ctx_term_type,gcp_tvb,0,0,ctx_term->term->type);
                        PROTO_ITEM_SET_GENERATED(pi);
                    }

                    if (ctx_term->term->bir) {
                        pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_bir,gcp_tvb,0,0,ctx_term->term->bir);
                        PROTO_ITEM_SET_GENERATED(pi);
                    }

                    if (ctx_term->term->nsap) {
                        pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_nsap,gcp_tvb,0,0,ctx_term->term->nsap);
                        PROTO_ITEM_SET_GENERATED(pi);
                    }

                    if (ctx_term->term->bir && ctx_term->term->nsap) {
                        gchar* tmp_key = ep_strdup_printf("%s:%s",ctx_term->term->nsap,ctx_term->term->bir);
                        gchar* key = g_ascii_strdown(tmp_key, -1);
                        alcap_tree_from_bearer_key(term_tree, gcp_tvb, key);
                        g_free(key);
                    }
                }
            }
        }
    }
}
Ejemplo n.º 11
0
static void
xmpp_bytestreams_activate(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, xmpp_element_t *element)
{
    proto_tree_add_string(tree, hf_xmpp_query_activate, tvb, element->offset, element->length, xmpp_elem_cdata(element));
    xmpp_unknown(tree, tvb, pinfo, element);
}
Ejemplo n.º 12
0
/*
 * This function dissects an "Ice context", adds hf(s) to "tree" and returns consumed
 * bytes in "*consumed", if errors "*consumed" is -1.
 */
static void dissect_ice_context(packet_info *pinfo, proto_tree *tree, proto_item *item, 
								tvbuff_t *tvb, guint32 offset, gint32 *consumed)
{
	/*  p. 588, chapter 23.2.7 and p. 613, 23.3.2:
	 *  "context" is a dictionary<string, string>
	 *
	 * dictionary<string, string> == Size + SizeKeyValuePairs
	 * dictionary<string, string> = 1byte (0..254) + SizeKeyValuePairs
	 * or
	 * dictionary<string, string>= 1byte (255) + 1int (255..2^32-1)+SizeKeyValuePairs
	 *
	 */

	guint32 Size = 0; /* number of key-value in the dictionary */
	guint32 i = 0;
	const char *s = NULL;

	(*consumed) = 0;

	/* check first byte */
	if ( !tvb_bytes_exist(tvb, offset, 1) ) {

		if (item)
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "context missing");

		col_append_str(mypinfo->cinfo, COL_INFO,
				       " (context missing)");

		(*consumed) = -1;
		return;
	}

	/* get first byte of Size */
	Size = tvb_get_guint8(tvb, offset);
	offset++;
	(*consumed)++;

	if ( Size == 255 ) {

		/* check for next 4 bytes */
		if ( !tvb_bytes_exist(tvb, offset, 4) ) {

			if (item)
				expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "second field of Size missing");

			col_append_str(mypinfo->cinfo, COL_INFO, " (second field of Size missing)");

			(*consumed) = -1;
			return;
		}

		/* get second field of Size */
		Size = tvb_get_letohl(tvb, offset);
		offset += 4;
		(*consumed) += 4;
	}

	DBG1("context.Size --> %d\n", Size);

	if ( Size > icep_max_ice_context_pairs ) {

		if (item)
			/* display the XX Size byte when click here */
			expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "too long context");

		col_append_str(mypinfo->cinfo, COL_INFO, " (too long context)");

		(*consumed) = -1;
		return;
	}

	if (Size == 0) {
		s = "(empty)";
		/* display the 0x00 Size byte when click on a empty context */
		if (tree)
			proto_tree_add_string(tree, hf_icep_context, tvb, offset - 1, 1, s);
		return;
	}

	/* looping through the dictionary */
	for ( i = 0; i < Size; i++ ) {
		/* key */
		gint32 consumed_key = 0;
		char *str_key = NULL;
		/* value */
		gint32 consumed_value = 0;
		char *str_value = NULL;
		proto_item *ti = NULL;

		DBG1("looping through context dictionary, loop #%d\n", i);
		ti = proto_tree_add_text(tree, tvb, offset, -1, "Invocation Context");

		dissect_ice_string(pinfo, tree, ti, hf_icep_invocation_key, tvb, offset, &consumed_key, &str_key);

		if ( consumed_key == -1 ) {
			(*consumed) = -1;
			return;
		}

		offset += consumed_key;
		(*consumed) += consumed_key;

		dissect_ice_string(pinfo, tree, ti, hf_icep_invocation_value, tvb, offset, &consumed_value, &str_value);

		if ( consumed_value == -1 ) {
			(*consumed) = -1;
			return;
		}

		offset += consumed_value;
		(*consumed) += consumed_value;
		if (ti)
			proto_item_set_len(ti, (consumed_key + consumed_value) + 1);
	}
}
Ejemplo n.º 13
0
/*
 * This function dissects an "Ice facet", adds hf(s) to "tree" and returns consumed
 * bytes in "*consumed", if errors "*consumed" is -1.
 */
static void dissect_ice_facet(packet_info *pinfo, proto_tree *tree, proto_item *item, int hf_icep,
			      tvbuff_t *tvb, guint32 offset, gint32 *consumed)
{
	/*  p. 588, chapter 23.2.6:
	 *  "facet" is a StringSeq, a StringSeq is a:
	 *  sequence<string>
	 *
	 *
	 * sequence == Size + SizeElements
	 * sequence = 1byte (0..254) + SizeElements
	 * or
	 * sequence = 1byte (255) + 1int (255..2^32-1) + SizeElements
	 *
	 *
	 * p.613. chapter 23.3.2
	 * "facet has either zero elements (empty) or one element"
	 *
	 *
	 */

	guint32 Size = 0; /* number of elements in the sequence */

	(*consumed) = 0;

	/* check first byte */
	if ( !tvb_bytes_exist(tvb, offset, 1) ) {

		if (item)
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "facet field missing");

		col_append_str(mypinfo->cinfo, COL_INFO,
				       " (facet field missing)");

		(*consumed) = -1;
		return;
	}

	/* get first byte of Size */
	Size = tvb_get_guint8(tvb, offset);
	offset++;
	(*consumed)++;

	if ( Size == 0 ) {

		if (tree) {
			/* display the 0x00 Size byte when click on a empty ice_string */
			proto_tree_add_string(tree, hf_icep, tvb, offset - 1, 1, "(empty)");
		}
		return;
	}

	if ( Size == 1 ) {

		gint32 consumed_facet = 0;

		dissect_ice_string(pinfo, tree, item, hf_icep, tvb, offset, &consumed_facet, NULL);

		if ( consumed_facet == -1 ) {
			(*consumed) = -1;
			return;
		}

		/*offset += consumed_facet;*/
		(*consumed) += consumed_facet;
		return;
	}

	/* if here => Size > 1 => not possible */

	if (item)
		/* display the XX Size byte when click here */
		expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "facet can be max one element");

	col_append_str(mypinfo->cinfo, COL_INFO,
			       " (facet can be max one element)");

	(*consumed) = -1;
	return;
}
Ejemplo n.º 14
0
/*
 * This function dissects an "Ice string", adds hf to "tree" and returns consumed
 * bytes in "*consumed", if errors "*consumed" is -1.
 *
 * "*dest" is a null terminated version of the dissected Ice string.
 */
static void dissect_ice_string(packet_info *pinfo, proto_tree *tree, proto_item *item, int hf_icep,
							   tvbuff_t *tvb, guint32 offset, gint32 *consumed, char **dest)
{
	/* p. 586 chapter 23.2.1 and p. 588 chapter 23.2.5
	 * string == Size + content
	 * string = 1byte (0..254) + string not null terminated
	 * or
	 * string = 1byte (255) + 1int (255..2^32-1) + string not null terminated
	 */

	guint32 Size = 0;
	char *s = NULL;

	(*consumed) = 0;

	/* check for first byte */
	if ( !tvb_bytes_exist(tvb, offset, 1) ) {

		if (item)
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "1st byte of Size missing");

		col_append_str(mypinfo->cinfo, COL_INFO, " (1st byte of Size missing)");

		(*consumed) = -1;
		return;
	}

	/* get the Size */
	Size = tvb_get_guint8(tvb, offset);
	offset++;
	(*consumed)++;

	if ( Size == 255 ) {

		/* check for next 4 bytes */
		if ( !tvb_bytes_exist(tvb, offset, 4) ) {

			if (item)
				expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "second field of Size missing");

			col_append_str(mypinfo->cinfo, COL_INFO, " (second field of Size missing)");

			(*consumed) = -1;
			return;
		}

		/* get second field of Size */
		Size = tvb_get_letohl(tvb, offset);
		offset += 4;
		(*consumed) += 4;
	}

	DBG1("string.Size --> %d\n", Size);

	/* check if the string exists */
	if ( !tvb_bytes_exist(tvb, offset, Size) ) {

		if (item)
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR, "missing or truncated string");

		col_append_str(mypinfo->cinfo, COL_INFO, " (missing or truncated string)");

		(*consumed) = -1;
		return;
	}

	if ( Size > icep_max_ice_string_len ) {

		if (item)
			expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "string too long");

		col_append_str(mypinfo->cinfo, COL_INFO, " (string too long)");

		(*consumed) = -1;
		return;
	}


	if ( Size != 0 ) {
		s = tvb_get_ephemeral_string(tvb, offset, Size);
		if (tree)
			proto_tree_add_string(tree, hf_icep, tvb, offset, Size, s);
	} else {
		s = g_strdup("(empty)");
		/* display the 0x00 Size byte when click on a empty ice_string */
		if (tree)
			proto_tree_add_string(tree, hf_icep, tvb, offset - 1, 1, s);
	}

	if ( dest != NULL )
		*dest = s;

	/*offset += Size;*/
	(*consumed) += Size;
	return;
}
Ejemplo n.º 15
0
static int
nmas_string(tvbuff_t* tvb, int hfinfo, proto_tree *nmas_tree, int offset, gboolean little)
{
        int     foffset = offset;
        guint32 str_length;
        char    *buffer;
        guint32 i;
        guint16 c_char;
        guint32 length_remaining = 0;

        buffer=ep_alloc(ITEM_LABEL_LENGTH+1);
        if (little) {
            str_length = tvb_get_letohl(tvb, foffset);
        }
        else
        {
            str_length = tvb_get_ntohl(tvb, foffset);
        }
        foffset += 4;
        if(str_length >= ITEM_LABEL_LENGTH)
        {
                proto_tree_add_string(nmas_tree, hfinfo, tvb, foffset,
                    length_remaining + 4, "<String too long to process>");
                foffset += length_remaining;
                return foffset;
        }
        if(str_length == 0)
        {
            proto_tree_add_string(nmas_tree, hfinfo, tvb, offset,
                4, "<Not Specified>");
            return foffset;
        }
        /*
         * XXX - other than the special-casing of null bytes,
         * we could just use "proto_tree_add_item()", as for
         * FT_STRING, FT_STRINGZ, and FT_UINT_STRING fields,
         * the display representation of an item is generated
         * using "format_text()", so it handles non-printable
         * characters.
         */
        for ( i = 0; i < str_length; i++ )
        {
                c_char = tvb_get_guint8(tvb, foffset );
                if (c_char<0x20 || c_char>0x7e)
                {
                        if (c_char != 0x00)
                        {
                                c_char = 0x2e;
                                buffer[i] = c_char & 0xff;
                        }
                        else
                        {
                                i--;
                                str_length--;
                        }
                }
                else
                {
                        buffer[i] = c_char & 0xff;
                }
                foffset++;
                length_remaining--;

                if(length_remaining==1)
                {
                        i++;
                        break;
                }
        }
        buffer[i] = '\0';

        if (little) {
            str_length = tvb_get_letohl(tvb, offset);
        }
        else
        {
            str_length = tvb_get_ntohl(tvb, offset);
        }
        proto_tree_add_string(nmas_tree, hfinfo, tvb, offset+4,
                str_length, buffer);
        return foffset;
}
Ejemplo n.º 16
0
static int
dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *name_tree;
    proto_tree *exclude_tree;
    proto_item *titem;
    struct ccn_parsed_interest interest;
    struct ccn_parsed_interest *pi = &interest;
    struct ccn_buf_decoder decoder;
    struct ccn_buf_decoder *d;
    const unsigned char *bloom;
    size_t bloom_size = 0;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    const unsigned char *blob;
    size_t blob_size;
    ssize_t l;
    unsigned int i;
    double lifetime;
    int res;
    
    comps = ccn_indexbuf_create();
    res = ccn_parse_interest(ccnb, ccnb_size, pi, comps);
    if (res < 0)
        return (res);
    
    /* Name */
    l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                  pi->offset[CCN_PI_B_Name], l,
                                  ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);
    
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }
    
    /* MinSuffixComponents */
    l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents];
    if (l > 0) {
        i = pi->min_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i);
    }
    
    /* MaxSuffixComponents */
    l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents];
    if (l > 0) {
        i = pi->max_suffix_comps;
        titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i);
    }
    
    /* PublisherPublicKeyDigest */
    /* Exclude */
    l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude];
    if (l > 0) {
        c = ccn_charbuf_create();
        d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l);
        if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) {
            ccn_charbuf_destroy(&c);
            return(-1);
        }
        ccn_charbuf_append_string(c, "Exclude: ");
        ccn_buf_advance(d);
        if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
            ccn_buf_advance(d);
            ccn_charbuf_append_string(c, "* ");
            ccn_buf_check_close(d);
        }
        else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
            ccn_buf_advance(d);
            if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                ccn_buf_advance(d);
            ccn_charbuf_append_string(c, "? ");
            ccn_buf_check_close(d);
        }
        while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
            ccn_buf_advance(d);
            comp_size = 0;
            if (ccn_buf_match_blob(d, &comp, &comp_size))
                ccn_buf_advance(d);
            ccn_uri_append_percentescaped(c, comp, comp_size);
            ccn_charbuf_append_string(c, " ");
            ccn_buf_check_close(d);
            if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
                ccn_buf_advance(d);
                ccn_charbuf_append_string(c, "* ");
                ccn_buf_check_close(d);
            }
            else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) {
                ccn_buf_advance(d);
                if (ccn_buf_match_blob(d, &bloom, &bloom_size))
                    ccn_buf_advance(d);
                ccn_charbuf_append_string(c, "? ");
                ccn_buf_check_close(d);
            }
        }
        
        titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l,
                                    "%s", ccn_charbuf_as_string(c));
        exclude_tree = proto_item_add_subtree(titem, ett_exclude);
        ccn_charbuf_destroy(&c);

    }
    /* ChildSelector */
    l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector];
    if (l > 0) {
        i = pi->orderpref;
        titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i);
        proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), ""));
        
    }
    
    /* AnswerOriginKind */
    l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind];
    if (l > 0) {
        i = pi->answerfrom;
        titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i);
    }
    
    /* Scope */
    l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope];
    if (l > 0) {
        i = pi->scope;
        titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i);
    }
    
    /* InterestLifetime */
    l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb,
                                pi->offset[CCN_PI_B_InterestLifetime],
                                pi->offset[CCN_PI_E_InterestLifetime],
                                &blob, &blob_size);
        lifetime = 0.0;
        for (i = 0; i < blob_size; i++)
            lifetime = lifetime * 256.0 + (double)blob[i];
        lifetime /= 4096.0;
        titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime);
    }
    
    /* Nonce */
    l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce];
    if (l > 0) {
        i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb,
                                pi->offset[CCN_PI_B_Nonce],
                                pi->offset[CCN_PI_E_Nonce],
                                &blob, &blob_size);
        if (check_col(pinfo->cinfo, COL_INFO)) {
            col_append_str(pinfo->cinfo, COL_INFO, ", <");
            for (i = 0; i < blob_size; i++)
                col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]);
            col_append_str(pinfo->cinfo, COL_INFO, ">");
        }
        titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    
    return (1);
    
}
Ejemplo n.º 17
0
static void
dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint       op;
    guint       sub;
    guint       rlen;
    proto_item *ti;
    proto_item *item;
    proto_tree *fip_tree;
    proto_tree *subtree;
    guint       dtype;
    guint       dlen;
    guint       desc_offset;
    guint       val;
    tvbuff_t   *desc_tvb;
    const char *info;
    const char *text;

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

    if (!tvb_bytes_exist(tvb, 0, FIP_HEADER_LEN)) {
        col_set_str(pinfo->cinfo, COL_INFO, "[packet too short]");
        if (tree)
            proto_tree_add_protocol_format(tree, proto_fip, tvb, 0,
                                            -1, "FIP [packet too short]");
        return;
    }

    op  = tvb_get_ntohs(tvb, 2);
    sub = tvb_get_guint8(tvb, 5);

    switch (op) {
    case FIP_OP_DISC:
        info = val_to_str(sub, fip_disc_subcodes, "Discovery 0x%x");
        break;
    case FIP_OP_LS:
        info = val_to_str(sub, fip_ls_subcodes, "Link Service 0x%x");
        break;
    case FIP_OP_CTRL:
        info = val_to_str(sub, fip_ctrl_subcodes, "Control 0x%x");
        break;
    case FIP_OP_VLAN:
        info = val_to_str(sub, fip_vlan_subcodes, "VLAN 0x%x");
        break;
    case FIP_OP_VN2VN:
        info = val_to_str(sub, fip_vn2vn_subcodes, "VN2VN 0x%x");
        break;
    default:
        info = val_to_str(op, fip_opcodes, "Unknown op 0x%x");
        break;
    }

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

    rlen = tvb_get_ntohs(tvb, 6);

    ti = proto_tree_add_protocol_format(tree, proto_fip, tvb, 0,
                                        FIP_HEADER_LEN + rlen * FIP_BPW,
                                        "FIP %s", info);
    fip_tree = proto_item_add_subtree(ti, ett_fip);
    proto_tree_add_item(fip_tree, hf_fip_ver, tvb, 0, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, ENC_BIG_ENDIAN);
    switch (op) {
    case FIP_OP_DISC:
        proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_LS:
        proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_CTRL:
        proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_VLAN:
        proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    case FIP_OP_VN2VN:
        proto_tree_add_item(fip_tree, hf_fip_vn2vn_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    default:
        proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, ENC_BIG_ENDIAN);
        break;
    }
    proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, ENC_BIG_ENDIAN);

    proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags,
            ett_fip_flags, hf_fip_flags_fields, ENC_BIG_ENDIAN);

    desc_offset = FIP_HEADER_LEN;
    rlen *= FIP_BPW;
    proto_tree_add_bytes_format(fip_tree, hf_fip_descriptors, tvb, desc_offset, rlen, NULL, "Descriptors");

    while ((rlen > 0) && tvb_bytes_exist(tvb, desc_offset, 2)) {
        dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW;
        if (!dlen) {
            proto_tree_add_expert(fip_tree, pinfo, &ei_fip_descriptors, tvb, desc_offset, -1);
            break;
        }
        if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) {
            break;
        }
        desc_tvb = tvb_new_subset(tvb, desc_offset, dlen, -1);
        dtype = tvb_get_guint8(desc_tvb, 0);
        desc_offset += dlen;
        rlen -= dlen;

        switch (dtype) {
        case FIP_DT_PRI:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_pri, &item);
            proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb,
                    3, 1, ENC_BIG_ENDIAN);
            proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3));
            break;
        case FIP_DT_MAC:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mac, &item);
            proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb,
                    2, 6, ENC_NA);
            proto_item_append_text(item, "%s",
                    tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'));
            break;
        case FIP_DT_MAP_OUI:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_map, &item);
            text = tvb_fc_to_str(desc_tvb, 5);
            proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb,
                    5, 3, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_NAME:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_name, &item);
            text = tvb_fcwwn_to_str(desc_tvb, 4);
            proto_tree_add_string(subtree, hf_fip_desc_name,
                    desc_tvb, 4, 8, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_FAB:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fab, &item);
            proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb,
                    2, 2, ENC_BIG_ENDIAN);
            text = tvb_fc_to_str(desc_tvb, 5);
            proto_tree_add_string(subtree, hf_fip_desc_fab_map, desc_tvb,
                    5, 3, text);
            text = tvb_fcwwn_to_str(desc_tvb, 8);
            proto_tree_add_string(subtree, hf_fip_desc_fab_name,
                    desc_tvb, 8, 8, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_FCOE_SIZE:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mdl, &item);
            proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb,
                    2, 2, ENC_BIG_ENDIAN);
            proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
            break;
        case FIP_DT_FLOGI:
        case FIP_DT_FDISC:
        case FIP_DT_LOGO:
        case FIP_DT_ELP: {
            tvbuff_t *ls_tvb;
            fc_data_t fc_data = {ETHERTYPE_FIP, 0};

            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_caps, &item);
            ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1);
            call_dissector_with_data(fc_handle, ls_tvb, pinfo, subtree, &fc_data);
            proto_item_append_text(item, "%u bytes", dlen - 4);
        }
            break;
        case FIP_DT_VN:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vn, &item);
            proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb,
                    2, 6, ENC_NA);
            proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb,
                    9, 3, ENC_BIG_ENDIAN);
            text = tvb_fcwwn_to_str(desc_tvb, 12);
            proto_tree_add_string(subtree, hf_fip_desc_vn_wwpn,
                    desc_tvb, 12, 8, text);
            proto_item_append_text(item, "MAC %s  FC_ID %6.6x",
                    tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'),
                    tvb_get_ntoh24(desc_tvb, 9));
            break;
        case FIP_DT_FKA:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fka, &item);
            val = tvb_get_ntohl(desc_tvb, 4);
            proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka,
                    desc_tvb, 4, 4, val, "%u ms", val);
            proto_item_append_text(item, "%u ms", val);
            break;
        case FIP_DT_VEND:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vend, &item);
            proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb,
                    4, 8, ENC_NA);
            if (tvb_bytes_exist(desc_tvb, 9, -1)) {
                proto_tree_add_item(subtree, hf_fip_desc_vend_data,
                     desc_tvb, 9, -1, ENC_NA);
            }
            break;
        case FIP_DT_VLAN:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vlan, &item);
            proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb,
                    2, 2, ENC_BIG_ENDIAN);
            proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
            break;
        case FIP_DT_FC4F:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fc4f, &item);
            fip_desc_fc4f(desc_tvb, subtree, item);
            break;
        default:
            subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_unk, &item);
            proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb,
                    2, -1, ENC_NA);
            break;
        }
    }
}
Ejemplo n.º 18
0
static int
dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_tree *signature_tree;
    proto_tree *name_tree;
    proto_tree *signedinfo_tree;
    proto_tree *content_tree;
    proto_item *titem;
    struct ccn_parsed_ContentObject co;
    struct ccn_parsed_ContentObject *pco = &co;
    struct ccn_charbuf *c;
    struct ccn_indexbuf *comps;
    const unsigned char *comp;
    size_t comp_size;
    size_t blob_size;
    const unsigned char *blob;
    int l;
    unsigned int i;
    double dt;
    nstime_t timestamp;
    int res;
    
    comps = ccn_indexbuf_create();
    res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps);
    if (res < 0) return (-1);
    
    /* Signature */
    l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature];
    titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE);
    signature_tree = proto_item_add_subtree(titem, ett_signature);
    
    /* DigestAlgorithm */
    l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb,
                                  pco->offset[CCN_PCO_B_DigestAlgorithm],
                                  pco->offset[CCN_PCO_E_DigestAlgorithm],
                                  &blob, &blob_size);
        titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb,
                                    blob - ccnb, blob_size, FALSE);
    }
    /* Witness */
    l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness];
    if (l > 0) {
        /* add the witness item to the signature tree */
    }
    
    /* Signature bits */
    l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb,
                                  pco->offset[CCN_PCO_B_SignatureBits],
                                  pco->offset[CCN_PCO_E_SignatureBits],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb,
                                     blob - ccnb, blob_size, blob);
    }
    
    /* /Signature */
    
    /* Name */
    l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name];
    c = ccn_charbuf_create();
    ccn_uri_append(c, ccnb, ccnb_size, 1);
    titem = proto_tree_add_string(tree, hf_ccn_name, tvb,
                                  pco->offset[CCN_PCO_B_Name], l,
                                  ccn_charbuf_as_string(c));
    name_tree = proto_item_add_subtree(titem, ett_name);
    ccn_charbuf_destroy(&c);
    
    /* Name Components */
    for (i = 0; i < comps->n - 1; i++) {
        res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size);
        titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE);
    }
    
    /* /Name */
    
    /* SignedInfo */
    l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo];
    titem = proto_tree_add_text(tree, tvb,
                                pco->offset[CCN_PCO_B_SignedInfo], l,
                                "SignedInfo");
    signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo);
    
    /* PublisherPublicKeyDigest */
    l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb,
                                  pco->offset[CCN_PCO_B_PublisherPublicKeyDigest],
                                  pco->offset[CCN_PCO_E_PublisherPublicKeyDigest],
                                  &blob, &blob_size);
        titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob);
    }
    
    /* Timestamp */
    l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb,
                                  pco->offset[CCN_PCO_B_Timestamp],
                                  pco->offset[CCN_PCO_E_Timestamp],
                                  &blob, &blob_size);
        dt = 0.0;
        for (i = 0; i < blob_size; i++)
            dt = dt * 256.0 + (double)blob[i];
        dt /= 4096.0;
        timestamp.secs = dt; /* truncates */
        timestamp.nsecs = (dt - (double) timestamp.secs) *  1000000000.0;
        titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, &timestamp);
    }
    
    /* Type */
    l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb,
                                  pco->offset[CCN_PCO_B_Type],
                                  pco->offset[CCN_PCO_E_Type],
                                  &blob, &blob_size);
        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type);
    } else {
        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type);
    }
    
    /* FreshnessSeconds */
    l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb,
                                  pco->offset[CCN_PCO_B_FreshnessSeconds],
                                  pco->offset[CCN_PCO_E_FreshnessSeconds],
                                  &blob, &blob_size);
        i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb,
                                                pco->offset[CCN_PCO_B_FreshnessSeconds],
                                                pco->offset[CCN_PCO_E_FreshnessSeconds]);
        
        titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i);
    }
    
    /* FinalBlockID */
    l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID];
    if (l > 0) {
        res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb,
                                  pco->offset[CCN_PCO_B_FinalBlockID],
                                  pco->offset[CCN_PCO_E_FinalBlockID],
                                  &blob, &blob_size);
        
        titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE);
    }
    /* TODO: KeyLocator */
    /* /SignedInfo */
    
    /* Content */
    l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content];
    res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb,
                              pco->offset[CCN_PCO_B_Content],
                              pco->offset[CCN_PCO_E_Content],
                              &blob, &blob_size);
    titem = proto_tree_add_text(tree, tvb,
                                pco->offset[CCN_PCO_B_Content], l,
                                "Content: %d bytes", blob_size);
    if (blob_size > 0) {
        content_tree = proto_item_add_subtree(titem, ett_content);
        titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE);
    }
    
    return (ccnb_size);
}
Ejemplo n.º 19
0
static void
dissect_gsm_um(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree *gsm_um_tree = NULL;
	proto_item *ti;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "GSM Um");

	if (pinfo->pseudo_header->gsm_um.uplink) {
		col_set_str(pinfo->cinfo, COL_RES_DL_DST, "BTS");
		col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "MS");
	}
	else {
		switch (pinfo->pseudo_header->gsm_um.channel) {
			case GSM_UM_CHANNEL_BCCH:
			case GSM_UM_CHANNEL_CCCH:
			case GSM_UM_CHANNEL_PCH:
			case GSM_UM_CHANNEL_AGCH:
				col_set_str(pinfo->cinfo, COL_RES_DL_DST, "Broadcast");
				break;
			default:
				col_set_str(pinfo->cinfo, COL_RES_DL_DST, "MS");
				break;
		}
		col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "BTS");
	}

	if (tree) {
		const char *channel;

		ti = proto_tree_add_item(tree, proto_gsm_um, tvb, 0, 0, ENC_NA);
		gsm_um_tree = proto_item_add_subtree(ti, ett_gsm_um);

		switch( pinfo->pseudo_header->gsm_um.channel ) {
			case GSM_UM_CHANNEL_BCCH: channel = "BCCH"; break;
			case GSM_UM_CHANNEL_CCCH: channel = "CCCH"; break;
			case GSM_UM_CHANNEL_PCH: channel = "PCH"; break;
			case GSM_UM_CHANNEL_AGCH: channel = "AGCH"; break;
			case GSM_UM_CHANNEL_SACCH: channel = "SACCH"; break;
			case GSM_UM_CHANNEL_FACCH: channel = "FACCH"; break;
			case GSM_UM_CHANNEL_SDCCH: channel = "SDCCH"; break;
			default: channel = "Unknown"; break;
		}

		if( pinfo->pseudo_header->gsm_um.uplink ) {
			proto_tree_add_string(gsm_um_tree, hf_gsm_um_direction, tvb, 0, 0, "Uplink");
		}
		else {
			proto_tree_add_string(gsm_um_tree, hf_gsm_um_direction, tvb, 0, 0, "Downlink");
		}

		proto_tree_add_string(gsm_um_tree, hf_gsm_um_channel, tvb, 0, 0, channel);

		/* Show the other fields, if we have them (ie. downlink, BTS->MS) */
		if( !pinfo->pseudo_header->gsm_um.uplink ) {
			const char *band;
			guint downlink, uplink;

			decode_arfcn(pinfo->pseudo_header->gsm_um.arfcn, &band, &uplink, &downlink);

			proto_tree_add_uint(gsm_um_tree, hf_gsm_um_arfcn, tvb, 0, 0,
				pinfo->pseudo_header->gsm_um.arfcn);
			proto_tree_add_text(gsm_um_tree, tvb, 0, 0,
				"Band: %s, Frequency: %u.%03uMHz", band,
				downlink / 1000, downlink % 1000);
			proto_tree_add_uint(gsm_um_tree, hf_gsm_um_bsic, tvb, 0, 0,
				pinfo->pseudo_header->gsm_um.bsic);
			proto_tree_add_uint(gsm_um_tree, hf_gsm_um_frame, tvb, 0, 0,
				pinfo->pseudo_header->gsm_um.tdma_frame);
			proto_tree_add_uint(gsm_um_tree, hf_gsm_um_error, tvb, 0, 0,
				pinfo->pseudo_header->gsm_um.error);
			proto_tree_add_uint(gsm_um_tree, hf_gsm_um_timeshift, tvb, 0, 0,
				pinfo->pseudo_header->gsm_um.timeshift);
		}
	}

	/* TODO: If CCCH downlink could work out of PCH or AGCH by peeking at next bytes, uplink is RACH */

	switch( pinfo->pseudo_header->gsm_um.channel ) {
		case GSM_UM_CHANNEL_BCCH:
		case GSM_UM_CHANNEL_CCCH:
		case GSM_UM_CHANNEL_PCH:
		case GSM_UM_CHANNEL_AGCH:
			if( !pinfo->pseudo_header->gsm_um.uplink ) {
				tvbuff_t *next_tvb;
				guint8 pseudo_len, len_left, len_byte;

				len_left = tvb_length(tvb);
				len_byte = tvb_get_guint8(tvb, 0);
				pseudo_len = len_byte >> 2;
				next_tvb = tvb_new_subset(tvb, 1, MIN(len_left, pseudo_len), -1);

				if (tree) {
					proto_tree_add_uint(gsm_um_tree, hf_gsm_um_l2_pseudo_len, tvb, 0, 1,
						len_byte);
				}

				/* Only dissect non-empty frames */
				if( tvb_length(next_tvb) ) {
					call_dissector(dtap_handle, next_tvb, pinfo, tree);
				}
			}
			else {
Ejemplo n.º 20
0
/* -----------------------------
	from netatalk/etc/afpd/status.c
*/
static gint
dissect_dsi_reply_get_status(tvbuff_t *tvb, proto_tree *tree, gint offset)
{
	proto_tree      *sub_tree;
	proto_item	*ti;

	guint16 ofs;
	guint16 flag;
	guint16 sign_ofs = 0;
	guint16 adr_ofs = 0;
	guint16 dir_ofs = 0;
	guint16 utf_ofs = 0;
	guint8	nbe;
	guint8  len;
	guint8  i;

	if (!tree)
		return offset;

	ti = proto_tree_add_text(tree, tvb, offset, -1, "Get Status");
	tree = proto_item_add_subtree(ti, ett_dsi_status);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_MACHOFF, 2, "Machine offset: %d", ofs);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_VERSOFF, 2, "Version offset: %d", ofs);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_UAMSOFF, 2, "UAMS offset: %d", ofs);

	ofs = tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
	proto_tree_add_text(tree, tvb, offset +AFPSTATUS_ICONOFF, 2, "Icon offset: %d", ofs);

	ofs = offset +AFPSTATUS_FLAGOFF;
	ti = proto_tree_add_item(tree, hf_dsi_server_flag, tvb, ofs, 2, ENC_BIG_ENDIAN);
	sub_tree = proto_item_add_subtree(ti, ett_dsi_status_server_flag);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_copyfile      , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_passwd        , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_no_save_passwd, tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_msg       , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_srv_sig       , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_tcpip         , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_notify        , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_reconnect     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_directory     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_utf8_name     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_uuid          , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_ext_sleep     , tvb, ofs, 2, ENC_BIG_ENDIAN);
	proto_tree_add_item(sub_tree, hf_dsi_server_flag_fast_copy     , tvb, ofs, 2, ENC_BIG_ENDIAN);

	proto_tree_add_item(tree, hf_dsi_server_name, tvb, offset +AFPSTATUS_PRELEN, 1, ENC_ASCII|ENC_NA);

	flag = tvb_get_ntohs(tvb, ofs);
	if ((flag & AFPSRVRINFO_SRVSIGNATURE)) {
		ofs = offset +AFPSTATUS_PRELEN +tvb_get_guint8(tvb, offset +AFPSTATUS_PRELEN) +1;
		if ((ofs & 1))
			ofs++;

		sign_ofs = tvb_get_ntohs(tvb, ofs);
		proto_tree_add_text(tree, tvb, ofs, 2, "Signature offset: %d", sign_ofs);
		sign_ofs += offset;

		if ((flag & AFPSRVRINFO_TCPIP)) {
			ofs += 2;
			adr_ofs =  tvb_get_ntohs(tvb, ofs);
			proto_tree_add_text(tree, tvb, ofs, 2, "Network address offset: %d", adr_ofs);
			adr_ofs += offset;
		}

		if ((flag & AFPSRVRINFO_SRVDIRECTORY)) {
			ofs += 2;
			dir_ofs =  tvb_get_ntohs(tvb, ofs);
			proto_tree_add_text(tree, tvb, ofs, 2, "Directory services offset: %d", dir_ofs);
			dir_ofs += offset;
		}
		if ((flag & AFPSRVRINFO_SRVUTF8)) {
			ofs += 2;
			utf_ofs =  tvb_get_ntohs(tvb, ofs);
			proto_tree_add_text(tree, tvb, ofs, 2, "UTF8 server name offset: %d", utf_ofs);
			utf_ofs += offset;
		}
	}

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_MACHOFF);
	if (ofs)
		proto_tree_add_item(tree, hf_dsi_server_type, tvb, ofs, 1, ENC_ASCII|ENC_NA);

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_VERSOFF);
	if (ofs) {
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "Version list: %d", nbe);
		ofs++;
		sub_tree = proto_item_add_subtree(ti, ett_dsi_vers);
		for (i = 0; i < nbe; i++) {
			len = tvb_get_guint8(tvb, ofs);
			proto_tree_add_item(sub_tree, hf_dsi_server_vers, tvb, ofs, 1, ENC_ASCII|ENC_NA);
			ofs += len + 1;
		}
	}

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_UAMSOFF);
	if (ofs) {
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "UAMS list: %d", nbe);
		ofs++;
		sub_tree = proto_item_add_subtree(ti, ett_dsi_uams);
		for (i = 0; i < nbe; i++) {
			len = tvb_get_guint8(tvb, ofs);
			proto_tree_add_item(sub_tree, hf_dsi_server_uams, tvb, ofs, 1, ENC_ASCII|ENC_NA);
			ofs += len + 1;
		}
	}

	ofs = offset +tvb_get_ntohs(tvb, offset +AFPSTATUS_ICONOFF);
	if (ofs)
		proto_tree_add_item(tree, hf_dsi_server_icon, tvb, ofs, 256, ENC_NA);

	if (sign_ofs) {
		proto_tree_add_item(tree, hf_dsi_server_signature, tvb, sign_ofs, 16, ENC_NA);
	}

	if (adr_ofs) {
		proto_tree *adr_tree;
		unsigned char *tmp;
		guint16 net;
		guint8  node;
		guint16 port;

		ofs = adr_ofs;
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "Address list: %d", nbe);
		ofs++;
		adr_tree = proto_item_add_subtree(ti, ett_dsi_addr);
		for (i = 0; i < nbe; i++) {
			guint8 type;

			len = tvb_get_guint8(tvb, ofs);
			type =  tvb_get_guint8(tvb, ofs +1);
			switch (type) {
			case 1:	/* IP */
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip: %s", tvb_ip_to_str(tvb, ofs+2));
				break;
			case 2: /* IP + port */
				port = tvb_get_ntohs(tvb, ofs+6);
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip %s:%d", tvb_ip_to_str(tvb, ofs+2), port);
				break;
			case 3: /* DDP, atalk_addr_to_str want host order not network */
				net  = tvb_get_ntohs(tvb, ofs+2);
				node = tvb_get_guint8(tvb, ofs +4);
				port = tvb_get_guint8(tvb, ofs +5);
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ddp: %u.%u:%u",
					net, node, port);
				break;
			case 4: /* DNS */
			case 5: /* SSH tunnel */
				if (len > 2) {
					tmp = tvb_get_string(wmem_packet_scope(), tvb, ofs +2, len -2);
					ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "%s: %s",
								(type==4)?"dns":"ssh tunnel", tmp);
					break;
				}
				else {
					ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Malformed address type %d", type);
				}
				break;
			case 6: /* IP6 */
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip6: %s",
				                tvb_ip6_to_str(tvb, ofs+2));
				break;
			case 7: /* IP6 + 2bytes port */
				port = tvb_get_ntohs(tvb, ofs+ 2+INET6_ADDRLEN);
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len, "ip6 %s:%d",
						tvb_ip6_to_str(tvb, ofs+2), port);
				break;
			default:
				ti = proto_tree_add_text(adr_tree, tvb, ofs, len,"Unknown type : %d", type);
				break;
			}
			len -= 2;
			sub_tree = proto_item_add_subtree(ti,ett_dsi_addr_line);
			proto_tree_add_item(sub_tree, hf_dsi_server_addr_len, tvb, ofs, 1, ENC_BIG_ENDIAN);
			ofs++;
			proto_tree_add_item(sub_tree, hf_dsi_server_addr_type, tvb, ofs, 1, ENC_BIG_ENDIAN);
			ofs++;
			proto_tree_add_item(sub_tree, hf_dsi_server_addr_value,tvb, ofs, len, ENC_NA);
			ofs += len;
		}
	}

	if (dir_ofs) {
		ofs = dir_ofs;
		nbe = tvb_get_guint8(tvb, ofs);
		ti = proto_tree_add_text(tree, tvb, ofs, 1, "Directory services list: %d", nbe);
		ofs++;
		sub_tree = proto_item_add_subtree(ti, ett_dsi_directory);
		for (i = 0; i < nbe; i++) {
			len = tvb_get_guint8(tvb, ofs);
			proto_tree_add_item(sub_tree, hf_dsi_server_directory, tvb, ofs, 1, ENC_ASCII|ENC_NA);
			ofs += len + 1;
		}
	}
	if (utf_ofs) {
		guint16 ulen;
		char *tmp;

		ofs = utf_ofs;
		ulen = tvb_get_ntohs(tvb, ofs);
		tmp = tvb_get_string(wmem_packet_scope(), tvb, ofs + 2, ulen);
		ti = proto_tree_add_text(tree, tvb, ofs, ulen + 2, "UTF8 server name: %s", tmp);
		sub_tree = proto_item_add_subtree(ti, ett_dsi_utf8_name);
		proto_tree_add_uint(sub_tree, hf_dsi_utf8_server_name_len, tvb, ofs, 2, ulen);
		ofs += 2;
		proto_tree_add_string(sub_tree, hf_dsi_utf8_server_name, tvb, ofs, ulen, tmp);
		ofs += ulen;
	}

	return ofs;
}
Ejemplo n.º 21
0
static int
dissect_ipmi_cmd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
		gint hf_parent_item, gint ett_tree, const ipmi_context_t * ctx)
{
	ipmi_packet_data_t * data;
	ipmi_netfn_t * cmd_list;
	ipmi_cmd_t * cmd;
	proto_item * ti;
	proto_tree * cmd_tree = NULL, * tmp_tree;
	guint8 prev_level, cc_val;
	guint offset, siglen, is_resp;
	const char * cc_str, * netfn_str;

	/* get packet data */
	data = get_packet_data(pinfo);
	if (!data) {
		return 0;
	}

	/* get prefix length */
	siglen = ipmi_getsiglen(ctx->hdr.netfn);

	/* get response flag */
	is_resp = ctx->hdr.netfn & 1;

	/* check message length */
	if (tvb_captured_length(tvb) < ctx->hdr_len + siglen + is_resp
			+ !(ctx->flags & IPMI_D_NO_CKS)) {
		/* don bother with anything */
		return call_data_dissector(tvb, pinfo, tree);
	}

	/* save nest level */
	prev_level = data->curr_level;

	/* assign next nest level */
	data->curr_level = data->next_level;

	/* increment next nest level */
	data->next_level++;

	/* check for the first invocation */
	if (!data->curr_level) {
		/* get current frame data */
		data->curr_frame = get_frame_data(data, pinfo->num);
		data->curr_frame_num = pinfo->num;

		/* copy frame timestamp */
		memcpy(&data->curr_frame->ts, &pinfo->abs_ts, sizeof(nstime_t));

		/* cache channel and direction */
		data->curr_channel = ctx->hdr.channel;
		data->curr_dir = ctx->hdr.dir;

		/* remove requests which are too old */
		remove_old_requests(data, &pinfo->abs_ts);
	}

	if (data->curr_level < MAX_NEST_LEVEL) {
		if (ctx->hdr.netfn & 1) {
			/* perform request/response matching */
			match_request_response(data, &ctx->hdr, ctx->flags);
		} else {
			/* add request to the list for later matching */
			add_request(data, &ctx->hdr);
		}
	}

	/* get command list by network function code */
	cmd_list = ipmi_getnetfn(ctx->hdr.netfn,
			tvb_get_ptr(tvb, ctx->hdr_len + is_resp, siglen));

	/* get command descriptor */
	cmd = ipmi_getcmd(cmd_list, ctx->hdr.cmd);

	/* check if response */
	if (is_resp) {
		/* get completion code */
		cc_val = tvb_get_guint8(tvb, ctx->hdr_len);

		/* get completion code desc */
		cc_str = ipmi_get_completion_code(cc_val, cmd);
	} else {
		cc_val = 0;
		cc_str = NULL;
	}

	/* check if not inside a message */
	if (!data->curr_level) {
		/* add packet info */
		add_command_info(pinfo, cmd, is_resp, cc_val, cc_str,
				ctx->flags & IPMI_D_BROADCAST ? TRUE : FALSE);
	}

	if (tree) {
		/* add parent node */
		if (!data->curr_level) {
			ti = proto_tree_add_item(tree, hf_parent_item, tvb, 0, -1, ENC_NA);
			cmd_tree = proto_item_add_subtree(ti, ett_tree);
		} else {
			char str[ITEM_LABEL_LENGTH];

			if (is_resp) {
				g_snprintf(str, ITEM_LABEL_LENGTH, "Rsp, %s, %s",
						cmd->desc, cc_str);
			} else {
				g_snprintf(str, ITEM_LABEL_LENGTH, "Req, %s", cmd->desc);
			}
			if (proto_registrar_get_ftype(hf_parent_item) == FT_STRING) {
				ti = proto_tree_add_string(tree, hf_parent_item, tvb, 0, -1, str);
				cmd_tree = proto_item_add_subtree(ti, ett_tree);
			}
			else
				cmd_tree = proto_tree_add_subtree(tree, tvb, 0, -1, ett_tree, NULL, str);
		}

		if (data->curr_level < MAX_NEST_LEVEL) {
			/* check if response */
			if (ctx->hdr.netfn & 1) {
				/* get current command data */
				ipmi_cmd_data_t * rs_data =
						data->curr_frame->cmd_data[data->curr_level];

				if (rs_data->matched_frame_num) {
					nstime_t ns;

					/* add "Request to:" field */
					ti = proto_tree_add_uint(cmd_tree, hf_ipmi_response_to,
							tvb, 0, 0, rs_data->matched_frame_num);

					/* mark field as a generated one */
					PROTO_ITEM_SET_GENERATED(ti);

					/* calculate delta time */
					nstime_delta(&ns, &pinfo->abs_ts,
							&get_frame_data(data,
									rs_data->matched_frame_num)->ts);

					/* add "Response time" field */
					ti = proto_tree_add_time(cmd_tree, hf_ipmi_response_time,
							tvb, 0, 0, &ns);

					/* mark field as a generated one */
					PROTO_ITEM_SET_GENERATED(ti);
					}
			} else {
				/* get current command data */
				ipmi_cmd_data_t * rq_data =
						data->curr_frame->cmd_data[data->curr_level];

				if (rq_data->matched_frame_num) {
					/* add "Response in:" field  */
					ti = proto_tree_add_uint(cmd_tree, hf_ipmi_response_in,
							tvb, 0, 0, rq_data->matched_frame_num);

					/* mark field as a generated one */
					PROTO_ITEM_SET_GENERATED(ti);
				}
			}
		}

		/* set starting offset */
		offset = 0;

		/* check if message is broadcast */
		if (ctx->flags & IPMI_D_BROADCAST) {
			/* skip first byte */
			offset++;
		}

		/* check if session handle is specified */
		if (ctx->flags & IPMI_D_SESSION_HANDLE) {
			/* add session handle field */
			proto_tree_add_item(cmd_tree, hf_ipmi_session_handle,
					tvb, offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* check if responder address is specified */
		if (ctx->flags & IPMI_D_TRG_SA) {
			/* add response address field */
			proto_tree_add_item(cmd_tree, hf_ipmi_header_trg, tvb,
					offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* get NetFn string */
		netfn_str = ipmi_getnetfnname(ctx->hdr.netfn, cmd_list);

		/* Network function + target LUN */
		tmp_tree = proto_tree_add_subtree_format(cmd_tree, tvb, offset, 1,
				ett_header_byte_1, NULL, "Target LUN: 0x%02x, NetFN: %s %s (0x%02x)",
				ctx->hdr.rs_lun, netfn_str,
				is_resp ? "Response" : "Request", ctx->hdr.netfn);

		/* add Net Fn */
		proto_tree_add_uint_format(tmp_tree, hf_ipmi_header_netfn, tvb,
				offset, 1, ctx->hdr.netfn << 2,
				"NetFn: %s %s (0x%02x)", netfn_str,
				is_resp ? "Response" : "Request", ctx->hdr.netfn);

		proto_tree_add_item(tmp_tree, hf_ipmi_header_trg_lun, tvb,
				offset++, 1, ENC_LITTLE_ENDIAN);

		/* check if cks1 is specified */
		if (!(ctx->flags & IPMI_D_NO_CKS)) {
			guint8 cks = tvb_get_guint8(tvb, offset);

			/* Header checksum */
			if (ctx->cks1) {
				guint8 correct = cks - ctx->cks1;

				proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_crc,
						tvb, offset++, 1, cks,
						"0x%02x (incorrect, expected 0x%02x)", cks, correct);
			} else {
				proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_crc,
						tvb, offset++, 1, cks,
						"0x%02x (correct)", cks);
			}
		}

		/* check if request address is specified */
		if (!(ctx->flags & IPMI_D_NO_RQ_SA)) {
			/* add request address field */
			proto_tree_add_item(cmd_tree, hf_ipmi_header_src, tvb,
					offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* check if request sequence is specified */
		if (!(ctx->flags & IPMI_D_NO_SEQ)) {
			/* Sequence number + source LUN */
			tmp_tree = proto_tree_add_subtree_format(cmd_tree, tvb, offset, 1,
					ett_header_byte_4, NULL, "%s: 0x%02x, SeqNo: 0x%02x",
					(ctx->flags & IPMI_D_TMODE) ? "Bridged" : "Source LUN",
							ctx->hdr.rq_lun, ctx->hdr.rq_seq);

			if (ctx->flags & IPMI_D_TMODE) {
				proto_tree_add_item(tmp_tree, hf_ipmi_header_bridged,
						tvb, offset, 1, ENC_LITTLE_ENDIAN);
			} else {
				proto_tree_add_item(tmp_tree, hf_ipmi_header_src_lun,
						tvb, offset, 1, ENC_LITTLE_ENDIAN);
			}

			/* print seq no */
			proto_tree_add_item(tmp_tree, hf_ipmi_header_sequence, tvb,
					offset++, 1, ENC_LITTLE_ENDIAN);
		}

		/* command code */
		proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_header_command,
				tvb, offset++, 1, ctx->hdr.cmd, "%s (0x%02x)",
				cmd->desc, ctx->hdr.cmd);

		if (is_resp) {
			/* completion code */
			proto_tree_add_uint_format_value(cmd_tree,
					hf_ipmi_header_completion, tvb, offset++, 1,
					cc_val, "%s (0x%02x)", cc_str, cc_val);
		}

		if (siglen) {
			/* command prefix (if present) */
			ti = proto_tree_add_item(cmd_tree, hf_ipmi_header_sig, tvb,
					offset, siglen, ENC_NA);
			proto_item_append_text(ti, " (%s)", netfn_str);
		}
	}

	if (tree || (cmd->flags & CMD_CALLRQ)) {
		/* calculate message data length */
		guint data_len = tvb_captured_length(tvb)
				- ctx->hdr_len
				- siglen
				- (is_resp ? 1 : 0)
				- !(ctx->flags & IPMI_D_NO_CKS);

		/* create data subset */
		tvbuff_t * data_tvb = tvb_new_subset_length(tvb,
				ctx->hdr_len + siglen + (is_resp ? 1 : 0), data_len);

		/* Select sub-handler */
		ipmi_cmd_handler_t hnd = is_resp ? cmd->parse_resp : cmd->parse_req;

		if (hnd && tvb_captured_length(data_tvb)) {
			/* create data field */
			tmp_tree = proto_tree_add_subtree(cmd_tree, data_tvb, 0, -1, ett_data, NULL, "Data");

			/* save current command */
			data->curr_hdr = &ctx->hdr;

			/* save current completion code */
			data->curr_ccode = cc_val;

			/* call command parser */
			hnd(data_tvb, pinfo, tmp_tree);
		}
	}

	/* check if cks2 is specified */
	if (tree && !(ctx->flags & IPMI_D_NO_CKS)) {
		guint8 cks;

		/* get cks2 offset */
		offset = tvb_captured_length(tvb) - 1;

		/* get cks2 */
		cks = tvb_get_guint8(tvb, offset);

		/* Header checksum */
		if (ctx->cks2) {
			guint8 correct = cks - ctx->cks2;

			proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_data_crc,
					tvb, offset, 1, cks,
					"0x%02x (incorrect, expected 0x%02x)", cks, correct);
		} else {
			proto_tree_add_uint_format_value(cmd_tree, hf_ipmi_data_crc,
					tvb, offset, 1, cks,
					"0x%02x (correct)", cks);
		}
	}

	/* decrement next nest level */
	data->next_level = data->curr_level;

	/* restore previous nest level */
	data->curr_level = prev_level;

	return tvb_captured_length(tvb);
}
Ejemplo n.º 22
0
static void
dissect_bfd_authentication(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    int         offset    = 24;
    guint8      auth_type;
    guint8      auth_len;
    proto_item *ti        = NULL;
    proto_item *auth_item = NULL;
    proto_tree *auth_tree = NULL;
    guint8     *password;

    auth_type = tvb_get_guint8(tvb, offset);
    auth_len  = tvb_get_guint8(tvb, offset + 1);

    if (tree) {
        auth_tree = proto_tree_add_subtree_format(tree, tvb, offset, auth_len,
                                        ett_bfd_auth, NULL, "Authentication: %s",
                                        val_to_str(auth_type,
                                                   bfd_control_auth_type_values,
                                                   "Unknown Authentication Type (%d)") );

        proto_tree_add_item(auth_tree, hf_bfd_auth_type, tvb, offset, 1, ENC_BIG_ENDIAN);

        ti = proto_tree_add_item(auth_tree, hf_bfd_auth_len, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
        proto_item_append_text(ti, " bytes");

        proto_tree_add_item(auth_tree, hf_bfd_auth_key, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
    }

    switch (auth_type) {
        case BFD_AUTH_SIMPLE:
            if (tree) {
                password = tvb_get_string_enc(wmem_packet_scope(), tvb, offset+3, auth_len-3, ENC_ASCII);
                proto_tree_add_string(auth_tree, hf_bfd_auth_password, tvb, offset+3,
                                      auth_len-3, password);
                proto_item_append_text(auth_item, ": %s", password);
            }
            break;
        case BFD_AUTH_MD5:
        case BFD_AUTH_MET_MD5:
        case BFD_AUTH_SHA1:
        case BFD_AUTH_MET_SHA1:
            if (auth_len != get_bfd_required_auth_len(auth_type)) {
                if (tree) {
                    ti = proto_tree_add_text(auth_tree, tvb, offset, auth_len,
                                             "Length of authentication is invalid (%d)", auth_len);
                    proto_item_append_text(auth_item, ": Invalid Authentication Section");
                }
                expert_add_info_format(pinfo, ti, &ei_bfd_auth_len_invalid,
                        "Length of authentication section is invalid for Authentication Type: %s",
                        val_to_str(auth_type, bfd_control_auth_type_values, "Unknown Authentication Type (%d)") );
            }

            if (tree) {
                proto_tree_add_item(auth_tree, hf_bfd_auth_seq_num, tvb, offset+4, 4, ENC_BIG_ENDIAN);

                proto_tree_add_text(auth_tree, tvb, offset+8, get_bfd_checksum_len(auth_type), "Checksum: 0x%s",
                                    tvb_bytes_to_ep_str(tvb, offset+8, get_bfd_checksum_len(auth_type)) );
            }
            break;
        default:
            break;
    }
}
Ejemplo n.º 23
0
/*FUNCTION:------------------------------------------------------
 *  NAME
 *      dissect_zbee_secure
 *  DESCRIPTION
 *      Dissects and decrypts secured ZigBee frames.
 *
 *      Will return a valid tvbuff only if security processing was
 *      successful. If processing fails, then this function will
 *      handle internally and return NULL.
 *  PARAMETERS
 *      tvbuff_t    *tvb    - pointer to buffer containing raw packet.
 *      packet_info *pinfo  - pointer to packet information fields
 *      proto_tree  *tree   - pointer to data tree Wireshark uses to display packet.
 *      guint       offset  - pointer to the start of the auxiliary security header.
 *      guint64     src64   - extended source address, or 0 if unknown.
 *  RETURNS
 *      tvbuff_t *
 *---------------------------------------------------------------
 */
tvbuff_t *
dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint offset)
{
    proto_tree     *sec_tree;

    zbee_security_packet    packet;
    guint           mic_len;
    gint            payload_len;
    tvbuff_t       *payload_tvb;

#ifdef HAVE_LIBGCRYPT
    proto_item         *ti;
    proto_item         *key_item;
    guint8             *enc_buffer;
    guint8             *dec_buffer;
    gboolean            decrypted;
    GSList            **nwk_keyring;
    GSList             *GSList_i;
    key_record_t       *key_rec = NULL;
#endif
    zbee_nwk_hints_t   *nwk_hints;
    ieee802154_hints_t *ieee_hints;
    ieee802154_map_rec *map_rec = NULL;

    static const int * sec_flags[] = {
        &hf_zbee_sec_key_id,
        &hf_zbee_sec_nonce,
        NULL
    };

    /* Init */
    memset(&packet, 0, sizeof(zbee_security_packet));

    /* Get pointers to any useful frame data from lower layers */
    nwk_hints = (zbee_nwk_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
                proto_get_id_by_filter_name(ZBEE_PROTOABBREV_NWK), 0);
    ieee_hints = (ieee802154_hints_t *)p_get_proto_data(wmem_file_scope(), pinfo,
                 proto_get_id_by_filter_name(IEEE802154_PROTOABBREV_WPAN), 0);

    /* Create a subtree for the security information. */
    sec_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_zbee_sec, NULL, "ZigBee Security Header");

    /*  Get and display the Security control field */
    packet.control  = tvb_get_guint8(tvb, offset);

    /* Patch the security level. */
    packet.control &= ~ZBEE_SEC_CONTROL_LEVEL;
    packet.control |= (ZBEE_SEC_CONTROL_LEVEL & gPREF_zbee_sec_level);

    /*
     * Eww, I think I just threw up a little...  ZigBee requires this field
     * to be patched before computing the MIC, but we don't have write-access
     * to the tvbuff. So we need to allocate a copy of the whole thing just
     * so we can fix these 3 bits. Memory allocated by tvb_memdup(wmem_packet_scope(),...)
     * is automatically freed before the next packet is processed.
     */
#ifdef HAVE_LIBGCRYPT
    enc_buffer = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, 0, tvb_captured_length(tvb));
    /*
     * Override the const qualifiers and patch the security level field, we
     * know it is safe to overide the const qualifiers because we just
     * allocated this memory via tvb_memdup(wmem_packet_scope(),...).
     */
    enc_buffer[offset] = packet.control;
#endif /* HAVE_LIBGCRYPT */
    packet.level    = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_LEVEL);
    packet.key_id   = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_KEY);
    packet.nonce    = zbee_get_bit_field(packet.control, ZBEE_SEC_CONTROL_NONCE);

    proto_tree_add_bitmask(sec_tree, tvb, offset, hf_zbee_sec_field, ett_zbee_sec_control, sec_flags, ENC_NA);
    offset += 1;

    /* Get and display the frame counter field. */
    packet.counter = tvb_get_letohl(tvb, offset);
    proto_tree_add_uint(sec_tree, hf_zbee_sec_counter, tvb, offset, 4, packet.counter);
    offset += 4;

    if (packet.nonce) {
        /* Get and display the source address of the device that secured this payload. */
        packet.src64 = tvb_get_letoh64(tvb, offset);
        proto_tree_add_item(sec_tree, hf_zbee_sec_src64, tvb, offset, 8, ENC_LITTLE_ENDIAN);
#if 1
        if (!pinfo->fd->flags.visited) {
            switch ( packet.key_id ) {
            case ZBEE_SEC_KEY_LINK:
                if (nwk_hints && ieee_hints) {
                    /* Map this long address with the nwk layer short address. */
                    nwk_hints->map_rec = ieee802154_addr_update(&zbee_nwk_map, nwk_hints->src,
                                         ieee_hints->src_pan, packet.src64, pinfo->current_proto, pinfo->num);
                }
                break;

            case ZBEE_SEC_KEY_NWK:
                if (ieee_hints) {
                    /* Map this long address with the ieee short address. */
                    ieee_hints->map_rec = ieee802154_addr_update(&zbee_nwk_map, ieee_hints->src16,
                                          ieee_hints->src_pan, packet.src64, pinfo->current_proto, pinfo->num);
                }
                break;

            /* We ignore the extended source addresses used to encrypt payloads with these
             * types of keys, because they can emerge from APS tunnels created by nodes whose
             * short address is not recorded in the packet. */
            case ZBEE_SEC_KEY_TRANSPORT:
            case ZBEE_SEC_KEY_LOAD:
                break;
            }
        }
#endif
        offset += 8;
    }
    else {
        /* Look for a source address in hints */
        switch ( packet.key_id ) {
        case ZBEE_SEC_KEY_NWK:
            /* use the ieee extended source address for NWK decryption */
            if ( ieee_hints && (map_rec = ieee_hints->map_rec) )
                packet.src64 = map_rec->addr64;
            else
                proto_tree_add_expert(sec_tree, pinfo, &ei_zbee_sec_extended_source_unknown, tvb, 0, 0);
            break;

        default:
            /* use the nwk extended source address for APS decryption */
            if ( nwk_hints && (map_rec = nwk_hints->map_rec) )
                packet.src64 = map_rec->addr64;
            else
                proto_tree_add_expert(sec_tree, pinfo, &ei_zbee_sec_extended_source_unknown, tvb, 0, 0);
            break;
        }
    }

    if (packet.key_id == ZBEE_SEC_KEY_NWK) {
        /* Get and display the key sequence number. */
        packet.key_seqno = tvb_get_guint8(tvb, offset);
        proto_tree_add_uint(sec_tree, hf_zbee_sec_key_seqno, tvb, offset, 1, packet.key_seqno);
        offset += 1;
    }

    /* Determine the length of the MIC. */
    switch (packet.level) {
    case ZBEE_SEC_ENC:
    case ZBEE_SEC_NONE:
    default:
        mic_len=0;
        break;

    case ZBEE_SEC_ENC_MIC32:
    case ZBEE_SEC_MIC32:
        mic_len=4;
        break;

    case ZBEE_SEC_ENC_MIC64:
    case ZBEE_SEC_MIC64:
        mic_len=8;
        break;

    case ZBEE_SEC_ENC_MIC128:
    case ZBEE_SEC_MIC128:
        mic_len=16;
        break;
    } /* switch */

    /* Get and display the MIC. */
    if (mic_len) {
        /* Display the MIC. */
        proto_tree_add_item(sec_tree, hf_zbee_sec_mic, tvb, (gint)(tvb_captured_length(tvb)-mic_len),
                            mic_len, ENC_NA);
    }

    /* Check for null payload. */
    payload_len = tvb_reported_length_remaining(tvb, offset+mic_len);
    if (payload_len == 0)
        return NULL;

    /**********************************************
     *  Perform Security Operations on the Frame  *
     **********************************************
     */
    if ((packet.level == ZBEE_SEC_NONE) ||
            (packet.level == ZBEE_SEC_MIC32) ||
            (packet.level == ZBEE_SEC_MIC64) ||
            (packet.level == ZBEE_SEC_MIC128)) {

        /* Payload is only integrity protected. Just return the sub-tvbuff. */
        return tvb_new_subset_length(tvb, offset, payload_len);
    }

#ifdef HAVE_LIBGCRYPT
    /* Have we captured all the payload? */
    if (tvb_captured_length_remaining(tvb, offset+mic_len) < payload_len) {
        /*
         * No - don't try to decrypt it.
         *
         * XXX - it looks as if the decryption code is assuming we have the
         * MIC, which won't be the case if the packet was cut short.  Is
         * that in fact that case, or can we still make this work with a
         * partially-captured packet?
         */
        /* Add expert info. */
        expert_add_info(pinfo, sec_tree, &ei_zbee_sec_encrypted_payload_sliced);
        /* Create a buffer for the undecrypted payload. */
        payload_tvb = tvb_new_subset_length(tvb, offset, payload_len);
        /* Dump the payload to the data dissector. */
        call_data_dissector(payload_tvb, pinfo, tree);
        /* Couldn't decrypt, so return NULL. */
        return NULL;
    }

    /* Allocate memory to decrypt the payload into. */
    dec_buffer = (guint8 *)wmem_alloc(pinfo->pool, payload_len);

    decrypted = FALSE;
    if ( packet.src64 ) {
        if (pinfo->fd->flags.visited) {
            if ( nwk_hints ) {
                /* Use previously found key */
                switch ( packet.key_id ) {
                case ZBEE_SEC_KEY_NWK:
                    if ( (key_rec = nwk_hints->nwk) ) {
                        decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
                                                              payload_len, mic_len, nwk_hints->nwk->key);
                    }
                    break;

                default:
                    if ( (key_rec = nwk_hints->link) ) {
                        decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
                                                              payload_len, mic_len, nwk_hints->link->key);
                    }
                    break;
                }
            }
        } /* ( !pinfo->fd->flags.visited ) */
        else {
            /* We only search for sniffed keys in the first pass,
             * to save time, and because decrypting with keys
             * transported in future packets is cheating */

            /* Lookup NWK and link key in hash for this pan. */
            /* This overkill approach is a placeholder for a hash that looks up
             * a key ring for a link key associated with a pair of devices.
             */
            if ( nwk_hints ) {
                nwk_keyring = (GSList **)g_hash_table_lookup(zbee_table_nwk_keyring, &nwk_hints->src_pan);

                if ( nwk_keyring ) {
                    GSList_i = *nwk_keyring;
                    while ( GSList_i && !decrypted ) {
                        decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
                                                              payload_len, mic_len, ((key_record_t *)(GSList_i->data))->key);

                        if (decrypted) {
                            /* save pointer to the successful key record */
                            switch (packet.key_id) {
                            case ZBEE_SEC_KEY_NWK:
                                key_rec = nwk_hints->nwk = (key_record_t *)(GSList_i->data);
                                break;

                            default:
                                key_rec = nwk_hints->link = (key_record_t *)(GSList_i->data);
                                break;
                            }
                        } else {
                            GSList_i = g_slist_next(GSList_i);
                        }
                    }
                }

                /* Loop through user's password table for preconfigured keys, our last resort */
                GSList_i = zbee_pc_keyring;
                while ( GSList_i && !decrypted ) {
                    decrypted = zbee_sec_decrypt_payload( &packet, enc_buffer, offset, dec_buffer,
                                                          payload_len, mic_len, ((key_record_t *)(GSList_i->data))->key);

                    if (decrypted) {
                        /* save pointer to the successful key record */
                        switch (packet.key_id) {
                        case ZBEE_SEC_KEY_NWK:
                            key_rec = nwk_hints->nwk = (key_record_t *)(GSList_i->data);
                            break;

                        default:
                            key_rec = nwk_hints->link = (key_record_t *)(GSList_i->data);
                            break;
                        }
                    } else {
                        GSList_i = g_slist_next(GSList_i);
                    }
                }
            }
        } /* ( ! pinfo->fd->flags.visited ) */
    } /* ( packet.src64 ) */

    if ( decrypted ) {
        if ( tree && key_rec ) {
            key_item = proto_tree_add_bytes(sec_tree, hf_zbee_sec_key, tvb, 0, ZBEE_SEC_CONST_KEYSIZE, key_rec->key);
            PROTO_ITEM_SET_GENERATED(key_item);

            if ( key_rec->frame_num == ZBEE_SEC_PC_KEY ) {
                ti = proto_tree_add_string(sec_tree, hf_zbee_sec_decryption_key, tvb, 0, 0, key_rec->label);
            } else {
                ti = proto_tree_add_uint(sec_tree, hf_zbee_sec_key_origin, tvb, 0, 0,
                                         key_rec->frame_num);
            }
            PROTO_ITEM_SET_GENERATED(ti);
        }

        /* Found a key that worked, setup the new tvbuff_t and return */
        payload_tvb = tvb_new_child_real_data(tvb, dec_buffer, payload_len, payload_len);
        add_new_data_source(pinfo, payload_tvb, "Decrypted ZigBee Payload");

        /* Done! */
        return payload_tvb;
    }
#endif /* HAVE_LIBGCRYPT */

    /* Add expert info. */
    expert_add_info(pinfo, sec_tree, &ei_zbee_sec_encrypted_payload);
    /* Create a buffer for the undecrypted payload. */
    payload_tvb = tvb_new_subset_length(tvb, offset, payload_len);
    /* Dump the payload to the data dissector. */
    call_data_dissector(payload_tvb, pinfo, tree);
    /* Couldn't decrypt, so return NULL. */
    return NULL;
} /* dissect_zbee_secure */
Ejemplo n.º 24
0
static int
dissect_form_urlencoded(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	proto_tree	*url_tree;
	proto_tree	*sub;
	proto_item	*ti;
	gint		offset = 0, next_offset;
	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;
			}
		}
	}

	if (data_name)
		col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)", data_name);

	ti = proto_tree_add_item(tree, hfi_urlencoded, tvb, 0, -1, ENC_NA);
	if (data_name)
		proto_item_append_text(ti, ": %s", data_name);
	url_tree = proto_item_add_subtree(ti, ett_form_urlencoded);

	while (tvb_reported_length_remaining(tvb, offset) > 0) {
		const int start_offset = offset;
		char *key, *value;

		ti = proto_tree_add_item(url_tree, &hfi_form_keyvalue, tvb, offset, 0, ENC_NA);

		sub = proto_item_add_subtree(ti, ett_form_keyvalue);

		next_offset = get_form_key_value(tvb, &key, offset, '=');
		if (next_offset == -1)
			break;
		proto_tree_add_string(sub, &hfi_form_key, tvb, offset, next_offset - offset, key);
		proto_item_append_text(sub, ": \"%s\"", key);

		offset = next_offset+1;

		next_offset = get_form_key_value(tvb, &value, offset, '&');
		if (next_offset == -1)
			break;
		proto_tree_add_string(sub, &hfi_form_value, tvb, offset, next_offset - offset, value);
		proto_item_append_text(sub, " = \"%s\"", value);

		offset = next_offset+1;

		proto_item_set_len(ti, offset - start_offset);
	}

	return tvb_length(tvb);
}
Ejemplo n.º 25
0
static void dissect_cimd_ud(tvbuff_t *tvb, proto_tree *tree, gint pindex, gint startOffset, gint endOffset)
{
  /* Set up structures needed to add the param subtree and manage it */
  proto_item *param_item;
  proto_tree *param_tree;

  gchar* payloadText;
  gchar* tmpBuffer          = (gchar*)ep_alloc(1024);
  gchar* tmpBuffer1         = (gchar*)ep_alloc(1024);
  int    loop,i,poz, bufPoz = 0, bufPoz1 = 0, size, size1, resch;
  gint   g_offset, g_size;
  gchar  token[4];
  gchar  ch;
  const char* mapping[128]  = {
    "_Oa" , "_L-", ""    , "_Y-", "_e`", "_e'", "_u`", "_i`", "_o`", "_C,",        /*10*/
    ""    , "_O/", "_o/" , ""   , "_A*", "_a*", "_gd", "_--", "_gf", "_gg", "_gl", /*21*/
    "_go" , "_gp", "_gi" , "_gs", "_gt", "_gx", "_XX", "_AE", "_ae", "_ss", "_E'", /*32*/
    ""    , ""   , "_qq" , ""   , "_ox", ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "",
    ""    , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "",
    "_!!" , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "",
    ""    , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , "_A\"", "_O\"", "_N~",
    "_U\"", "_so", "_??" , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   ,
    ""    , ""   , ""    , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""   , ""    , ""    , ""   , "", "_a\"",
    "_o\"", "_n~", "_n\"","_a`"
  };

  param_item = proto_tree_add_text(tree, tvb,
    startOffset + 1, endOffset - (startOffset + 1),
    "%s", cimd_vals_PC[pindex].strptr
  );
  param_tree = proto_item_add_subtree(param_item, (*vals_hdr_PC[pindex].ett_p));
  proto_tree_add_string(param_tree, hf_cimd_pcode_indicator, tvb,
    startOffset + 1, CIMD_PC_LENGTH, tvb_format_text(tvb, startOffset + 1, CIMD_PC_LENGTH)
  );

  g_offset = startOffset + 1 + CIMD_PC_LENGTH + 1;
  g_size   = endOffset - g_offset;

  payloadText = tvb_format_text(tvb, g_offset, g_size);
  size = (int)strlen(payloadText);
  for (loop = 0; loop < size; loop++)
  {
    if (payloadText[loop] == '_')
    {
      if (loop < size - 2)
      {
        token[0] = payloadText[loop++];
        token[1] = payloadText[loop++];
        token[2] = payloadText[loop];
        token[3] = '\0';
        poz = -1;
        for (i = 0; i < 128; i++)
        {
          if (strcmp(token, mapping[i]) == 0)
          {
            poz = i;
            break;
          }
        }
        if (poz > 0)
        {
          tmpBuffer[bufPoz++] = poz;
        }
        else
        {
          tmpBuffer[bufPoz++] = payloadText[loop-2];
          tmpBuffer[bufPoz++] = payloadText[loop-1];
          tmpBuffer[bufPoz++] = payloadText[loop];
        }
      }
      else
      {
        if (loop < size) tmpBuffer[bufPoz++] = payloadText[loop++];
        if (loop < size) tmpBuffer[bufPoz++] = payloadText[loop++];
        if (loop < size) tmpBuffer[bufPoz++] = payloadText[loop++];
      }
    }
    else
    {
      tmpBuffer[bufPoz++] = payloadText[loop];
    }
  }
  tmpBuffer[bufPoz] = '\0';

  size1 = (int)strlen(tmpBuffer);
  for (loop=0; loop<size1; loop++)
  {
    ch = tmpBuffer[loop];
    switch ((gint)ch)
    {
    case 0x40: resch = 0x0040; break;
    case 0x01: resch = 0x00A3; break;
    case 0x02: resch = 0x0024; break;
    case 0x03: resch = 0x00A5; break;
    case 0x04: resch = 0x00E8; break;
    case 0x05: resch = 0x00E9; break;
    case 0x06: resch = 0x00F9; break;
    case 0x07: resch = 0x00EC; break;
    case 0x08: resch = 0x00F2; break;
    case 0x09: resch = 0x00E7; break;
    case 0x0B: resch = 0x00D8; break;
    case 0x0C: resch = 0x00F8; break;
    case 0x0E: resch = 0x00C5; break;
    case 0x0F: resch = 0x00E5; break;
    case 0x11: resch = 0x005F; break;
/*  case 0x1B14: resch = 0x005E; break; */
/*  case 0x1B28: resch = 0x007B; break; */
/*  case 0x1B29: resch = 0x007D; break; */
/*  case 0x1B2F: resch = 0x005C; break; */
/*  case 0x1B3C: resch = 0x005B; break; */
/*  case 0x1B3D: resch = 0x007E; break; */
/*  case 0x1B3E: resch = 0x005D; break; */
/*  case 0x1B40: resch = 0x007C; break; */
    case 0x1C: resch = 0x00C6; break;
    case 0x1D: resch = 0x00E6; break;
    case 0x1E: resch = 0x00DF; break;
    case 0x1F: resch = 0x00C9; break;
    case 0x20: resch = 0x0020; break;
    case 0x21: resch = 0x0021; break;
    case 0x22: resch = 0x0022; break;
    case 0x23: resch = 0x0023; break;
    case 0xA4: resch = 0x00A4; break;
    case 0x25: resch = 0x0025; break;
    case 0x26: resch = 0x0026; break;
    case 0x27: resch = 0x0027; break;
    case 0x28: resch = 0x0028; break;
    case 0x29: resch = 0x0029; break;
    case 0x2A: resch = 0x002A; break;
    case 0x2B: resch = 0x002B; break;
    case 0x2C: resch = 0x002C; break;
    case 0x2D: resch = 0x002D; break;
    case 0x2E: resch = 0x002E; break;
    case 0x2F: resch = 0x002F; break;
    case 0x30: resch = 0x0030; break;
    case 0x31: resch = 0x0031; break;
    case 0x32: resch = 0x0032; break;
    case 0x33: resch = 0x0033; break;
    case 0x34: resch = 0x0034; break;
    case 0x35: resch = 0x0035; break;
    case 0x36: resch = 0x0036; break;
    case 0x37: resch = 0x0037; break;
    case 0x38: resch = 0x0038; break;
    case 0x39: resch = 0x0039; break;
    case 0x3A: resch = 0x003A; break;
    case 0x3B: resch = 0x003B; break;
    case 0x3C: resch = 0x003C; break;
    case 0x3D: resch = 0x003D; break;
    case 0x3E: resch = 0x003E; break;
    case 0x3F: resch = 0x003F; break;
/*  case 0x40: resch = 0x00A1; break; */
    case 0x41: resch = 0x0041; break;
    case 0x42: resch = 0x0042; break;
/*  case 0x42: resch = 0x0392; break; */
    case 0x43: resch = 0x0043; break;
    case 0x44: resch = 0x0044; break;
    case 0x45: resch = 0x0045; break;
    case 0x46: resch = 0x0046; break;
    case 0x47: resch = 0x0047; break;
    case 0x48: resch = 0x0048; break;
    case 0x49: resch = 0x0049; break;
    case 0x4A: resch = 0x004A; break;
    case 0x4B: resch = 0x004B; break;
    case 0x4C: resch = 0x004C; break;
    case 0x4D: resch = 0x004D; break;
    case 0x4E: resch = 0x004E; break;
    case 0x4F: resch = 0x004F; break;
    case 0x50: resch = 0x0050; break;
    case 0x51: resch = 0x0051; break;
    case 0x52: resch = 0x0052; break;
    case 0x53: resch = 0x0053; break;
    case 0x54: resch = 0x0054; break;
    case 0x55: resch = 0x0055; break;
    case 0x56: resch = 0x0056; break;
    case 0x57: resch = 0x0057; break;
    case 0x58: resch = 0x0058; break;
    case 0x59: resch = 0x0059; break;
    case 0x5A: resch = 0x005A; break;
    case 0x5B: resch = 0x00C4; break;
    case 0x5C: resch = 0x00D6; break;
    case 0x5D: resch = 0x00D1; break;
    case 0x5E: resch = 0x00DC; break;
    case 0x5F: resch = 0x00A7; break;
    case 0x60: resch = 0x00BF; break;
    case 0x61: resch = 0x0061; break;
    case 0x62: resch = 0x0062; break;
    case 0x63: resch = 0x0063; break;
    case 0x64: resch = 0x0064; break;
    case 0x65: resch = 0x0065; break;
    case 0x66: resch = 0x0066; break;
    case 0x67: resch = 0x0067; break;
    case 0x68: resch = 0x0068; break;
    case 0x69: resch = 0x0069; break;
    case 0x6A: resch = 0x006A; break;
    case 0x6B: resch = 0x006B; break;
    case 0x6C: resch = 0x006C; break;
    case 0x6D: resch = 0x006D; break;
    case 0x6E: resch = 0x006E; break;
    case 0x6F: resch = 0x006F; break;
    case 0x70: resch = 0x0070; break;
    case 0x71: resch = 0x0071; break;
    case 0x72: resch = 0x0072; break;
    case 0x73: resch = 0x0073; break;
    case 0x74: resch = 0x0074; break;
    case 0x75: resch = 0x0075; break;
    case 0x76: resch = 0x0076; break;
    case 0x77: resch = 0x0077; break;
    case 0x78: resch = 0x0078; break;
    case 0x79: resch = 0x0079; break;
    case 0x7A: resch = 0x007A; break;
    case 0x7B: resch = 0x00E4; break;
    case 0x7C: resch = 0x00F6; break;
    case 0x7D: resch = 0x00F1; break;
    case 0x7F: resch = 0x00E0; break;
    default:resch = ch; break;
    }
    tmpBuffer1[bufPoz1++] = (gchar)resch;
  }

  tmpBuffer1[bufPoz1] = '\0';
  proto_tree_add_string(param_tree, (*vals_hdr_PC[pindex].hf_p), tvb, g_offset, g_size, tmpBuffer1);
}
Ejemplo n.º 26
0
/* dissect the "device" suboption */
static int
dissect_PNDCP_Suboption_Device(tvbuff_t *tvb, int offset, packet_info *pinfo,
                               proto_tree *tree, proto_item *block_item, proto_item *dcp_item,
                               guint8 service_id, gboolean is_response)
{
    guint8    suboption;
    guint16   block_length;
    gchar    *info_str;
    guint8    device_role;
    guint16   vendor_id;
    guint16   device_id;
    char     *typeofstation;
    char     *nameofstation;
    char     *aliasname;
    guint16   block_info;
    guint16   block_qualifier;
    gboolean  have_block_info      = FALSE;
    gboolean  have_block_qualifier = FALSE;
    guint8    device_instance_high;
    guint8    device_instance_low;


    /* SuboptionDevice... */
    offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device, &suboption);
    /* DCPBlockLength */
    offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_length, &block_length);

    /* BlockInfo? */
    if ( ((service_id == PNDCP_SERVICE_ID_IDENTIFY) &&  is_response) ||
         ((service_id == PNDCP_SERVICE_ID_HELLO)    && !is_response) ||
         ((service_id == PNDCP_SERVICE_ID_GET)      &&  is_response)) {
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_info, &block_info);
        have_block_info = TRUE;
        block_length -= 2;
    }

    /* BlockQualifier? */
    if ( (service_id == PNDCP_SERVICE_ID_SET) && !is_response) {
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_block_qualifier, &block_qualifier);
        have_block_qualifier = TRUE;
        block_length -= 2;
    }

    switch (suboption) {
    case PNDCP_SUBOPTION_DEVICE_MANUF:
        typeofstation = (char *)wmem_alloc(wmem_packet_scope(), block_length+1);
        tvb_memcpy(tvb, (guint8 *) typeofstation, offset, block_length);
        typeofstation[block_length] = '\0';
        proto_tree_add_string (tree, hf_pn_dcp_suboption_device_typeofstation, tvb, offset, block_length, typeofstation);
        pn_append_info(pinfo, dcp_item, ", DeviceVendorValue");
        proto_item_append_text(block_item, "Device/Manufacturer specific");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info){
            proto_item_append_text(block_item, ", BlockInfo: %s",
                                   val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        }
        proto_item_append_text(block_item, ", DeviceVendorValue: \"%s\"", typeofstation);
        offset += block_length;
        break;
    case PNDCP_SUBOPTION_DEVICE_NAMEOFSTATION:
        nameofstation = (char *)wmem_alloc(wmem_packet_scope(), block_length+1);
        tvb_memcpy(tvb, (guint8 *) nameofstation, offset, block_length);
        nameofstation[block_length] = '\0';
        proto_tree_add_string (tree, hf_pn_dcp_suboption_device_nameofstation, tvb, offset, block_length, nameofstation);
        pn_append_info(pinfo, dcp_item, wmem_strdup_printf(wmem_packet_scope(), ", NameOfStation:\"%s\"", nameofstation));
        proto_item_append_text(block_item, "Device/NameOfStation");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info) {
            proto_item_append_text(block_item, ", BlockInfo: %s",
                                   val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        }
        proto_item_append_text(block_item, ", \"%s\"", nameofstation);
        offset += block_length;
        break;
    case PNDCP_SUBOPTION_DEVICE_DEV_ID:
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_vendor_id, &vendor_id);
        offset = dissect_pn_uint16(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_id, &device_id);
        pn_append_info(pinfo, dcp_item, ", Dev-ID");
        proto_item_append_text(block_item, "Device/Device ID");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info) {
            proto_item_append_text(block_item, ", BlockInfo: %s",
                                   val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        }
        proto_item_append_text(block_item, ", VendorID: 0x%04x / DeviceID: 0x%04x", vendor_id, device_id);
        break;
    case PNDCP_SUBOPTION_DEVICE_DEV_ROLE:
        offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_role, &device_role);
        offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_reserved8, NULL);
        pn_append_info(pinfo, dcp_item, ", Dev-Role");
        proto_item_append_text(block_item, "Device/Device Role");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info)
            proto_item_append_text(block_item, ", BlockInfo: %s", val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        if (device_role & 0x01)
            proto_item_append_text(block_item, ", IO-Device");
        if (device_role & 0x02)
            proto_item_append_text(block_item, ", IO-Controller");
        if (device_role & 0x04)
            proto_item_append_text(block_item, ", IO-Multidevice");
        if (device_role & 0x08)
            proto_item_append_text(block_item, ", PN-Supervisor");
        break;
    case PNDCP_SUBOPTION_DEVICE_DEV_OPTIONS:
        info_str = wmem_strdup_printf(wmem_packet_scope(), ", Dev-Options(%u)", block_length/2);
        pn_append_info(pinfo, dcp_item, info_str);
        proto_item_append_text(block_item, "Device/Device Options");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info) {
            proto_item_append_text(block_item, ", BlockInfo: %s",
                                   val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        }
        proto_item_append_text(block_item, ", %u options", block_length/2);
        for( ; block_length != 0; block_length -= 2) {
            offset = dissect_PNDCP_Option(tvb, offset, pinfo, tree, NULL /*block_item*/, hf_pn_dcp_option,
                FALSE /* append_col */);
        }
        break;
    case PNDCP_SUBOPTION_DEVICE_ALIAS_NAME:
        aliasname = (char *)wmem_alloc(wmem_packet_scope(), block_length+1);
        tvb_memcpy(tvb, (guint8 *) aliasname, offset, block_length);
        aliasname[block_length] = '\0';
        proto_tree_add_string (tree, hf_pn_dcp_suboption_device_aliasname, tvb, offset, block_length, aliasname);
        pn_append_info(pinfo, dcp_item, wmem_strdup_printf(wmem_packet_scope(), ", AliasName:\"%s\"", aliasname));
        proto_item_append_text(block_item, "Device/AliasName");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info) {
            proto_item_append_text(block_item, ", BlockInfo: %s",
                                   val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        }
        proto_item_append_text(block_item, ", \"%s\"", aliasname);
        offset += block_length;
        break;
    case PNDCP_SUBOPTION_DEVICE_DEV_INSTANCE:
        offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_instance_high, &device_instance_high);
        offset = dissect_pn_uint8(tvb, offset, pinfo, tree, hf_pn_dcp_suboption_device_instance_low, &device_instance_low);
        pn_append_info(pinfo, dcp_item, ", Dev-Instance");
        proto_item_append_text(block_item, "Device/Device Instance");
        if (have_block_qualifier) {
            proto_item_append_text(block_item, ", BlockQualifier: %s",
                                   val_to_str(block_qualifier, pn_dcp_block_qualifier, "Unknown"));
        }
        if (have_block_info) {
            proto_item_append_text(block_item, ", BlockInfo: %s",
                                   val_to_str(block_info, pn_dcp_block_info, "Unknown"));
        }
        proto_item_append_text(block_item, ", InstanceHigh: %d, Instance Low: %d",
                               device_instance_high, device_instance_low);
        break;
    default:
        offset = dissect_pn_undecoded(tvb, offset, pinfo, tree, block_length);
    }

    return offset;
}
Ejemplo n.º 27
0
/* dissect a response. more work to do here.
 */
static void
display_rsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ajp13_tree, ajp13_conv_data* cd)
{
  int pos = 0;
  guint8 mcode = 0;
  int i;

  /* MAGIC
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_magic, tvb, pos, 2, ENC_NA);
  pos+=2;

  /* PDU LENGTH
   */
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_len,   tvb, pos, 2, ENC_BIG_ENDIAN);
  pos+=2;

  /* MESSAGE TYPE CODE
   */
  mcode = tvb_get_guint8(tvb, pos);
  col_append_str(pinfo->cinfo, COL_INFO, val_to_str(mcode, mtype_codes, "Unknown message code %u"));
  if (ajp13_tree)
    proto_tree_add_item(ajp13_tree, hf_ajp13_code, tvb, pos, 1, ENC_BIG_ENDIAN);
  pos+=1;

  switch (mcode) {

  case MTYPE_END_RESPONSE:
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_reusep, tvb, pos, 1, ENC_BIG_ENDIAN);
    /*pos+=1;*/
    break;

  case MTYPE_SEND_HEADERS:
  {
    const gchar *rsmsg;
    guint16 rsmsg_len;
    guint16 nhdr;
    guint16 rcode_num;

    /* HTTP RESPONSE STATUS CODE
     */
    rcode_num = tvb_get_ntohs(tvb, pos);
    col_append_fstr(pinfo->cinfo, COL_INFO, ":%d", rcode_num);
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_rstatus, tvb, pos, 2, ENC_BIG_ENDIAN);
    pos+=2;

    /* HTTP RESPONSE STATUS MESSAGE
     */
    rsmsg = ajp13_get_nstring(tvb, pos, &rsmsg_len);
    col_append_fstr(pinfo->cinfo, COL_INFO, " %s", rsmsg);
    if (ajp13_tree)
      proto_tree_add_string(ajp13_tree, hf_ajp13_rsmsg, tvb, pos, rsmsg_len+2, rsmsg);
    pos+=rsmsg_len+2;

    /* NUMBER OF HEADERS
     */
    nhdr = tvb_get_ntohs(tvb, pos);
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_nhdr, tvb, pos, 2, ENC_BIG_ENDIAN);
    pos+=2;

    /* HEADERS
     */
    for(i=0; i<nhdr; i++) {

      guint8 hcd;
      guint8 hid;
      const gchar *hval;
      guint16 hval_len, hname_len;
      const gchar* hname = NULL;
      int hpos = pos;
      /* int cl = 0; TODO: Content-Length header (encoded by 0x08) is special */

      /* HEADER CODE/NAME
       */
      hcd = tvb_get_guint8(tvb, pos);

      if (hcd == 0xA0) {
        pos+=1;
        hid = tvb_get_guint8(tvb, pos);
        pos+=1;

        if (hid >= array_length(rsp_headers))
          hid = 0;

        hval = ajp13_get_nstring(tvb, pos, &hval_len);

        proto_tree_add_string_format_value(ajp13_tree, *rsp_headers[hid],
                                       tvb, hpos, 2+hval_len+2, hval,
                                       "%s", hval);
        pos+=hval_len+2;
#if 0
        /* TODO: Content-Length header (encoded by 0x08) is special */
        if (hid == 0x08)
          cl = 1;
#endif
      } else {
        hname = ajp13_get_nstring(tvb, pos, &hname_len);
        pos+=hname_len+2;

        hval = ajp13_get_nstring(tvb, pos, &hval_len);

        proto_tree_add_string_format(ajp13_tree, hf_ajp13_additional_header,
                                tvb, hpos, hname_len+2+hval_len+2,
                                wmem_strdup_printf(wmem_packet_scope(), "%s: %s", hname, hval),
                                "%s: %s", hname, hval);
        pos+=hval_len+2;
      }
    }
    break;
  }

  case MTYPE_GET_BODY_CHUNK:
  {
    guint16 rlen;
    rlen = tvb_get_ntohs(tvb, pos);
    cd->content_length = rlen;
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_rlen, tvb, pos, 2, ENC_BIG_ENDIAN);
    /*pos+=2;*/
    break;
  }

  case MTYPE_CPONG:
    break;

  default:
    /* MESSAGE DATA (COPOUT)
     */
    if (ajp13_tree)
      proto_tree_add_item(ajp13_tree, hf_ajp13_data,  tvb, pos+2, -1, ENC_UTF_8|ENC_NA);
    break;
  }
}
Ejemplo n.º 28
0
/* ---------------------------------------------- */
static void
dissect_fix_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item    *ti;
    proto_tree    *fix_tree;
    int            pdu_len;
    int            offset = 0;
    int            field_offset, ctrla_offset;
    int            tag_value;
    char          *value;
    char          *tag_str;
    fix_parameter *tag;

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

    /* get at least the fix version: 8=FIX.x.x */
    if (fix_marker(tvb, 0) != 0) {
        /* not a fix packet start but it's a fix packet */
        col_set_str(pinfo->cinfo, COL_INFO, "[FIX continuation]");
        ti = proto_tree_add_item(tree, proto_fix, tvb, 0, -1, ENC_NA);
        fix_tree = proto_item_add_subtree(ti, ett_fix);
        proto_tree_add_item(fix_tree, hf_fix_data, tvb, 0, -1, ENC_NA);
        return;
    }

    pdu_len = tvb_reported_length(tvb);
    ti = proto_tree_add_item(tree, proto_fix, tvb, 0, -1, ENC_NA);
    fix_tree = proto_item_add_subtree(ti, ett_fix);

    /* begin string */
    ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
    if (ctrla_offset == -1) {
        return;
    }
    offset = ctrla_offset + 1;

    /* msg length */
    ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
    if (ctrla_offset == -1) {
        return;
    }
    offset = ctrla_offset + 1;

    /* msg type */
    if (!(tag = fix_param(tvb, offset)) || tag->value_len < 1) {
        return;
    }

    if (check_col(pinfo->cinfo, COL_INFO)) {
        const char *msg_type;

        value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len);
        msg_type = str_to_str(value, messages_val, "FIX Message (%s)");
        col_add_str(pinfo->cinfo, COL_INFO, msg_type);
    }

    /* In the interest of speed, if "tree" is NULL, don't do any work not
     * necessary to generate protocol tree items.
     */
    field_offset = 0;

    while(field_offset < pdu_len && (tag = fix_param(tvb, field_offset)) ) {
        int i, found;

        if (tag->tag_len < 1) {
            field_offset =  tag->ctrla_offset + 1;
            continue;
        }

        tag_str = tvb_get_ephemeral_string(tvb, field_offset, tag->tag_len);
        tag_value = atoi(tag_str);
        if (tag->value_len < 1) {
            proto_tree *field_tree;
            /* XXX - put an error indication here.  It's too late
               to return FALSE; we've already started dissecting,
               and if a heuristic dissector starts dissecting
               (either updating the columns or creating a protocol
               tree) and then gives up, it leaves crud behind that
               messes up other dissectors that might process the
               packet. */
            ti = proto_tree_add_text(fix_tree, tvb, field_offset, tag->field_len, "%i: <missing value>", tag_value);
            field_tree = proto_item_add_subtree(ti, ett_badfield);
            proto_tree_add_uint(field_tree, hf_fix_field_tag, tvb, field_offset, tag->tag_len, tag_value);
            field_offset =  tag->ctrla_offset + 1;
            continue;
        }

        /* fix_fields array is sorted by tag_value */
        found = 0;
        if ((i = tag_search(tag_value)) >= 0) {
            found = 1;
        }

        value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len);
        if (found) {
            if (fix_fields[i].table) {
                if (tree) {
                    switch (fix_fields[i].type) {
                    case 1: /* strings */
                        proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value,
                            "%s (%s)", value, str_to_str(value, fix_fields[i].table, "unknown %s"));
                        break;
                    case 2: /* char */
                        proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value,
                            "%s (%s)", value, val_to_str(*value, fix_fields[i].table, "unknown %d"));
                        break;
                    default:
                        proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value,
                            "%s (%s)", value, val_to_str(atoi(value), fix_fields[i].table, "unknown %d"));
                        break;
                    }
                }
            }
            else {
              proto_item *item;

              /* checksum */
              switch(tag_value) {
              case 10:
                {
                    proto_tree *checksum_tree;
                    guint8 sum = 0;
                    const guint8 *data = tvb_get_ptr(tvb, 0, field_offset);
                    gboolean sum_ok;
                    int j;

                    for (j = 0; j < field_offset; j++, data++) {
                         sum += *data;
                    }
                    sum_ok = (atoi(value) == sum);
                    if (sum_ok) {
                        item = proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len,
                                value, "%s [correct]", value);
                    }
                    else {
                        item = proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len,
                                value, "%s [incorrect should be %d]", value, sum);
                    }
                    checksum_tree = proto_item_add_subtree(item, ett_checksum);
                    item = proto_tree_add_boolean(checksum_tree, hf_fix_checksum_good, tvb, field_offset, tag->field_len, sum_ok);
                    PROTO_ITEM_SET_GENERATED(item);
                    item = proto_tree_add_boolean(checksum_tree, hf_fix_checksum_bad, tvb, field_offset, tag->field_len, !sum_ok);
                    PROTO_ITEM_SET_GENERATED(item);
                    if (!sum_ok)
                        expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
                }
                break;
              default:
                proto_tree_add_string(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value);
                break;
              }
            }
        }
        else if (tree) {
          proto_tree *field_tree;

          /* XXX - it could be -1 if the tag isn't a number */
          ti = proto_tree_add_text(fix_tree, tvb, field_offset, tag->field_len, "%i: %s", tag_value, value);
          field_tree = proto_item_add_subtree(ti, ett_unknow);
          proto_tree_add_uint(field_tree, hf_fix_field_tag, tvb, field_offset, tag->tag_len, tag_value);
          proto_tree_add_item(field_tree, hf_fix_field_value, tvb, tag->value_offset, tag->value_len, ENC_ASCII|ENC_NA);
        }

        field_offset =  tag->ctrla_offset + 1;

        tag_str = NULL;
    }
    return;
}
Ejemplo n.º 29
0
static void
dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint op;
    guint sub;
    guint rlen;
    guint flags;
    proto_item *ti;
    proto_item *item;
    proto_tree *fip_tree;
    proto_tree *subtree;
    guint dtype;
    guint dlen;
    guint desc_offset;
    guint val;
    tvbuff_t *desc_tvb;
    tvbuff_t *ls_tvb = NULL;
    const char *info;
    char *text;

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

    if (!tvb_bytes_exist(tvb, 0, FIP_HEADER_LEN)) {
        col_set_str(pinfo->cinfo, COL_INFO, "[packet too short]");
        if (tree)
            proto_tree_add_protocol_format(tree, proto_fip, tvb, 0,
                                           -1, "FIP [packet too short]");
        return;
    }

    op = tvb_get_ntohs(tvb, 2);
    sub = tvb_get_guint8(tvb, 5);

    switch (op) {
    case FIP_OP_DISC:
        info = val_to_str(sub, fip_disc_subcodes, "Discovery 0x%x");
        break;
    case FIP_OP_LS:
        info = val_to_str(sub, fip_ls_subcodes, "Link Service 0x%x");
        break;
    case FIP_OP_CTRL:
        info = val_to_str(sub, fip_ctrl_subcodes, "Control 0x%x");
        break;
    case FIP_OP_VLAN:
        info = val_to_str(sub, fip_vlan_subcodes, "VLAN 0x%x");
        break;
    default:
        info = val_to_str(op, fip_opcodes, "Unknown op 0x%x");
        break;
    }

    if (check_col(pinfo->cinfo, COL_INFO))
        col_set_str(pinfo->cinfo, COL_INFO, info);

    rlen = tvb_get_ntohs(tvb, 6);
    flags = tvb_get_ntohs(tvb, 8);

    ti = proto_tree_add_protocol_format(tree, proto_fip, tvb, 0,
                                        FIP_HEADER_LEN + rlen * FIP_BPW,
                                        "FIP %s", info);
    fip_tree = proto_item_add_subtree(ti, ett_fip);
    proto_tree_add_item(fip_tree, hf_fip_ver, tvb, 0, 1, FALSE);
    proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, FALSE);
    switch (op) {
    case FIP_OP_DISC:
        proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, FALSE);
        break;
    case FIP_OP_LS:
        proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, FALSE);
        break;
    case FIP_OP_CTRL:
        proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, FALSE);
        break;
    case FIP_OP_VLAN:
        proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, FALSE);
        break;
    default:
        proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, FALSE);
        break;
    }
    proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, FALSE);

    proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags,
                           ett_fip_flags, hf_fip_flags_fields, FALSE);

    desc_offset = FIP_HEADER_LEN;
    rlen *= FIP_BPW;
    proto_tree_add_text(fip_tree, tvb, desc_offset, rlen, "Descriptors:");

    while (rlen > 0 && tvb_bytes_exist(tvb, desc_offset, 2)) {
        dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW;
        if (!dlen) {
            proto_tree_add_text(fip_tree, tvb, desc_offset, -1,
                                "Descriptor [length error]");
            break;
        }
        if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) {
            break;
        }
        desc_tvb = tvb_new_subset(tvb, desc_offset, dlen, -1);
        dtype = tvb_get_guint8(desc_tvb, 0);
        desc_offset += dlen;
        rlen -= dlen;

        item = proto_tree_add_text(fip_tree, desc_tvb, 0, -1, "Descriptor: %s ",
                                   val_to_str(dtype, fip_desc_types, "Unknown 0x%x"));

        switch (dtype) {
        case FIP_DT_PRI:
            subtree = proto_item_add_subtree(item, ett_fip_dt_pri);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb,
                                3, 1, FALSE);
            proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3));
            break;
        case FIP_DT_MAC:
            subtree = proto_item_add_subtree(item, ett_fip_dt_mac);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb,
                                2, 6, FALSE);
            proto_item_append_text(item, "%s",
                                   tvb_bytes_to_str_punct(desc_tvb, 2, 6, ':'));
            break;
        case FIP_DT_MAP_OUI:
            subtree = proto_item_add_subtree(item, ett_fip_dt_map);
            fip_desc_type_len(subtree, desc_tvb);
            text = fc_to_str(tvb_get_ptr(desc_tvb, 5, 3));
            proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb,
                                  5, 3, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_NAME:
            subtree = proto_item_add_subtree(item, ett_fip_dt_name);
            fip_desc_type_len(subtree, desc_tvb);
            text = fcwwn_to_str(tvb_get_ptr(desc_tvb, 4, 8));
            proto_tree_add_string(subtree, hf_fip_desc_name,
                                  desc_tvb, 4, 8, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_FAB:
            subtree = proto_item_add_subtree(item, ett_fip_dt_fab);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb,
                                2, 2, FALSE);
            text = fc_to_str(tvb_get_ptr(desc_tvb, 5, 3));
            proto_tree_add_string(subtree, hf_fip_desc_fab_map, desc_tvb,
                                  5, 3, text);
            text = fcwwn_to_str(tvb_get_ptr(desc_tvb, 8, 8));
            proto_tree_add_string(subtree, hf_fip_desc_fab_name,
                                  desc_tvb, 8, 8, text);
            proto_item_append_text(item, "%s", text);
            break;
        case FIP_DT_FCOE_SIZE:
            subtree = proto_item_add_subtree(item, ett_fip_dt_mdl);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb,
                                2, 2, FALSE);
            proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
            break;
        case FIP_DT_FLOGI:
        case FIP_DT_FDISC:
        case FIP_DT_LOGO:
        case FIP_DT_ELP:
            subtree = proto_item_add_subtree(item, ett_fip_dt_caps);
            fip_desc_type_len(subtree, desc_tvb);
            ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1);
            call_dissector(fc_handle, ls_tvb, pinfo, subtree);
            proto_item_append_text(item, "%u bytes", dlen - 4);
            break;
        case FIP_DT_VN:
            subtree = proto_item_add_subtree(item, ett_fip_dt_vn);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb,
                                2, 6, FALSE);
            proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb,
                                9, 3, FALSE);
            text = fcwwn_to_str(tvb_get_ptr(desc_tvb, 12, 8));
            proto_tree_add_string(subtree, hf_fip_desc_vn_wwpn,
                                  desc_tvb, 12, 8, text);
            proto_item_append_text(item, "MAC %s  FC_ID %6.6x",
                                   tvb_bytes_to_str_punct(desc_tvb, 2, 6, ':'),
                                   tvb_get_ntoh24(desc_tvb, 9));
            break;
        case FIP_DT_FKA:
            subtree = proto_item_add_subtree(item, ett_fip_dt_fka);
            fip_desc_type_len(subtree, desc_tvb);
            val = tvb_get_ntohl(desc_tvb, 4);
            proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka,
                                             desc_tvb, 4, 4, val, "%u ms", val);
            proto_item_append_text(item, "%u ms", val);
            break;
        case FIP_DT_VEND:
            subtree = proto_item_add_subtree(item, ett_fip_dt_vend);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb,
                                4, 8, FALSE);
            if (tvb_bytes_exist(desc_tvb, 9, -1)) {
                proto_tree_add_item(subtree, hf_fip_desc_vend_data,
                                    desc_tvb, 9, -1, FALSE);
            }
            break;
        case FIP_DT_VLAN:
            subtree = proto_item_add_subtree(item, ett_fip_dt_vlan);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb,
                                2, 2, FALSE);
            proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2));
            break;
        default:
            subtree = proto_item_add_subtree(item, ett_fip_dt_unk);
            fip_desc_type_len(subtree, desc_tvb);
            proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb,
                                2, -1, FALSE);
            break;
        }
    }
}
Ejemplo n.º 30
0
static void
dissect_quakeworld_ConnectionlessPacket(tvbuff_t *tvb, packet_info *pinfo,
	proto_tree *tree, int direction)
{
	proto_tree	*cl_tree   = NULL;
	proto_tree	*text_tree = NULL;
	guint8		*text;
	int		len;
	int		offset;
	guint32		marker;
	int		command_len;
	const char	*command = "";
	gboolean	command_finished = FALSE;

	marker = tvb_get_ntohl(tvb, 0);
	if (tree) {
		proto_item *cl_item;
		cl_item = proto_tree_add_text(tree, tvb, 0, -1, "Connectionless");
		cl_tree = proto_item_add_subtree(cl_item, ett_quakeworld_connectionless);

		proto_tree_add_uint(cl_tree, hf_quakeworld_connectionless_marker,
				tvb, 0, 4, marker);
	}

	/* all the rest of the packet is just text */
        offset = 4;

	text = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII|ENC_NA);
	/* actually, we should look for a eol char and stop already there */

        if (cl_tree) {
		proto_item *text_item;
                text_item = proto_tree_add_string(cl_tree, hf_quakeworld_connectionless_text,
						  tvb, offset, len, text);
		text_tree = proto_item_add_subtree(text_item, ett_quakeworld_connectionless_text);
        }

	if (direction == DIR_C2S) {
		/* client to server commands */
		const char *c;

		Cmd_TokenizeString(text);
		c = Cmd_Argv(0);

		/* client to sever commands */
		if (strcmp(c,"ping") == 0) {
			command = "Ping";
			command_len = 4;
		} else if (strcmp(c,"status") == 0) {
			command = "Status";
			command_len = 6;
		} else if (strcmp(c,"log") == 0) {
			command = "Log";
			command_len = 3;
		} else if (strcmp(c,"connect") == 0) {
			int version;
			int qport;
			int challenge;
			const char *infostring;
			proto_tree *argument_tree = NULL;
			command = "Connect";
			command_len = Cmd_Argv_length(0);
			if (text_tree) {
				proto_item *argument_item;
				proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
					tvb, offset, command_len, command);
				argument_item = proto_tree_add_string(text_tree,
					hf_quakeworld_connectionless_arguments,
					tvb, offset + Cmd_Argv_start(1), len + 1 - Cmd_Argv_start(1),
					text + Cmd_Argv_start(1));
				argument_tree = proto_item_add_subtree(argument_item,
								       ett_quakeworld_connectionless_arguments);
				command_finished=TRUE;
			}
			version    = atoi(Cmd_Argv(1));
			qport      = atoi(Cmd_Argv(2));
			challenge  = atoi(Cmd_Argv(3));
			infostring = Cmd_Argv(4);
			if (argument_tree) {
				proto_item *info_item;
				proto_tree *info_tree;
				proto_tree_add_uint(argument_tree,
					hf_quakeworld_connectionless_connect_version,
					tvb,
					offset + Cmd_Argv_start(1),
					Cmd_Argv_length(1), version);
				proto_tree_add_uint(argument_tree,
					hf_quakeworld_connectionless_connect_qport,
					tvb,
					offset + Cmd_Argv_start(2),
					Cmd_Argv_length(2), qport);
				proto_tree_add_int(argument_tree,
					hf_quakeworld_connectionless_connect_challenge,
					tvb,
					offset + Cmd_Argv_start(3),
					Cmd_Argv_length(3), challenge);
				info_item = proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_connect_infostring,
					tvb,
					offset + Cmd_Argv_start(4),
					Cmd_Argv_length(4), infostring);
				info_tree = proto_item_add_subtree(
					info_item, ett_quakeworld_connectionless_connect_infostring);
				dissect_id_infostring(tvb, info_tree, offset + Cmd_Argv_start(4),
					wmem_strdup(wmem_packet_scope(), infostring),
					ett_quakeworld_connectionless_connect_infostring_key_value,
					hf_quakeworld_connectionless_connect_infostring_key_value,
					hf_quakeworld_connectionless_connect_infostring_key,
					hf_quakeworld_connectionless_connect_infostring_value);
			}
		} else if (strcmp(c,"getchallenge") == 0) {
			command = "Get Challenge";
			command_len = Cmd_Argv_length(0);
		} else if (strcmp(c,"rcon") == 0) {
			const char* password;
			int i;
			char remaining[MAX_TEXT_SIZE+1];
			proto_tree *argument_tree = NULL;
			command = "Remote Command";
			command_len = Cmd_Argv_length(0);
			if (text_tree) {
				proto_item *argument_item;
				proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
					tvb, offset, command_len, command);
				argument_item = proto_tree_add_string(text_tree,
					hf_quakeworld_connectionless_arguments,
					tvb, offset + Cmd_Argv_start(1), len - Cmd_Argv_start(1),
					text + Cmd_Argv_start(1));
				argument_tree =	proto_item_add_subtree(argument_item,
								       ett_quakeworld_connectionless_arguments);
				command_finished=TRUE;
			}
			password = Cmd_Argv(1);
			if (argument_tree) {
				proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_rcon_password,
					tvb,
					offset + Cmd_Argv_start(1),
					Cmd_Argv_length(1), password);
			}
			remaining[0] = '\0';
			for (i=2; i<Cmd_Argc() ; i++) {
				g_strlcat (remaining, Cmd_Argv(i), MAX_TEXT_SIZE+1);
				g_strlcat (remaining, " ", MAX_TEXT_SIZE+1);
			}
			if (text_tree) {
				proto_tree_add_string(argument_tree,
					hf_quakeworld_connectionless_rcon_command,
					tvb, offset + Cmd_Argv_start(2),
					Cmd_Argv_start(Cmd_Argc()-1) + Cmd_Argv_length(Cmd_Argc()-1) -
					Cmd_Argv_start(2),
					remaining);
			}
		} else if (c[0]==A2A_PING && ( c[1]=='\0' || c[1]=='\n')) {
			command = "Ping";
			command_len = 1;
		} else if (c[0]==A2A_ACK && ( c[1]=='\0' || c[1]=='\n')) {
			command = "Ack";
			command_len = 1;
		} else {
			command = "Unknown";
			command_len = len - 1;
		}
	}
	else {
		/* server to client commands */
		if (text[0] == S2C_CONNECTION) {
			command = "Connected";
			command_len = 1;
		} else if (text[0] == A2C_CLIENT_COMMAND) {
			command = "Client Command";
			command_len = 1;
			/* stringz (command), stringz (localid) */
		} else if (text[0] == A2C_PRINT) {
			command = "Print";
			command_len = 1;
			/* string */
		} else if (text[0] == A2A_PING) {
			command = "Ping";
			command_len = 1;
		} else if (text[0] == S2C_CHALLENGE) {
			command = "Challenge";
			command_len = 1;
			/* string, atoi */
		} else {
			command = "Unknown";
			command_len = len - 1;
		}
	}

	col_append_fstr(pinfo->cinfo, COL_INFO, " %s", command);

	if (!command_finished) {
		proto_tree_add_string(text_tree, hf_quakeworld_connectionless_command,
			tvb, offset, command_len, command);
	}
	/*offset += len;*/
}