Esempio n. 1
0
static int
dissect_kt_remove_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz;
    gint new_offset, rec_start_offset;
    proto_item *ti;
    proto_item *pi;
    proto_tree *rec_tree;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    next32 = tvb_get_ntohl(tvb, new_offset);

    if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) { /* request */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST);
        proto_item_set_generated(pi);

        proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32);
        new_offset += 4;

        rnum = tvb_get_ntohl(tvb, new_offset);
        proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum);
        new_offset += 4;

        while (rnum > 0) {
            /* Create a sub-tree for each record */
            ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
            rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
            rec_start_offset = new_offset;

            proto_tree_add_item(rec_tree, hf_kt_dbidx, tvb, new_offset, 2, ENC_BIG_ENDIAN);
            new_offset += 2;

            ksiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
            new_offset += 4;

            proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                proto_item_set_generated(pi);
            }
            new_offset += ksiz;

            proto_item_set_len(ti, new_offset - rec_start_offset);
            rnum--;
        }
    } else { /* response */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        proto_item_set_generated(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

        proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, next32);
        new_offset += 4;
    }

    return new_offset;
}
Esempio n. 2
0
static void
dissect_bacnet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    proto_item *ti;
    proto_item *ct;
    proto_tree *bacnet_tree;
    proto_tree *control_tree;

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

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

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

    offset = 0;
    bacnet_version = tvb_get_guint8(tvb, offset);
    bacnet_control = tvb_get_guint8(tvb, offset+1);
    bacnet_dlen = 0;
    bacnet_slen = 0;
    bacnet_mesgtyp = 0;
    bacnet_rejectreason = 0;
    bacnet_rportnum = 0;
    bacnet_pinfolen =0;
    i = 0;
    j = 0;

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

    bacnet_tree = proto_item_add_subtree(ti, ett_bacnet);

    proto_tree_add_uint_format_value(bacnet_tree, hf_bacnet_version, tvb,
                                     offset, 1,
                                     bacnet_version,"0x%02x (%s)",bacnet_version,
                                     (bacnet_version == 0x01)?"ASHRAE 135-1995":"unknown");
    offset ++;
    ct = proto_tree_add_uint(bacnet_tree, hf_bacnet_control,
                             tvb, offset, 1, bacnet_control);
    control_tree = proto_item_add_subtree(ct, ett_bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_net,
                           tvb, offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_res1, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_dest, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_res2, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_src, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_expect, tvb,
                           offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_high,
                           tvb, offset, 1, bacnet_control);
    proto_tree_add_boolean(control_tree, hf_bacnet_control_prio_low,
                           tvb, offset, 1, bacnet_control);
    offset ++;
    if (bacnet_control & BAC_CONTROL_DEST) { /* DNET, DLEN, DADR */
        proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                            tvb, offset, 2, FALSE);
        offset += 2;
        bacnet_dlen = tvb_get_guint8(tvb, offset);
        /* DLEN = 0 is broadcast on dest.network */
        if( bacnet_dlen == 0) {
            /* append to hf_bacnet_dlen: broadcast */
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
                                             "%d indicates Broadcast on Destination Network",
                                             bacnet_dlen);
            offset ++;
            /* going to SNET */
        } else if (bacnet_dlen==6) {
            proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
                                tvb, offset, 1, bacnet_dlen);
            offset ++;
            /* Ethernet MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_dadr_eth, tvb, offset,
                                bacnet_dlen, FALSE);
            offset += bacnet_dlen;
        } else if (bacnet_dlen==1) {
            proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
                                tvb, offset, 1, bacnet_dlen);
            offset ++;
            /* MS/TP or ARCNET MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_dadr_mstp, tvb, offset,
                                bacnet_dlen, FALSE);
            offset += bacnet_dlen;
        } else if (bacnet_dlen<7) {
            proto_tree_add_uint(bacnet_tree, hf_bacnet_dlen,
                                tvb, offset, 1, bacnet_dlen);
            offset ++;
            /* Other MAC formats should be included here */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_dadr_tmp, tvb, offset,
                                bacnet_dlen, FALSE);
            offset += bacnet_dlen;
        } else {
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_dlen, tvb, offset, 1, bacnet_dlen,
                                             "%d invalid!",
                                             bacnet_dlen);
        }
    }
    if (bacnet_control & BAC_CONTROL_SRC) { /* SNET, SLEN, SADR */
        /* SNET */
        proto_tree_add_uint(bacnet_tree, hf_bacnet_snet,
                            tvb, offset, 2, tvb_get_ntohs(tvb, offset));
        offset += 2;
        bacnet_slen = tvb_get_guint8(tvb, offset);
        if( bacnet_slen == 0) { /* SLEN = 0 invalid */
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
                                             "%d invalid!",
                                             bacnet_slen);
            offset ++;
        } else if (bacnet_slen==6) {
            /* SLEN */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
                                tvb, offset, 1, bacnet_slen);
            offset ++;
            /* Ethernet MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_sadr_eth, tvb, offset,
                                bacnet_slen, FALSE);
            offset += bacnet_slen;
        } else if (bacnet_slen==1) {
            /* SLEN */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
                                tvb, offset, 1, bacnet_slen);
            offset ++;
            /* MS/TP or ARCNET MAC */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_sadr_mstp, tvb, offset,
                                bacnet_slen, FALSE);
            offset += bacnet_slen;
        } else if (bacnet_slen<6) { /* LON MAC */
            /* SLEN */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_slen,
                                tvb, offset, 1, bacnet_slen);
            offset ++;
            /* Other MAC formats should be included here */
            proto_tree_add_item(bacnet_tree,
                                hf_bacnet_sadr_tmp, tvb, offset,
                                bacnet_slen, FALSE);
            offset += bacnet_slen;
        } else {
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_slen, tvb, offset, 1, bacnet_slen,
                                             "%d invalid!",
                                             bacnet_slen);
            offset ++;
        }
    }
    if (bacnet_control & BAC_CONTROL_DEST) { /* Hopcount */
        proto_tree_add_item(bacnet_tree, hf_bacnet_hopc,
                            tvb, offset, 1, FALSE);
        offset ++;
    }
    /* Network Layer Message Type */
    if (bacnet_control & BAC_CONTROL_NET) {
        bacnet_mesgtyp =  tvb_get_guint8(tvb, offset);
        proto_tree_add_uint_format_value(bacnet_tree,
                                         hf_bacnet_mesgtyp, tvb, offset, 1, bacnet_mesgtyp,
                                         "%02x (%s)", bacnet_mesgtyp,
                                         bacnet_mesgtyp_name(bacnet_mesgtyp));
        /* Put the NPDU Type in the info column */
        if (check_col(pinfo->cinfo, COL_INFO))
        {
            col_clear(pinfo->cinfo, COL_INFO);
            col_add_str(pinfo->cinfo, COL_INFO,
                        bacnet_mesgtyp_name(bacnet_mesgtyp));
        }
        offset ++;
        /* Vendor ID
        * The standard says: "If Bit 7 of the control octet is 1 and
        * the Message Type field contains a value in the range
        * X'80' - X'FF', then a Vendor ID field shall be present (...)."
        * We should not go any further in dissecting the packet if it's
        * not present, but we don't know about that: No length field...
        */
        if (bacnet_mesgtyp > 0x7f) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_vendor,
                                tvb, offset, 2, FALSE);
            offset += 2;
            /* attention: doesnt work here because of if(tree) */
            call_dissector(data_handle,
                           tvb_new_subset_remaining(tvb, offset), pinfo, tree);
        }
        /* Performance Index (in I-Could-Be-Router-To-Network) */
        if (bacnet_mesgtyp == BAC_NET_ICB_R) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, FALSE);
            offset += 2;
            proto_tree_add_item(bacnet_tree, hf_bacnet_perf,
                                tvb, offset, 1, FALSE);
            offset ++;
        }
        /* Reason, DNET (in Reject-Message-To-Network) */
        if (bacnet_mesgtyp == BAC_NET_REJ) {
            bacnet_rejectreason = tvb_get_guint8(tvb, offset);
            proto_tree_add_uint_format_value(bacnet_tree,
                                             hf_bacnet_rejectreason,
                                             tvb, offset, 1,
                                             bacnet_rejectreason, "%d (%s)",
                                             bacnet_rejectreason,
                                             bacnet_rejectreason_name(bacnet_rejectreason));
            offset ++;
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, FALSE);
            offset += 2;
        }
        /* N*DNET (in Router-Busy-To-Network,Router-Available-To-Network) */
        if ((bacnet_mesgtyp == BAC_NET_R_BUSY) ||
                (bacnet_mesgtyp == BAC_NET_WHO_R) ||
                (bacnet_mesgtyp == BAC_NET_R_AVA) ||
                (bacnet_mesgtyp == BAC_NET_IAM_R) ) {
            while(tvb_reported_length_remaining(tvb, offset) > 1 ) {
                proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                    tvb, offset, 2, FALSE);
                offset += 2;
            }
        }
        /* Initialize-Routing-Table */
        if ( (bacnet_mesgtyp == BAC_NET_INIT_RTAB) ||
                (bacnet_mesgtyp == BAC_NET_INIT_RTAB_ACK) ) {
            bacnet_rportnum = tvb_get_guint8(tvb, offset);
            /* number of ports */
            proto_tree_add_uint(bacnet_tree, hf_bacnet_rportnum,
                                tvb, offset, 1, bacnet_rportnum);
            offset ++;
            for(i=0; i<bacnet_rportnum; i++) {
                /* Connected DNET */
                proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                    tvb, offset, 2, FALSE);
                offset += 2;
                /* Port ID */
                proto_tree_add_item(bacnet_tree, hf_bacnet_portid,
                                    tvb, offset, 1, FALSE);
                offset ++;
                /* Port Info Length */
                bacnet_pinfolen = tvb_get_guint8(tvb, offset);
                proto_tree_add_uint(bacnet_tree, hf_bacnet_pinfolen,
                                    tvb, offset, 1, bacnet_pinfolen);
                offset ++;
                proto_tree_add_text(bacnet_tree, tvb, offset,
                                    bacnet_pinfolen, "Port Info: %s",
                                    tvb_bytes_to_str(tvb, offset, bacnet_pinfolen));
                offset += bacnet_pinfolen;
            }
        }
        /* Establish-Connection-To-Network */
        if (bacnet_mesgtyp == BAC_NET_EST_CON) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, FALSE);
            offset += 2;
            proto_tree_add_item(bacnet_tree, hf_bacnet_term_time_value,
                                tvb, offset, 1, FALSE);
            offset ++;
        }
        /* Disconnect-Connection-To-Network */
        if (bacnet_mesgtyp == BAC_NET_DISC_CON) {
            proto_tree_add_item(bacnet_tree, hf_bacnet_dnet,
                                tvb, offset, 2, FALSE);
            offset += 2;
        }
        proto_item_set_len(ti, offset);
    }
    /* dissect BACnet APDU */
    next_tvb = tvb_new_subset_remaining(tvb,offset);
    if (bacnet_control & BAC_CONTROL_NET) {
        /* Unknown function - dissect the payload as data */
        call_dissector(data_handle, next_tvb, pinfo, tree);
    } else {
        /* APDU - call the APDU dissector */
        call_dissector(bacapp_handle, next_tvb, pinfo, tree);
    }
}
Esempio n. 3
0
/*
 * Optionally do reassembly of the request/response line, headers, and body.
 */
gboolean
req_resp_hdrs_do_reassembly(tvbuff_t *tvb, const int offset, packet_info *pinfo,
    const gboolean desegment_headers, const gboolean desegment_body)
{
	gint		next_offset;
	gint		next_offset_sav;
	gint		length_remaining, reported_length_remaining;
	int		linelen;
	gchar		*header_val;
	int		content_length;
	gboolean	content_length_found = FALSE;
	gboolean	content_type_found = FALSE;
	gboolean	chunked_encoding = FALSE;
	gboolean	keepalive_found = FALSE;
	gchar		*line;
	gchar		*content_type = NULL;

	/*
	 * Do header desegmentation if we've been told to.
	 *
	 * RFC 2616 defines HTTP messages as being either of the
	 * Request or the Response type
	 * (HTTP-message = Request | Response).
	 * Request and Response are defined as:
	 *     Request = Request-Line
	 *         *(( general-header
	 *         | request-header
	 *         | entity-header ) CRLF)
	 *         CRLF
	 *         [ message-body ]
	 *     Response = Status-Line
	 *         *(( general-header
	 *         | response-header
	 *         | entity-header ) CRLF)
	 *         CRLF
	 *         [ message-body ]
	 * that's why we can always assume two consecutive line
	 * endings (we allow CR, LF, or CRLF, as some clients
	 * or servers might not use a full CRLF) to mark the end
	 * of the headers.  The worst thing that would happen
	 * otherwise would be the packet not being desegmented
	 * or being interpreted as only headers.
	 *
	 * RFC 2326 says RTSP works the same way; RFC 3261 says SIP
	 * works the same way.
	 */

	/*
	 * If header desegmentation is activated, check that all
	 * headers are in this tvbuff (search for an empty line
	 * marking end of headers) or request one more byte (we
	 * don't know how many bytes we'll need, so we just ask
	 * for one).
	 */
	if (desegment_headers && pinfo->can_desegment) {
		next_offset = offset;
		for (;;) {
			next_offset_sav = next_offset;

			reported_length_remaining =
			    tvb_reported_length_remaining(tvb, next_offset);

			/*
			 * Request one more byte if there're no
			 * bytes left in the reported data (if there're
			 * bytes left in the reported data, but not in
			 * the available data, requesting more bytes
			 * won't help, as those bytes weren't captured).
			 */
			if (reported_length_remaining < 1) {
				pinfo->desegment_offset = offset;
				pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
				return FALSE;
			}

			length_remaining = tvb_captured_length_remaining(tvb,
			    next_offset);

			/*
			 * Request one more byte if we cannot find a
			 * header (i.e. a line end).
			 */
			linelen = tvb_find_line_end(tvb, next_offset,
			    length_remaining, &next_offset, TRUE);
			if (linelen == -1 &&
			    length_remaining >= reported_length_remaining) {
				/*
				 * Not enough data; ask for one more
				 * byte.
				 */
				pinfo->desegment_offset = offset;
				pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
				return FALSE;
			}

                        if (linelen == 0) {
				/*
				 * We found the end of the headers.
				 */
				break;
			}

			/*
			 * Is this a Content-Length or Transfer-Encoding
			 * header?  If not, it either means that we are in
			 * a different header line, or that we are
			 * at the end of the headers, or that there
			 * isn't enough data; the two latter cases
			 * have already been handled above.
			 */
			if (desegment_body) {
				/* Optimization to avoid fetching the whole (potentially very long)
				 * line and doing expensive string comparisons if the first
				 * character doesn't match. Shaves about 20% off the load time of
				 * one of my sample files that's HTTP-alike. */
				guchar first_byte = tvb_get_guint8(tvb, next_offset_sav);
				if (! (first_byte == 'c' || first_byte == 'C' ||
				       first_byte == 't' || first_byte == 'T')) {
					continue;
				}

				/*
				 * Check if we've found Content-Length.
				 */
				line = tvb_get_string_enc(wmem_packet_scope(), tvb, next_offset_sav, linelen, ENC_UTF_8|ENC_NA);
				if (g_ascii_strncasecmp(line, "Content-Length:", 15) == 0) {
					/* XXX - what if it doesn't fit in an int?
					   (Do not "fix" that by making this
					   a "long"; make it a gint64 or a
					   guint64.) */
					if (sscanf(line+15,"%i", &content_length) == 1)
						content_length_found = TRUE;
				} else if (g_ascii_strncasecmp(line, "Content-Type:", 13) == 0) {
					content_type_found = TRUE;
					content_type = line+13;
					while (*content_type == ' ') {
						content_type++;
					}
				} else if (g_ascii_strncasecmp(line, "Connection:", 11) == 0) {
					/* Check for keep-alive */
					header_val = line+11;
					if(header_val){
						while(*header_val==' '){
							header_val++;
						}
						if(!g_ascii_strncasecmp(header_val, "Keep-Alive", 10)){
							keepalive_found = TRUE;
						}
					}
				} else if (g_ascii_strncasecmp( line, "Transfer-Encoding:", 18) == 0) {
					/*
					 * Find out if this Transfer-Encoding is
					 * chunked.  It should be, since there
					 * really aren't any other types, but
					 * RFC 2616 allows for them.
					 */
					gchar *p;
					guint len;

					header_val = line+18;
					p = header_val;
					len = (guint) strlen(header_val);
					/* Skip white space */
					while (p < header_val + len &&
					    (*p == ' ' || *p == '\t'))
						p++;
					if (p <= header_val + len) {
						if (g_ascii_strncasecmp(p, "chunked", 7)
						    == 0) {
							/*
							 * Don't bother looking
							 * for extensions;
							 * since we don't
							 * understand them,
							 * they should be
							 * ignored.
							 */
							chunked_encoding = TRUE;
						}
					}
				}
			}
		}
	}

	/*
	 * The above loop ends when we reached the end of the headers, so
	 * there should be content_length bytes after the 4 terminating bytes
	 * and next_offset points to after the end of the headers.
	 */
	if (desegment_body) {
		if (chunked_encoding) {
			/*
			 * This data is chunked, so we need to keep pulling
			 * data until we reach the end of the stream, or a
			 * zero sized chunk.
			 *
			 * XXX
			 * This doesn't bother with trailing headers; I don't
			 * think they are really used, and we'd have to use
			 * is_http_request_or_reply() to determine if it was
			 * a trailing header, or the start of a new response.
			 */
			gboolean done_chunking = FALSE;

			while (!done_chunking) {
				guint chunk_size = 0;
				gint  chunk_offset = 0;
				gchar *chunk_string = NULL;
				gchar *c = NULL;

				reported_length_remaining =
				    tvb_reported_length_remaining(tvb,
				    next_offset);

				if (reported_length_remaining < 1) {
					pinfo->desegment_offset = offset;
					pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
					return FALSE;
				}

				length_remaining = tvb_captured_length_remaining(tvb,
				    next_offset);

				linelen = tvb_find_line_end(tvb, next_offset,
						length_remaining, &chunk_offset, TRUE);

				if (linelen == -1 &&
				    length_remaining >=
				    reported_length_remaining) {
					 pinfo->desegment_offset = offset;
					 pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
					 return FALSE;
				}

				/* We have a line with the chunk size in it.*/
				chunk_string = tvb_get_string(wmem_packet_scope(), tvb, next_offset,
				    linelen);
				c = chunk_string;

				/*
				 * We don't care about the extensions.
				 */
				if ((c = strchr(c, ';'))) {
					*c = '\0';
				}

				if (sscanf(chunk_string, "%x", &chunk_size) < 1) {
					/* We couldn't get the chunk size,
					 * so stop trying.
					 */
					return TRUE;
				}
				if (chunk_size > 1U<<31) {
					/* Chunk size is unreasonable. */
					/* XXX What /is/ reasonable? */
					return TRUE;
				}

				if (chunk_size == 0) {
					/*
					 * This is the last chunk.  Let's pull in the
					 * trailing CRLF.
					 */
					linelen = tvb_find_line_end(tvb,
					    chunk_offset, length_remaining, &chunk_offset, TRUE);

					if (linelen == -1 &&
					    length_remaining >=
					    reported_length_remaining) {
						pinfo->desegment_offset = offset;
						pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
						return FALSE;
					}

					pinfo->desegment_offset = chunk_offset;
					pinfo->desegment_len = 0;
					done_chunking = TRUE;
				} else {
					/*
					 * Skip to the next chunk if we
					 * already have it
					 */
					if (reported_length_remaining >
					        (gint) chunk_size) {

						next_offset = chunk_offset
						    + chunk_size + 2;
					} else {
						/*
						 * Fetch this chunk, plus the
						 * trailing CRLF.
						 */
						pinfo->desegment_offset = offset;
						pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT;
						return FALSE;
					}
				}

			}
		} else if (content_length_found) {
			if (content_length >= 128*1024) { /* MS-RPCH stipulate that the content-length must be between 128K and 2G */
				gchar *tmp;
				if (content_type_found &&
				strncmp(content_type, "application/rpc", 15) == 0) {
					/* It looks like a RPC_IN_DATA request or a RPC_OUT_DATA response
					 * in which the content-length is meaningless
					 */
					return TRUE;
				}
				/* Following sizeof will return the length of the string + \0 we need to not count it*/
				tmp = tvb_get_string(wmem_packet_scope(), tvb, 0, sizeof("RPC_OUT_DATA") - 1);
				if ((strncmp(tmp, "RPC_IN_DATA", sizeof("RPC_IN_DATA") - 1) == 0) ||
				    (strncmp(tmp, "RPC_OUT_DATA", sizeof("RPC_OUT_DATA") - 1) == 0)) {
					return TRUE;
				}
			}
			/* next_offset has been set to the end of the headers */
			if (!tvb_bytes_exist(tvb, next_offset, content_length)) {
				length_remaining = tvb_captured_length_remaining(tvb,
				    next_offset);
				reported_length_remaining =
				    tvb_reported_length_remaining(tvb, next_offset);
				if (length_remaining < reported_length_remaining) {
					/*
					 * It's a waste of time asking for more
					 * data, because that data wasn't captured.
					 */
					return TRUE;
				}
				if (length_remaining == -1)
					length_remaining = 0;
				pinfo->desegment_offset = offset;
				pinfo->desegment_len =
				    content_length - length_remaining;
				return FALSE;
			}
		} else if (content_type_found && pinfo->can_desegment) {
			/* We found a content-type but no content-length.
			 * This is probably a HTTP header for a session with
			 * only one HTTP PDU and where the content spans
			 * until the end of the tcp session, unless there
			 * is a keepalive header present in which case we
			 * assume there is no message body at all and thus
			 * we won't do any reassembly.
			 * Set up tcp reassembly until the end of this session.
			 */
			length_remaining = tvb_captured_length_remaining(tvb, next_offset);
			reported_length_remaining = tvb_reported_length_remaining(tvb, next_offset);
			if (length_remaining < reported_length_remaining) {
				/*
				 * It's a waste of time asking for more
				 * data, because that data wasn't captured.
				 */
				return TRUE;
			}

			if (keepalive_found) {
				/* We have a keep-alive but no content-length.
				 * Assume there is no message body and don't
				 * do any reassembly.
				 */
				return TRUE;
			}

			pinfo->desegment_offset = offset;
			pinfo->desegment_len = DESEGMENT_UNTIL_FIN;

			return FALSE;
		}

	}

	/*
	 * No further desegmentation needed.
	 */
	return TRUE;
}
Esempio n. 4
0
static void
dissect_cmstatus (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
  proto_item *it;
  proto_tree *cmstatus_tree = NULL;
  guint16 transid;
  guint8 event_type;
  guint16 len;
  transid = tvb_get_ntohs (tvb, 0);
  event_type = tvb_get_guint8 (tvb, 2);
  len = tvb_reported_length_remaining (tvb, 3);
  col_clear (pinfo->cinfo, COL_INFO);
  col_add_fstr (pinfo->cinfo, COL_INFO, "CM-STATUS Report: Transaction ID = %u", transid);

  if (tree)
  {
    it = proto_tree_add_protocol_format (tree, proto_docsis_cmstatus, tvb, 0, -1, "CM-STATUS Report");
    cmstatus_tree = proto_item_add_subtree (it, ett_docsis_cmstatus);
    proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_tranid, tvb, 0, 2, ENC_BIG_ENDIAN);

    switch (event_type)
    {
    case SEC_CH_MDD_TIMEOUT:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_mdd_t, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case QAM_FEC_LOCK_FAILURE:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_qfl_f, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case SEQ_OUT_OF_RANGE:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_s_o, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case SEC_CH_MDD_RECOVERY:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_mdd_r, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case QAM_FEC_LOCK_RECOVERY:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_qfl_r, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case T4_TIMEOUT:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_t4_t, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case T3_RETRIES_EXCEEDED:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_t3_e, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case SUCCESS_RANGING_AFTER_T3_RETRIES_EXCEEDED:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_rng_s, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case CM_ON_BATTERY:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_cm_b, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;

    case CM_ON_AC_POWER:
      proto_tree_add_item (cmstatus_tree, hf_docsis_cmstatus_e_t_cm_a, tvb, 2, 1, ENC_BIG_ENDIAN);
      break;
    } /* switch */

  }
    /* Call Dissector TLV's */
  dissect_cmstatus_tlv(tvb, cmstatus_tree, 3, len);
}
Esempio n. 5
0
static void dissect_tftp_message(tftp_conv_info_t *tftp_info,
                                 tvbuff_t *tvb, packet_info *pinfo,
                                 proto_tree *tree)
{
    proto_tree *tftp_tree = NULL;
    proto_item *ti;
    gint        offset    = 0;
    guint16     opcode;
    guint16     bytes;
    guint16     blocknum;
    guint       i1;
    guint16     error;
    tvbuff_t    *data_tvb = NULL;

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

    opcode = tvb_get_ntohs(tvb, offset);

    col_add_str(pinfo->cinfo, COL_INFO,
                val_to_str(opcode, tftp_opcode_vals, "Unknown (0x%04x)"));

    if (tree) {
        ti = proto_tree_add_item(tree, proto_tftp, tvb, offset, -1, ENC_NA);
        tftp_tree = proto_item_add_subtree(ti, ett_tftp);

        if (tftp_info->source_file) {
            ti = proto_tree_add_string(tftp_tree, hf_tftp_source_file, tvb,
                                       0, 0, tftp_info->source_file);
            PROTO_ITEM_SET_GENERATED(ti);
        }

        if (tftp_info->destination_file) {
            ti = proto_tree_add_string(tftp_tree, hf_tftp_destination_file, tvb,
                                       0, 0, tftp_info->destination_file);
            PROTO_ITEM_SET_GENERATED(ti);
        }

        proto_tree_add_uint(tftp_tree, hf_tftp_opcode, tvb,
                            offset, 2, opcode);
    }
    offset += 2;

    switch (opcode) {

    case TFTP_RRQ:
        i1 = tvb_strsize(tvb, offset);
        proto_tree_add_item(tftp_tree, hf_tftp_source_file,
                            tvb, offset, i1, ENC_ASCII|ENC_NA);

        tftp_info->source_file = tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
                        tvb_format_stringzpad(tvb, offset, i1));

        offset += i1;

        i1 = tvb_strsize(tvb, offset);
        proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
                            tvb, offset, i1, ENC_ASCII|ENC_NA);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s",
                        tvb_format_stringzpad(tvb, offset, i1));

        offset += i1;

        tftp_dissect_options(tvb, pinfo,  offset, tftp_tree,
                             opcode, tftp_info);
        break;

    case TFTP_WRQ:
        i1 = tvb_strsize(tvb, offset);
        proto_tree_add_item(tftp_tree, hf_tftp_destination_file,
                            tvb, offset, i1, ENC_ASCII|ENC_NA);

        tftp_info->destination_file =
            tvb_get_string_enc(wmem_file_scope(), tvb, offset, i1, ENC_ASCII);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", File: %s",
                        tvb_format_stringzpad(tvb, offset, i1));

        offset += i1;

        i1 = tvb_strsize(tvb, offset);
        proto_tree_add_item(tftp_tree, hf_tftp_transfer_type,
                            tvb, offset, i1, ENC_ASCII|ENC_NA);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", Transfer type: %s",
                        tvb_format_stringzpad(tvb, offset, i1));

        offset += i1;

        tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
                             opcode,  tftp_info);
        break;

    case TFTP_INFO:
        tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
                             opcode,  tftp_info);
        break;

    case TFTP_DATA:
        blocknum = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2,
                            blocknum);

        /* Sequence analysis on blocknums (first pass only) */
        if (!pinfo->fd->flags.visited) {
            if (blocknum > tftp_info->next_block_num) {
                /* There is a gap.  Don't try to recover from this. */
                tftp_info->next_block_num = blocknum + 1;
                tftp_info->blocks_missing = TRUE;
                /* TODO: add info to a result table for showing expert info in later passes */
            }
            else if (blocknum == tftp_info->next_block_num) {
                /* OK, inc what we expect next */
                tftp_info->next_block_num++;
            }
        }
        offset += 2;

        /* Show number of bytes in this block, and whether it is the end of the file */
        bytes = tvb_reported_length_remaining(tvb, offset);
        col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i%s",
                        blocknum,
                        (bytes < tftp_info->blocksize)?" (last)":"" );

        /* Show data in tree */
        if (bytes > 0) {
            data_tvb = tvb_new_subset(tvb, offset, -1, bytes);
            call_dissector(data_handle, data_tvb, pinfo, tree);
        }

        /* If Export Object tap is listening, need to accumulate blocks info list
           to send to tap. But if already know there are blocks missing, there is no
           point in trying. */
        if (have_tap_listener(tftp_eo_tap) && !tftp_info->blocks_missing) {
            file_block_t *block;

            if (blocknum == 1) {
                /* Reset data for this conversation, freeing any accumulated blocks! */
                cleanup_tftp_blocks(tftp_info);
                tftp_info->next_tap_block_num = 1;
            }

            if (blocknum != tftp_info->next_tap_block_num) {
                /* Ignore.  Could be missing frames, or just clicking previous frame */
                return;
            }

            if (bytes > 0) {
                /* Create a block for this block */
                block = (file_block_t*)g_malloc(sizeof(file_block_t));
                block->length = bytes;
                block->data = tvb_memdup(NULL, data_tvb, 0, bytes);

                /* Add to the end of the list (does involve traversing whole list..) */
                tftp_info->block_list = g_slist_append(tftp_info->block_list, block);
                tftp_info->file_length += bytes;

                /* Look for next blocknum next time */
                tftp_info->next_tap_block_num++;
            }

            /* Tap export object only when reach end of file */
            if (bytes < tftp_info->blocksize) {
                tftp_eo_t        *eo_info;

                /* If don't have a filename, won't tap file info */
                if ((tftp_info->source_file == NULL) && (tftp_info->destination_file == NULL)) {
                    cleanup_tftp_blocks(tftp_info);
                    return;
                }

                /* Create the eo_info to pass to the listener */
                eo_info = wmem_new(wmem_packet_scope(), tftp_eo_t);

                /* Set filename */
                if (tftp_info->source_file) {
                    eo_info->filename = g_strdup(tftp_info->source_file);
                }
                else if (tftp_info->destination_file) {
                    eo_info->filename = g_strdup(tftp_info->destination_file);
                }

                /* Send block list, which will be combined and freed at tap. */
                eo_info->payload_len = tftp_info->file_length;
                eo_info->pkt_num = blocknum;
                eo_info->block_list = tftp_info->block_list;

                /* Send to tap */
                tap_queue_packet(tftp_eo_tap, pinfo, eo_info);

                /* Have sent, so forget list of blocks, and only pay attention if we
                   get back to the first block again. */
                tftp_info->block_list = NULL;
                tftp_info->next_tap_block_num = 1;
            }
        }
        break;

    case TFTP_ACK:
        blocknum = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(tftp_tree, hf_tftp_blocknum, tvb, offset, 2,
                            blocknum);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", Block: %i",
                        blocknum);
        break;

    case TFTP_ERROR:
        error = tvb_get_ntohs(tvb, offset);
        proto_tree_add_uint(tftp_tree, hf_tftp_error_code, tvb, offset, 2,
                            error);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", Code: %s",
                        val_to_str(error, tftp_error_code_vals, "Unknown (%u)"));

        offset += 2;

        i1 = tvb_strsize(tvb, offset);
        proto_tree_add_item(tftp_tree, hf_tftp_error_string, tvb, offset,
                            i1, ENC_ASCII|ENC_NA);

        col_append_fstr(pinfo->cinfo, COL_INFO, ", Message: %s",
                        tvb_format_stringzpad(tvb, offset, i1));

        expert_add_info(pinfo, NULL, &ei_tftp_blocksize_range);
        break;

    case TFTP_OACK:
        tftp_dissect_options(tvb, pinfo, offset, tftp_tree,
                             opcode, tftp_info);
        break;

    default:
        proto_tree_add_text(tftp_tree, tvb, offset, -1,
                            "Data (%d bytes)", tvb_reported_length_remaining(tvb, offset));
        break;

    }

    return;
}
Esempio n. 6
0
static int
dissect_bfcp_attributes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int bfcp_payload_length)
{
	proto_item *ti, *item;
	proto_tree  *bfcp_attr_tree = NULL;
	gint        attr_start_offset;
	gint        length;
	guint8      attribute_type;
	gint        read_attr = 0;
	guint8      first_byte, pad_len;

	while ((tvb_reported_length_remaining(tvb, offset) >= 2) &&
			((bfcp_payload_length - read_attr) >= 2))
	{

		attr_start_offset = offset;
		first_byte = tvb_get_guint8(tvb, offset);

		/* Padding so continue to next attribute */
		if (first_byte == 0){
			read_attr++;
			continue;
		}

		ti = proto_tree_add_item(tree, hf_bfcp_attribute_types, tvb, offset, 1, ENC_BIG_ENDIAN);
		bfcp_attr_tree = proto_item_add_subtree(ti, ett_bfcp_attr);
		proto_tree_add_item(bfcp_attr_tree, hf_bfcp_attribute_types_m_bit, tvb, offset, 1, ENC_BIG_ENDIAN);

		attribute_type = (first_byte & 0xFE) >> 1;
		offset++;

	/*   Length: This 8-bit field contains the length of the attribute in
	 *   octets, excluding any padding defined for specific attributes.  The
	 *   length of attributes that are not grouped includes the Type, 'M' bit,
	 *   and Length fields.  The Length in grouped attributes is the length of
	 *   the grouped attribute itself (including Type, 'M' bit, and Length
	 *   fields) plus the total length (including padding) of all the included
	 *   attributes.
	 */

		item = proto_tree_add_item(bfcp_attr_tree, hf_bfcp_attribute_length, tvb, offset, 1, ENC_BIG_ENDIAN);
		length = tvb_get_guint8(tvb, offset);
		offset++;

		switch(attribute_type){
		case 1: /* Beneficiary ID */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_beneficiary_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			break;
		case 2: /* FLOOR-ID */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_floor_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			break;
		case 3: /* FLOOR-REQUEST-ID */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_floor_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			break;
		case 4: /* PRIORITY */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_priority, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			break;
		case 5: /* REQUEST-STATUS */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_request_status, tvb, offset,1, ENC_BIG_ENDIAN);
			offset++;
			/* Queue Position */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_queue_pos, tvb, offset,1, ENC_BIG_ENDIAN);
			offset++;
			break;
		case 6: /* ERROR-CODE */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_error_code, tvb, offset, 1, ENC_BIG_ENDIAN);
			offset++;
			if(length>3){
				/* We have Error Specific Details */
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, length-3, "Error Specific Details");
			}
			offset = offset + length-3;
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 7: /* ERROR-INFO */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_error_info_text, tvb, offset, length-3, ENC_ASCII|ENC_NA);
			offset = offset + length-3;
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 8: /* PARTICIPANT-PROVIDED-INFO */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_part_prov_info_text, tvb, offset, length-3, ENC_ASCII|ENC_NA);
			offset = offset + length-3;
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 9: /* STATUS-INFO */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_status_info_text, tvb, offset, length-3, ENC_ASCII|ENC_NA);
			offset = offset + length-3;
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 10: /* SUPPORTED-ATTRIBUTES */

			while(offset < (attr_start_offset+length)){
				proto_tree_add_item(bfcp_attr_tree, hf_bfcp_supp_attr, tvb, offset, 1, ENC_BIG_ENDIAN);
				offset+=1;
			}
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 11: /* SUPPORTED-PRIMITIVES */

			while(offset < (attr_start_offset+length)){
				proto_tree_add_item(bfcp_attr_tree, hf_bfcp_supp_prim, tvb, offset, 1, ENC_BIG_ENDIAN);
				offset+=1;
			}
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 12: /* USER-DISPLAY-NAME */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_user_disp_name, tvb, offset, length-3, ENC_ASCII|ENC_NA);
			offset = offset + length-3;
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 13: /* USER-URI */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_user_uri, tvb, offset, length-3, ENC_ASCII|ENC_NA);
			offset = offset + length-3;
			pad_len = length & 0x03;
			if(pad_len != 0){
				pad_len = 4 - pad_len;
				proto_tree_add_text(bfcp_attr_tree, tvb, offset, pad_len, "Padding");
			}
			offset = offset + pad_len;
			break;
		case 14: /* BENEFICIARY-INFORMATION */
			/*    The BENEFICIARY-INFORMATION attribute is a grouped attribute that
			 *   consists of a header, which is referred to as BENEFICIARY-
			 *   INFORMATION-HEADER, followed by a sequence of attributes.
			 */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_beneficiary_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			offset = dissect_bfcp_attributes(tvb, pinfo, bfcp_attr_tree, offset, length -4);
			break;
		case 15: /* FLOOR-REQUEST-INFORMATION */
			/*    The FLOOR-REQUEST-INFORMATION attribute is a grouped attribute that
			 *   consists of a header, which is referred to as FLOOR-REQUEST-
			 *   INFORMATION-HEADER, followed by a sequence of attributes.
			 */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_floor_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			offset = dissect_bfcp_attributes(tvb, pinfo, bfcp_attr_tree, offset, length -4);
			break;
		case 16: /*  REQUESTED-BY-INFORMATION */
			/*    The  REQUESTED-BY-INFORMATION attribute is a grouped attribute that
			 *   consists of a header, which is referred to as FLOOR-REQUEST-STATUS-
			 *   -HEADER, followed by a sequence of attributes.
			 */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_req_by_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			offset = dissect_bfcp_attributes(tvb, pinfo, bfcp_attr_tree, offset, length -4);
			break;
		case 17: /*  FLOOR-REQUEST-STATUS */
			/*    The  FLOOR-REQUEST-STATUS attribute is a grouped attribute that
			 *   consists of a header, which is referred to as OVERALL-REQUEST-STATUS-
			 *   -HEADER, followed by a sequence of attributes.
			 */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_floor_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			offset = dissect_bfcp_attributes(tvb, pinfo, bfcp_attr_tree, offset, length -4);
			break;
		case 18: /* OVERALL-REQUEST-STATUS */
			/*    The OVERALL-REQUEST-STATUS attribute is a grouped attribute that
			 *   consists of a header, which is referred to as FLOOR-REQUEST-
			 *   INFORMATION-HEADER, followed by a sequence of attributes.
			 */
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_floor_request_id, tvb, offset, 2, ENC_BIG_ENDIAN);
			offset+=2;
			offset = dissect_bfcp_attributes(tvb, pinfo, bfcp_attr_tree, offset, length -4);
			break;

		default:
			proto_tree_add_item(bfcp_attr_tree, hf_bfcp_payload, tvb, offset, length-2, ENC_NA);
			offset = offset + length - 2;
			break;
		}
		if (length < (offset - attr_start_offset)){
			expert_add_info_format(pinfo, item, &ei_bfcp_attribute_length_too_small,
							"Attribute length is too small (%d bytes)", length);
			break;
		}
		read_attr = read_attr + length;
	}

	return offset;
}
Esempio n. 7
0
static int
dissect_dvmrp_v3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
{
	guint8 code,count;

	/* version */
	proto_tree_add_uint(parent_tree, hf_version, tvb, 0, 0, 3);

	/* type of command */
	proto_tree_add_uint(parent_tree, hf_type, tvb, offset, 1, 0x13);
	offset += 1;

	/* code */
	code = tvb_get_guint8(tvb, offset);
	proto_tree_add_uint(parent_tree, hf_code_v3, tvb, offset, 1, code);
	offset += 1;
	col_add_fstr(pinfo->cinfo, COL_INFO,
			"V%d %s",3 ,val_to_str(code, code_v3,
				"Unknown Type:0x%02x"));

	/* checksum */
	igmp_checksum(parent_tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
	offset += 2;

	/* skip unused byte */
	offset += 1;

	/* PROBE and NEIGHBORS 2 packets have capabilities flags, unused
	   for other packets */
	if (code==DVMRP_V3_PROBE || code==DVMRP_V3_NEIGHBORS_2) {
		proto_tree *tree;
		proto_item *item;

		item = proto_tree_add_item(parent_tree, hf_capabilities,
				tvb, offset, 1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_capabilities);

		count = tvb_get_guint8(tvb, offset);
		proto_tree_add_boolean(tree, hf_cap_netmask, tvb, offset, 1, count);
		proto_tree_add_boolean(tree, hf_cap_snmp, tvb, offset, 1, count);
		proto_tree_add_boolean(tree, hf_cap_mtrace, tvb, offset, 1, count);
		proto_tree_add_boolean(tree, hf_cap_genid, tvb, offset, 1, count);
		proto_tree_add_boolean(tree, hf_cap_prune, tvb, offset, 1, count);
		proto_tree_add_boolean(tree, hf_cap_leaf, tvb, offset, 1, count);
	}
	offset += 1;

	/* minor version */
	proto_tree_add_item(parent_tree, hf_min_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	/* major version */
	proto_tree_add_item(parent_tree, hf_maj_ver, tvb, offset, 1, ENC_BIG_ENDIAN);
	offset += 1;

	switch (code) {
	case DVMRP_V3_PROBE:
		/* generation id */
		proto_tree_add_item(parent_tree, hf_genid, tvb,
			offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		while (tvb_reported_length_remaining(tvb, offset)>=4) {
			proto_tree_add_item(parent_tree, hf_neighbor,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
		}
		break;
	case DVMRP_V3_REPORT:
		offset = dissect_v3_report(tvb, parent_tree, offset);
		break;
	case DVMRP_V3_PRUNE:
		/* source address */
		proto_tree_add_item(parent_tree, hf_saddr,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* group address */
		proto_tree_add_item(parent_tree, hf_maddr,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* prune lifetime */
		proto_tree_add_item(parent_tree, hf_life,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* source netmask */
		if (tvb_reported_length_remaining(tvb, offset)>=4) {
			proto_tree_add_item(parent_tree, hf_netmask,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
		}
		break;
	case DVMRP_V3_GRAFT:
		/* source address */
		proto_tree_add_item(parent_tree, hf_saddr,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* group address */
		proto_tree_add_item(parent_tree, hf_maddr,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* source netmask */
		if (tvb_reported_length_remaining(tvb, offset)>=4) {
			proto_tree_add_item(parent_tree, hf_netmask,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
		}
		break;
	case DVMRP_V3_GRAFT_ACK:
		/* source address */
		proto_tree_add_item(parent_tree, hf_saddr,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* group address */
		proto_tree_add_item(parent_tree, hf_maddr,
			tvb, offset, 4, ENC_BIG_ENDIAN);
		offset += 4;
		/* source netmask */
		if (tvb_reported_length_remaining(tvb, offset)>=4) {
			proto_tree_add_item(parent_tree, hf_netmask,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
		}
		break;
	case DVMRP_V3_ASK_NEIGHBORS:
	case DVMRP_V3_NEIGHBORS:
		/* XXX - obsolete, and the draft doesn't describe them */
		break;
	case DVMRP_V3_ASK_NEIGHBORS_2:
		/* No data */
		break;
	case DVMRP_V3_NEIGHBORS_2:
		while (tvb_reported_length_remaining(tvb, offset)>=12) {
			guint8 neighbor_count;

			/* local address */
			proto_tree_add_item(parent_tree, hf_local,
				tvb, offset, 4, ENC_BIG_ENDIAN);
			offset += 4;
			/* Metric */
			proto_tree_add_item(parent_tree, hf_metric,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			/* Threshold */
			proto_tree_add_item(parent_tree, hf_threshold,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;
			/* Flags */
			{
				proto_tree *tree;
				proto_item *item;

				item = proto_tree_add_item(parent_tree, hf_flags,
					tvb, offset, 1, ENC_NA);
				tree = proto_item_add_subtree(item, ett_flags);

				proto_tree_add_item(tree, hf_flag_tunnel, tvb,
					offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tree, hf_flag_srcroute, tvb,
					offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tree, hf_flag_down, tvb,
					offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tree, hf_flag_disabled, tvb,
					offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tree, hf_flag_querier, tvb,
					offset, 1, ENC_BIG_ENDIAN);
				proto_tree_add_item(tree, hf_flag_leaf, tvb,
					offset, 1, ENC_BIG_ENDIAN);
			}
			offset += 1;
			/* Neighbor count */
			neighbor_count = tvb_get_guint8(tvb, offset);
			proto_tree_add_item(parent_tree, hf_ncount,
				tvb, offset, 1, ENC_BIG_ENDIAN);
			offset += 1;

			while ((tvb_reported_length_remaining(tvb, offset)>=4)
				&& (neighbor_count>0)) {
				proto_tree_add_item(parent_tree, hf_neighbor,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
				neighbor_count--;
			}
		}
		break;
	}

	return offset;
}
/*
* Dissect DISP PDUs inside a ROS PDUs
*/
static void
dissect_disp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
{
	int offset = 0;
	int old_offset;
	proto_item *item=NULL;
	proto_tree *tree=NULL;
	int (*disp_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL;
	const char *disp_op_name;
	asn1_ctx_t asn1_ctx;

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

	/* do we have operation information from the ROS dissector?  */
	if( !pinfo->private_data ){
		if(parent_tree){
			proto_tree_add_text(parent_tree, tvb, offset, -1,
				"Internal error: can't get operation information from ROS dissector.");
		}
		return  ;
	} else {
		session  = ( (struct SESSION_DATA_STRUCTURE*)(pinfo->private_data) );
	}

	if(parent_tree){
		item = proto_tree_add_item(parent_tree, proto_disp, tvb, 0, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_disp);
	}
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "DISP");
  	col_clear(pinfo->cinfo, COL_INFO);

	switch(session->ros_op & ROS_OP_MASK) {
	case (ROS_OP_BIND | ROS_OP_ARGUMENT):	/*  BindInvoke */
	  disp_dissector = dissect_disp_DSAShadowBindArgument;
	  disp_op_name = "Shadow-Bind-Argument";
	  break;
	case (ROS_OP_BIND | ROS_OP_RESULT):	/*  BindResult */
	  disp_dissector = dissect_disp_DSAShadowBindResult;
	  disp_op_name = "Shadow-Bind-Result";
	  break;
	case (ROS_OP_BIND | ROS_OP_ERROR):	/*  BindError */
	  disp_dissector = dissect_disp_DSAShadowBindError;
	  disp_op_name = "Shadow-Bind-Error";
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ARGUMENT):	/*  Invoke Argument */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* requestShadowUpdate */
	    disp_dissector = dissect_disp_RequestShadowUpdateArgument;
	    disp_op_name = "Request-Shadow-Update-Argument";
	    break;
	  case 2: /* updateShadow*/
	    disp_dissector = dissect_disp_UpdateShadowArgument;
	    disp_op_name = "Update-Shadow-Argument";
	    break;
	  case 3: /* coordinateShadowUpdate */
	    disp_dissector = dissect_disp_CoordinateShadowUpdateArgument;
	    disp_op_name = "Coordinate-Shadow-Update-Argument";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_RESULT):	/*  Return Result */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* requestShadowUpdate */
	    disp_dissector = dissect_disp_RequestShadowUpdateResult;
	    disp_op_name = "Request-Shadow-Result";
	    break;
	  case 2: /* updateShadow */
	    disp_dissector = dissect_disp_UpdateShadowResult;
	    disp_op_name = "Update-Shadow-Result";
	    break;
	  case 3: /* coordinateShadowUpdate */
	    disp_dissector = dissect_disp_CoordinateShadowUpdateResult;
	    disp_op_name = "Coordinate-Shadow-Update-Result";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP opcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ERROR):	/*  Return Error */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* shadowError */
	    disp_dissector = dissect_disp_ShadowError;
	    disp_op_name = "Shadow-Error";
	    break;
	  default:
	    proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP errcode (%d)",
				session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	default:
	  proto_tree_add_text(tree, tvb, offset, -1,"Unsupported DISP PDU");
	  return;
	}

	if(disp_dissector) {
	  col_set_str(pinfo->cinfo, COL_INFO, disp_op_name);

	  while (tvb_reported_length_remaining(tvb, offset) > 0){
	    old_offset=offset;
	    offset=(*disp_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1);
	    if(offset == old_offset){
	      proto_tree_add_text(tree, tvb, offset, -1,"Internal error, zero-byte DISP PDU");
	      break;
	    }
	  }
	}
}
Esempio n. 9
0
/* Dissector for xcsl */
static void dissect_xcsl_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {

    guint        offset = 0;
    gint         length_remaining;
    guint8       idx;
    gboolean     request;
    guint8       par;
    guint8       str[MAXLEN];
    guint8       result;
    const gchar *code;
    guint        len;
    gint         next_offset;
    proto_tree  *xcsl_tree = NULL;

    /* color support */
    col_set_str(pinfo->cinfo, COL_PROTOCOL, "Xcsl");
    col_clear(pinfo->cinfo, COL_INFO);

    /* Create display tree for the xcsl protocol */
    if (tree) {
        proto_item  *xcsl_item;
        xcsl_item = proto_tree_add_item(tree, hfi_xcsl, tvb, offset, -1, ENC_NA);
        xcsl_tree = proto_item_add_subtree(xcsl_item, ett_xcsl);
    }

    /* reset idx */
    idx = 0;

    /* reset the parameter count */
    par = 0;

    /* switch whether it concerns a command or an answer */
    request = FALSE;

    while (tvb_reported_length_remaining(tvb, offset) != 0) {

        length_remaining = tvb_ensure_length_remaining(tvb, offset);
        if ( length_remaining == -1 ) {
            return;
        }

        /* get next item */
        if (!(get_next_item(tvb, offset, length_remaining, str, &next_offset, &len))) {
            /* do not continue when get_next_item returns false */
            return;
        }

        /* do not add to the tree when the string is of zero length */
        if ( strlen(str) == 0 ) {
            offset = next_offset + 1;
            continue;
        }

        /* Xcsl (Call Specification Language) protocol in brief :
         *
         * Request :
         *
         *    <xcsl-version>;<transaction-id>;<command>;[parameter1;parameter2;parameter3;....]
         *
         * Reply :
         *
         *    <xcsl-version>;transaction-id;<result>;[answer data;answer data];...
         *
         * If result is one or more digits, this is determined as a Reply.
         *
         * Example :
         *
         * -->      xcsl-1.0;1000;offhook;+31356871234
         * <--      xcsl-1.0;1000;0                              <- success
         *
         * -->      xcsl-1.0;1001;dial;+31356871234;+31356875678
         * <--      xcsl-1.0;1001;0                              <- success
         *
         *
         * index :  0        1    2    3            4
         *
         * Index 2 represents the return code (see the xcsl_action_vals[] definitions)
         *
         */

        /* One by one go through each item ';' separated */
        switch (idx) {

            /* This is the protocol item */
            case 0:
                proto_tree_add_item(xcsl_tree, &hfi_xcsl_protocol_version, tvb, offset, len, ENC_ASCII|ENC_NA);
                break;

                /* This should be the transaction ID, if non-digit, it is treated as info */
            case 1:
                if ( isdigit(str[0]) ) {
                    proto_tree_add_item(xcsl_tree, &hfi_xcsl_transaction_id, tvb, offset, len, ENC_ASCII|ENC_NA);
                } else {
                    proto_tree_add_item(xcsl_tree, &hfi_xcsl_information, tvb, offset, len, ENC_ASCII|ENC_NA);
                }
                col_append_fstr(pinfo->cinfo, COL_INFO, "%s ",str);
                break;

                /* Starting with non-digit -> Command, if it starts with a digit -> reply */
            case 2:
                if ( isdigit(str[0]) ) {
                    proto_item *xcsl_item;

                    request = FALSE;
                    result = atoi(str);
                    if ( result >= XCSL_NONE ) {
                        result = XCSL_UNDEFINED;
                    }
                    code = val_to_str(result, xcsl_action_vals, "Unknown: %d");

                    /* Print result code and description */
                    xcsl_item = proto_tree_add_item(xcsl_tree, &hfi_xcsl_result, tvb, offset, len, ENC_ASCII|ENC_NA);
                    proto_item_append_text(xcsl_item, " (%s)", code);

                    if (result != 0)
                        col_append_fstr(pinfo->cinfo, COL_INFO, "[%s] ", code);

                } else {

                    request = TRUE;
                    proto_tree_add_item(xcsl_tree, &hfi_xcsl_command, tvb, offset, len, ENC_ASCII|ENC_NA);

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

                }
                break;

                /* This is a command parameter */
            default:
                proto_tree_add_item(xcsl_tree, &hfi_xcsl_parameter, tvb, offset, len, ENC_ASCII|ENC_NA);

                if ( request == TRUE ) {
                    col_append_fstr(pinfo->cinfo, COL_INFO, ": %s ",str);
                } else {
                    if (par == 0) {
                        col_append_fstr(pinfo->cinfo, COL_INFO, "reply: %s ",str);
                    } else {
                        col_append_fstr(pinfo->cinfo, COL_INFO, ": %s ",str);
                    }
                }

                /* increment the parameter count */
                par++;

                break;
        }

        offset = next_offset + 1;
        idx++;

    }


    return;
}
Esempio n. 10
0
void
dissect_802_3(volatile int length, gboolean is_802_2, tvbuff_t *tvb,
              int offset_after_length, packet_info *pinfo, proto_tree *tree,
              proto_tree *fh_tree, int length_id, int trailer_id, expert_field* ei_len,
              int fcs_len)
{
    proto_item		*length_it;
    tvbuff_t		*volatile next_tvb = NULL;
    tvbuff_t		*trailer_tvb = NULL;
    const char		*saved_proto;
    gint			captured_length, reported_length;
    void			*pd_save;

    length_it = proto_tree_add_uint(fh_tree, length_id, tvb,
                                    offset_after_length - 2, 2, length);

    /* Get the length of the payload.
       If the FCS length is positive, remove the FCS.
       (If it's zero, there's no FCS; if it's negative, we don't know whether
       there's an FCS, so we'll guess based on the length of the trailer.) */
    reported_length = tvb_reported_length_remaining(tvb, offset_after_length);
    if (fcs_len > 0) {
        if (reported_length >= fcs_len)
            reported_length -= fcs_len;
    }

    /* Make sure the length in the 802.3 header doesn't go past the end of
       the payload. */
    if (length > reported_length) {
        length = reported_length;
        expert_add_info(pinfo, length_it, ei_len);
    }

    /* Give the next dissector only 'length' number of bytes. */
    captured_length = tvb_length_remaining(tvb, offset_after_length);
    if (captured_length > length)
        captured_length = length;
    next_tvb = tvb_new_subset(tvb, offset_after_length, captured_length, length);

    /* Dissect the payload either as IPX or as an LLC frame.
       Catch non-fatal exceptions, so that if the reported length
       of "next_tvb" was reduced by some dissector before an
       exception was thrown, we can still put in an item for
       the trailer. */
    saved_proto = pinfo->current_proto;
    pd_save = pinfo->private_data;
    TRY {
        if (is_802_2)
            call_dissector(llc_handle, next_tvb, pinfo, tree);
        else {
            /* Check if first three bits of payload are 0x7.
               If so, then payload is IPX.  If not, then it's CCSDS.
               Refer to packet-eth.c for setting of is_802_2 variable. */
            if (tvb_get_bits8(next_tvb, 0, 3) == 7)
                call_dissector(ipx_handle, next_tvb, pinfo, tree);
            else
                call_dissector(ccsds_handle, next_tvb, pinfo, tree);
        }
    }
    CATCH_NONFATAL_ERRORS {
        /* Somebody threw an exception that means that there was a problem
           dissecting the payload; that means that a dissector was found,
           so we don't need to dissect the payload as data or update the
           protocol or info columns.

           Just show the exception and then drive on to show the trailer,
           after noting that a dissector was found and restoring the
           protocol value that was in effect before we called the subdissector. */
        pinfo->private_data = pd_save;

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

    /* Restore the protocol value, so that any exception thrown by
       tvb_new_subset_remaining() refers to the protocol for which
       this is a trailer, and restore the private_data structure in
       case one of the called dissectors modified it. */
    pinfo->private_data = pd_save;
    pinfo->current_proto = saved_proto;

    /* Construct a tvbuff for the trailer; if the trailer is past the
       end of the captured data, this will throw a BoundsError, which
       is what we want, as it'll report that the packet was cut short. */
    trailer_tvb = tvb_new_subset_remaining(tvb, offset_after_length + length);

    add_ethernet_trailer(pinfo, tree, fh_tree, trailer_id, tvb, trailer_tvb, fcs_len);
}
Esempio n. 11
0
static int
dissect_banana_element(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) {
    proto_item *ti;
    proto_tree *list_tree;
    guint8 byte = 0;
    gint64 val = 0;
    gint val_len = 0;
    int start_offset = offset;
    int old_offset;
    int i;

    /* Accumulate our value/length 'til we hit a valid type */
    while (tvb_reported_length_remaining(tvb, offset) > 0) {
        byte = tvb_get_guint8(tvb, offset);
        offset++;

        if (byte & 0x80) {
            if (is_element(byte)) {
                break;
            } else {
                expert_add_info_format(pinfo, NULL, &ei_banana_unknown_type, "Unknown type %u", byte);
            }
        } else {
            val_len++;
            if (val_len > MAX_ELEMENT_VAL_LEN) {
                expert_add_info(pinfo, NULL, &ei_banana_too_many_value_bytes);
            }
            val += byte + (val << 7);
        }
    }

    /* Type */
    switch (byte) {
        case BE_LIST:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "List length %" G_GINT64_MODIFIER "d longer than we can handle", val);
            }
            ti = proto_tree_add_uint_format_value(tree, hf_banana_list, tvb, start_offset, offset - start_offset - 1, (guint32) val, "(%d items)", (gint) val);
            list_tree = proto_item_add_subtree(ti, ett_list);
            for (i = 0; i < val; i++) {
                old_offset = offset;
                offset += dissect_banana_element(tvb, pinfo, list_tree, offset);
                if (offset <= old_offset) {
                    return offset - start_offset;
                }
            }
            break;
        case BE_INT:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value %" G_GINT64_MODIFIER "d too large", val);
            }
            proto_tree_add_uint(tree, hf_banana_int, tvb, start_offset, offset - start_offset, (guint32) val);
            break;
        case BE_STRING:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_length_too_long, "String length %" G_GINT64_MODIFIER "d longer than we can handle", val);
            }
            proto_tree_add_item(tree, hf_banana_string, tvb, offset, (guint32) val, ENC_ASCII|ENC_NA);
            offset += (gint) val;
            break;
        case BE_NEG_INT:
            if (val > MAX_ELEMENT_VAL) {
                expert_add_info_format(pinfo, NULL, &ei_banana_value_too_large, "Integer value -%" G_GINT64_MODIFIER "d too large", val);
            }
            proto_tree_add_int(tree, hf_banana_neg_int, tvb, start_offset, offset - start_offset, (gint32) val * -1);
            break;
        case BE_FLOAT:
            proto_tree_add_item(tree, hf_banana_float, tvb, offset, 8, ENC_BIG_ENDIAN);
            offset += 8;
            break;
        case BE_LG_INT:
            proto_tree_add_item(tree, hf_banana_lg_int, tvb, start_offset, offset - start_offset, ENC_NA);
            break;
        case BE_LG_NEG_INT:
            proto_tree_add_item(tree, hf_banana_lg_neg_int, tvb, start_offset, offset - start_offset, ENC_NA);
            break;
        case BE_PB:
            if (val_len > 1) {
                expert_add_info(pinfo, NULL, &ei_banana_pb_error);
            }
            /*
             * The spec says the pb dictionary value comes after the tag.
             * In real-world captures it comes before.
             */
            proto_tree_add_item(tree, hf_banana_pb, tvb, offset - 2, 1, ENC_BIG_ENDIAN);
            break;
        default:
            return 0;
            break;
    }
    return offset - start_offset;
}
Esempio n. 12
0
static void
dissect_forces(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset)
{
    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *ti, *tlv_item;
    proto_tree *forces_tree, *forces_flags_tree;
    proto_tree *forces_main_header_tree, *forces_tlv_tree, *tlv_tree;
    gint        length_count;

    guint8      message_type;
    guint16     tlv_type;

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

    ti = proto_tree_add_item(tree, proto_forces, tvb, 0, -1, ENC_NA);
    forces_tree = proto_item_add_subtree(ti, ett_forces);

    ti = proto_tree_add_text(forces_tree, tvb, 0, ForCES_HEADER_LENGTH, "Common Header");
    forces_main_header_tree = proto_item_add_subtree(ti, ett_forces_main_header);

    proto_tree_add_item(forces_main_header_tree, hf_forces_version, tvb, 0, 1, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_main_header_tree, hf_forces_rsvd,    tvb, 0, 1, ENC_BIG_ENDIAN);

    message_type = tvb_get_guint8(tvb, offset+1);
    proto_tree_add_item( forces_main_header_tree, hf_forces_messagetype, tvb, offset+1, 1, ENC_BIG_ENDIAN);

    length_count = tvb_get_ntohs(tvb, offset+2) * 4;  /*multiply 4 DWORD*/
    ti = proto_tree_add_uint_format( forces_main_header_tree, hf_forces_length,
                                     tvb, offset+2, 2, length_count, "Length: %u Bytes", length_count);
    if (length_count != tvb_reported_length_remaining(tvb, offset))
        expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is wrong),should be (%u bytes)",
            length_count, tvb_reported_length_remaining(tvb, offset));
    if (length_count < 24)
        expert_add_info_format(pinfo, ti, &ei_forces_length, "Bogus: ForCES Header length (%u bytes) is less than 24bytes)", length_count);

    col_add_fstr(pinfo->cinfo, COL_INFO, "Message Type: %s, Total Length:  %u Bytes",
            val_to_str(message_type, message_type_vals, "Unknown messagetype 0x%x"), length_count);

    proto_tree_add_item( forces_main_header_tree, hf_forces_sid,        tvb, offset+4,  4, ENC_BIG_ENDIAN);
    proto_tree_add_item( forces_main_header_tree, hf_forces_did,        tvb, offset+8,  4, ENC_BIG_ENDIAN);
    proto_tree_add_item( forces_main_header_tree, hf_forces_correlator, tvb, offset+12, 8, ENC_BIG_ENDIAN);

    /*Add flags tree*/
    ti = proto_tree_add_item(forces_main_header_tree, hf_forces_flags, tvb, offset+20, 4, ENC_BIG_ENDIAN);
    forces_flags_tree = proto_item_add_subtree(ti, ett_forces_flags);

    proto_tree_add_item(forces_flags_tree, hf_forces_flags_ack,      tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_at,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_em,       tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_pri,      tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_reserved, tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_rsrvd,    tvb, offset+20, 4, ENC_BIG_ENDIAN);
    proto_tree_add_item(forces_flags_tree, hf_forces_flags_tp,       tvb, offset+20, 4, ENC_BIG_ENDIAN);

    offset += 24;
    while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
    {
        ti = proto_tree_add_text(forces_tree, tvb, offset, TLV_TL_LENGTH, "TLV");
        forces_tlv_tree = proto_item_add_subtree(ti, ett_forces_tlv);

        tlv_type = tvb_get_ntohs(tvb, offset);
        tlv_item = proto_tree_add_item(forces_tlv_tree, hf_forces_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);
        length_count = tvb_get_ntohs(tvb, offset+2) * 4;
        proto_item_set_len(ti, length_count);
        ti = proto_tree_add_uint_format_value(forces_tlv_tree, hf_forces_tlv_length,
                                        tvb, offset+2, 2, length_count, "%u Bytes", length_count);
        if (tvb_reported_length_remaining(tvb, offset) < length_count)
            expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus: Main TLV length (%u bytes) is wrong", length_count);

        if (length_count < TLV_TL_LENGTH)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_tlv_length, "Bogus TLV length: %u", length_count);
            break;
        }

        offset       += TLV_TL_LENGTH;
        length_count -= TLV_TL_LENGTH;

        switch(tlv_type)
        {
        case LFBselect_TLV:
            ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "LFB select TLV");
            tlv_tree = proto_item_add_subtree(ti, ett_forces_lfbselect_tlv_type);
            dissect_lfbselecttlv(tvb, pinfo, tlv_tree, offset, length_count);
            break;

        case REDIRECT_TLV:
            ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "Redirect TLV");
            tlv_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_type);
            dissect_redirecttlv(tvb, pinfo, tlv_tree, offset);
            break;

        case ASResult_TLV:
            ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "ASResult TLV");
            tlv_tree = proto_item_add_subtree(ti, ett_forces_asresult_tlv);
            proto_tree_add_item(tlv_tree, hf_forces_asresult_association_setup_result, tvb, offset, 4, ENC_BIG_ENDIAN);
            break;

        case ASTreason_TLV:
            ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "ASTreason TLV");
            tlv_tree = proto_item_add_subtree(ti, ett_forces_astreason_tlv);
            proto_tree_add_item(tlv_tree, hf_forces_astreason_tlv_teardown_reason, tvb, offset, 4, ENC_BIG_ENDIAN);
            break;

        default:
            expert_add_info(pinfo, tlv_item, &ei_forces_tlv_type);
            ti = proto_tree_add_text(forces_tlv_tree, tvb, offset, length_count, "Unknown TLV");
            tlv_tree = proto_item_add_subtree(ti, ett_forces_unknown_tlv);
            proto_tree_add_item(tlv_tree, hf_forces_unknown_tlv, tvb, offset, length_count, ENC_NA);
            break;
        }

        offset += length_count;
    }
}
Esempio n. 13
0
static void
dissect_redirecttlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    proto_tree *meta_data_tree, *meta_data_ilv_tree, *redirect_data_tree;
    gint        start_offset;
    gint        length_meta, length_ilv, length_redirect;
    proto_item *ti;
    address     src_addr     = pinfo->src,
                src_net_addr = pinfo->net_src,
                dst_addr     = pinfo->dst,
                dst_net_addr = pinfo->net_dst;

    ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "Meta Data TLV");
    meta_data_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_meta_data_tlv);
    proto_tree_add_item(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_type, tvb, offset, 2, ENC_BIG_ENDIAN);

    length_meta = tvb_get_ntohs(tvb, offset+2);
    proto_tree_add_uint_format_value(meta_data_tree, hf_forces_redirect_tlv_meta_data_tlv_length, tvb, offset+2, 2,
                               length_meta, "%u Bytes", length_meta);
    proto_item_set_len(ti, length_meta);

    start_offset = offset;
    while ((tvb_reported_length_remaining(tvb, offset) >= 8) && (start_offset+length_meta > offset))
    {
        ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "Meta Data ILV");
        meta_data_ilv_tree =  proto_item_add_subtree(ti, ett_forces_redirect_tlv_meta_data_tlv_meta_data_ilv);

        proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_id,
                                   tvb, offset+8, 4, ENC_BIG_ENDIAN);
        length_ilv = tvb_get_ntohl(tvb, offset+12);
        proto_tree_add_uint_format_value(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv_length,
                                   tvb,  offset+12, 4, length_ilv, "%u Bytes", length_ilv);
        if (length_ilv > 0)
            proto_tree_add_item(meta_data_ilv_tree, hf_forces_redirect_tlv_meta_data_tlv_meta_data_ilv,
                                   tvb, offset+8, length_ilv, ENC_NA);

        proto_item_set_len(ti, length_ilv + 8);
        offset += length_ilv + 8;
    }

    if (tvb_reported_length_remaining(tvb, offset) > 0)
    {
        ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "Redirect Data TLV");
        redirect_data_tree = proto_item_add_subtree(ti, ett_forces_redirect_tlv_redirect_data_tlv);

        proto_tree_add_item(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_type,
                            tvb, offset, 2,  ENC_BIG_ENDIAN);
        length_redirect = tvb_get_ntohs(tvb, offset+2);
        proto_tree_add_uint_format_value(redirect_data_tree, hf_forces_redirect_tlv_redirect_data_tlv_length,
                            tvb, offset+2, 2, length_redirect, "%u Bytes", length_redirect);

        if (tvb_reported_length_remaining(tvb, offset) < length_redirect)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) is wrong", length_redirect);
        }
        else if (length_redirect < TLV_TL_LENGTH + MIN_IP_HEADER_LENGTH)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_redirect_tlv_redirect_data_tlv_length, "Bogus: Redirect Data TLV length (%u bytes) not big enough for IP layer", length_redirect);
        }
        else
        {
            tvbuff_t  *next_tvb;

            next_tvb = tvb_new_subset(tvb, offset+4, length_redirect-TLV_TL_LENGTH, length_redirect-TLV_TL_LENGTH);
            call_dissector(ip_handle, next_tvb, pinfo, redirect_data_tree);

            /* Restore IP info */
            memcpy(&(pinfo->src),     &src_addr,     sizeof(address));
            memcpy(&(pinfo->net_src), &src_net_addr, sizeof(address));
            memcpy(&(pinfo->dst),     &dst_addr,     sizeof(address));
            memcpy(&(pinfo->net_dst), &dst_net_addr, sizeof(address));
        }
    }
}
Esempio n. 14
0
static void
dissect_path_data_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    proto_item *ti, *flag_item;
    guint       length_TLV, IDcount, i;
    guint16     type, flag;
    proto_tree *tlv_tree, *path_data_tree, *flag_tree;

    while (tvb_reported_length_remaining(tvb, offset) >= TLV_TL_LENGTH)
    {
        ti = proto_tree_add_text(tree, tvb, offset, TLV_TL_LENGTH, "TLV");
        tlv_tree = proto_item_add_subtree(ti, ett_forces_path_data_tlv);

        type = tvb_get_ntohs(tvb, offset);
        proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_type,
                            tvb, offset, 2, ENC_BIG_ENDIAN);
        length_TLV = tvb_get_ntohs(tvb, offset+2);
        proto_tree_add_item(tlv_tree, hf_forces_lfbselect_tlv_type_operation_path_length,
                            tvb, offset+2, 2, ENC_BIG_ENDIAN);
        if (length_TLV < TLV_TL_LENGTH)
        {
            expert_add_info_format(pinfo, ti, &ei_forces_lfbselect_tlv_type_operation_path_length, "Bogus TLV length: %u", length_TLV);
            break;
        }
        proto_item_set_len(ti, length_TLV);

        if (type == PATH_DATA_TLV)
        {
            ti = proto_tree_add_text(tree, tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, "Path Data TLV");
            path_data_tree = proto_item_add_subtree(ti, ett_forces_path_data_tlv);

            flag = tvb_get_ntohs(tvb, offset+TLV_TL_LENGTH);
            flag_item = proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_flags,
                                tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
            flag_tree = proto_item_add_subtree(flag_item, ett_forces_path_data_tlv_flags);
            proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_selector,
                                tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);
            proto_tree_add_item(flag_tree, hf_forces_lfbselect_tlv_type_operation_path_flags_reserved,
                                tvb, offset+TLV_TL_LENGTH, 2, ENC_BIG_ENDIAN);

            IDcount = tvb_get_ntohs(tvb, offset + TLV_TL_LENGTH + 2);
            proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDcount,
                                tvb, offset+TLV_TL_LENGTH+2, 2, ENC_BIG_ENDIAN);

            for (i = 0; i < IDcount; i++)
                proto_tree_add_item(path_data_tree, hf_forces_lfbselect_tlv_type_operation_path_IDs,
                                    tvb, offset+TLV_TL_LENGTH+2+(i*4), 4, ENC_BIG_ENDIAN);
        }
        else
        {
            flag = 0;
            proto_tree_add_item(tree, hf_forces_lfbselect_tlv_type_operation_path_data,
                                tvb, offset+TLV_TL_LENGTH, length_TLV-TLV_TL_LENGTH, ENC_NA);
        }

        if ((flag & FLAG_SELECTOR) == 0)
            break;

        offset += length_TLV;
    }
}
Esempio n. 15
0
static void dissect_cisco (tvbuff_t * tvb, proto_tree * tree,
                           gint vsif_len);

/* Dissection */
static int
dissect_vsif (tvbuff_t * tvb, packet_info * pinfo _U_, proto_tree * tree, void* data _U_)
{
  proto_item *it;
  proto_tree *vsif_tree;
  guint8 type;
  guint8 length;
  guint32 value;
  gint vsif_len;

  /* get the reported length of the VSIF TLV */
  vsif_len = tvb_reported_length_remaining (tvb, 0);

  /* The first TLV in the VSIF encodings must be type 0x08 (Vendor ID) and
   * length 3.
   */
  type = tvb_get_guint8 (tvb, 0);
  if (type != 0x08)
    {
      THROW (ReportedBoundsError);
    }

  length = tvb_get_guint8 (tvb, 1);
  if (length != 3)
    {
      THROW (ReportedBoundsError);
    }
Esempio n. 16
0
/* Code to actually dissect the packets */
static void
  dissect_ucd (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree)
{
  int pos, endtlvpos;
  guint8 type, length;
  guint8 tlvlen, tlvtype;
  proto_tree *ucd_tree;
  proto_item *ucd_item;
  proto_tree *tlv_tree;
  proto_item *tlv_item;
  gint len;
  guint8 upchid, symrate;
   
  len = tvb_reported_length_remaining (tvb, 0);
   upchid = tvb_get_guint8 (tvb, 0);
   
   /* if the upstream Channel ID is 0 then this is for Telephony Return) */
	if (upchid > 0)
	  col_add_fstr (pinfo->cinfo, COL_INFO,
			"UCD Message:  Channel ID = %u (U%u)", upchid,
			upchid - 1);
	else
	  col_add_fstr (pinfo->cinfo, COL_INFO,
			"UCD Message:  Channel ID = %u (Telephony Return)",
			upchid);
   
   if (tree)
     {
	ucd_item =
	proto_tree_add_protocol_format (tree, proto_docsis_ucd, tvb, 0, -1,
					"UCD Message");
	ucd_tree = proto_item_add_subtree (ucd_item, ett_docsis_ucd);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_upstream_chid, tvb, 0, 1,
			     ENC_BIG_ENDIAN);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_config_ch_cnt, tvb, 1, 1,
			     ENC_BIG_ENDIAN);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_mini_slot_size, tvb, 2, 1,
			     ENC_BIG_ENDIAN);
	proto_tree_add_item (ucd_tree, hf_docsis_ucd_down_chid, tvb, 3, 1,
			     ENC_BIG_ENDIAN);
	
	pos = 4;
	while (pos < len)
	  {
	  type = tvb_get_guint8 (tvb, pos);
	  tlv_item = proto_tree_add_text (ucd_tree, tvb, pos, -1,
					  "%s",
					  val_to_str(type, channel_tlv_vals,
						     "Unknown TLV (%u)"));  
	  tlv_tree = proto_item_add_subtree (tlv_item, ett_tlv);
	  proto_tree_add_uint (tlv_tree, hf_docsis_ucd_type,
			       tvb, pos, 1, type);
	  pos++;
	  length = tvb_get_guint8 (tvb, pos);
	  proto_tree_add_uint (tlv_tree, hf_docsis_ucd_length,
			       tvb, pos, 1, length);
	  pos++;
	  proto_item_set_len(tlv_item, length + 2);
	     switch (type)
	       {
		case UCD_SYMBOL_RATE:
		  if (length == 1)
		    {
		       symrate = tvb_get_guint8 (tvb, pos);
		       proto_tree_add_uint (tlv_tree, hf_docsis_ucd_symbol_rate,
					    tvb, pos, length, symrate * 160);
		    }
		  else
		    {
		       THROW (ReportedBoundsError);
		    }
		  pos = pos + length;
		  break;
		case UCD_FREQUENCY:
		  if (length == 4)
		    {
		       proto_tree_add_item (tlv_tree, hf_docsis_ucd_frequency, tvb,
					    pos, length, ENC_BIG_ENDIAN);
		       pos = pos + length;
		    }
		  else
		    {
		       THROW (ReportedBoundsError);
		    }
		  break;
		case UCD_PREAMBLE:
		  proto_tree_add_item (tlv_tree, hf_docsis_ucd_preamble_pat, tvb,
				       pos, length, ENC_NA);
		  pos = pos + length;
		  break;
		case UCD_BURST_DESCR:
		  proto_tree_add_item (tlv_tree, hf_docsis_ucd_iuc, tvb,
				       pos++, 1, ENC_BIG_ENDIAN);
		  endtlvpos = pos + length - 1;
		  while (pos < endtlvpos)
		    {
		       tlvtype = tvb_get_guint8 (tvb, pos++);
		       tlvlen = tvb_get_guint8 (tvb, pos++);
		       switch (tlvtype)
			 {
			  case UCD_MODULATION:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_mod_type, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_DIFF_ENCODING:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_diff_encoding,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_LEN:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_VAL_OFF:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_val_off,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec, tvb, pos,
						      tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC_CODEWORD:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec_codeword,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_SEED:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_seed,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_MAX_BURST:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_max_burst, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_GUARD_TIME:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_guard_time,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_LAST_CW_LEN:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_last_cw_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_ONOFF:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_onoff,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			 }		/* switch(tlvtype) */
		       pos = pos + tlvlen;
		    }		/* while (pos < endtlvpos) */
		  break;
		case UCD_BURST_DESCR5:
		  /* DOCSIS 2.0 Upstream Channel Descriptor */
		  proto_tree_add_item (tlv_tree, hf_docsis_ucd_iuc, tvb,
				       pos++, 1, ENC_BIG_ENDIAN);
		  endtlvpos = pos + length - 1;
		  while (pos < endtlvpos)
		    {
		       tlvtype = tvb_get_guint8 (tvb, pos++);
		       tlvlen = tvb_get_guint8 (tvb, pos++);
		       switch (tlvtype)
			 {
			  case UCD_MODULATION:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_mod_type, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_DIFF_ENCODING:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_diff_encoding,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_LEN:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_VAL_OFF:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_preamble_val_off,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec, tvb, pos,
						      tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_FEC_CODEWORD:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_fec_codeword,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_SEED:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_seed,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_MAX_BURST:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_max_burst, tvb,
						      pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_GUARD_TIME:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_guard_time,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_LAST_CW_LEN:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_last_cw_len,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCRAMBLER_ONOFF:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_burst_scrambler_onoff,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			    /* New cases added for DOCSIS 2.0 US Physical Burst Descriptor TLV */
			    /* #define UCD_RS_INT_DEPTH 12
			     *  * #define UCD_RS_INT_BLOCK 13
			     *  * #define UCD_PREAMBLE_TYPE 14
			     *  * #define UCD_SCMDA_SCRAMBLER_ONOFF 15
			     *  * #define UCD_SCDMA_CODES_PER_SUBFRAME 16
			     *  * #define UCD_SCDMA_FRAMER_INT_STEP_SIZE 17
			     *  * #define UCD_TCM_ENABLED 18
			     *  */
			  case UCD_RS_INT_DEPTH:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_rs_int_depth,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_RS_INT_BLOCK:
			    if (tlvlen == 2)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_rs_int_block,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_PREAMBLE_TYPE:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_preamble_type,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCMDA_SCRAMBLER_ONOFF:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_scdma_scrambler_onoff,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCDMA_CODES_PER_SUBFRAME:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_scdma_codes_per_subframe,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_SCDMA_FRAMER_INT_STEP_SIZE:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_scdma_framer_int_step_size,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			  case UCD_TCM_ENABLED:
			    if (tlvlen == 1)
			      {
				 proto_tree_add_item (tlv_tree,
						      hf_docsis_tcm_enabled,
						      tvb, pos, tlvlen, ENC_BIG_ENDIAN);
			      }
			    else
			      {
				 THROW (ReportedBoundsError);
			      }
			    break;
			 }           /* switch(tlvtype) */
		       pos = pos + tlvlen;
		    }               /* while (pos < endtlvpos) */
		  break;
	       }                   /* switch(type) */
	  }                       /* while (pos < len) */
     }                           /* if (tree) */
   
}
Esempio n. 17
0
/*
 * XXX - do reassembly, using the EOM flag.  (Then do that in the Netware
 * SPX implementation, too.)
 *
 * XXX - hand off to subdissectors based on the socket number.
 */
static void
dissect_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*spp_tree = NULL;
	proto_item	*ti;
	tvbuff_t	*next_tvb;
	guint8		conn_ctrl;
	proto_tree	*cc_tree;
	guint8		datastream_type;
	const char	*datastream_type_string;
	guint16         spp_seq;
	const char	*spp_msg_string;
	guint16		low_socket, high_socket;

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

	if (tree) {
		ti = proto_tree_add_item(tree, proto_spp, tvb, 0, SPP_HEADER_LEN, ENC_NA);
		spp_tree = proto_item_add_subtree(ti, ett_spp);
	}

	conn_ctrl = tvb_get_guint8(tvb, 0);
	spp_msg_string = spp_conn_ctrl(conn_ctrl);
	if (check_col(pinfo->cinfo, COL_INFO))
		col_append_fstr(pinfo->cinfo, COL_INFO, " %s", spp_msg_string);
	if (tree) {
		ti = proto_tree_add_uint_format(spp_tree, hf_spp_connection_control, tvb,
						0, 1, conn_ctrl,
						"Connection Control: %s (0x%02X)",
						spp_msg_string, conn_ctrl);
		cc_tree = proto_item_add_subtree(ti, ett_spp_connctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_sys, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_send_ack, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_attn, tvb,
				       0, 1, conn_ctrl);
		proto_tree_add_boolean(cc_tree, hf_spp_connection_control_eom, tvb,
				       0, 1, conn_ctrl);
	}

	datastream_type = tvb_get_guint8(tvb, 1);
	datastream_type_string = spp_datastream(datastream_type);
	if (datastream_type_string != NULL) {
		if (check_col(pinfo->cinfo, COL_INFO))
			col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)",
			    datastream_type_string);
	}
	if (tree) {
		if (datastream_type_string != NULL) {
			proto_tree_add_uint_format(spp_tree, hf_spp_datastream_type, tvb,
						   1, 1, datastream_type,
						   "Datastream Type: %s (0x%02X)",
						   datastream_type_string,
						   datastream_type);
		} else {
			proto_tree_add_uint_format(spp_tree, hf_spp_datastream_type, tvb,
						   1, 1, datastream_type,
						   "Datastream Type: 0x%02X",
						   datastream_type);
		}
		proto_tree_add_item(spp_tree, hf_spp_src_id, tvb,  2, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(spp_tree, hf_spp_dst_id, tvb,  4, 2, ENC_BIG_ENDIAN);
	}
	spp_seq = tvb_get_ntohs(tvb, 6);
	if (tree) {
		proto_tree_add_uint(spp_tree, hf_spp_seq_nr, tvb,  6, 2, spp_seq);
		proto_tree_add_item(spp_tree, hf_spp_ack_nr, tvb,  8, 2, ENC_BIG_ENDIAN);
		proto_tree_add_item(spp_tree, hf_spp_all_nr, tvb, 10, 2, ENC_BIG_ENDIAN);
	}

	if (tvb_reported_length_remaining(tvb, SPP_HEADER_LEN) > 0) {
		if (pinfo->srcport > pinfo->destport) {
			low_socket = pinfo->destport;
			high_socket = pinfo->srcport;
		} else {
			low_socket = pinfo->srcport;
			high_socket = pinfo->destport;
		}

		next_tvb = tvb_new_subset_remaining(tvb, SPP_HEADER_LEN);
		if (dissector_try_uint(spp_socket_dissector_table, low_socket,
		    next_tvb, pinfo, tree))
			return;
		if (dissector_try_uint(spp_socket_dissector_table, high_socket,
		    next_tvb, pinfo, tree))
			return;
		call_dissector(data_handle, next_tvb, pinfo, tree);
	}
}
Esempio n. 18
0
/* Code to dissect extensions */
static void
dissect_mip_extensions( tvbuff_t *tvb, int offset, proto_tree *tree)
{
  proto_item   *ti;
  proto_tree   *exts_tree=NULL;
  proto_tree   *ext_tree;
  proto_tree   *tf;
  proto_tree   *ext_flags_tree;
  proto_tree   *tp;
  proto_tree   *pmipv4_tree;
  gint          ext_len;
  guint8        ext_type;
  guint8        ext_subtype=0;
  guint8        pmipv4skipext_subscriberid_type;
  guint16       flags;
  gint          hdrLen;
  guint32       cvse_vendor_id;
  guint16       cvse_vendor_type;
  guint16       nvse_vendor_type;
  int           cvse_local_offset= 0;
  int           nvse_local_offset= 0;

  /* None of this really matters if we don't have a tree */
  if (!tree) return;

  /* Add our tree, if we have extensions */
  ti = proto_tree_add_text(tree, tvb, offset, -1, "Extensions");
  exts_tree = proto_item_add_subtree(ti, ett_mip_exts);

  /* And, handle each extension */
  while (tvb_reported_length_remaining(tvb, offset) > 0) {

    /* Get our extension info */
    ext_type = tvb_get_guint8(tvb, offset);
    if (ext_type == GEN_AUTH_EXT || ext_type == PMIPv4_NON_SKIP_EXT) {
      /*
       * Very nasty . . breaks normal extensions, since the length is
       * in the wrong place :(
       */
      ext_subtype = tvb_get_guint8(tvb, offset + 1);
      ext_len = tvb_get_ntohs(tvb, offset + 2);
      hdrLen = 4;
    }
    else if(ext_type==CVSE_EXT){
      /*
       * CVSE also breaks since it added reserved field before
       * the length field
      */
      ext_len = tvb_get_ntohs(tvb, offset + 2);
      hdrLen = 4;
    }
    else {
      ext_len = tvb_get_guint8(tvb, offset + 1);
      hdrLen = 2;
    }

    ti = proto_tree_add_text(exts_tree, tvb, offset, ext_len + hdrLen,
                 "Extension: %s",
                 val_to_str(ext_type, mip_ext_types,
                            "Unknown Extension %u"));
    ext_tree = proto_item_add_subtree(ti, ett_mip_ext);

    proto_tree_add_uint(ext_tree, hf_mip_ext_type, tvb, offset, 1, ext_type);
    offset++;
    if (ext_type != GEN_AUTH_EXT &&
        ext_type != PMIPv4_NON_SKIP_EXT &&
        ext_type != CVSE_EXT) {
      /* Another nasty hack since GEN_AUTH_EXT and PMIPv4_NON_SKIP_EXT broke everything */
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 1, ext_len);
      offset++;
    }

    switch (ext_type) {
    case MH_AUTH_EXT:
    case MF_AUTH_EXT:
    case FH_AUTH_EXT:
      /* All these extensions look the same.  4 byte SPI followed by a key */
      proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, ENC_BIG_ENDIAN);
      proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset+4, ext_len-4, ENC_NA);
      break;
    case MN_NAI_EXT:
      proto_tree_add_item(ext_tree, hf_mip_next_nai, tvb, offset,
                          ext_len, ENC_ASCII|ENC_NA);
      break;

    case GEN_AUTH_EXT:      /* RFC 3012 */
      /*
       * Very nasty . . breaks normal extensions, since the length is
       * in the wrong place :(
       */
      proto_tree_add_uint(ext_tree, hf_mip_gaext_stype, tvb, offset, 1, ext_subtype);
      offset++;
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
      offset+=2;
      /* SPI */
      proto_tree_add_item(ext_tree, hf_mip_aext_spi, tvb, offset, 4, ENC_BIG_ENDIAN);
      /* Key */
      proto_tree_add_item(ext_tree, hf_mip_aext_auth, tvb, offset + 4,
                          ext_len - 4, ENC_NA);

      break;
        case REV_SUPP_EXT:      /* RFC 3543 */
      /* flags */
      flags = tvb_get_ntohs(tvb, offset);
      tf = proto_tree_add_uint(ext_tree, hf_mip_rext_flags, tvb, offset, 2, flags);
      ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_rext_i, tvb, offset, 2, flags);

      /* reserved */
      proto_tree_add_uint(ext_flags_tree, hf_mip_rext_reserved, tvb, offset, 2, flags);
      /* registration revocation timestamp */
      proto_tree_add_item(ext_tree, hf_mip_rext_tstamp, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
      break;
    case DYN_HA_EXT:      /* RFC 4433 */
      /* subtype */
      proto_tree_add_item(ext_tree, hf_mip_dhaext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);
      /* Home Agent */
      proto_tree_add_item(ext_tree, hf_mip_dhaext_addr, tvb, offset + 1, 4, ENC_BIG_ENDIAN);
      break;
    case MSG_STR_EXT:
      /* sub-type */
      proto_tree_add_item(ext_tree, hf_mip_mstrext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);

      /* text */
      proto_tree_add_item(ext_tree, hf_mip_mstrext_text, tvb, offset + 1, ext_len-1, ENC_ASCII|ENC_NA);
      break;
    case UDP_TUN_REQ_EXT:   /* RFC 3519 */
      /* sub-type */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);

      /* reserved 1 */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved1, tvb, offset + 1, 1, ENC_BIG_ENDIAN);

      /* flags */
      flags = tvb_get_guint8(tvb, offset + 2);
      tf = proto_tree_add_uint(ext_tree, hf_mip_utrqext_flags, tvb, offset + 2, 1, flags);
      ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_utrqext_f, tvb, offset + 2, 1, flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_utrqext_r, tvb, offset + 2, 1, flags);

      /* reserved 2 */
      proto_tree_add_uint(ext_flags_tree, hf_mip_utrqext_reserved2, tvb, offset + 2, 1, flags);
      /* encapsulation */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_encap_type, tvb, offset + 3, 1, ENC_BIG_ENDIAN);

      /* reserved 3 */
      proto_tree_add_item(ext_tree, hf_mip_utrqext_reserved3, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
      break;
    case UDP_TUN_REP_EXT:   /* RFC 3519 */
      /* sub-type */
      proto_tree_add_item(ext_tree, hf_mip_utrpext_stype, tvb, offset, 1, ENC_BIG_ENDIAN);

      /* code */
      proto_tree_add_item(ext_tree, hf_mip_utrpext_code, tvb, offset + 1, 1, ENC_BIG_ENDIAN);

      /* flags */
      flags = tvb_get_ntohs(tvb, offset+2);
      tf = proto_tree_add_uint(ext_tree, hf_mip_utrpext_flags, tvb, offset + 2, 2, flags);
      ext_flags_tree = proto_item_add_subtree(tf, ett_mip_flags);
      proto_tree_add_boolean(ext_flags_tree, hf_mip_utrpext_f, tvb, offset + 2, 2, flags);

      /* reserved */
      proto_tree_add_uint(ext_flags_tree, hf_mip_utrpext_reserved, tvb, offset + 2, 2, flags);

      /* keepalive interval */
      proto_tree_add_item(ext_tree, hf_mip_utrpext_keepalive, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
      break;
    case PMIPv4_NON_SKIP_EXT:   /* draft-leung-mip4-proxy-mode */
      /* sub-type */
      proto_tree_add_uint(ext_tree, hf_mip_pmipv4nonskipext_stype, tvb, offset, 1, ext_subtype);
      offset++;
          /* len */
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
      offset+=2;
      if(ext_subtype == 1){
        /* Sub-type == 1 : PMIPv4 Per-Node Authentication Method */
        proto_tree_add_item(ext_tree, hf_mip_pmipv4nonskipext_pernodeauthmethod, tvb, offset, 1, ENC_BIG_ENDIAN);
      }
      break;
    case PMIPv4_SKIP_EXT:   /* draft-leung-mip4-proxy-mode */
      /* sub-type */
      ext_subtype = tvb_get_guint8(tvb, offset);
      tp = proto_tree_add_text(ext_tree, tvb, offset, ext_len,
                   "PMIPv4 Sub-Type: %s",
                   val_to_str(ext_subtype, mip_pmipv4skipext_stypes, "Unknown Sub-Type %u"));
      pmipv4_tree = proto_item_add_subtree(tp, ett_mip_pmipv4_ext);
      proto_tree_add_uint(pmipv4_tree, hf_mip_pmipv4skipext_stype, tvb, offset, 1, ext_subtype);

      if (ext_subtype == PMIPv4_SKIPEXT_STYPE_INTERFACE_ID) {
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_interfaceid, tvb, offset + 1, ext_len-1, ENC_NA);
      } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_DEVICE_ID) {
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_deviceid_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_deviceid_id, tvb, offset + 2, ext_len - 2, ENC_NA);
      } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_SUBSCRIBER_ID) {
        pmipv4skipext_subscriberid_type = tvb_get_guint8(tvb, offset + 1);
        proto_tree_add_uint(pmipv4_tree, hf_mip_pmipv4skipext_subscriberid_type, tvb, offset + 1, 1, pmipv4skipext_subscriberid_type);
        if (pmipv4skipext_subscriberid_type == 1) {
          proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_subscriberid_id, tvb, offset + 2, ext_len - 2, ENC_NA);
        }
      } else if (ext_subtype == PMIPv4_SKIPEXT_STYPE_ACCESS_TECHNOLOGY) {
        proto_tree_add_item(pmipv4_tree, hf_mip_pmipv4skipext_accesstechnology_type, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
      }
      break;

    case OLD_CVSE_EXT:      /* RFC 3115 */
    case CVSE_EXT:          /* RFC 3115 */
      /*
       * Very nasty . . breaks normal extensions, since the length is
       * in the wrong place :(
       */
      proto_tree_add_item(ext_tree, hf_mip_cvse_reserved, tvb, offset, 1, ENC_BIG_ENDIAN);
      offset++;
      proto_tree_add_uint(ext_tree, hf_mip_ext_len, tvb, offset, 2, ext_len);
      offset+=2;
      /* Vendor/Org ID */
      /*Vendor ID & cvse type & cvse value are included in ext_len, so do not increment offset for them here.*/
      cvse_local_offset = offset;
      proto_tree_add_item(ext_tree, hf_mip_cvse_vendor_org_id, tvb, cvse_local_offset, 4, ENC_BIG_ENDIAN);
      cvse_vendor_id = tvb_get_ntohl(tvb, cvse_local_offset);
      cvse_local_offset+=4;
      /*Vendor CVSE Type*/
      if( cvse_vendor_id == VENDOR_VERIZON ){
        /*Verizon CVSE type*/
           proto_tree_add_item(ext_tree, hf_mip_cvse_verizon_cvse_type, tvb, cvse_local_offset, 2, ENC_BIG_ENDIAN);
      }
      else{
        /*CVSE Type of Other vendor, just show raw numbers currently*/
        cvse_vendor_type = tvb_get_ntohs(tvb, cvse_local_offset);
        proto_tree_add_uint(ext_tree, hf_mip_cvse_vendor_cvse_type, tvb, cvse_local_offset, 2, cvse_vendor_type);
      }
      cvse_local_offset+=2;
      /* Vendor-CVSE-Value */
      /* Vendor CVSE Type+Vendor/Org ID = 6 bytes*/
      proto_tree_add_item(ext_tree, hf_mip_cvse_vendor_cvse_value, tvb, cvse_local_offset, ext_len - 6, ENC_NA);
      break;

    case OLD_NVSE_EXT:      /* RFC 3115 */
    case NVSE_EXT:          /* RFC 3115 */
      proto_tree_add_item(ext_tree, hf_mip_nvse_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);

      /* Vendor/Org ID */
      /*Vendor ID & nvse type & nvse value are included in ext_len, so do not increment offset for them here.*/
      nvse_local_offset = offset + hdrLen;
      proto_tree_add_item(ext_tree, hf_mip_nvse_vendor_org_id, tvb, nvse_local_offset, 4, ENC_BIG_ENDIAN);
      nvse_local_offset+=4;

      /*Vendor NVSE Type*/
      nvse_vendor_type = tvb_get_ntohs(tvb, nvse_local_offset);
      proto_tree_add_uint(ext_tree, hf_mip_nvse_vendor_nvse_type, tvb, nvse_local_offset, 2, nvse_vendor_type);
      nvse_local_offset+=2;

      /* Vendor-NVSE-Value */
      proto_tree_add_item(ext_tree, hf_mip_nvse_vendor_nvse_value, tvb, nvse_local_offset, ext_len - 8, ENC_NA);
      break;

    case MF_CHALLENGE_EXT:  /* RFC 3012 */
      /* The default dissector is good here.  The challenge is all hex anyway. */
    default:
      proto_tree_add_item(ext_tree, hf_mip_ext, tvb, offset, ext_len, ENC_NA);
      break;
    } /* ext type */

    offset += ext_len;
  } /* while data remaining */

} /* dissect_mip_extensions */
Esempio n. 19
0
static int
dissect_v3_report(tvbuff_t *tvb, proto_tree *parent_tree, int offset)
{
	guint8 m0,m1,m2,m3;
	guint8 s0,s1,s2,s3;
	guint8 metric;
	guint32 ip;

	while (tvb_reported_length_remaining(tvb, offset) > 0) {
		proto_tree *tree;
		proto_item *item;
		int old_offset_a = offset;

		item = proto_tree_add_item(parent_tree, hf_route,
				tvb, offset, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_route);

		m0 = 0xff;
		/* read the mask */
		m1 = tvb_get_guint8(tvb, offset);
		m2 = tvb_get_guint8(tvb, offset+1);
		m3 = tvb_get_guint8(tvb, offset+2);

		ip = m3;
		ip = (ip<<8)|m2;
		ip = (ip<<8)|m1;
		ip = (ip<<8)|m0;
		proto_tree_add_ipv4(tree, hf_netmask, tvb, offset, 3, ip);

		offset += 3;

		/* read every srcnet, metric  pairs */
		do {
			int old_offset_b = offset;
			m0 = 0xff;

			s1 = 0;
			s2 = 0;
			s3 = 0;

			s0 = tvb_get_guint8(tvb, offset);
			offset += 1;
			if (m1) {
				s1 = tvb_get_guint8(tvb, offset);
				offset += 1;
			}
			if (m2) {
				s2 = tvb_get_guint8(tvb, offset);
				offset += 1;
			}
			if (m3) {
				s3 = tvb_get_guint8(tvb, offset);
				offset += 1;
			}

			/* handle special case for default route V3/3.4.3 */
			if ((!m1)&&(!m2)&&(!m3)&&(!s0)) {
				m0 = 0;
			}

			ip = s3;
			ip = (ip<<8)|s2;
			ip = (ip<<8)|s1;
			ip = (ip<<8)|s0;
			proto_tree_add_ipv4_format(tree, hf_saddr, tvb,
				old_offset_b, offset-old_offset_b, ip,
				"%s %d.%d.%d.%d (netmask %d.%d.%d.%d)",
				m0?"Source Network":"Default Route",
				s0,s1,s2,s3,m0,m1,m2,m3);

			metric = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_metric, tvb,
				offset, 1, metric&0x7f);
			offset += 1;


		} while (!(metric&0x80));

		proto_item_set_len(item, offset-old_offset_a);
	}

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

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

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

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

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

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

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

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

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

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

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

      /* Identifier - assumed to be an NTP time here */
      proto_tree_add_item(mip_tree, hf_mip_ident, tvb, offset, 8, ENC_TIME_NTP|ENC_BIG_ENDIAN);
      offset += 8;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  if (tree) {
    if (tvb_reported_length_remaining(tvb, offset) > 0)
      dissect_mip_extensions(tvb, offset, mip_tree);
  }
} /* dissect_mip */
Esempio n. 21
0
static int
dissect_dvmrp_v1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
{
	guint8 code;
	guint8 af=2; /* default */

	/* version */
	proto_tree_add_uint(parent_tree, hf_version, tvb, 0, 0, 1);

	/* type of command */
	proto_tree_add_uint(parent_tree, hf_type, tvb, offset, 1, 0x13);
	offset += 1;

	/* code */
	code = tvb_get_guint8(tvb, offset);
	proto_tree_add_uint(parent_tree, hf_code_v1, tvb, offset, 1, code);
	offset += 1;
	col_add_fstr(pinfo->cinfo, COL_INFO,
			"V%d %s",1 ,val_to_str(code, code_v1,
				"Unknown Type:0x%02x"));

	/* checksum */
	igmp_checksum(parent_tree, tvb, hf_checksum, hf_checksum_bad, pinfo, 0);
	offset += 2;

	/* decode all the v1 commands */
	while (tvb_reported_length_remaining(tvb, offset) > 0) {
		proto_tree *tree;
		proto_item *item;
		guint8 cmd,count;
		int old_offset = offset;

		item = proto_tree_add_item(parent_tree, hf_commands,
				tvb, offset, -1, ENC_NA);
		tree = proto_item_add_subtree(item, ett_commands);

		cmd = tvb_get_guint8(tvb, offset);
		proto_tree_add_uint(tree, hf_command, tvb,
			offset, 1, cmd);
		offset += 1;

		switch (cmd){
		case V1_COMMAND_NULL:
			offset += 1; /* skip ignored/pad byte*/
			if (item) {
				proto_item_set_text(item, "Command: NULL");
			}
			break;
		case V1_COMMAND_AFI:
			af = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_afi, tvb,
				offset, 1, af);
			offset += 1;
			if (item) {
				proto_item_set_text(item, "%s: %s",
					val_to_str(cmd, command, "Unknown Command:0x%02x"),
					val_to_str(af, afi, "Unknown Family:0x%02x")
				);
			}
			break;
		case V1_COMMAND_SUBNETMASK:
			count = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_count, tvb,
				offset, 1, count);
			offset += 1;
			if (count) { /* must be 0 or 1 */
				proto_tree_add_item(tree, hf_netmask,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				if (item) {
					proto_item_set_text(item, "%s: %d.%d.%d.%d",
						val_to_str(cmd, command, "Unknown Command:0x%02x"),
						tvb_get_guint8(tvb, offset),
						tvb_get_guint8(tvb, offset+1),
						tvb_get_guint8(tvb, offset+2),
						tvb_get_guint8(tvb, offset+3));
				}
				offset += 4;
			} else {
				if (item) {
					proto_item_set_text(item, "%s: <no mask supplied>",
						val_to_str(cmd, command, "Unknown Command:0x%02x"));
				}
			}
			break;
		case V1_COMMAND_METRIC:
			proto_tree_add_item(tree, hf_metric, tvb,
				offset, 1, ENC_BIG_ENDIAN);
			if (item) {
				proto_item_set_text(item, "%s: %d",
					val_to_str(cmd, command, "Unknown Command:0x%02x"),
					tvb_get_guint8(tvb, offset));
			}
			offset += 1;
			break;
		case V1_COMMAND_FLAGS0:
			count = tvb_get_guint8(tvb, offset);
			proto_tree_add_boolean(tree, hf_dest_unr, tvb, offset, 1, count);
			proto_tree_add_boolean(tree, hf_split_horiz, tvb, offset, 1, count);
			if (item) {
				proto_item_set_text(item, "%s: 0x%02x",
					val_to_str(cmd, command, "Unknown Command:0x%02x"), count);
			}
			offset += 1;
			break;
		case V1_COMMAND_INFINITY:
			proto_tree_add_item(tree, hf_infinity, tvb,
				offset, 1, ENC_BIG_ENDIAN);
			if (item) {
				proto_item_set_text(item, "%s: %d",
					val_to_str(cmd, command, "Unknown Command:0x%02x"), tvb_get_guint8(tvb, offset));
			}
			offset += 1;
			break;
		case V1_COMMAND_DA:
		case V1_COMMAND_RDA: /* same as DA */
			count = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_count, tvb,
				offset, 1, count);
			offset += 1;
			while (count--) {
				proto_tree_add_item(tree, hf_daddr,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			if (item) {
				proto_item_set_text(item, "%s",
					val_to_str(cmd, command, "Unknown Command:0x%02x"));
			}
			break;
		case V1_COMMAND_NMR:
			count = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_count, tvb,
				offset, 1, count);
			offset += 1;
			while (count--) {
				proto_tree_add_item(tree, hf_maddr,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
				proto_tree_add_item(tree, hf_hold, tvb,
					offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			if (item) {
				proto_item_set_text(item, "%s",
					val_to_str(cmd, command, "Unknown Command:0x%02x"));
			}
			break;
		case V1_COMMAND_NMR_CANCEL:
			count = tvb_get_guint8(tvb, offset);
			proto_tree_add_uint(tree, hf_count, tvb,
				offset, 1, count);
			offset += 1;
			while (count--) {
				proto_tree_add_item(tree, hf_maddr,
					tvb, offset, 4, ENC_BIG_ENDIAN);
				offset += 4;
			}
			if (item) {
				proto_item_set_text(item, "%s",
					val_to_str(cmd, command, "Unknown Command:0x%02x"));
			}
			break;
		}

		proto_item_set_len(item, offset-old_offset);
	}

	return offset;
}
Esempio n. 22
0
    msg_off++;
    pri = 0;
    while (tvb_bytes_exist(tvb, msg_off, 1) &&
           isdigit(tvb_get_guint8(tvb, msg_off)) && msg_off <= MAX_DIGITS) {
      pri = pri * 10 + (tvb_get_guint8(tvb, msg_off) - '0');
      msg_off++;
    }
    if (tvb_get_guint8(tvb, msg_off) == '>')
      msg_off++;
    fac = (pri & FACILITY_MASK) >> 3;
    lev = pri & PRIORITY_MASK;
  }

  msg_len = tvb_ensure_length_remaining(tvb, msg_off);
  msg_str = tvb_format_text(tvb, msg_off, msg_len);
  reported_msg_len = tvb_reported_length_remaining(tvb, msg_off);

  mtp3_tvb = mtp3_msu_present(tvb, pinfo, fac, lev, msg_str,
			      (reported_msg_len - msg_len));

  if (mtp3_tvb == NULL && check_col(pinfo->cinfo, COL_INFO)) {
    if (pri >= 0) {
      col_add_fstr(pinfo->cinfo, COL_INFO, "%s.%s: %s",
        val_to_str(fac, short_fac, "UNKNOWN"),
        val_to_str(lev, short_lev, "UNKNOWN"), msg_str);
    } else {
      col_add_str(pinfo->cinfo, COL_INFO, msg_str);
    }
  }

  if (tree) {
/* Parse Short Message, only if UDH present
 * (otherwise this function is not called).
 * Call WSP dissector if port matches WSP traffic.
 */
static void
parse_gsm_sms_ud_message(proto_tree *sm_tree, tvbuff_t *tvb, packet_info *pinfo,
                         proto_tree *top_tree)
{
    tvbuff_t *sm_tvb = NULL;
    proto_item *subtree, *tree;
    guint8 udh_len, udh, len;
    guint sm_len = tvb_reported_length (tvb);
    guint sm_data_len;
    guint32 i = 0;
    /* Multiple Messages UDH */
    gboolean is_fragmented = FALSE;
    fragment_data *fd_sm = NULL;
    guint16 sm_id = 0, frags = 0, frag = 0;
    gboolean save_fragmented = FALSE, try_gsm_sms_ud_reassemble = FALSE;
    /* SMS Message reassembly */
    gboolean reassembled = FALSE;
    guint32 reassembled_in = 0;
    /* Port Number UDH */
    guint16 p_src = 0, p_dst = 0;
    gboolean ports_available = FALSE;

    udh_len = tvb_get_guint8(tvb, i++);
    tree = proto_tree_add_uint(sm_tree, hf_gsm_sms_udh_length, tvb, 0, 1, udh_len);
    tree = proto_item_add_subtree(tree, ett_udh);
    while (i < udh_len) {
        udh = tvb_get_guint8(tvb, i++);
        len = tvb_get_guint8(tvb, i++);
        subtree = proto_tree_add_uint(tree, hf_gsm_sms_udh_iei,
                                      tvb, i-2, 2+len, udh);
        switch (udh) {
        case 0x00: /* Multiple messages - 8-bit message ID */
            if (len == 3) {
                sm_id = tvb_get_guint8(tvb, i++);
                frags = tvb_get_guint8(tvb, i++);
                frag  = tvb_get_guint8(tvb, i++);
                if (frags > 1)
                    is_fragmented = TRUE;
                proto_item_append_text(subtree,
                                       ": message %u, part %u of %u", sm_id, frag, frags);
                subtree = proto_item_add_subtree(subtree,
                                                 ett_udh_ie);
                proto_tree_add_uint (subtree,
                                     hf_gsm_sms_udh_multiple_messages_msg_id,
                                     tvb, i-3, 1, sm_id);
                proto_tree_add_uint (subtree,
                                     hf_gsm_sms_udh_multiple_messages_msg_parts,
                                     tvb, i-2, 1, frags);
                proto_tree_add_uint (subtree,
                                     hf_gsm_sms_udh_multiple_messages_msg_part,
                                     tvb, i-1, 1, frag);
            } else {
                proto_item_append_text(subtree, " - Invalid format!");
                i += len;
            }
            break;

        case 0x08: /* Multiple messages - 16-bit message ID */
            if (len == 4) {
                sm_id = tvb_get_ntohs(tvb, i);
                i += 2;
                frags = tvb_get_guint8(tvb, i++);
                frag  = tvb_get_guint8(tvb, i++);
                if (frags > 1)
                    is_fragmented = TRUE;
                proto_item_append_text(subtree,
                                       ": message %u, part %u of %u", sm_id, frag, frags);
                subtree = proto_item_add_subtree(subtree,
                                                 ett_udh_ie);
                proto_tree_add_uint (subtree,
                                     hf_gsm_sms_udh_multiple_messages_msg_id,
                                     tvb, i-4, 2, sm_id);
                proto_tree_add_uint (subtree,
                                     hf_gsm_sms_udh_multiple_messages_msg_parts,
                                     tvb, i-2, 1, frags);
                proto_tree_add_uint (subtree,
                                     hf_gsm_sms_udh_multiple_messages_msg_part,
                                     tvb, i-1, 1, frag);
            } else {
                proto_item_append_text(subtree, " - Invalid format!");
                i += len;
            }
            break;

        case 0x04: /* Port Number UDH - 8-bit address */
            if (len == 2) { /* Port fields */
                p_dst = tvb_get_guint8(tvb, i++);
                p_src = tvb_get_guint8(tvb, i++);
                proto_item_append_text(subtree,
                                       ": source port %u, destination port %u",
                                       p_src, p_dst);
                subtree = proto_item_add_subtree(subtree, ett_udh_ie);
                proto_tree_add_uint (subtree, hf_gsm_sms_udh_ports_dst,
                                     tvb, i-2, 1, p_dst);
                proto_tree_add_uint (subtree, hf_gsm_sms_udh_ports_src,
                                     tvb, i-1, 1, p_src);
                ports_available = TRUE;
            } else {
                proto_item_append_text(subtree, " - Invalid format!");
                i += len;
            }
            break;

        case 0x05: /* Port Number UDH - 16-bit address */
            if (len == 4) { /* Port fields */
                p_dst = tvb_get_ntohs(tvb, i);
                i += 2;
                p_src = tvb_get_ntohs(tvb, i);
                i += 2;
                proto_item_append_text(subtree,
                                       ": source port %u, destination port %u",
                                       p_src, p_dst);
                subtree = proto_item_add_subtree(subtree, ett_udh_ie);
                proto_tree_add_uint (subtree, hf_gsm_sms_udh_ports_dst,
                                     tvb, i-4, 2, p_dst);
                proto_tree_add_uint (subtree, hf_gsm_sms_udh_ports_src,
                                     tvb, i-2, 2, p_src);
                ports_available = TRUE;
            } else {
                proto_item_append_text(subtree, " - Invalid format!");
                i += len;
            }
            break;

        default:
            i += len;
            break;
        }
    }
    if (tvb_reported_length_remaining(tvb, i) <= 0)
        return; /* No more data */

    /*
     * XXX - where does the "1" come from?  If it weren't there,
     * "sm_data_len" would, I think, be the same as
     * "tvb_reported_length_remaining(tvb, i)".
     *
     * I think that the above check ensures that "sm_len" won't
     * be less than or equal to "udh_len", so it ensures that
     * "sm_len" won't be less than "1 + udh_len", so we don't
     * have to worry about "sm_data_len" being negative.
     */
    sm_data_len = sm_len - (1 + udh_len);
    if (sm_data_len == 0)
        return;	/* no more data */

    /*
     * Try reassembling the packets.
     * XXX - fragment numbers are 1-origin, but the fragment number
     * field could be 0.
     * Should we flag a fragmented message with a fragment number field
     * of 0?
     * What if the fragment count is 0?  Should we flag that as well?
     */
    if ( is_fragmented && frag != 0 && frags != 0 &&
            tvb_bytes_exist (tvb, i, sm_data_len) ) {
        try_gsm_sms_ud_reassemble = TRUE;
        save_fragmented = pinfo->fragmented;
        pinfo->fragmented = TRUE;
        fd_sm = fragment_add_seq_check (tvb, i, pinfo,
                                        sm_id, /* guint32 ID for fragments belonging together */
                                        sm_fragment_table, /* list of message fragments */
                                        sm_reassembled_table, /* list of reassembled messages */
                                        frag-1, /* guint32 fragment sequence number */
                                        sm_data_len, /* guint32 fragment length */
                                        (frag != frags)); /* More fragments? */
        if (fd_sm) {
            reassembled = TRUE;
            reassembled_in = fd_sm->reassembled_in;
        }
        sm_tvb = process_reassembled_data(tvb, i, pinfo,
                                          "Reassembled Short Message", fd_sm, &sm_frag_items,
                                          NULL, sm_tree);
        if (reassembled) { /* Reassembled */
            col_append_str (pinfo->cinfo, COL_INFO,
                            " (Short Message Reassembled)");
        } else {
            /* Not last packet of reassembled Short Message */
            col_append_fstr (pinfo->cinfo, COL_INFO,
                             " (Short Message fragment %u of %u)", frag, frags);
        }
    } /* Else: not fragmented */

    if (! sm_tvb) /* One single Short Message, or not reassembled */
        sm_tvb = tvb_new_subset_remaining (tvb, i);
    /* Try calling a subdissector */
    if (sm_tvb) {
        if ((reassembled && pinfo->fd->num == reassembled_in)
                || frag==0 || (frag==1 && try_dissect_1st_frag)) {
            /* Try calling a subdissector only if:
             *  - the Short Message is reassembled in this very packet,
             *  - the Short Message consists of only one "fragment",
             *  - the preference "Always Try Dissection for 1st SM fragment"
             *    is switched on, and this is the SM's 1st fragment. */
            if ( ports_available ) {
                gboolean disallow_write = FALSE; /* TRUE if we changed writability
								    of the columns of the summary */
                if ( prevent_subdissectors_changing_columns && col_get_writable(pinfo->cinfo) ) {
                    disallow_write = TRUE;
                    col_set_writable(pinfo->cinfo, FALSE);
                }

                if ( port_number_udh_means_wsp ) {
                    call_dissector (wsp_handle, sm_tvb, pinfo, top_tree);
                } else {
                    if (! dissector_try_uint(gsm_sms_dissector_table, p_src,
                                             sm_tvb, pinfo, top_tree)) {
                        if (! dissector_try_uint(gsm_sms_dissector_table, p_dst,
                                                 sm_tvb, pinfo, top_tree)) {
                            if (sm_tree) { /* Only display if needed */
                                proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
                                                     "Short Message body");
                            }
                        }
                    }
                }

                if ( disallow_write )
                    col_set_writable(pinfo->cinfo, TRUE);
            } else { /* No ports IE */
                proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
                                     "Short Message body");
            }
        } else {
            /* The packet is not reassembled,
             * or it is reassembled in another packet */
            proto_tree_add_text (sm_tree, sm_tvb, 0, -1,
                                 "Unreassembled Short Message fragment %u of %u",
                                 frag, frags);
        }
    }

    if (try_gsm_sms_ud_reassemble) /* Clean up defragmentation */
        pinfo->fragmented = save_fragmented;
    return;
}
Esempio n. 24
0
static void
dissect_pw_fr( tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree )
{
	gint packet_size;
	gint payload_size;
	gint payload_padding;
	const int encaps_size = 4; /*encapsulation consists of mandatory CW only*/
	enum {
		PQ_CW_BAD				= 0x001
		    ,PQ_CW_BAD_BITS03 			= 0x002
		    ,PQ_CW_BAD_LEN_GT_PACKET		= 0x004
		    ,PQ_CW_BAD_LEN_MUST_BE_ZERO		= 0x008
		    ,PQ_CW_BAD_LEN_MUST_BE_NONZERO	= 0x010
		,PQ_PAYLOAD_SIZE_ZERO			= 0x020
	} packet_quality;
	
	packet_size = tvb_reported_length_remaining(tvb, 0);
	if (packet_size < encaps_size)
	{
		if (tree)
		{
			proto_item  *item;
			item = proto_tree_add_item(tree, proto_encaps, tvb, 0, -1, FALSE); 
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"PW packet (%d) is smaller than PW encapsulation header (%d)"
				,(int)packet_size,(int)encaps_size);
		}
		col_set_str(pinfo->cinfo, COL_PROTOCOL, "FR PW");
		col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet < PW encapsulation header");
		return;
	}

	if (dissect_try_cw_first_nibble(tvb,pinfo,tree))
	{
		return;
	}

	/* check how "good" is this packet */   
	/* also decide payload length from packet size and CW */
	packet_quality = 0;
	if (0 != (tvb_get_guint8(tvb, 0) & 0xf0 /*bits03*/))
	{
		packet_quality |= PQ_CW_BAD + PQ_CW_BAD_BITS03;
	}
	{
		/* RFC4619:
		 * [ If the frame's length (defined as the
		 * length of the layer 2 payload plus the length of the control word)
		 * is less than 64 octets, the length field MUST be set to the PW
		 * payload length.  Otherwise, the length field MUST be set to zero. ] 
		 * 
		 * Note difference from RFC4385 which states that:  
		 * [..the length field MUST be set to the length of the PW payload 
		 * *plus* the length of the *PWMCW*. ]
		 */
		int cw_len;
		gint payload_size_packet; /*derived from packet size*/

		cw_len = tvb_get_guint8(tvb, 1) & 0x3f; 
		payload_size_packet = packet_size - encaps_size;
		
		/* 
		 * Initial assumptions.
		 */
		payload_size = payload_size_packet; 
		payload_padding = 0;  
		
		if (payload_size_packet < 64)
		{
			gint payload_size_cw; /*derived from cw*/
			payload_size_cw = cw_len; /*RFC4619-specific*/ 
			if (payload_size_cw == 0)
			{
				packet_quality |= PQ_CW_BAD + PQ_CW_BAD_LEN_MUST_BE_NONZERO;
			}
			else if (payload_size_cw > payload_size_packet)
			{
				packet_quality |= PQ_CW_BAD + PQ_CW_BAD_LEN_GT_PACKET;
			}
			else /* ok */
			{
				payload_size = payload_size_cw;
				payload_padding = payload_size_packet - payload_size_cw; /* >=0 */
			}
		}
		else /* payload_size_packet >= 64 */
		{          
			if (cw_len != 0)
			{
				packet_quality |= PQ_CW_BAD + PQ_CW_BAD_LEN_MUST_BE_ZERO;
			}
		}
	}
	if ((payload_size == 0))
	{		
		packet_quality |= PQ_PAYLOAD_SIZE_ZERO;
	}

	col_set_str(pinfo->cinfo, COL_PROTOCOL, "FR PW");  
	if (check_col(pinfo->cinfo, COL_INFO))
	{
		col_clear(pinfo->cinfo, COL_INFO);
		if (packet_quality & PQ_CW_BAD) 
		{
			col_append_str(pinfo->cinfo, COL_INFO, "CW:Malformed, ");
		}
		col_append_fstr(pinfo->cinfo, COL_INFO, "%d payload octets", (int)payload_size);
	
		if (payload_padding != 0)
		{
			col_append_fstr(pinfo->cinfo, COL_INFO, ", %d padding", (int)payload_padding);
		}
	}

	if (tree)
	{
		proto_tree* subtree;
		proto_item* item_headline;
		proto_item* item;
		
		item_headline = proto_tree_add_item(tree, proto_encaps, tvb, 0, 4, FALSE); 
		proto_item_append_text(item_headline, ": 0x%.8" G_GINT32_MODIFIER "x", tvb_get_ntohl(tvb, 0));
		subtree = proto_item_add_subtree(item_headline, ett_encaps);
		
		if (packet_quality & PQ_CW_BAD_BITS03) /*display only if value is wrong*/
		{
			item = proto_tree_add_item(subtree, hf_cw_bits03, tvb, 0, 1, FALSE);
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"Bits 0..3 of Control Word must be 0");
		}
		
		(void)proto_tree_add_item( subtree, hf_cw_fecn, tvb, 0, 1, FALSE );
		(void)proto_tree_add_item( subtree, hf_cw_becn, tvb, 0, 1, FALSE );
		(void)proto_tree_add_item( subtree, hf_cw_de, tvb, 0, 1, FALSE );
		(void)proto_tree_add_item( subtree, hf_cw_cr, tvb, 0, 1, FALSE );
		(void)proto_tree_add_item( subtree, hf_cw_frg, tvb, 1, 1, FALSE );
		
		item = proto_tree_add_item( subtree, hf_cw_len, tvb, 1, 1, FALSE );
		if (packet_quality & PQ_CW_BAD_LEN_GT_PACKET)
		{
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"Bad Length: greater than FR payload size (%d)", 
				(int)payload_size);
		}  
		if (packet_quality & PQ_CW_BAD_LEN_MUST_BE_NONZERO)
		{
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"Bad Length: must be non-zero if FR PW packet size (%d) is < 64",
				(int)(payload_size+encaps_size));
		}
		if (packet_quality & PQ_CW_BAD_LEN_MUST_BE_ZERO)
		{
			expert_add_info_format(pinfo, item, PI_MALFORMED, PI_ERROR,
				"Bad Length: must be 0 if FR PW packet size (%d) is >= 64",
				(int)(payload_size+encaps_size));
		}
		
		proto_tree_add_item( subtree, hf_cw_seq, tvb, 2, 2, FALSE );

		if (payload_padding > 0)
		{
			proto_tree_add_text(subtree, tvb, 
				encaps_size+payload_size, payload_padding, 
				"[Padding: %d octets]",(int)payload_padding);
		}               

		if (packet_quality & PQ_PAYLOAD_SIZE_ZERO)
		{
			expert_add_info_format(pinfo, item_headline, PI_MALFORMED, PI_WARN,
				"FR payload size must be non-zero");
		}

	}
	if (payload_size > 0)
	{
		tvbuff_t *tvb_payload;
		tvb_payload = tvb_new_subset(tvb, encaps_size, payload_size, payload_size);
		call_dissector( fr_stripped_address_handle, tvb_payload, pinfo, tree );
	} 
	return;
}
Esempio n. 25
0
static void
dissect_rtacser_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
/* Set up structures needed to add the protocol subtree and manage it */
    proto_item    *rtacser_item, *ts_item, *cl_item, *data_payload;
    proto_tree    *rtacser_tree, *cl_tree;
    int           offset=0, len=0;
    guint         event_type;
    guint32       timestamp1, timestamp2;
    gboolean      cts, dcd, dsr, rts, dtr, ring, mbok;
    tvbuff_t      *payload_tvb;

    len = RTACSER_HEADER_LEN;

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

    if (tree) {

        rtacser_item = proto_tree_add_protocol_format(tree, proto_rtacser, tvb, 0, len, "RTAC Serial Line");
        rtacser_tree = proto_item_add_subtree(rtacser_item, ett_rtacser);

        /* Time-stamp is stored as 2 x 32-bit unsigned integers, the left and right-hand side of the decimal point respectively */
        /* The format mirrors the timeval struct - absolute Epoch time (seconds since 1/1/1970) with an added microsecond component */
        timestamp1 = tvb_get_ntohl(tvb, offset);
        timestamp2 = tvb_get_ntohl(tvb, offset+4);
        ts_item = proto_tree_add_item(rtacser_tree, hf_rtacser_timestamp, tvb, offset, 8, ENC_BIG_ENDIAN);
        proto_item_set_text(ts_item, "Arrived At Time: %u.%u" , timestamp1, timestamp2);
        offset += 8;

        /* Set INFO column with RTAC Serial Event Type */
        event_type = tvb_get_guint8(tvb, offset);
        col_clear(pinfo->cinfo, COL_INFO); /* clear out stuff in the info column */
        col_add_fstr(pinfo->cinfo, COL_INFO, "%-21s", val_to_str_const(event_type, rtacser_eventtype_vals, "Unknown Type"));

        /* Add event type to tree */
        proto_tree_add_item(rtacser_tree, hf_rtacser_event_type, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        /* Retrieve EIA-232 serial control line states */
        cts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_CTS;
        dcd = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DCD;
        dsr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DSR;
        rts = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RTS;
        dtr = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_DTR;
        ring = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_RING;
        mbok = tvb_get_guint8(tvb, offset) & RTACSER_CTRL_MBOK;

        cl_item = proto_tree_add_text(rtacser_tree, tvb, offset, 1, "Control Lines");
        cl_tree = proto_item_add_subtree(cl_item, ett_rtacser_cl);

        /* Add UART Control Line information to INFO column */
        col_append_str(pinfo->cinfo, COL_INFO, " ( ");
        (cts)  ? col_append_str(pinfo->cinfo, COL_INFO, "CTS") : col_append_str(pinfo->cinfo, COL_INFO, "/CTS");
        (dcd)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DCD") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DCD");
        (dsr)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DSR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DSR");
        (rts)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RTS") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RTS");
        (dtr)  ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DTR") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/DTR");
        (ring) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "RING") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/RING");
        (mbok) ? col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "MBOK") : col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "/MBOK");
        col_append_str(pinfo->cinfo, COL_INFO, " )");

        /* Add UART Control Line information to tree */
        proto_item_append_text(cl_item, " (");
        (cts)  ? proto_item_append_text(cl_item, "CTS, ") : proto_item_append_text(cl_item, "/CTS, ");
        (dcd)  ? proto_item_append_text(cl_item, "DCD, ") : proto_item_append_text(cl_item, "/DCD, ");
        (dsr)  ? proto_item_append_text(cl_item, "DSR, ") : proto_item_append_text(cl_item, "/DSR, ");
        (rts)  ? proto_item_append_text(cl_item, "RTS, ") : proto_item_append_text(cl_item, "/RTS, ");
        (dtr)  ? proto_item_append_text(cl_item, "DTR, ") : proto_item_append_text(cl_item, "/DTR, ");
        (ring) ? proto_item_append_text(cl_item, "RING, ") : proto_item_append_text(cl_item, "/RING, ");
        (mbok) ? proto_item_append_text(cl_item, "MBOK") : proto_item_append_text(cl_item, "/MBOK");
        proto_item_append_text(cl_item, ")");

        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_cts, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dcd, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dsr, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_rts, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_dtr, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_ring, tvb, offset, 1, ENC_BIG_ENDIAN);
        proto_tree_add_item(cl_tree, hf_rtacser_ctrl_mbok, tvb, offset, 1, ENC_BIG_ENDIAN);
        offset += 1;

        /* 2-byte footer */
        proto_tree_add_item(rtacser_tree, hf_rtacser_footer, tvb, offset, 2, ENC_BIG_ENDIAN);
        offset += 2;

        /* If no payload dissector has been selected, indicate to the user the preferences options */
        if ((tvb_reported_length_remaining(tvb, offset) > 0) && (global_rtacser_payload_proto == RTACSER_PAYLOAD_NONE)) {
            data_payload = proto_tree_add_item(tree, hf_rtacser_data, tvb, offset, -1, ENC_NA);
            proto_item_set_text(data_payload,"Payload Protocol not selected.  Check 'Preferences-> Protocols-> RTAC Serial' for options");
            return;
        }

    } /* tree */

    /* Determine correct message type and call appropriate dissector */
    if (tvb_reported_length_remaining(tvb, RTACSER_HEADER_LEN) > 0) {

        switch (global_rtacser_payload_proto) {
            case RTACSER_PAYLOAD_SELFM:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(selfm_handle, payload_tvb, pinfo, tree);
                break;
            case RTACSER_PAYLOAD_DNP3:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(dnp3_handle, payload_tvb, pinfo, tree);
                break;
            case RTACSER_PAYLOAD_MODBUS:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(modbus_handle, payload_tvb, pinfo, tree);
                break;
            case RTACSER_PAYLOAD_SYNPHASOR:
                payload_tvb = tvb_new_subset_remaining(tvb, RTACSER_HEADER_LEN);
                call_dissector(synphasor_handle, payload_tvb, pinfo, tree);
                break;
            default:
                break;
        }
    }

}
Esempio n. 26
0
static int
dissect_report_segment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ltp_tree, int frame_offset) {
	guint64 rpt_sno;
	guint64 chkp_sno;
	guint64 upper_bound;
	guint64 lower_bound;
	int rcpt_clm_cnt;
	guint64 offset;
	guint64 length;

	int rpt_sno_size;
	int chkp_sno_size;
	int upper_bound_size;
	int lower_bound_size;
	int rcpt_clm_cnt_size;
	int offset_size;
	int length_size;

	int segment_offset = 0;
	int i;

	proto_item *ltp_rpt_item;
	proto_item *ltp_rpt_clm_item;

	proto_tree *ltp_rpt_tree;
	proto_tree *ltp_rpt_clm_tree;

	/* Create the subtree for report segment under the main LTP tree and all the report segment fields under it */
	ltp_rpt_tree = proto_tree_add_subtree(ltp_tree, tvb, frame_offset, -1, ett_rpt_segm, &ltp_rpt_item, "Report Segment");

	/* Extract the report segment info */
	rpt_sno = evaluate_sdnv_64(tvb, frame_offset, &rpt_sno_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_sno, tvb, frame_offset + segment_offset, rpt_sno_size, rpt_sno);
	segment_offset += rpt_sno_size;

	chkp_sno = evaluate_sdnv_64(tvb, frame_offset + segment_offset, &chkp_sno_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_chkp, tvb, frame_offset + segment_offset, chkp_sno_size, chkp_sno);
	segment_offset += chkp_sno_size;

	upper_bound = evaluate_sdnv(tvb, frame_offset + segment_offset, &upper_bound_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_ub, tvb, frame_offset + segment_offset, upper_bound_size, upper_bound);
	segment_offset += upper_bound_size;

	lower_bound = evaluate_sdnv(tvb, frame_offset + segment_offset, &lower_bound_size);
	proto_tree_add_uint64(ltp_rpt_tree, hf_ltp_rpt_lb, tvb, frame_offset + segment_offset, lower_bound_size, lower_bound);
	segment_offset += lower_bound_size;

	rcpt_clm_cnt = evaluate_sdnv(tvb, frame_offset + segment_offset, &rcpt_clm_cnt_size);
	if (rcpt_clm_cnt < 0){
		proto_item_set_end(ltp_rpt_item, tvb, frame_offset + segment_offset);
		expert_add_info_format(pinfo, ltp_tree, &ei_ltp_neg_reception_claim_count,
				"Negative reception claim count: %d", rcpt_clm_cnt);
		return 0;
	}
	/* Each reception claim is at least 2 bytes, so if the count is larger than the
	 * max number of claims we can possibly squeeze into the remaining tvbuff, then
	 * the packet is malformed.
	 */
	if (rcpt_clm_cnt > tvb_reported_length_remaining(tvb, frame_offset + segment_offset) / 2) {
		proto_item_set_end(ltp_rpt_item, tvb, frame_offset + segment_offset);
		expert_add_info_format(pinfo, ltp_tree, &ei_ltp_mal_reception_claim,
				"Reception claim count impossibly large: %d > %d", rcpt_clm_cnt,
				tvb_reported_length_remaining(tvb, frame_offset + segment_offset) / 2);
		return 0;
	}
	proto_tree_add_uint(ltp_rpt_tree, hf_ltp_rpt_clm_cnt, tvb, frame_offset + segment_offset, rcpt_clm_cnt_size, rcpt_clm_cnt);
	segment_offset += rcpt_clm_cnt_size;

	ltp_rpt_clm_tree = proto_tree_add_subtree(ltp_rpt_tree, tvb, frame_offset + segment_offset, -1, ett_rpt_clm, &ltp_rpt_clm_item, "Reception claims");

	/* There can be multiple reception claims in the same report segment */
	for(i = 0; i<rcpt_clm_cnt; i++){
		offset = evaluate_sdnv(tvb,frame_offset + segment_offset, &offset_size);
		proto_tree_add_uint64_format(ltp_rpt_clm_tree, hf_ltp_rpt_clm_off, tvb, frame_offset + segment_offset, offset_size, offset,
				"Offset[%d] : %"G_GINT64_MODIFIER"d", i, offset);
		segment_offset += offset_size;

		length = evaluate_sdnv(tvb,frame_offset + segment_offset, &length_size);
		proto_tree_add_uint64_format(ltp_rpt_clm_tree, hf_ltp_rpt_clm_len, tvb, frame_offset + segment_offset, length_size, length,
				"Length[%d] : %"G_GINT64_MODIFIER"d",i, length);
		segment_offset += length_size;
	}
	proto_item_set_end(ltp_rpt_clm_item, tvb, frame_offset + segment_offset);
	proto_item_set_end(ltp_rpt_item, tvb, frame_offset + segment_offset);
	return segment_offset;
}
Esempio n. 27
0
/*
* Dissect X518 PDUs inside a ROS PDUs
*/
static int
dissect_dsp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data)
{
	int offset = 0;
	int old_offset;
	proto_item *item;
	proto_tree *tree;
	struct SESSION_DATA_STRUCTURE* session;
	int (*dsp_dissector)(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, asn1_ctx_t *actx, proto_tree *tree, int hf_index _U_) = NULL;
	const char *dsp_op_name;
	asn1_ctx_t asn1_ctx;

	/* do we have operation information from the ROS dissector? */
	if (data == NULL)
		return 0;
	session  = (struct SESSION_DATA_STRUCTURE*)data;

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

	item = proto_tree_add_item(parent_tree, proto_dsp, tvb, 0, -1, ENC_NA);
	tree = proto_item_add_subtree(item, ett_dsp);

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

	asn1_ctx.private_data = session;

	switch(session->ros_op & ROS_OP_MASK) {
	case (ROS_OP_BIND | ROS_OP_ARGUMENT):	/*  BindInvoke */
	  dsp_dissector = dissect_dsp_DSASystemBindArgument;
	  dsp_op_name = "System-Bind-Argument";
	  break;
	case (ROS_OP_BIND | ROS_OP_RESULT):	/*  BindResult */
	  dsp_dissector = dissect_dsp_DSASystemBindResult;
	  dsp_op_name = "System-Bind-Result";
	  break;
	case (ROS_OP_BIND | ROS_OP_ERROR):	/*  BindError */
	  dsp_dissector = dissect_dsp_DSASystemBindError;
	  dsp_op_name = "System-Bind-Error";
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ARGUMENT):	/*  Invoke Argument */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* read */
	    dsp_dissector = dissect_dsp_ChainedReadArgument;
	    dsp_op_name = "Chained-Read-Argument";
	    break;
	  case 2: /* compare */
	    dsp_dissector = dissect_dsp_ChainedCompareArgument;
	    dsp_op_name = "Chained-Compare-Argument";
	    break;
	  case 3: /* abandon */
	    dsp_dissector = dissect_dsp_ChainedAbandonArgument;
	    dsp_op_name = "Chained-Abandon-Argument";
	    break;
	  case 4: /* list */
	    dsp_dissector = dissect_dsp_ChainedListArgument;
	    dsp_op_name = "Chained-List-Argument";
	    break;
	  case 5: /* search */
	    dsp_dissector = dissect_dsp_ChainedSearchArgument;
	    dsp_op_name = "Chained-Search-Argument";
	    break;
	  case 6: /* addEntry */
	    dsp_dissector = dissect_dsp_ChainedAddEntryArgument;
	    dsp_op_name = "Chained-Add-Entry-Argument";
	    break;
	  case 7: /* removeEntry */
	    dsp_dissector = dissect_dsp_ChainedRemoveEntryArgument;
	    dsp_op_name = "Chained-Remove-Entry-Argument";
	    break;
	  case 8: /* modifyEntry */
	    dsp_dissector = dissect_dsp_ChainedModifyEntryArgument;
	    dsp_op_name = "ChainedModify-Entry-Argument";
	    break;
	  case 9: /* modifyDN */
	    dsp_dissector = dissect_dsp_ChainedModifyDNArgument;
	    dsp_op_name = "ChainedModify-DN-Argument";
	    break;
	  default:
	    proto_tree_add_expert_format(tree, pinfo, &ei_dsp_unsupported_opcode, tvb, offset, -1,
	        "Unsupported DSP opcode (%d)", session->ros_op & ROS_OP_OPCODE_MASK);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_RESULT):	/*  Return Result */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* read */
	    dsp_dissector = dissect_dsp_ChainedReadResult;
	    dsp_op_name = "Chained-Read-Result";
	    break;
	  case 2: /* compare */
	    dsp_dissector = dissect_dsp_ChainedCompareResult;
	    dsp_op_name = "Chained-Compare-Result";
	    break;
	  case 3: /* abandon */
	    dsp_dissector = dissect_dsp_ChainedAbandonResult;
	    dsp_op_name = "Chained-Abandon-Result";
	    break;
	  case 4: /* list */
	    dsp_dissector = dissect_dsp_ChainedListResult;
	    dsp_op_name = "Chained-List-Result";
	    break;
	  case 5: /* search */
	    dsp_dissector = dissect_dsp_ChainedSearchResult;
	    dsp_op_name = "Chained-Search-Result";
	    break;
	  case 6: /* addEntry */
	    dsp_dissector = dissect_dsp_ChainedAddEntryResult;
	    dsp_op_name = "Chained-Add-Entry-Result";
	    break;
	  case 7: /* removeEntry */
	    dsp_dissector = dissect_dsp_ChainedRemoveEntryResult;
	    dsp_op_name = "Chained-Remove-Entry-Result";
	    break;
	  case 8: /* modifyEntry */
	    dsp_dissector = dissect_dsp_ChainedModifyEntryResult;
	    dsp_op_name = "Chained-Modify-Entry-Result";
	    break;
	  case 9: /* modifyDN */
	    dsp_dissector = dissect_dsp_ChainedModifyDNResult;
	    dsp_op_name = "ChainedModify-DN-Result";
	    break;
	  default:
	    proto_tree_add_expert(tree, pinfo, &ei_dsp_unsupported_opcode, tvb, offset, -1);
	    break;
	  }
	  break;
	case (ROS_OP_INVOKE | ROS_OP_ERROR):	/*  Return Error */
	  switch(session->ros_op & ROS_OP_OPCODE_MASK) {
	  case 1: /* attributeError */
	    dsp_dissector = dissect_dap_AttributeError;
	    dsp_op_name = "Attribute-Error";
	    break;
	  case 2: /* nameError */
	    dsp_dissector = dissect_dap_NameError;
	    dsp_op_name = "Name-Error";
	    break;
	  case 3: /* serviceError */
	    dsp_dissector = dissect_dap_ServiceError;
	    dsp_op_name = "Service-Error";
	    break;
	  case 4: /* referral */
	    dsp_dissector = dissect_dap_Referral;
	    dsp_op_name = "Referral";
	    break;
	  case 5: /* abandoned */
	    dsp_dissector = dissect_dap_Abandoned;
	    dsp_op_name = "Abandoned";
	    break;
	  case 6: /* securityError */
	    dsp_dissector = dissect_dap_SecurityError;
	    dsp_op_name = "Security-Error";
	    break;
	  case 7: /* abandonFailed */
	    dsp_dissector = dissect_dap_AbandonFailedError;
	    dsp_op_name = "Abandon-Failed-Error";
	    break;
	  case 8: /* updateError */
	    dsp_dissector = dissect_dap_UpdateError;
	    dsp_op_name = "Update-Error";
	    break;
	  case 9: /* DSAReferral */
	    dsp_dissector = dissect_dsp_DSAReferral;
	    dsp_op_name = "DSA-Referral";
	    break;
	  default:
	    proto_tree_add_expert(tree, pinfo, &ei_dsp_unsupported_errcode, tvb, offset, -1);
	    break;
	  }
	  break;
	default:
	  proto_tree_add_expert(tree, pinfo, &ei_dsp_unsupported_pdu, tvb, offset, -1);
	  return tvb_captured_length(tvb);
	}

	if(dsp_dissector) {
    col_set_str(pinfo->cinfo, COL_INFO, dsp_op_name);

	  while (tvb_reported_length_remaining(tvb, offset) > 0){
	    old_offset=offset;
	    offset=(*dsp_dissector)(FALSE, tvb, offset, &asn1_ctx, tree, -1);
	    if(offset == old_offset){
	      proto_tree_add_expert(tree, pinfo, &ei_dsp_zero_pdu, tvb, offset, -1);
	      break;
	    }
	  }
	}

	return tvb_captured_length(tvb);
}
Esempio n. 28
0
/*
	5.1.1 Picture Start Code (PSC) (22 bits)
	PSC is a word of 22 bits. Its value is 0000 0000 0000 0000 1 00000. All picture start codes shall be
	byte aligned.
	( 1000 00xx)

	End Of Sequence (EOS) (22 bits)
	A codeword of 22 bits. Its value is 0000 0000 0000 0000 1 11111.
	( 1111 11xx )

	Group of Block Start Code (GBSC) (17 bits)
	A word of 17 bits. Its value is 0000 0000 0000 0000 1.
	( 1xxx xxxx )

	End Of Sub-Bitstream code (EOSBS) (23 bits)
	The EOSBS code is a codeword of 23 bits. Its value is 0000 0000 0000 0000 1 11110 0.
	( 1111 100x )

	Slice Start Code (SSC) (17 bits)
	A word of 17 bits. Its value is 0000 0000 0000 0000 1.
	( 1xxx xxxx )
  */
static void dissect_h263_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
{
	guint offset = 0;
	proto_item *h263_payload_item	= NULL;
	proto_tree *h263_payload_tree	= NULL;
	guint32 data;
	guint8 startcode;
	int length;

	col_append_str( pinfo->cinfo, COL_INFO, "H263 payload ");

	if( tree ) {
	  h263_payload_item = proto_tree_add_item( tree, proto_h263_data, tvb, offset, -1, ENC_NA );
	  h263_payload_tree = proto_item_add_subtree( h263_payload_item, ett_h263_payload );
	}

	length = tvb_reported_length_remaining(tvb,0);
	if(length<4){
		if( tree )
			proto_tree_add_item( h263_payload_tree, hf_h263_data, tvb, offset, -1, ENC_NA );
		return;
	}
	/* Check for PSC, PSC is a word of 22 bits. Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx. */
	data = tvb_get_ntohl(tvb, offset);

	if (( data & 0xffff8000) == 0x00008000 ) {
		/* Start Code found
		 *
		 * Startc code holds bit 17 -23 of the codeword
		 */
		startcode = tvb_get_guint8(tvb,offset+2)&0xfe;
		if (startcode & 0x80){
			switch(startcode){
			case 0xf8:
				/* End Of Sub-Bitstream code (EOSBS)
				 * ( 1111 100. )
				 */
				break;
			case 0x80:
			case 0x82:
				/* Picture Start Code (PSC)
				 * ( 1000 00x.)
				 */
				col_append_str( pinfo->cinfo, COL_INFO, "(PSC) ");
				offset = dissect_h263_picture_layer( tvb, pinfo, h263_payload_tree, offset, -1, ENC_NA);
				break;
			case 0xfc:
			case 0xfe:
				/* End Of Sequence (EOS)
				 * ( 1111 11x. )
				 */
			default:
				/* Group of Block Start Code (GBSC) or
				 * Slice Start Code (SSC)
				 */
				col_append_str( pinfo->cinfo, COL_INFO, "(GBSC) ");
				offset = dissect_h263_group_of_blocks_layer( tvb, h263_payload_tree, offset,FALSE);
				break;
			}
		}else{
			/* Error */
		}
	}
	if( tree )
		proto_tree_add_item( h263_payload_tree, hf_h263_data, tvb, offset, -1, ENC_NA );
}
Esempio n. 29
0
    ti = proto_tree_add_item(tree, proto_bofl, tvb, 0, -1, ENC_NA);
    bofl_tree = proto_item_add_subtree(ti, ett_bofl);

    pdu = tvb_get_ntohl(tvb, 0);
    col_add_fstr(pinfo->cinfo, COL_INFO,
        "PDU: 0x%08x", pdu);
    proto_tree_add_uint(bofl_tree, hf_bofl_pdu, tvb, 0, 4, pdu);

    sequence = tvb_get_ntohl(tvb, 4);

    col_append_fstr(pinfo->cinfo, COL_INFO,
        " Sequence: %u", sequence);

    proto_tree_add_uint(bofl_tree, hf_bofl_sequence, tvb, 4, 4, sequence);

    len = tvb_reported_length_remaining(tvb, 8);
    if (len > 0)
        proto_tree_add_item(bofl_tree, hf_bofl_padding, tvb, 8, -1, ENC_NA);

    return tvb_captured_length(tvb);
}


void
proto_register_bofl(void)
{
    static hf_register_info hf[] = {
        { &hf_bofl_pdu,
          { "PDU", "bofl.pdu",
            FT_UINT32, BASE_HEX, NULL, 0,
            "PDU; normally equals 0x01010000 or 0x01011111", HFILL }
Esempio n. 30
0
static int
dissect_kt_play_script(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset)
{
    guint32 next32, rnum, ksiz, vsiz, nsiz;
    gint new_offset, rec_start_offset;
    proto_item *ti;
    proto_item *pi;
    proto_tree *rec_tree;

    new_offset = offset;

    proto_tree_add_item(tree, hf_kt_magic, tvb, new_offset, 1, ENC_BIG_ENDIAN);
    new_offset++;

    next32 = tvb_get_ntohl(tvb, new_offset);

    if (next32 == 0) {
        if (tvb_reported_length_remaining(tvb, (new_offset + 4)) > 0) {
            /* There's more data after the 32 bits. This is a request */
            pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_REQUEST);
            proto_item_set_generated(pi);

            proto_tree_add_uint(tree, hf_kt_flags, tvb, new_offset, 4, next32);
            new_offset += 4;

            nsiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_nsiz, tvb, new_offset, 4, nsiz);
            new_offset += 4;

            rnum = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, rnum);
            new_offset += 4;

            proto_tree_add_item(tree, hf_kt_name, tvb, new_offset, nsiz, ENC_ASCII|ENC_NA);
            new_offset += nsiz;

            while (rnum > 0) {
                /* Create a sub-tree for each record */
                ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
                rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
                rec_start_offset = new_offset;

                ksiz = tvb_get_ntohl(tvb, new_offset);
                proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
                new_offset += 4;

                vsiz = tvb_get_ntohl(tvb, new_offset);
                proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz);
                new_offset += 4;

                proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
                if (kt_present_key_val_as_ascii) {
                    pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                    proto_item_set_generated(pi);
                }
                new_offset += ksiz;

                proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA);
                if (kt_present_key_val_as_ascii) {
                    pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA);
                    proto_item_set_generated(pi);
                }
                new_offset += vsiz;

                proto_item_set_len(ti, new_offset - rec_start_offset);
                rnum--;
            }
        } else {
            /* Nothing remaining after the 32 bits. This is a response with no records. */
            pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
            proto_item_set_generated(pi);
            col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

            proto_tree_add_uint(tree, hf_kt_rnum, tvb, new_offset, 4, next32);
            new_offset += 4;
        }
    } else { /* response - one or more records */
        pi = proto_tree_add_uint(tree, hf_kt_type, tvb, offset, 1, KT_OPER_RESPONSE);
        proto_item_set_generated(pi);
        col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "[response]");

        rnum = tvb_get_ntohl(tvb, new_offset);
        proto_tree_add_uint(tree, hf_kt_hits, tvb, new_offset, 4, rnum);
        new_offset += 4;

        while (rnum > 0) {
            /* Create a sub-tree for each record */
            ti = proto_tree_add_item(tree, hf_kt_rec, tvb, new_offset, -1, ENC_NA);
            rec_tree = proto_item_add_subtree(ti, ett_kt_rec);
            rec_start_offset = new_offset;

            ksiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_ksiz, tvb, new_offset, 4, ksiz);
            new_offset += 4;

            vsiz = tvb_get_ntohl(tvb, new_offset);
            proto_tree_add_uint(rec_tree, hf_kt_vsiz, tvb, new_offset, 4, vsiz);
            new_offset += 4;

            proto_tree_add_item(rec_tree, hf_kt_key, tvb, new_offset, ksiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_key_str, tvb, new_offset, ksiz, ENC_ASCII|ENC_NA);
                proto_item_set_generated(pi);
            }
            new_offset += ksiz;

            proto_tree_add_item(rec_tree, hf_kt_val, tvb, new_offset, vsiz, ENC_NA);
            if (kt_present_key_val_as_ascii) {
                pi = proto_tree_add_item(rec_tree, hf_kt_val_str, tvb, new_offset, vsiz, ENC_ASCII|ENC_NA);
                proto_item_set_generated(pi);
            }
            new_offset += vsiz;

            proto_item_set_len(ti, new_offset - rec_start_offset);
            rnum--;
        }
    }

    return new_offset;
}