Пример #1
0
static gboolean
find_dir_tokens(tvbuff_t *tvb, gint name_start, gint *sel_start, gint *host_start, gint *port_start, gint *line_len, gint *next_offset) {
    gint remain;

    if (tvb_length_remaining(tvb, name_start) < MIN_DIR_LINE_LEN)
        return FALSE;

    if (! (sel_start && host_start && port_start && line_len && next_offset) )
        return FALSE;

    *line_len = tvb_find_line_end(tvb, name_start, MAX_DIR_LINE_LEN, next_offset, FALSE);
    if (*line_len < MIN_DIR_LINE_LEN)
        return FALSE;

    remain = *line_len;
    *sel_start = tvb_find_guint8(tvb, name_start, remain, '\t') + 1;
    if (*sel_start < name_start + 1)
        return FALSE;

    remain -= *sel_start - name_start;
    *host_start = tvb_find_guint8(tvb, *sel_start, remain, '\t') + 1;
    if (*host_start < *sel_start + 1)
        return FALSE;

    remain -= *host_start - *sel_start;
    *port_start = tvb_find_guint8(tvb, *host_start, remain, '\t') + 1;
    if (*port_start < *host_start + 1)
        return FALSE;

    return TRUE;
}
Пример #2
0
static void
rtpproxy_add_notify_addr(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint end)
{
    gint offset = 0;
    gint tmp = 0;
    gboolean ipv6 = FALSE;
    proto_item *ti;

    /* Check for at least one colon */
    offset = tvb_find_guint8(tvb, begin, end, ':');
    if(offset != -1) {
        /* Find if it's the latest colon (not in case of a IPv6) */
        while((tmp = tvb_find_guint8(tvb, offset+1, end, ':')) != -1) {
            ipv6 = TRUE;
            offset = tmp;
        }
        /* We have ip:port */
        if(ipv6)
            proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv6, tvb, begin, offset - begin, ENC_ASCII | ENC_NA);
        else
            proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, begin, offset - begin, ENC_ASCII | ENC_NA);
        proto_tree_add_uint(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, offset+1, end - (offset+1),
                            (guint16) g_ascii_strtoull((gchar*)tvb_get_string(wmem_packet_scope(), tvb, offset+1, end - (offset+1)), NULL, 10));
    }
    else {
        /* Only port is supplied */
        ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, begin, 0, ENC_ASCII | ENC_NA);
        proto_item_append_text(ti, "<skipped>");
        PROTO_ITEM_SET_GENERATED(ti);
        proto_tree_add_uint(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, begin, end - begin,
                            (guint16) g_ascii_strtoull((gchar*)tvb_get_string(wmem_packet_scope(), tvb, begin, end - begin), NULL, 10));
    }
}
Пример #3
0
/* This code is modeled on the code in packet-sip.c
 *  ABNF code for the MSRP header:
 *  The following syntax specification uses the augmented Backus-Naur
 *  Form (BNF) as described in RFC-2234 [6].
 *
 *
 *  msrp-req-or-resp = msrp-request / msrp-response
 *  msrp-request = req-start headers [content-stuff] end-line
 *  msrp-response = resp-start headers end-line
 *
 *  req-start  = pMSRP SP transact-id SP method CRLF
 *  resp-start = pMSRP SP transact-id SP status-code [SP phrase] CRLF
 *  phrase = utf8text
 *
 *  pMSRP = %x4D.53.52.50 ; MSRP in caps
 *  transact-id = ident
 *  method = mSEND / mREPORT / other-method
 *  mSEND = %x53.45.4e.44 ; SEND in caps
 *  mREPORT = %x52.45.50.4f.52.54; REPORT in caps
 *  other-method = 1*UPALPHA
 *  Examples:
 *  "MSRP 1234 SEND(CRLF)"
 *	"MSRP 1234 200 OK(CRLF)
 */
static gboolean
check_msrp_header(tvbuff_t *tvb)
{
	gint offset = 0;
	gint linelen;
	gint space_offset;
	gint next_offset = 0;
	guint token_1_len;
	gint token_2_start;

	/*
	 * Note that "tvb_find_line_end()" will return a value that
	 * is not longer than what's in the buffer, so the
	 * "tvb_get_ptr()" calls below won't throw exceptions.	 *
	 */
	offset = 0;
	if(tvb_length(tvb) < 4 ||  tvb_get_ntohl(tvb, 0) != 0x4d535250 /* MSRP */){
		return FALSE;
	}

	linelen = tvb_find_line_end(tvb, 0, -1, &next_offset, FALSE);
	/* Find the first SP */
	space_offset = tvb_find_guint8(tvb, 0, -1, ' ');

	if (space_offset <= 0) {
		/*
		 * Either there's no space in the line (which means
		 * the line is empty or doesn't have a token followed
		 * by a space; neither is valid for a request or response), or
		 * the first character in the line is a space ( which isn't valid
		 * for a MSRP header.)
		 */
		return FALSE;
	}

	token_1_len = space_offset;
	token_2_start = space_offset + 1;
	space_offset = tvb_find_guint8(tvb, token_2_start, -1, ' ');
	if (space_offset == -1) {
		/*
		 * There's no space after the second token, so we don't
		 * have a third token.
		 */
		return FALSE;
	}
	/*
	 * Is the first token "MSRP"?
	 */
	if (token_1_len == MSRP_HDR_LEN) { /*  && tvb_strneql(tvb, 0, MSRP_HDR, MSRP_HDR_LEN) == 0){ */
		/* This check can be made more strict but accept we do have MSRP for now */
		return TRUE;

	}
	return FALSE;
}
Пример #4
0
/* ---------------------------------------------- */
static int fix_header_len(tvbuff_t *tvb, int offset)
{
    int            base_offset, ctrla_offset;
    char          *value;
    int            size;
    fix_parameter *tag;

    base_offset = offset;

    /* get at least the fix version: 8=FIX.x.x */
    if (fix_marker(tvb, offset) != 0) {
        return fix_next_header(tvb, offset);
    }

    /* begin string */
    ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
    if (ctrla_offset == -1) {
        /* it should be there, (minimum size is big enough)
         * if not maybe it's not really
         * a FIX packet but it's too late to bail out.
        */
        return fix_next_header(tvb, offset +MARKER_LEN) +MARKER_LEN;
    }
    offset = ctrla_offset + 1;

    /* msg length */
    if (!(tag = fix_param(tvb, offset)) || tvb_strneql(tvb, offset, "9=", 2)) {
        /* not a tag or not the BodyLength tag, give up */
        return fix_next_header(tvb, offset);
    }

    value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len);
    /* Fix version, msg type, length and checksum aren't in body length.
     * If the packet is big enough find the checksum
    */
    size = atoi(value) +tag->ctrla_offset - base_offset +1;
    if (tvb_length_remaining(tvb, base_offset) > size +4) {
        /* 10= should be there */
        offset = base_offset +size;
        if (tvb_strneql(tvb, offset, "10=", 3) != 0) {
            /* No? bogus packet, try to find the next header */
            return fix_next_header(tvb, base_offset +MARKER_LEN)  +MARKER_LEN;
        }
        ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
        if (ctrla_offset == -1) {
            /* assume checksum is 7 bytes 10=xxx\01 */
            return size+7;
        }
        return size +ctrla_offset -offset +1;
    }
    else {
    }
    /* assume checksum is 7 bytes 10=xxx\01 */
    return size +7;
}
Пример #5
0
static gint
find_printer_string(tvbuff_t *tvb, int offset)
{
	int	i;

	/* try to find end of string, either '\n' or '\0' */
	i = tvb_find_guint8(tvb, offset, -1, '\0');
	if (i == -1)
		i = tvb_find_guint8(tvb, offset, -1, '\n');
	if (i == -1)
		return -1;
	return i - offset;	/* length of string */
}
Пример #6
0
/** Dissects an SIR packet. */
static void
dissect_sir(tvbuff_t *tvb, packet_info *pinfo, proto_tree *root)
{
    gint offset = 0;
    gint bof_offset;
    gint eof_offset;

    while (tvb_length_remaining(tvb, offset) > 0) {
        bof_offset = tvb_find_guint8(tvb, offset, -1, SIR_BOF);
        eof_offset = (bof_offset == -1) ? -1 :
                     tvb_find_guint8(tvb, bof_offset, -1, SIR_EOF);

        if (bof_offset == -1 || eof_offset == -1) {
            if (pinfo->can_desegment) {
                pinfo->desegment_offset = offset;
                pinfo->desegment_len = 1;
            }
            return;
        } else {
            guint preamble_len = bof_offset - offset;
            gint data_offset = bof_offset + 1;
            tvbuff_t* next_tvb = tvb_new_subset(tvb,
                                                data_offset, eof_offset - data_offset, -1);
            next_tvb = unescape_data(next_tvb, pinfo);
            if (root) {
                guint data_len = tvb_length(next_tvb) < 2 ? 0 :
                                 tvb_length(next_tvb) - 2;
                proto_tree* ti = proto_tree_add_protocol_format(root,
                                 proto_sir, tvb, offset, eof_offset - offset + 1,
                                 "Serial Infrared, Len: %d", data_len);
                proto_tree* tree = proto_item_add_subtree(ti, ett_sir);
                if (preamble_len > 0)
                    proto_tree_add_item(tree, hf_sir_preamble, tvb,
                                        offset, preamble_len, ENC_NA);
                proto_tree_add_item(tree, hf_sir_bof, tvb,
                                    bof_offset, 1, ENC_BIG_ENDIAN);
                proto_tree_add_uint(tree, hf_sir_length,
                                    next_tvb, 0, data_len, data_len);
                next_tvb = checksum_data(next_tvb, tree);
                proto_tree_add_item(tree, hf_sir_eof, tvb,
                                    eof_offset, 1, ENC_BIG_ENDIAN);
            } else {
                next_tvb = checksum_data(next_tvb, NULL);
            }
            call_dissector(irda_handle, next_tvb, pinfo, root);
        }
        offset = eof_offset + 1;
    }
}
Пример #7
0
/** Unescapes the data. */
static tvbuff_t *
unescape_data(tvbuff_t *tvb, packet_info *pinfo)
{
    if (tvb_find_guint8(tvb, 0, -1, SIR_CE) == -1) {
        return tvb;
    } else {
        guint length = tvb_length(tvb);
        guint offset;
        guint8 *data = (guint8 *)g_malloc(length);
        guint8 *dst = data;
        tvbuff_t *next_tvb;

        for (offset = 0; offset < length; )
        {
            guint8 c = tvb_get_guint8(tvb, offset++);
            if ((c == SIR_CE) && (offset < length))
                c = SIR_ESCAPE(tvb_get_guint8(tvb, offset++));
            *dst++ = c;
        }

        next_tvb = tvb_new_child_real_data(tvb, data, (guint) (dst-data), (guint) (dst-data));
        tvb_set_free_cb(next_tvb, g_free);
        add_new_data_source(pinfo, next_tvb, "Unescaped SIR");
        return next_tvb;
    }
}
Пример #8
0
static gint
subset_find_guint8(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle)
{
	struct tvb_subset *subset_tvb = (struct tvb_subset *) tvb;

	return tvb_find_guint8(subset_tvb->subset.tvb, subset_tvb->subset.offset + abs_offset, limit, needle);
}
Пример #9
0
/* Find the delimiter, '*'.
 * Returns the number of bytes from foffset to the delimiter or 0 if not
 * found within 256 bytes from foffset */
static int
find_delimiter(tvbuff_t *tvb, int foffset)
{
    int offset;

    offset = tvb_find_guint8(tvb, foffset, 256, '*');
    if (offset >= foffset) {
        return offset - foffset;
    }
    return 0;
}
Пример #10
0
/* ----------------------------------------------
  Format: name=value\001
*/
static fix_parameter *fix_param(tvbuff_t *tvb, int offset)
{
    static fix_parameter ret;
    int                  equals;

    ret.ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01);
    if (ret.ctrla_offset == -1) {
        return NULL;
    }

    ret.field_len = ret.ctrla_offset - offset + 1;
    equals = tvb_find_guint8(tvb, offset, ret.field_len, '=');
    if (equals == -1) {
        return NULL;
    }

    ret.value_offset = equals + 1;
    ret.tag_len      = ret.value_offset - offset - 1;
    ret.value_len    = ret.ctrla_offset - ret.value_offset;
    return &ret;
}
Пример #11
0
static gint
rtpproxy_add_tag(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint realsize)
{
    proto_item *ti = NULL;
    proto_tree *another_tree = NULL;
    gint new_offset;
    guint end;

    new_offset = tvb_find_guint8(tvb, begin, -1, ' ');
    if(new_offset < 0)
        end = realsize; /* No more parameters */
    else
        end = new_offset;

    /* SER/OpenSER/OpenSIPS/Kamailio adds Media-ID right after the Tag
     * separated by a semicolon
     */
    new_offset = tvb_find_guint8(tvb, begin, end, ';');
    if(new_offset == -1) {
        ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_tag, tvb, begin, end - begin, ENC_ASCII | ENC_NA);
        another_tree = proto_item_add_subtree(ti, ett_rtpproxy_tag);
        ti = proto_tree_add_item(another_tree, hf_rtpproxy_mediaid, tvb, new_offset+1, 0, ENC_ASCII | ENC_NA);
        proto_item_append_text(ti, "<skipped>");
        PROTO_ITEM_SET_GENERATED(ti);
    }
    else {
        ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_tag, tvb, begin, new_offset - begin, ENC_ASCII | ENC_NA);
        if ((guint)new_offset == begin) {
            proto_item_append_text(ti, "<skipped>"); /* A very first Offer/Update command */
            PROTO_ITEM_SET_GENERATED(ti);
        }
        another_tree = proto_item_add_subtree(ti, ett_rtpproxy_tag);
        proto_tree_add_item(another_tree, hf_rtpproxy_mediaid, tvb, new_offset+1, end - (new_offset+1), ENC_ASCII | ENC_NA);
    }
    return (end == realsize ? -1 : (gint)end);
}
Пример #12
0
static void
dissect_cimd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  guint8   OC;                  /* Operation Code */
  guint8   PN;                  /* Packet number */
  guint16  checksum        = 0; /* Checksum */
  guint16  pkt_check       = 0;
  gint     etxp            = 0; /* ETX position */
  gint     offset          = 0;
  gboolean checksumIsValid = TRUE;
  guint8   last1, last2, last3;

  etxp = tvb_find_guint8(tvb, CIMD_PN_OFFSET + CIMD_PN_LENGTH, -1, CIMD_ETX);
  if (etxp == -1) return;

  OC = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, ENC_ASCII), NULL, 10);
  PN = (guint8)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, ENC_ASCII), NULL, 10);

  last1 = tvb_get_guint8(tvb, etxp - 1);
  last2 = tvb_get_guint8(tvb, etxp - 2);
  last3 = tvb_get_guint8(tvb, etxp - 3);

  if (last1 == CIMD_DELIM) {
    /* valid packet, CC is missing */
  } else if (last1 != CIMD_DELIM && last2 != CIMD_DELIM && last3 == CIMD_DELIM) {
    /* looks valid, it would be nice to check that last1 and last2 are HEXA */
    /* CC is present */
    checksum = (guint16)strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, etxp - 2, 2, ENC_ASCII), NULL, 16);
    for (; offset < (etxp - 2); offset++)
    {
      pkt_check += tvb_get_guint8(tvb, offset);
      pkt_check &= 0xFF;
    }
    checksumIsValid = (checksum == pkt_check);
  } else {
    checksumIsValid = FALSE;
  }

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

  if (checksumIsValid)
    col_add_str(pinfo->cinfo, COL_INFO, val_to_str(OC, vals_hdr_OC, "Unknown (%d)"));
  else
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s - %s", val_to_str(OC, vals_hdr_OC, "Unknown (%d)"), "invalid checksum");

  dissect_cimd_operation(tvb, tree, etxp, checksum, last1, OC, PN);
}
Пример #13
0
WSLUA_METHOD TvbRange_strsize(lua_State* L) {
        /* Find the size of a zero terminated string from a `TvbRange`.
           The size of the string includes the terminating zero.

           @since 1.11.3
         */
#define WSLUA_OPTARG_TvbRange_strsize_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */
    TvbRange tvbr = checkTvbRange(L,1);
    guint encoding = (guint)luaL_optinteger(L,WSLUA_OPTARG_TvbRange_strsize_ENCODING, ENC_ASCII|ENC_NA);
    gint offset;
    gunichar2 uchar;

    if ( !(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    switch (encoding & ENC_CHARENCODING_MASK) {

    case ENC_UTF_16:
    case ENC_UCS_2:
        offset = tvbr->offset;
        do {
            if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) {
                luaL_error(L,"out of bounds");
                return 0;
            }
            /* Endianness doesn't matter when looking for null */
            uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset);
            offset += 2;
        } while (uchar != 0);
        lua_pushinteger(L, tvb_unicode_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
        break;

    default:
        if (tvb_find_guint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
            luaL_error(L,"out of bounds");
            return 0;
        }
        lua_pushinteger(L, tvb_strsize(tvbr->tvb->ws_tvb, tvbr->offset));
        break;
    }

    WSLUA_RETURN(1); /* Length of the zero terminated string. */
}
Пример #14
0
WSLUA_METHOD TvbRange_stringz(lua_State* L) {
	/* Obtain a zero terminated string from a TvbRange */
#define WSLUA_OPTARG_TvbRange_stringz_ENCODING 2 /* The encoding to use. Defaults to ENC_ASCII. */
    TvbRange tvbr = checkTvbRange(L,1);
    guint encoding = (guint)luaL_optint(L,WSLUA_OPTARG_TvbRange_stringz_ENCODING, ENC_ASCII|ENC_NA);
    gint offset;
    gunichar2 uchar;

    if ( !(tvbr && tvbr->tvb)) return 0;
    if (tvbr->tvb->expired) {
        luaL_error(L,"expired tvb");
        return 0;
    }

    switch (encoding & ENC_CHARENCODING_MASK) {

    case ENC_UTF_16:
    case ENC_UCS_2:
        offset = tvbr->offset;
        do {
            if (!tvb_bytes_exist (tvbr->tvb->ws_tvb, offset, 2)) {
                luaL_error(L,"out of bounds");
                return 0;
            }
            /* Endianness doesn't matter when looking for null */
            uchar = tvb_get_ntohs (tvbr->tvb->ws_tvb, offset);
            offset += 2;
        } while(uchar != 0);
        break;

    default:
        if (tvb_find_guint8 (tvbr->tvb->ws_tvb, tvbr->offset, -1, 0) == -1) {
            luaL_error(L,"out of bounds");
            return 0;
        }
        break;
    }

    lua_pushstring(L, (gchar*)tvb_get_stringz_enc(wmem_packet_scope(),tvbr->tvb->ws_tvb,tvbr->offset,NULL,encoding));

    WSLUA_RETURN(1); /* The zero terminated string */
}
Пример #15
0
static int
dissect_fullcollectionname(tvbuff_t *tvb, guint offset, proto_tree *tree)
{
  gint32 fcn_length, dbn_length;
  proto_item *ti;
  proto_tree *fcn_tree;

  fcn_length = tvb_strsize(tvb, offset);
  ti = proto_tree_add_item(tree, hf_mongo_fullcollectionname, tvb, offset, fcn_length, ENC_ASCII|ENC_NA);

  /* If this doesn't find anything, we'll just throw an exception below */
  dbn_length = tvb_find_guint8(tvb, offset, fcn_length, '.') - offset;

  fcn_tree = proto_item_add_subtree(ti, ett_mongo_fcn);

  proto_tree_add_item(fcn_tree, hf_mongo_database_name, tvb, offset, dbn_length, ENC_ASCII|ENC_NA);

  proto_tree_add_item(fcn_tree, hf_mongo_collection_name, tvb, offset + 1 + dbn_length, fcn_length - dbn_length - 2, ENC_ASCII|ENC_NA);

  return fcn_length;
}
Пример #16
0
/**
 * This is the ROS connection header dissector. The general packet format is described
 * here: http://wiki.ros.org/ROS/TCPROS
 * In short, a connection header looks like such: '4-byte length + [4-byte field length + "field=value" ]*'
 */
static gint
dissect_ros_connection_header_field(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, gint offset)
{
	proto_item *ti;
	proto_tree *field_tree;

	guint32 fLen = 0;
	gint  sep, ret = 0;

	/** Do we have enough for a length field? (ie: 4 bytes) */
	if( tvb_reported_length_remaining(tvb, offset) > SIZE_OF_LENGTH_FIELD ) {
		/** Get the length of the next field */
		fLen = tvb_get_letohl(tvb, offset);

		/** Display the field as a utf-8 string */
		ti = proto_tree_add_item(tree, hf_tcpros_connection_header_field, tvb, offset, SIZE_OF_LENGTH_FIELD, ENC_UTF_8|ENC_LITTLE_ENDIAN);
		field_tree = proto_item_add_subtree(ti, ett_tcpros);


		proto_tree_add_item(field_tree, hf_tcpros_connection_header_field_length, tvb, offset, SIZE_OF_LENGTH_FIELD, ENC_LITTLE_ENDIAN);
		offset += SIZE_OF_LENGTH_FIELD;
		ti = proto_tree_add_item(field_tree, hf_tcpros_connection_header_field_data, tvb, offset, fLen, ENC_UTF_8|ENC_NA);

		/** Look for the '=' separator */
		sep = (tvb_find_guint8(tvb, offset, fLen, '=') - offset);

		/** If we find a separator, then split field name and value */
		if( sep > 0 ) {
			field_tree = proto_item_add_subtree(ti, ett_tcpros);
			proto_tree_add_item(field_tree, hf_tcpros_connection_header_field_name, tvb, offset, sep, ENC_UTF_8|ENC_NA);
			proto_tree_add_item(field_tree, hf_tcpros_connection_header_field_value, tvb, offset+sep+1, fLen - sep - 1, ENC_UTF_8|ENC_NA);

			col_append_str(pinfo->cinfo, COL_INFO, tvb_get_string_enc(wmem_packet_scope(), tvb, offset, sep, ENC_UTF_8));
		}
		ret = fLen + SIZE_OF_LENGTH_FIELD;
	}

	return ret;
}
Пример #17
0
static void
dissect_cimd_operation(tvbuff_t *tvb, proto_tree *tree, gint etxp, guint16 checksum, guint8 last1,guint8 OC, guint8 PN)
{
  guint32     PC        = 0;    /* Parameter code */
  gint        idx;
  gint        offset    = 0;
  gint        endOffset = 0;
  proto_item *cimd_item;
  proto_tree *cimd_tree;

    /* create display subtree for the protocol */
  cimd_item = proto_tree_add_item(tree, proto_cimd, tvb, 0, etxp + 1, ENC_NA);
  cimd_tree = proto_item_add_subtree(cimd_item, ett_cimd);
  proto_tree_add_uint(cimd_tree, hf_cimd_opcode_indicator, tvb, CIMD_OC_OFFSET, CIMD_OC_LENGTH, OC);
  proto_tree_add_uint(cimd_tree, hf_cimd_packet_number_indicator, tvb, CIMD_PN_OFFSET, CIMD_PN_LENGTH, PN);

  offset = CIMD_PN_OFFSET + CIMD_PN_LENGTH;
  while (offset < etxp && tvb_get_guint8(tvb, offset) == CIMD_DELIM)
  {
    endOffset = tvb_find_guint8(tvb, offset + 1, etxp, CIMD_DELIM);
    if (endOffset == -1)
      break;

    PC = (guint32) strtoul(tvb_get_string_enc(wmem_packet_scope(), tvb, offset + 1, CIMD_PC_LENGTH, ENC_ASCII), NULL, 10);
    try_val_to_str_idx(PC, cimd_vals_PC, &idx);
    if (idx != -1 && tree)
    {
      (vals_hdr_PC[idx].diss)(tvb, cimd_tree, idx, offset, endOffset);
    }
    offset = endOffset;
  }

  if (last1 != CIMD_DELIM)
  {
    /* Checksum is present */
    proto_tree_add_uint(cimd_tree, hf_cimd_checksum_indicator, tvb, etxp - 2, 2, checksum);
  }
}
Пример #18
0
static void
dissect_imf_address(tvbuff_t *tvb, int offset, int length, proto_item *item, packet_info *pinfo)
{
  proto_tree *group_tree;
  proto_item *group_item;
  int addr_pos;

  /* if there is a colon present it is a group */
  if((addr_pos = tvb_find_guint8(tvb, offset, length, ':')) == -1) {

    /* there isn't - so it must be a mailbox */
    dissect_imf_mailbox(tvb, offset, length, item, pinfo);

  } else {

    /* it is a group */
    group_tree = proto_item_add_subtree(item, ett_imf_group);

    /* the display-name is mandatory */
    group_item = proto_tree_add_item(group_tree, hf_imf_display_name, tvb, offset, addr_pos - offset - 1, ENC_ASCII|ENC_NA);

    /* consume any whitespace */
    for(addr_pos++ ;addr_pos < (offset + length); addr_pos++) {
      if(!isspace(tvb_get_guint8(tvb, addr_pos))) {
        break;
      }
    }

    if(tvb_get_guint8(tvb, addr_pos) != ';') {

      dissect_imf_mailbox_list(tvb, addr_pos, length - (addr_pos - offset), group_item, pinfo);

      /* XXX: need to check for final ';' */

    }

  }
}
Пример #19
0
static const guint8*
get_quoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len)
{
    int c;
    const guint8* s = NULL;
    guint l = 0;
    gint o;

    c = tvb_get_guint8(tvb, offset);
    if (c == '"') {
        o = tvb_find_guint8(tvb, offset+1, -1, '"');
        if (o != -1) {
            offset++;
            l = o - offset;
            s = tvb_get_ptr(tvb, offset, l);
            offset = o + 1;
        }
    }

    *next_offset = offset;
    *len = l;

    return s;
}
Пример #20
0
/* Code to actually dissect the packets */
static int
dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gint offset = 0;
	gint next_offset = 0;
	proto_item *ti, *th, *msrp_headers_item, *msrp_element_item;
	proto_tree *msrp_tree, *reqresp_tree, *raw_tree, *msrp_hdr_tree, *msrp_end_tree;
	proto_tree *msrp_element_tree, *msrp_data_tree;
	gint linelen;
	gint space_offset;
	gint token_2_start;
	guint token_2_len;
	gint token_3_start;
	guint token_3_len;
	gint token_4_start = 0;
	guint token_4_len = 0;
	gboolean is_msrp_response;
	gint end_line_offset;
	gint end_line_len;
	gint line_end_offset;
	gint message_end_offset;
	gint colon_offset;
	char *transaction_id_str = NULL;
	gint header_len;
	gint hf_index;
	gint value_offset;
	guchar c;
	gint value_len;
	char *value;
	gboolean have_body = FALSE;
	gboolean found_match = FALSE;
	gint content_type_len, content_type_parameter_str_len;
	gchar *media_type_str_lower_case = NULL;
	char *content_type_parameter_str = NULL;
	tvbuff_t *next_tvb;
	gint parameter_offset;
	gint semi_colon_offset;

	if ( !check_msrp_header(tvb)){
		return 0;
	}
	/* We have a MSRP header with at least three tokens
	 *
	 * Note that "tvb_find_line_end()" will return a value that
	 * is not longer than what's in the buffer, so the
	 * "tvb_get_ptr()" calls below won't throw exceptions.	 *
	 */
	offset = 0;
	linelen = tvb_find_line_end(tvb, 0, -1, &next_offset, FALSE);

	/* Find the first SP and skip the first token */
	token_2_start = tvb_find_guint8(tvb, 0, linelen, ' ') + 1;

	/* Work out 2nd token's length by finding next space */
	space_offset = tvb_find_guint8(tvb, token_2_start, linelen-token_2_start, ' ');
	token_2_len = space_offset - token_2_start;

	/* Transaction ID found store it for later use */
	transaction_id_str = tvb_get_ephemeral_string(tvb, token_2_start, token_2_len);

	/* Look for another space in this line to indicate a 4th token */
	token_3_start = space_offset + 1;
	space_offset = tvb_find_guint8(tvb, token_3_start,linelen-token_3_start, ' ');
	if ( space_offset == -1){
		/* 3rd token runs to the end of the line */
		token_3_len = linelen - token_3_start;
	}else{
		/* We have a fourth token */
		token_3_len = space_offset - token_3_start;
		token_4_start = space_offset + 1;
		token_4_len = linelen - token_4_start;
	}

	/*
	 * Yes, so this is either a msrp-request or msrp-response.
	 * To be a msrp-response, the second token must be
	 * a 3-digit number.
	 */
	is_msrp_response = FALSE;
	if (token_3_len == 3) {
			if (isdigit(tvb_get_guint8(tvb, token_3_start)) &&
			    isdigit(tvb_get_guint8(tvb, token_3_start + 1)) &&
			    isdigit(tvb_get_guint8(tvb, token_3_start + 2))) {
				is_msrp_response = TRUE;
			}
	}

	/* Make entries in Protocol column and Info column on summary display */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "MSRP");
	if (is_msrp_response){
		if (check_col(pinfo->cinfo, COL_INFO)) {
			col_add_fstr(pinfo->cinfo, COL_INFO, "Response: %s ",
					tvb_format_text(tvb, token_3_start, token_3_len));

			if (token_4_len )
				col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",
					tvb_format_text(tvb, token_4_start, token_4_len));

			col_append_fstr(pinfo->cinfo, COL_INFO, "Transaction ID: %s",
					tvb_format_text(tvb, token_2_start, token_2_len));
		}
	}else{
		if (check_col(pinfo->cinfo, COL_INFO)) {
			proto_tree_add_text(tree, tvb, token_3_start, token_3_len,
					"Col %s L=%u", tvb_format_text(tvb, token_3_start, token_3_len),token_3_len);

			col_add_fstr(pinfo->cinfo, COL_INFO, "Request: %s ",
					tvb_format_text(tvb, token_3_start, token_3_len));

			col_append_fstr(pinfo->cinfo, COL_INFO, "Transaction ID: %s",
					tvb_format_text(tvb, token_2_start, token_2_len));
		}
	}

	/* Find the end line to be able to process the headers
	 * Note that in case of [content-stuff] headers and [content-stuff] is separated by CRLF
	 */

	offset = next_offset;
	end_line_offset = find_end_line(tvb,offset);
	/* TODO if -1 (No end line found, is returned do something) */
	end_line_len =  tvb_find_line_end(tvb, end_line_offset, -1, &next_offset, FALSE);
	message_end_offset = end_line_offset + end_line_len + 2;


	if (tree) {
		ti = proto_tree_add_item(tree, proto_msrp, tvb, 0, message_end_offset, FALSE);
		msrp_tree = proto_item_add_subtree(ti, ett_msrp);

		if (is_msrp_response){
			th = proto_tree_add_item(msrp_tree,hf_msrp_response_line,tvb,0,linelen,FALSE);
			reqresp_tree = proto_item_add_subtree(th, ett_msrp_reqresp);
			proto_tree_add_item(reqresp_tree,hf_msrp_transactionID,tvb,token_2_start,token_2_len,FALSE);
			proto_tree_add_uint(reqresp_tree,hf_msrp_status_code,tvb,token_3_start,token_3_len,
			                    atoi(tvb_get_ephemeral_string(tvb, token_3_start, token_3_len)));

		}else{
			th = proto_tree_add_item(msrp_tree,hf_msrp_request_line,tvb,0,linelen,FALSE);
			reqresp_tree = proto_item_add_subtree(th, ett_msrp_reqresp);
			proto_tree_add_item(reqresp_tree,hf_msrp_transactionID,tvb,token_2_start,token_2_len,FALSE);
			proto_tree_add_item(reqresp_tree,hf_msrp_method,tvb,token_3_start,token_3_len,FALSE);
		}

		/* Conversation setup info */
		if (global_msrp_show_setup_info)
		{
			show_setup_info(tvb, pinfo, msrp_tree);
		}

		/* Headers */
		msrp_headers_item = proto_tree_add_item(msrp_tree, hf_msrp_msg_hdr, tvb, offset,(end_line_offset - offset), FALSE);
		msrp_hdr_tree = proto_item_add_subtree(msrp_headers_item, ett_msrp_hdr);

		/*
		 * Process the headers
		 */
		while (tvb_reported_length_remaining(tvb, offset) > 0 && offset < end_line_offset  ) {
			/* 'desegment' is FALSE so will set next_offset to beyond the end of
			   the buffer if no line ending is found */
			linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
			if (linelen == 0) {
				/*
				 * This is a blank line separating the
				 * message header from the message body.
				 */
				have_body = TRUE;
				break;
			}
			line_end_offset = offset + linelen;
			colon_offset = tvb_find_guint8(tvb, offset, linelen, ':');
			if (colon_offset == -1) {
				/*
				 * Malformed header - no colon after the name.
				 */
				proto_tree_add_text(msrp_hdr_tree, tvb, offset,
					                next_offset - offset, "%s",
						            tvb_format_text(tvb, offset, linelen));
			} else {
				header_len = colon_offset - offset;
				hf_index = msrp_is_known_msrp_header(tvb, offset, header_len);

				if (hf_index == -1) {
					proto_tree_add_text(msrp_hdr_tree, tvb,
				                    offset, next_offset - offset, "%s",
				                    tvb_format_text(tvb, offset, linelen));
				} else {
					/*
					 * Skip whitespace after the colon.
					 */
					value_offset = colon_offset + 1;
					while (value_offset < line_end_offset &&
					       ((c = tvb_get_guint8(tvb, value_offset)) == ' ' ||
					         c == '\t'))
						value_offset++;
					/*
					 * Fetch the value.
					 */
					value_len = line_end_offset - value_offset;
					value = tvb_get_ephemeral_string(tvb, value_offset,
				                       value_len);

					/*
					 * Add it to the protocol tree,
					 * but display the line as is.
					 */
					msrp_element_item = proto_tree_add_string_format(msrp_hdr_tree,
				                   hf_header_array[hf_index], tvb,
				                   offset, next_offset - offset,
				                   value, "%s",
				                   tvb_format_text(tvb, offset, linelen));
					msrp_element_tree = proto_item_add_subtree( msrp_element_item, ett_msrp_element);

					switch ( hf_index ) {

						case MSRP_CONTENT_TYPE :
							content_type_len = value_len;
							semi_colon_offset = tvb_find_guint8(tvb, value_offset,linelen, ';');
							if ( semi_colon_offset != -1) {
								parameter_offset = semi_colon_offset +1;
								/*
								 * Skip whitespace after the semicolon.
								 */
								while (parameter_offset < line_end_offset
								       && ((c = tvb_get_guint8(tvb, parameter_offset)) == ' '
								         || c == '\t'))
									parameter_offset++;
								content_type_len = semi_colon_offset - value_offset;
								content_type_parameter_str_len = line_end_offset - parameter_offset;
								content_type_parameter_str = tvb_get_ephemeral_string(tvb,
										     parameter_offset, content_type_parameter_str_len);
							}
							media_type_str_lower_case = ascii_strdown_inplace(
                                                            (gchar *)tvb_get_ephemeral_string(tvb, value_offset, content_type_len));
							break;

						default:
							break;
					}
				}
			}
			offset = next_offset;
		}/* End while */

		if ( have_body ){
			/*
			 * There's a message body starting at "next_offset".
			 * Set the length of the header item.
			 */
			proto_item_set_end(msrp_headers_item, tvb, next_offset);

			/* Create new tree & tvb for data */
			next_tvb = tvb_new_subset_remaining(tvb, next_offset);
			ti = proto_tree_add_item(msrp_tree, hf_msrp_data, tvb,
			                         next_offset, -1, FALSE);
			msrp_data_tree = proto_item_add_subtree(ti, ett_msrp_data);

			/* give the content type parameters to sub dissectors */

			if ( media_type_str_lower_case != NULL ) {
				void *save_private_data = pinfo->private_data;
				pinfo->private_data = content_type_parameter_str;
				found_match = dissector_try_string(media_type_dissector_table,
			                                   media_type_str_lower_case,
			                                   next_tvb, pinfo,
			                                   msrp_data_tree);
				pinfo->private_data = save_private_data;
				/* If no match dump as text */
			}
			if ( found_match != TRUE )
			{
				offset = 0;
				while (tvb_offset_exists(next_tvb, offset)) {
					tvb_find_line_end(next_tvb, offset, -1, &next_offset, FALSE);
					linelen = next_offset - offset;
					proto_tree_add_text(msrp_data_tree, next_tvb, offset, linelen,
				                    "%s", tvb_format_text(next_tvb, offset, linelen));
					offset = next_offset;
				}/* end while */
			}

		}



		/* End line */
		ti = proto_tree_add_item(msrp_tree,hf_msrp_end_line,tvb,end_line_offset,end_line_len,FALSE);
		msrp_end_tree = proto_item_add_subtree(ti, ett_msrp_end_line);

		proto_tree_add_item(msrp_end_tree,hf_msrp_transactionID,tvb,end_line_offset + 7,token_2_len,FALSE);
		/* continuation-flag */
		proto_tree_add_item(msrp_end_tree,hf_msrp_cnt_flg,tvb,end_line_offset+end_line_len-1,1,FALSE);

		if (global_msrp_raw_text){
			ti = proto_tree_add_text(tree, tvb, 0, -1,"Message Session Relay Protocol(as raw text)");
			raw_tree = proto_item_add_subtree(ti, ett_msrp);
			tvb_raw_text_add(tvb,raw_tree);
		}

	}/* if tree */
	return message_end_offset;
	/*	return tvb_length(tvb); */

/* If this protocol has a sub-dissector call it here, see section 1.8 */
}
Пример #21
0
static int
ssh_dissect_protocol(tvbuff_t *tvb, packet_info *pinfo,
		struct ssh_flow_data *global_data,
		int offset, proto_tree *tree, int is_response, guint * version,
		gboolean *need_desegmentation)
{
	guint	remain_length;
	gint	linelen, protolen;

	/*
	 *  If the first packet do not contain the banner,
	 *  it is dump in the middle of a flow or not a ssh at all
	 */
	if (tvb_strncaseeql(tvb, offset, "SSH-", 4) != 0) {
		offset = ssh_dissect_encrypted_packet(tvb, pinfo,
			&global_data->peer_data[is_response], offset, tree);
		return offset;
	}

	if (!is_response) {
		if (tvb_strncaseeql(tvb, offset, "SSH-2.", 6) == 0) {
			*(version) = SSH_VERSION_2;
		} else if (tvb_strncaseeql(tvb, offset, "SSH-1.99-", 9) == 0) {
			*(version) = SSH_VERSION_2;
		} else if (tvb_strncaseeql(tvb, offset, "SSH-1.", 6) == 0) {
			*(version) = SSH_VERSION_1;
		}
	}

	/*
	 * We use "tvb_ensure_length_remaining()" to make sure there
	 * actually *is* data remaining.
	 *
	 * This means we're guaranteed that "remain_length" is positive.
	 */
	remain_length = tvb_ensure_length_remaining(tvb, offset);
	/*linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
	 */
	linelen = tvb_find_guint8(tvb, offset, -1, '\n');

	if (ssh_desegment && pinfo->can_desegment) {
		if (linelen == -1 || remain_length < (guint)linelen-offset) {
			pinfo->desegment_offset = offset;
			pinfo->desegment_len = linelen-remain_length;
			*need_desegmentation = TRUE;
			return offset;
		}
	}
	if (linelen == -1) {
		/* XXX - reassemble across segment boundaries? */
		linelen = remain_length;
		protolen = linelen;
	} else {
		linelen = linelen - offset + 1;

		if (linelen > 1 && tvb_get_guint8(tvb, offset + linelen - 2) == '\r')
			protolen = linelen - 2;
		else
			protolen = linelen - 1;
	}

	col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "Protocol (%s)",
			tvb_format_text(tvb, offset, protolen));

	proto_tree_add_item(tree, hf_ssh_protocol,
					tvb, offset, linelen, ENC_ASCII|ENC_NA);
	offset+=linelen;
	return offset;
}
Пример #22
0
static void
dissect_exec(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 *exec_tree=NULL;

	/* Variables for extracting and displaying data from the packet */
	guchar *field_stringz; /* Temporary storage for each field we extract */

	gint length;
	guint offset = 0;
	conversation_t *conversation;
	exec_hash_entry_t *hash_info;

	conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);

	if(!conversation){  /* Conversation does not exist yet - create it */
		conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0);
	}


	/* Retrieve information from conversation 
	 * or add it if it isn't there yet
	 */
	hash_info = conversation_get_proto_data(conversation, proto_exec);
	if(!hash_info){
		hash_info = se_alloc(sizeof(exec_hash_entry_t));
      
		hash_info->first_packet_number = pinfo->fd->num;
		hash_info->second_packet_number = 0;
		hash_info->third_packet_number  = 0;
		hash_info->fourth_packet_number  = 0;

		hash_info->state = WAIT_FOR_STDERR_PORT; /* The first field we'll see */

		/* Start with empty username and command strings */
		hash_info->username=NULL;
		hash_info->command=NULL;

		/* These will be set on the first pass by the first 
		 * four packets of the conversation
		 */
		hash_info->first_packet_state  = NONE;
		hash_info->second_packet_state = NONE;
		hash_info->third_packet_state  = NONE;
		hash_info->fourth_packet_state  = NONE;

		conversation_add_proto_data(conversation, proto_exec, hash_info);
	}

	/* Store the number of the first three packets of this conversation
	 * as we reach them the first time */

	if(!hash_info->second_packet_number
	&& pinfo->fd->num > hash_info->first_packet_number){
		/* We're on the second packet of the conversation */
		hash_info->second_packet_number = pinfo->fd->num;
	} else if(hash_info->second_packet_number
	 && !hash_info->third_packet_number
	 && pinfo->fd->num > hash_info->second_packet_number) {
		/* We're on the third packet of the conversation */
		hash_info->third_packet_number = pinfo->fd->num;
	} else if(hash_info->third_packet_number
	 && !hash_info->fourth_packet_number
	 && pinfo->fd->num > hash_info->third_packet_number) {
		/* We're on the fourth packet of the conversation */
		hash_info->fourth_packet_number = pinfo->fd->num;
	}

	/* Save this packet's state so we can retrieve it if this packet
	 * is selected again later.  If the packet's state was already stored,
	 * then retrieve it */
	if(pinfo->fd->num == hash_info->first_packet_number){
		if(hash_info->first_packet_state == NONE){
			hash_info->first_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->first_packet_state;
		}
	}
      
	if(pinfo->fd->num == hash_info->second_packet_number){
		if(hash_info->second_packet_state == NONE){
			hash_info->second_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->second_packet_state;
		}
	}
      
	if(pinfo->fd->num == hash_info->third_packet_number){
		if(hash_info->third_packet_state == NONE){
			hash_info->third_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->third_packet_state;
		}
	}
      
	if(pinfo->fd->num == hash_info->fourth_packet_number){
		if(hash_info->fourth_packet_state == NONE){
			hash_info->fourth_packet_state = hash_info->state;
		} else {
			hash_info->state = hash_info->fourth_packet_state;
		}
	}

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

	if(check_col(pinfo->cinfo, COL_INFO)){
		/* First, clear the info column */
		col_clear(pinfo->cinfo, COL_INFO);

		/*username */
		if(hash_info->username && preference_info_show_username == TRUE){
			col_append_fstr(pinfo->cinfo, COL_INFO, "Username:%s ", hash_info->username);
		}
      
		/* Command */
		if(hash_info->command && preference_info_show_command == TRUE){
			col_append_fstr(pinfo->cinfo, COL_INFO, "Command:%s ", hash_info->command);
		}
	}
  
	/* create display subtree for the protocol */
	ti = proto_tree_add_item(tree, proto_exec, tvb, 0, -1, FALSE);
	exec_tree = proto_item_add_subtree(ti, ett_exec);

	/* If this packet doesn't end with a null terminated string,
	 * then it must be session data only and we can skip looking
	 * for the other fields.
	 */
	if(tvb_find_guint8(tvb, tvb_length(tvb)-1, 1, '\0') == -1){
		hash_info->state = WAIT_FOR_DATA;
	}

	if(hash_info->state == WAIT_FOR_STDERR_PORT
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);

		/* Check if this looks like the stderr_port field.
		 * It is optional, so it may only be 1 character long
		 * (the NULL)
		 */
		if(length == 1 || (exec_isdigit_string(field_stringz)
		&& length <= EXEC_STDERR_PORT_LEN)){
			proto_tree_add_string(exec_tree, hf_exec_stderr_port, tvb, offset, length, (gchar*)field_stringz);
			 /* Next field we need */
			hash_info->state = WAIT_FOR_USERNAME;
		} else { 
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
       
		/* Used if the next field is in the same packet */
		offset += length;
	}
  
 
	if(hash_info->state == WAIT_FOR_USERNAME
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);
	  
		/* Check if this looks like the username field */
		if(length != 1 && length <= EXEC_USERNAME_LEN
		&& exec_isprint_string(field_stringz)){
			proto_tree_add_string(exec_tree, hf_exec_username, tvb, offset, length, (gchar*)field_stringz);

			/* Store the username so we can display it in the 
			 * info column of the entire conversation
			 */
			if(!hash_info->username){
				hash_info->username=se_strdup((gchar*)field_stringz);
			}

			 /* Next field we need */
			hash_info->state = WAIT_FOR_PASSWORD;
		} else { 
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
 
		/* Used if the next field is in the same packet */
		offset += length;
	}
      

	if(hash_info->state == WAIT_FOR_PASSWORD
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);
	  
		/* Check if this looks like the password field */
		if(length != 1 && length <= EXEC_PASSWORD_LEN
		&& exec_isprint_string(field_stringz)){
			proto_tree_add_string(exec_tree, hf_exec_password, tvb, offset, length, (gchar*)field_stringz);

			/* Next field we need */
			hash_info->state = WAIT_FOR_COMMAND;
		} else {
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
	  
		/* Used if the next field is in the same packet */
		offset += length;
		 /* Next field we are looking for */
		hash_info->state = WAIT_FOR_COMMAND;
	}
      

	if(hash_info->state == WAIT_FOR_COMMAND
	&& tvb_length_remaining(tvb, offset)){
		field_stringz = tvb_get_ephemeral_stringz(tvb, offset, &length);
	  
		/* Check if this looks like the command field */
		if(length != 1 && length <= EXEC_COMMAND_LEN
		&& exec_isprint_string(field_stringz)){
			proto_tree_add_string(exec_tree, hf_exec_command, tvb, offset, length, (gchar*)field_stringz);
	      
			/* Store the username so we can display it in the 
			 * info column of the entire conversation
			 */
			if(!hash_info->command){
				hash_info->command=se_strdup((gchar*)field_stringz);
			}

		} else {
			/* Since the data doesn't match this field, it must be data only */
			hash_info->state = WAIT_FOR_DATA;
		}
	}

  
	if(hash_info->state == WAIT_FOR_DATA
	&& tvb_length_remaining(tvb, offset)){
		if(pinfo->destport == EXEC_PORT){
			/* Packet going to the server */
			/* offset = 0 since the whole packet is data */
			proto_tree_add_text(exec_tree, tvb, 0, -1, "Client -> Server Data");
	  
			if(check_col(pinfo->cinfo, COL_INFO))
				col_append_str(pinfo->cinfo, COL_INFO, "Client -> Server data");
		} else {
			/* This packet must be going back to the client */
			/* offset = 0 since the whole packet is data */
			proto_tree_add_text(exec_tree, tvb, 0, -1, "Server -> Client Data");
	  
			if(check_col(pinfo->cinfo, COL_INFO))
				col_append_str(pinfo->cinfo, COL_INFO, "Server -> Client Data");
		}
	}

	/* We haven't seen all of the fields yet */
	if(hash_info->state < WAIT_FOR_DATA){
		col_set_str(pinfo->cinfo, COL_INFO, "Session Establishment");
	}
}
Пример #23
0
/****************************************************************
 * Main dissection function
 ****************************************************************/
static int
dissect_rlogin(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	struct tcpinfo *tcpinfo = (struct tcpinfo *)data;
	conversation_t *conversation;
	rlogin_hash_entry_t *hash_info;
	guint length;
	gint ti_offset;

	/* Get or create conversation */
	conversation = find_or_create_conversation(pinfo);

	/* Get or create data associated with this conversation */
	hash_info = (rlogin_hash_entry_t *)conversation_get_proto_data(conversation, proto_rlogin);
	if (!hash_info)
	{
		/* Populate new data struct... */
		hash_info = wmem_new(wmem_file_scope(), rlogin_hash_entry_t);
		hash_info->state = NONE;
		hash_info->info_framenum = 0;  /* no frame has the number 0 */
		hash_info->user_name[0] = '\0';

		/* ... and store in conversation */
		conversation_add_proto_data(conversation, proto_rlogin, hash_info);
	}

	/* Set protocol column text */
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "Rlogin");

	/* Set info column */
	/* Show user-name if available */
	if (hash_info->user_name[0])
	{
		col_add_fstr(pinfo->cinfo, COL_INFO,
		              "User name: %s, ", hash_info->user_name);
	}
	else
	{
		col_clear(pinfo->cinfo, COL_INFO);
	}

	/* Work out packet content summary for display */
	length = tvb_reported_length(tvb);
	if (length != 0)
	{
		/* Initial NULL byte represents part of connection handshake */
		if (tvb_get_guint8(tvb, 0) == '\0')
		{
			col_append_str(pinfo->cinfo, COL_INFO,
				               (pinfo->destport == RLOGIN_PORT) ?
				                   "Start Handshake" :
				                   "Startup info received");
		}
		else
		if (tcpinfo && IS_TH_URG(tcpinfo->flags) && length >= tcpinfo->urgent_pointer)
		{
			/* Urgent pointer inside current data represents a control message */
			col_append_str(pinfo->cinfo, COL_INFO, "Control Message");
		}
		else
		{
			/* Search for 2 consecutive ff bytes
			  (signifies window change control message) */
			ti_offset = tvb_find_guint8(tvb, 0, -1, 0xff);
			if (ti_offset != -1 &&
			    tvb_bytes_exist(tvb, ti_offset + 1, 1) &&
			    tvb_get_guint8(tvb, ti_offset + 1) == 0xff)
			{
				col_append_str(pinfo->cinfo, COL_INFO, "Terminal Info");
			}
			else
			{
				/* Show any text data in the frame */
				int bytes_to_copy = tvb_captured_length(tvb);
				if (bytes_to_copy > 128)
				{
					/* Truncate to 128 bytes for display */
					bytes_to_copy = 128;
				}

				/* Add data into info column */
				col_append_fstr(pinfo->cinfo, COL_INFO,
				                "Data: %s",
				                 tvb_format_text(tvb, 0, bytes_to_copy));
			}
		}
	}

	/* See if conversation state needs to be updated */
	rlogin_state_machine(hash_info, tvb, pinfo);

	/* Dissect in detail */
	rlogin_display(hash_info, tvb, pinfo, tree, tcpinfo);

	return tvb_captured_length(tvb);
}
Пример #24
0
/* Dissect details of packet */
static void rlogin_display(rlogin_hash_entry_t *hash_info,
			   tvbuff_t *tvb,
			   packet_info *pinfo,
			   proto_tree *tree,
			   struct tcpinfo *tcpinfo)
{
	/* Display the proto tree */
	int             offset = 0;
	proto_tree      *rlogin_tree, *user_info_tree, *window_tree;
	proto_item      *ti;
	guint           length;
	int             str_len;
	gint            ti_offset;
	proto_item      *user_info_item, *window_info_item;

	/* Create rlogin subtree */
	ti = proto_tree_add_item(tree, proto_rlogin, tvb, 0, -1, ENC_NA);
	rlogin_tree = proto_item_add_subtree(ti, ett_rlogin);

	/* Return if data empty */
	length = tvb_captured_length(tvb);
	if (length == 0)
	{
		return;
	}

	/*
	 * XXX - this works only if the urgent pointer points to something
	 * in this segment; to make it work if the urgent pointer points
	 * to something past this segment, we'd have to remember the urgent
	 * pointer setting for this conversation.
	 */
	if (tcpinfo && IS_TH_URG(tcpinfo->flags) &&      /* if urgent pointer set */
	    length >= tcpinfo->urgent_pointer) /* and it's in this frame */
	{
		/* Get urgent byte into Temp */
		int urgent_offset = tcpinfo->urgent_pointer - 1;
		guint8 control_byte;

		/* Check for text data in front */
		if (urgent_offset > offset)
		{
			proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, urgent_offset, ENC_ASCII|ENC_NA);
		}

		/* Show control byte */
		proto_tree_add_item(rlogin_tree, hf_control_message, tvb,
		                    urgent_offset, 1, ENC_BIG_ENDIAN);
		control_byte = tvb_get_guint8(tvb, urgent_offset);
		col_append_fstr(pinfo->cinfo, COL_INFO,
			               " (%s)", val_to_str_const(control_byte, control_message_vals, "Unknown"));

		offset = urgent_offset + 1; /* adjust offset */
	}
	else
	if (tvb_get_guint8(tvb, offset) == '\0')
	{
		/* Startup */
		if (pinfo->srcport == RLOGIN_PORT)   /* from server */
		{
			proto_tree_add_item(rlogin_tree, hf_startup_info_received_flag,
			                    tvb, offset, 1, ENC_BIG_ENDIAN);
		}
		else
		{
			proto_tree_add_item(rlogin_tree, hf_client_startup_flag,
			                    tvb, offset, 1, ENC_BIG_ENDIAN);
		}
		++offset;
	}

	if (!tvb_offset_exists(tvb, offset))
	{
		/* No more data to check */
		return;
	}

	if (hash_info->info_framenum == pinfo->num)
	{
		gint info_len;
		gint slash_offset;

		/* First frame of conversation, assume user info... */

		info_len = tvb_captured_length_remaining(tvb, offset);
		if (info_len <= 0)
			return;

		/* User info tree */
		user_info_item = proto_tree_add_string_format(rlogin_tree, hf_user_info, tvb,
		                                              offset, info_len, FALSE,
		                                              "User info (%s)",
		                                              tvb_format_text(tvb, offset, info_len));
		user_info_tree = proto_item_add_subtree(user_info_item,
		                                        ett_rlogin_user_info);

		/* Client user name. */
		str_len = tvb_strsize(tvb, offset);
		proto_tree_add_item(user_info_tree, hf_user_info_client_user_name,
		                    tvb, offset, str_len, ENC_ASCII|ENC_NA);
		offset += str_len;

		/* Server user name. */
		str_len = tvb_strsize(tvb, offset);
		proto_tree_add_item(user_info_tree, hf_user_info_server_user_name,
		                    tvb, offset, str_len, ENC_ASCII|ENC_NA);
		offset += str_len;

		/* Terminal type/speed. */
		slash_offset = tvb_find_guint8(tvb, offset, -1, '/');
		if (slash_offset != -1)
		{
			guint8* str = NULL;
			guint32 term_len = 0;
			gboolean term_len_valid;
			proto_item* pi = NULL;

			/* Terminal type */
			proto_tree_add_item(user_info_tree, hf_user_info_terminal_type,
			                    tvb, offset, slash_offset-offset, ENC_ASCII|ENC_NA);
			offset = slash_offset + 1;

			/* Terminal speed */
			str_len = tvb_strsize(tvb, offset);
			str = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, str_len,
				ENC_NA|ENC_ASCII);
			term_len_valid = ws_strtou32(str, NULL, &term_len);
			pi = proto_tree_add_uint(user_info_tree,
				hf_user_info_terminal_speed,
				tvb, offset, str_len, term_len);
			if (!term_len_valid)
				expert_add_info(pinfo, pi, &ei_rlogin_termlen_invalid);

			offset += str_len;
		}
	}

	if (!tvb_offset_exists(tvb, offset))
	{
		/* No more data to check */
		return;
	}

	/* Test for terminal information, the data will have 2 0xff bytes */
	/* look for first 0xff byte */
	ti_offset = tvb_find_guint8(tvb, offset, -1, 0xff);

	/* Next byte must also be 0xff */
	if (ti_offset != -1 &&
	    tvb_bytes_exist(tvb, ti_offset + 1, 1) &&
	    tvb_get_guint8(tvb, ti_offset + 1) == 0xff)
	{
		guint16 rows, columns;

		/* Have found terminal info. */
		if (ti_offset > offset)
		{
			/* There's data before the terminal info. */
			proto_tree_add_item(rlogin_tree, hf_data, tvb,
			                    offset, ti_offset - offset, ENC_ASCII|ENC_NA);
		}

		/* Create window info tree */
		window_info_item =
			proto_tree_add_item(rlogin_tree, hf_window_info, tvb, offset, 12, ENC_NA);
		window_tree = proto_item_add_subtree(window_info_item, ett_rlogin_window);

		/* Cookie */
		proto_tree_add_item(window_tree, hf_magic_cookie, tvb, offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* These bytes should be "ss" */
		proto_tree_add_item(window_tree, hf_window_info_ss, tvb, offset, 2, ENC_ASCII|ENC_NA);
		offset += 2;

		/* Character rows */
		rows = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(window_tree, hf_window_info_rows, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* Characters per row */
		columns = tvb_get_ntohs(tvb, offset);
		proto_tree_add_item(window_tree, hf_window_info_cols, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* x pixels */
		proto_tree_add_item(window_tree, hf_window_info_x_pixels, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* y pixels */
		proto_tree_add_item(window_tree, hf_window_info_y_pixels, tvb,
		                    offset, 2, ENC_BIG_ENDIAN);
		offset += 2;

		/* Show setting highlights in info column */
		col_append_fstr(pinfo->cinfo, COL_INFO, " (rows=%u, cols=%u)",
			                rows, columns);
	}

	if (tvb_offset_exists(tvb, offset))
	{
		/* There's more data in the frame. */
		proto_tree_add_item(rlogin_tree, hf_data, tvb, offset, -1, ENC_ASCII|ENC_NA);
	}
}
Пример #25
0
static int
dissect_rtspmessage(tvbuff_t *tvb, int offset, packet_info *pinfo,
	proto_tree *tree)
{
	proto_tree		*rtsp_tree = NULL;
	proto_tree		*sub_tree = NULL;
	proto_item		*ti = NULL;
	const guchar		*line;
	gint			next_offset;
	const guchar		*linep, *lineend;
	int			orig_offset;
	int			first_linelen, linelen;
	int			line_end_offset;
	int			colon_offset;
	gboolean		is_request_or_reply;
	gboolean		body_requires_content_len;
	gboolean		saw_req_resp_or_header;
	guchar			c;
	rtsp_type_t		rtsp_type;
	gboolean		is_header;
	int			datalen;
	int			content_length;
	int			reported_datalen;
	int			value_offset;
	int			value_len;
	e164_info_t		e164_info;
	gint			rdt_feature_level = 0;
	gchar			*media_type_str_lower_case = NULL;
	int			semi_colon_offset;
	int			par_end_offset;

	/*
	 * Is this a request or response?
	 *
	 * Note that "tvb_find_line_end()" will return a value that
	 * is not longer than what's in the buffer, so the
	 * "tvb_get_ptr()" call won't throw an exception.
	 */
	first_linelen = tvb_find_line_end(tvb, offset,
	    tvb_ensure_length_remaining(tvb, offset), &next_offset,
	    FALSE);

	/*
	 * Is the first line a request or response?
	 */
	line = tvb_get_ptr(tvb, offset, first_linelen);
	is_request_or_reply = is_rtsp_request_or_reply(line, first_linelen,
	    &rtsp_type);
	if (is_request_or_reply) {
                /*
		 * Yes, it's a request or response.
		 * Do header desegmentation if we've been told to,
		 * and do body desegmentation if we've been told to and
		 * we find a Content-Length header.
		 */
		if (!req_resp_hdrs_do_reassembly(tvb, offset, pinfo,
		    rtsp_desegment_headers, rtsp_desegment_body)) {
			/*
			 * More data needed for desegmentation.
			 */
			return -1;
		}
	}

	/*
	 * RFC 2326 says that a content length must be specified
	 * in requests that have a body, although section 4.4 speaks
	 * of a server closing the connection indicating the end of
	 * a reply body.
	 *
	 * We assume that an absent content length in a request means
	 * that we don't have a body, and that an absent content length
	 * in a reply means that the reply body runs to the end of
	 * the connection.  If the first line is neither, we assume
	 * that whatever follows a blank line should be treated as a
	 * body; there's not much else we can do, as we're jumping
	 * into the message in the middle.
	 *
	 * XXX - if there was no Content-Length entity header, we should
	 * accumulate all data until the end of the connection.
	 * That'd require that the TCP dissector call subdissectors
	 * for all frames with FIN, even if they contain no data,
	 * which would require subdissectors to deal intelligently
	 * with empty segments.
	 */
	if (rtsp_type == RTSP_REQUEST)
		body_requires_content_len = TRUE;
	else
		body_requires_content_len = FALSE;

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSP");
	if (check_col(pinfo->cinfo, COL_INFO)) {
		/*
		 * Put the first line from the buffer into the summary
 		 * if it's an RTSP request or reply (but leave out the
		 * line terminator).
		 * Otherwise, just call it a continuation.
		 *
		 * Note that "tvb_find_line_end()" will return a value that
		 * is not longer than what's in the buffer, so the
		 * "tvb_get_ptr()" call won't throw an exception.
		 */
		line = tvb_get_ptr(tvb, offset, first_linelen);
		if (is_request_or_reply)
			if ( rtsp_type == RTSP_REPLY ) {
				col_set_str(pinfo->cinfo, COL_INFO, "Reply: ");
				col_append_str(pinfo->cinfo, COL_INFO,
					format_text(line, first_linelen));
			}
			else
				col_add_str(pinfo->cinfo, COL_INFO,
					format_text(line, first_linelen));

		else
			col_set_str(pinfo->cinfo, COL_INFO, "Continuation");

	}

	orig_offset = offset;
	if (tree) {
		ti = proto_tree_add_item(tree, proto_rtsp, tvb, offset,	-1,
		    FALSE);
		rtsp_tree = proto_item_add_subtree(ti, ett_rtsp);
	}

	/*
	 * We haven't yet seen a Content-Length header.
	 */
	content_length = -1;

	/*
	 * Process the packet data, a line at a time.
	 */
	saw_req_resp_or_header = FALSE;	/* haven't seen anything yet */
	while (tvb_reported_length_remaining(tvb, offset) != 0) {
		/*
		 * We haven't yet concluded that this is a header.
		 */
		is_header = FALSE;

		/*
		 * Find the end of the line.
		 */
		linelen = tvb_find_line_end(tvb, offset,
		    tvb_ensure_length_remaining(tvb, offset), &next_offset,
		    FALSE);
		if (linelen < 0)
			return -1;
		line_end_offset = offset + linelen;
		/*
		 * colon_offset may be -1
		 */
		colon_offset = tvb_find_guint8(tvb, offset, linelen, ':');


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

		/*
		 * OK, does it look like an RTSP request or response?
		 */
		is_request_or_reply = is_rtsp_request_or_reply(line, linelen, &rtsp_type);
		if (is_request_or_reply)
			goto is_rtsp;

		/*
		 * No.  Does it look like a blank line (as would appear
		 * at the end of an RTSP request)?
		 */
		if (linelen == 0)
			goto is_rtsp;	/* Yes. */

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

			/*
			 * This must be a CHAR to be part of a token; that
			 * means it must be ASCII.
			 */
			if (!isascii(c))
				break;	/* not ASCII, thus not a CHAR */

			/*
			 * This mustn't be a CTL to be part of a token.
			 *
			 * XXX - what about leading LWS on continuation
			 * lines of a header?
			 */
			if (iscntrl(c))
				break;	/* CTL, not part of a header */

			switch (c) {

			case '(':
			case ')':
			case '<':
			case '>':
			case '@':
			case ',':
			case ';':
			case '\\':
			case '"':
			case '/':
			case '[':
			case ']':
			case '?':
			case '=':
			case '{':
			case '}':
				/*
				 * It's a tspecial, so it's not
				 * part of a token, so it's not
				 * a field name for the beginning
				 * of a header.
				 */
				goto not_rtsp;

			case ':':
				/*
				 * This ends the token; we consider
				 * this to be a header.
				 */
				is_header = TRUE;
				goto is_rtsp;

			case ' ':
			case '\t':
				/*
				 * LWS (RFC-2616, 4.2); continue the previous
				 * header.
				 */
				goto is_rtsp;
			}
		}

		/*
		 * We haven't seen the colon, but everything else looks
		 * OK for a header line.
		 *
		 * If we've already seen an RTSP request or response
		 * line, or a header line, and we're at the end of
		 * the tvbuff, we assume this is an incomplete header
		 * line.  (We quit this loop after seeing a blank line,
		 * so if we've seen a request or response line, or a
		 * header line, this is probably more of the request
		 * or response we're presumably seeing.  There is some
		 * risk of false positives, but the same applies for
		 * full request or response lines or header lines,
		 * although that's less likely.)
		 *
		 * We throw an exception in that case, by checking for
		 * the existence of the next byte after the last one
		 * in the line.  If it exists, "tvb_ensure_bytes_exist()"
		 * throws no exception, and we fall through to the
		 * "not RTSP" case.  If it doesn't exist,
		 * "tvb_ensure_bytes_exist()" will throw the appropriate
		 * exception.
		 */
		if (saw_req_resp_or_header)
			tvb_ensure_bytes_exist(tvb, offset, linelen + 1);

	not_rtsp:
		/*
		 * We don't consider this part of an RTSP request or
		 * reply, so we don't display it.
		 */
		break;

	is_rtsp:
		/*
		 * Process this line.
		 */
		if (linelen == 0) {
			/*
			 * This is a blank line, which means that
			 * whatever follows it isn't part of this
			 * request or reply.
			 */
			proto_tree_add_text(rtsp_tree, tvb, offset,
			                    next_offset - offset, "%s",
			                    tvb_format_text(tvb, offset, next_offset - offset));
			offset = next_offset;
			break;
		}

		/*
		 * Not a blank line - either a request, a reply, or a header
		 * line.
		 */
		saw_req_resp_or_header = TRUE;
		if (rtsp_tree) {

			switch (rtsp_type)
			{
				case RTSP_REQUEST:
					process_rtsp_request(tvb, offset, line, linelen, next_offset, rtsp_tree);
					break;
	
				case RTSP_REPLY:
					process_rtsp_reply(tvb, offset, line, linelen, next_offset, rtsp_tree);
					break;
	
				case RTSP_NOT_FIRST_LINE:
					/* Drop through, it may well be a header line */
					break;
			}
		}

		if (is_header)
		{
			/* We know that colon_offset must be set */
			
			/* Skip whitespace after the colon. */
			value_offset = colon_offset + 1;
			while ((value_offset < line_end_offset) &&
				   ((c = tvb_get_guint8(tvb, value_offset)) == ' ' || c == '\t'))
			{
				value_offset++;
			}
			value_len = line_end_offset - value_offset;

			/*
			 * Process some headers specially.
			 */
#define HDR_MATCHES(header) \
	( (size_t)linelen > STRLEN_CONST(header) && \
	 g_ascii_strncasecmp(line, (header), STRLEN_CONST(header)) == 0)

			if (HDR_MATCHES(rtsp_transport))
			{
				proto_tree_add_string(rtsp_tree, hf_rtsp_transport, tvb,
				                      offset, linelen,
				                      tvb_format_text(tvb, value_offset,
				                                      value_len));

				/*
				 * Based on the port numbers specified
				 * in the Transport: header, set up
				 * a conversation that will be dissected
				 * with the appropriate dissector.
				 */
				rtsp_create_conversation(pinfo, line, linelen, rdt_feature_level);
			} else if (HDR_MATCHES(rtsp_content_type))
			{
				proto_tree_add_string(rtsp_tree, hf_rtsp_content_type,
				                      tvb, offset, linelen,
				                      tvb_format_text(tvb, value_offset,
				                                      value_len));

				offset = offset + STRLEN_CONST(rtsp_content_type);
				/* Skip wsp */
				offset = tvb_skip_wsp(tvb, offset, value_len);
				semi_colon_offset = tvb_find_guint8(tvb, value_offset, value_len, ';');
				if ( semi_colon_offset != -1) {
					/* m-parameter present */
					par_end_offset = tvb_skip_wsp_return(tvb, semi_colon_offset-1);
					value_len = par_end_offset - offset;
				}

				media_type_str_lower_case = ascii_strdown_inplace(
                                    (gchar *)tvb_get_ephemeral_string(tvb, offset, value_len));

			} else if (HDR_MATCHES(rtsp_content_length))
			{
				proto_tree_add_uint(rtsp_tree, hf_rtsp_content_length,
				                    tvb, offset, linelen,
				                    atoi(tvb_format_text(tvb, value_offset,
				                                         value_len)));

				/*
				 * Only the amount specified by the
				 * Content-Length: header should be treated
				 * as payload.
				 */
				content_length = rtsp_get_content_length(line, linelen);

			} else if (HDR_MATCHES(rtsp_Session))
			{
				/* Put the value into the protocol tree */
				proto_tree_add_string(rtsp_tree, hf_rtsp_session, tvb,
				                      offset, linelen,
				                      tvb_format_text(tvb, value_offset, value_len));

			} else if (HDR_MATCHES(rtsp_X_Vig_Msisdn)) {
				/*
				 * Extract the X_Vig_Msisdn string
				 */
				if (colon_offset != -1)
				{
					/* Put the value into the protocol tree */
					ti = proto_tree_add_string(rtsp_tree, hf_rtsp_X_Vig_Msisdn,tvb,
					                           offset, linelen ,
					                           tvb_format_text(tvb, value_offset, value_len));
					sub_tree = proto_item_add_subtree(ti, ett_rtsp_method);

					e164_info.e164_number_type = CALLING_PARTY_NUMBER;
					e164_info.nature_of_address = 0;

					e164_info.E164_number_str = tvb_get_ephemeral_string(tvb, value_offset,
					                                              value_len);
					e164_info.E164_number_length = value_len;
					dissect_e164_number(tvb, sub_tree, value_offset,
					                    value_len, e164_info);
				}
			} else if (HDR_MATCHES(rtsp_rdt_feature_level))
			{
				rdt_feature_level = atoi(tvb_format_text(tvb, value_offset,
				                                         value_len));
				proto_tree_add_uint(rtsp_tree, hf_rtsp_rdtfeaturelevel,
				                    tvb, offset, linelen,
				                    atoi(tvb_format_text(tvb, value_offset,
				                                         value_len)));
			}
			else
			{
				/* Default case for headers. Show line as text */
				proto_tree_add_text(rtsp_tree, tvb, offset,
				                    next_offset - offset, "%s",
				                    tvb_format_text(tvb, offset, next_offset - offset));
			}
		}
		else if (rtsp_type == RTSP_NOT_FIRST_LINE)
		{
			/* Catch-all for all other lines... Show line as text.
			   TODO: should these be shown as errors? */
			proto_tree_add_text(rtsp_tree, tvb, offset,
			                    next_offset - offset, "%s",
			                    tvb_format_text(tvb, offset, next_offset - offset));
		}
		
		offset = next_offset;
	}

	/*
	 * Have now read all of the lines of this message.
	 *
	 * If a content length was supplied, the amount of data to be
	 * processed as RTSP payload is the minimum of the content
	 * length and the amount of data remaining in the frame.
	 *
	 * If no content length was supplied (or if a bad content length
	 * was supplied), the amount of data to be processed is the amount
	 * of data remaining in the frame.
	 */
	datalen = tvb_length_remaining(tvb, offset);
	reported_datalen = tvb_reported_length_remaining(tvb, offset);
	if (content_length != -1) {
		/*
		 * Content length specified; display only that amount
		 * as payload.
		 */
		if (datalen > content_length)
			datalen = content_length;

		/*
		 * XXX - limit the reported length in the tvbuff we'll
		 * hand to a subdissector to be no greater than the
		 * content length.
		 *
		 * We really need both unreassembled and "how long it'd
		 * be if it were reassembled" lengths for tvbuffs, so
		 * that we throw the appropriate exceptions for
		 * "not enough data captured" (running past the length),
		 * "packet needed reassembly" (within the length but
		 * running past the unreassembled length), and
		 * "packet is malformed" (running past the reassembled
		 * length).
		 */
		if (reported_datalen > content_length)
			reported_datalen = content_length;
	} else {
		/*
		 * No content length specified; if this message doesn't
		 * have a body if no content length is specified, process
		 * nothing as payload.
		 */
		if (body_requires_content_len)
			datalen = 0;
	}

	if (datalen > 0) {
		/*
		 * There's stuff left over; process it.
		 */
		tvbuff_t *new_tvb;

		/*
		 * Now create a tvbuff for the Content-type stuff and
		 * dissect it.
		 *
		 * The amount of data to be processed that's
		 * available in the tvbuff is "datalen", which
		 * is the minimum of the amount of data left in
		 * the tvbuff and any specified content length.
		 *
		 * The amount of data to be processed that's in
		 * this frame, regardless of whether it was
		 * captured or not, is "reported_datalen",
		 * which, if no content length was specified,
		 * is -1, i.e. "to the end of the frame.
		 */
		new_tvb = tvb_new_subset(tvb, offset, datalen,
			    reported_datalen);

		if (media_type_str_lower_case && 
			dissector_try_string(media_type_dissector_table,
				media_type_str_lower_case,
				new_tvb, pinfo, rtsp_tree)){
			
		}else {
			/*
			 * Fix up the top-level item so that it doesn't
			 * include the SDP stuff.
			 */
			if (ti != NULL)
				proto_item_set_len(ti, offset);

			if (tvb_get_guint8(tvb, offset) == RTSP_FRAMEHDR) {
				/*
				 * This is interleaved stuff; don't
				 * treat it as raw data - set "datalen"
				 * to 0, so we won't skip the offset
				 * past it, which will cause our
				 * caller to process that stuff itself.
				 */
				datalen = 0;
			} else {
				proto_tree_add_text(rtsp_tree, tvb, offset,
				    datalen, "Data (%d bytes)",
				    reported_datalen);
			}
		}

		/*
		 * We've processed "datalen" bytes worth of data
		 * (which may be no data at all); advance the
		 * offset past whatever data we've processed.
		 */
		offset += datalen;
	}
	return offset - orig_offset;
}
Пример #26
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;
}
Пример #27
0
static void
dissect_irc_response(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, int offset, int linelen)
{
    proto_tree *response_tree, *command_tree = NULL;
    proto_item *response_item, *hidden_item;
    int         start_offset                 = offset;
    int         end_offset                   = start_offset+linelen;
    gint        eop_offset                   = -1,
                eoc_offset                   = -1,
                eocp_offset,
                tag_start_offset, tag_end_offset;
    guint8*     str_command;
    guint16     num_command;
    guchar      found_tag_needle             = 0;
    gboolean    first_command_param          = TRUE;

    response_item = proto_tree_add_item(tree, hf_irc_response, tvb, offset, linelen, ENC_ASCII|ENC_NA);
    if (linelen <= 0)
        return;

    response_tree = proto_item_add_subtree(response_item, ett_irc_response );

    /* Check if message has a prefix */
    if (tvb_get_guint8(tvb, offset) == ':')
    {
        /* find the end of the prefix */
        eop_offset = tvb_find_guint8(tvb, offset+1, linelen-1, ' ');
        if (eop_offset == -1)
        {
            expert_add_info(pinfo, response_item, &ei_irc_prefix_missing_ending_space);
            return;
        }

        proto_tree_add_item(response_tree, hf_irc_response_prefix, tvb, offset+1, eop_offset-offset-1, ENC_ASCII|ENC_NA);
        offset = eop_offset+1;
    }

    /* clear out any whitespace before command */
    while(offset < end_offset && tvb_get_guint8(tvb, offset) == ' ')
    {
        offset++;
    }
    if (offset == end_offset)
    {
        expert_add_info(pinfo, response_item, &ei_irc_response_command);
        return;
    }

    eoc_offset = tvb_find_guint8(tvb, offset, end_offset-offset, ' ');
    if (eoc_offset == -1)
    {
        proto_tree_add_item(response_tree, hf_irc_response_command, tvb, offset, end_offset-offset, ENC_ASCII|ENC_NA);
        col_append_fstr( pinfo->cinfo, COL_INFO, " (%s)",
              tvb_get_string_enc(wmem_packet_scope(), tvb, offset, end_offset-offset, ENC_ASCII|ENC_NA));

        /* if response command is numeric, allow it to be filtered as an integer */
        if ((end_offset-offset == 3) &&
            (g_ascii_isdigit(tvb_get_guint8(tvb, offset))) &&
            (g_ascii_isdigit(tvb_get_guint8(tvb, offset+1))) &&
            (g_ascii_isdigit(tvb_get_guint8(tvb, offset+2))))
        {
            num_command = ((tvb_get_guint8(tvb, offset)-0x30)*100) + ((tvb_get_guint8(tvb, offset+1)-0x30)*10) + (tvb_get_guint8(tvb, offset+2)-0x30);
            hidden_item = proto_tree_add_uint(response_tree, hf_irc_response_num_command, tvb, offset, end_offset-offset, num_command);
            PROTO_ITEM_SET_HIDDEN(hidden_item);
        }
        return;
    }

    proto_tree_add_item(response_tree, hf_irc_response_command, tvb, offset, eoc_offset-offset, ENC_ASCII|ENC_NA);
    str_command = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, eoc_offset-offset, ENC_ASCII|ENC_NA);
    col_append_fstr( pinfo->cinfo, COL_INFO, " (%s)", str_command);

    /* if response command is numeric, allow it to be filtered as an integer */
    if ((eoc_offset-offset == 3) &&
       (g_ascii_isdigit(tvb_get_guint8(tvb, offset))) &&
       (g_ascii_isdigit(tvb_get_guint8(tvb, offset+1))) &&
       (g_ascii_isdigit(tvb_get_guint8(tvb, offset+2))))
    {
        num_command = ((tvb_get_guint8(tvb, offset)-0x30)*100) + ((tvb_get_guint8(tvb, offset+1)-0x30)*10) + (tvb_get_guint8(tvb, offset+2)-0x30);
        hidden_item = proto_tree_add_uint(response_tree, hf_irc_response_num_command, tvb, offset, eoc_offset-offset, num_command);
        PROTO_ITEM_SET_HIDDEN(hidden_item);
    }

    offset = eoc_offset+1;

    /* clear out any whitespace before command parameter */
    while(offset < end_offset && tvb_get_guint8(tvb, offset) == ' ')
    {
        offset++;
    }
    if (offset == end_offset)
    {
        /* No command parameters */
        return;
    }

    /* Check if message has a trailer */
    if (tvb_get_guint8(tvb, offset) == ':')
    {
        proto_tree_add_item(response_tree, hf_irc_response_trailer, tvb, offset+1, end_offset-offset-1, ENC_ASCII|ENC_NA);
        dissect_irc_tag_data(response_tree, response_item, tvb, offset+1, end_offset-offset-1, pinfo, str_command);
        return;
    }

    while(offset < end_offset)
    {
        eocp_offset = tvb_find_guint8(tvb, offset, end_offset-offset, ' ');
        tag_start_offset = tvb_ws_mempbrk_pattern_guint8(tvb, offset, end_offset-offset, &pbrk_tag_delimiter, &found_tag_needle);

        /* Create subtree when the first parameter is found */
        if (first_command_param)
        {
            command_tree = proto_tree_add_subtree(response_tree, tvb, offset, end_offset-offset,
                                        ett_irc_response_command , NULL, "Command parameters");
            first_command_param = FALSE;
        }

        if ((tag_start_offset == -1) || (eocp_offset < tag_start_offset))
        {
            /* regular message should be dissected */

            if (eocp_offset == -1)
            {
                proto_tree_add_item(command_tree, hf_irc_response_command_param, tvb, offset, end_offset-offset, ENC_ASCII|ENC_NA);
                return;
            }

            proto_tree_add_item(command_tree, hf_irc_response_command_param, tvb, offset, eocp_offset-offset, ENC_ASCII|ENC_NA);
            offset = eocp_offset+1;

            /* clear out any whitespace before next command parameter */
            while(offset < end_offset && tvb_get_guint8(tvb, offset) == ' ')
            {
                offset++;
            }
            if (offset == end_offset)
            {
                break;
            }

            /* Check if message has a trailer */
            if (tvb_get_guint8(tvb, offset) == ':')
            {
                proto_tree_add_item(response_tree, hf_irc_response_trailer, tvb, offset+1, end_offset-offset-1, ENC_ASCII|ENC_NA);
                dissect_irc_tag_data(response_tree, response_item, tvb, offset+1, end_offset-offset-1, pinfo, str_command);
                return;
            }
        }
        else if ((eocp_offset == -1) || (eocp_offset > tag_start_offset))
        {
            /* tag data dissected */

            found_tag_needle = 0;
            tag_end_offset = tvb_ws_mempbrk_pattern_guint8(tvb, tag_start_offset+1, end_offset-tag_start_offset-1, &pbrk_tag_delimiter, &found_tag_needle);
            if (tag_end_offset == -1)
            {
                expert_add_info(pinfo, response_item, &ei_irc_missing_end_delimiter);
                return;
            }

            dissect_irc_tag_data(response_tree, response_item, tvb, tag_start_offset, tag_end_offset-tag_start_offset, pinfo, str_command);
            offset = tag_end_offset+1;
        }
    }
}