Example #1
0
static void
wmem_test_allocator_jumbo(wmem_allocator_type_t type, wmem_verify_func verify)
{
    wmem_allocator_t *allocator;
    char *ptr, *ptr1;

    allocator = wmem_allocator_force_new(type);

    ptr = (char*)wmem_alloc0(allocator, 4*1024*1024);
    wmem_free(allocator, ptr);
    wmem_gc(allocator);
    ptr = (char*)wmem_alloc0(allocator, 4*1024*1024);

    if (verify) (*verify)(allocator);
    wmem_free(allocator, ptr);
    wmem_gc(allocator);
    if (verify) (*verify)(allocator);

    ptr  = (char *)wmem_alloc0(allocator, 10*1024*1024);
    ptr1 = (char *)wmem_alloc0(allocator, 13*1024*1024);
    ptr1 = (char *)wmem_realloc(allocator, ptr1, 10*1024*1024);
    memset(ptr1, 0, 10*1024*1024);
    ptr = (char *)wmem_realloc(allocator, ptr, 13*1024*1024);
    memset(ptr, 0, 13*1024*1024);
    if (verify) (*verify)(allocator);
    wmem_gc(allocator);
    if (verify) (*verify)(allocator);
    wmem_free(allocator, ptr1);
    if (verify) (*verify)(allocator);
    wmem_free_all(allocator);
    wmem_gc(allocator);
    if (verify) (*verify)(allocator);

    wmem_destroy_allocator(allocator);
}
Example #2
0
static void
wmem_test_allocator_det(wmem_allocator_t *allocator, wmem_verify_func verify,
        guint len)
{
    int i;
    char *ptrs[MAX_SIMULTANEOUS_ALLOCS];

    /* we use wmem_alloc0 in part because it tests slightly more code, but
     * primarily so that if the allocator doesn't give us enough memory or
     * gives us memory that includes its own metadata, we write to it and
     * things go wrong, causing the tests to fail */
    for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
        ptrs[i] = (char *)wmem_alloc0(allocator, len);
    }
    for (i=MAX_SIMULTANEOUS_ALLOCS-1; i>=0; i--) {
        /* no wmem_realloc0 so just use memset manually */
        ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], 4*len);
        memset(ptrs[i], 0, 4*len);
    }
    for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
        wmem_free(allocator, ptrs[i]);
    }

    if (verify) (*verify)(allocator);
    wmem_free_all(allocator);
    wmem_gc(allocator);
    if (verify) (*verify)(allocator);
}
Example #3
0
/*
 * Returns an initialized MPA connection state or throws an out of
 * memory exception.
 */
static mpa_state_t *
init_mpa_state(void)
{
	mpa_state_t *state;

	state = (mpa_state_t *) wmem_alloc0(wmem_file_scope(), sizeof(mpa_state_t));
	state->revision = -1;
	return state;
}
/* Main dissection function. */
static void dissect_mac_lte_framed(tvbuff_t *tvb, packet_info *pinfo,
                                   proto_tree *tree)
{
    gint                 offset = 0;
    struct mac_lte_info  *p_mac_lte_info;
    tvbuff_t             *mac_tvb;
    gboolean             infoAlreadySet = FALSE;

    /* Need to find enabled mac-lte dissector */
    dissector_handle_t   mac_lte_handle = find_dissector("mac-lte");
    if (!mac_lte_handle) {
        return;
    }

    /* Do this again on re-dissection to re-discover offset of actual PDU */

    /* Needs to be at least as long as:
       - fixed header bytes
       - tag for data
       - at least one byte of MAC PDU payload */
    if ((size_t)tvb_length_remaining(tvb, offset) < (3+2)) {
        return;
    }

    /* If redissecting, use previous info struct (if available) */
    p_mac_lte_info = (struct mac_lte_info*)p_get_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0);
    if (p_mac_lte_info == NULL) {
        /* Allocate new info struct for this frame */
        p_mac_lte_info = (struct mac_lte_info*)wmem_alloc0(wmem_file_scope(), sizeof(struct mac_lte_info));
        infoAlreadySet = FALSE;
    }
    else {
        infoAlreadySet = TRUE;
    }

    /* Dissect the fields to populate p_mac_lte */
    if (!dissect_mac_lte_context_fields(p_mac_lte_info, tvb, &offset)) {
        return;
    }

    /* Store info in packet (first time) */
    if (!infoAlreadySet) {
        p_add_proto_data(wmem_file_scope(), pinfo, proto_mac_lte, 0, p_mac_lte_info);
    }

    /**************************************/
    /* OK, now dissect as MAC LTE         */

    /* Create tvb that starts at actual MAC PDU */
    mac_tvb = tvb_new_subset_remaining(tvb, offset);
    call_dissector_only(mac_lte_handle, mac_tvb, pinfo, tree, NULL);
}
Example #5
0
char *
fvalue_to_string_repr(wmem_allocator_t *scope, fvalue_t *fv, ftrepr_t rtype, int field_display)
{
	char *buf;
	int len;
	if (fv->ftype->val_to_string_repr == NULL) {
		/* no value-to-string-representation function, so the value cannot be represented */
		return NULL;
	}

	if ((len = fvalue_string_repr_len(fv, rtype, field_display)) >= 0) {
		buf = (char *)wmem_alloc0(scope, len + 1);
	} else {
		/* the value cannot be represented in the given representation type (rtype) */
		return NULL;
	}

	fv->ftype->val_to_string_repr(fv, rtype, field_display, buf, (unsigned int)len+1);
	return buf;
}
Example #6
0
/* Calculates a CRC32 checksum from the tvb zeroing out four bytes at the offset and checks it with the given crc32 and adds the result to the tree
 * Returns true if the calculated CRC32 matches the passed CRC32.
 * */
static gboolean ts2_add_checked_crc32(proto_tree *tree, int hf_item, tvbuff_t *tvb, guint16 offset, guint32 icrc32 )
{
    guint8  *zero;
    gint     len;
    guint32  ocrc32;

    zero = (guint8 *)wmem_alloc0(wmem_packet_scope(), 4);
    ocrc32 = crc32_ccitt_tvb(tvb, offset);
    ocrc32 = crc32_ccitt_seed(zero, 4, 0xffffffff-ocrc32);
    len = tvb_reported_length_remaining(tvb, offset+4);
    if (len<0)
        return FALSE;
    ocrc32 = crc32_ccitt_tvb_offset_seed(tvb, offset+4, (guint)len, 0xffffffff-ocrc32);
    if(icrc32==ocrc32)
    {
        proto_tree_add_uint_format(tree, hf_item, tvb, offset, 4, tvb_get_letohl(tvb, 16), "crc32: 0x%04x [correct]", tvb_get_letohl(tvb, offset));
        return TRUE;
    }
    else
    {
        proto_tree_add_uint_format(tree, hf_item, tvb, offset, 4, tvb_get_letohl(tvb,16), "crc32: 0x%04x [incorrect, should be 0x%04x]", tvb_get_letohl(tvb, offset),ocrc32);
        return FALSE;
    }
}
Example #7
0
/* Transfers happen in response to broadcasts, they are always TCP and are
 * used to send the file to the port mentioned in the broadcast. There are
 * 2 types of transfers: Pushes, which are direct responses to searches,
 * in which the peer that has the file connects to the peer that doesn't and
 * sends it, then disconnects. The other type of transfer is a pull, where
 * the peer that doesn't have the file connects to the peer that does and
 * requests it be sent.
 *
 * Pulls have a file request which identifies the desired file,
 * while pushes simply send the file. In practice this works because every
 * file the implementation sends searches for is on a different TCP port
 * on the searcher's machine. */
static int
dissect_ldss_transfer (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
	conversation_t *transfer_conv;
	ldss_transfer_info_t *transfer_info;
	struct tcpinfo *transfer_tcpinfo;
	proto_tree *ti, *line_tree = NULL, *ldss_tree = NULL;
	nstime_t broadcast_response_time;

	/* Reject the packet if data is NULL */
	if (data == NULL)
		return 0;
	transfer_tcpinfo = (struct tcpinfo *)data;

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

	/* Look for the transfer conversation; this was created during
	 * earlier broadcast dissection (see prepare_ldss_transfer_conv) */
	transfer_conv = find_conversation (pinfo->num, &pinfo->src, &pinfo->dst,
					   PT_TCP, pinfo->srcport, pinfo->destport, 0);
	transfer_info = (ldss_transfer_info_t *)conversation_get_proto_data(transfer_conv, proto_ldss);

	/* For a pull, the first packet in the TCP connection is the file request.
	 * First packet is identified by relative seq/ack numbers of 1.
	 * File request only appears on a pull (triggered by an offer - see above
	 * about broadcasts) */
	if (transfer_tcpinfo->seq == 1 &&
	    transfer_tcpinfo->lastackseq == 1 &&
	    transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND) {
		/* LDSS pull transfers look a lot like HTTP.
		 * Sample request:
		 * md5:01234567890123...
		 * Size: 2550
		 * Start: 0
		 * Compression: 0
		 * (remote end sends the file identified by the digest) */
		guint offset = 0;
		gboolean already_dissected = TRUE;

		col_set_str(pinfo->cinfo, COL_INFO, "LDSS File Transfer (Requesting file - pull)");

		if (highest_num_seen == 0 ||
		    highest_num_seen < pinfo->num) {

			already_dissected = FALSE;
			transfer_info->req = wmem_new0(wmem_file_scope(), ldss_file_request_t);
			transfer_info->req->file = wmem_new0(wmem_file_scope(), ldss_file_t);
			highest_num_seen = pinfo->num;
		}

		if (tree) {
			ti = proto_tree_add_item(tree, proto_ldss,
						 tvb, 0, tvb_reported_length(tvb), ENC_NA);
			ldss_tree = proto_item_add_subtree(ti, ett_ldss_transfer);
		}

		/* Populate digest data into the file struct in the request */
		transfer_info->file = transfer_info->req->file;

		/* Grab each line from the packet, there should be 4 but lets
		 * not walk off the end looking for more. */
		while (tvb_offset_exists(tvb, offset)) {
			gint next_offset;
			const guint8 *line;
			int linelen;
			gboolean is_digest_line;
			guint digest_type_len;

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

			/* Include new-line in line */
			line = (guint8 *)tvb_memdup(NULL, tvb, offset, linelen+1); /* XXX - memory leak? */

			line_tree = proto_tree_add_subtree(ldss_tree, tvb, offset, linelen,
							 ett_ldss_transfer_req, NULL,
							 tvb_format_text(tvb, offset, next_offset-offset));

			/* Reduce code duplication processing digest lines.
			 * There are too many locals to pass to a function - the signature
			 * looked pretty ugly when I tried! */
			is_digest_line = FALSE;

			if (strncmp(line,"md5:",4)==0) {
				is_digest_line = TRUE;
				digest_type_len = 4;
				transfer_info->file->digest_type = DIGEST_TYPE_MD5;
			}
			else if (strncmp(line, "sha1:", 5)==0) {
				is_digest_line = TRUE;
				digest_type_len = 5;
				transfer_info->file->digest_type = DIGEST_TYPE_SHA1;
			}
			else if (strncmp(line, "sha256:", 7)==0) {
				is_digest_line = TRUE;
				digest_type_len = 7;
				transfer_info->file->digest_type = DIGEST_TYPE_SHA256;
			}
			else if (strncmp(line, "unknown:", 8)==0) {
				is_digest_line = TRUE;
				digest_type_len = 8;
				transfer_info->file->digest_type = DIGEST_TYPE_UNKNOWN;
			}
			else if (strncmp(line, "Size: ", 6)==0) {
				/* Sample size line:
				 * Size: 2550\n */
				transfer_info->req->size = g_ascii_strtoull(line+6, NULL, 10);
				if (tree) {
					ti = proto_tree_add_uint64(line_tree, hf_ldss_size,
								   tvb, offset+6, linelen-6, transfer_info->req->size);
					PROTO_ITEM_SET_GENERATED(ti);
				}
			}
			else if (strncmp(line, "Start: ", 7)==0) {
				/* Sample offset line:
				 * Start: 0\n */
				transfer_info->req->offset = g_ascii_strtoull(line+7, NULL, 10);
				if (tree) {
					ti = proto_tree_add_uint64(line_tree, hf_ldss_offset,
								   tvb, offset+7, linelen-7, transfer_info->req->offset);
					PROTO_ITEM_SET_GENERATED(ti);
				}
			}
			else if (strncmp(line, "Compression: ", 13)==0) {
				/* Sample compression line:
				 * Compression: 0\n */
				transfer_info->req->compression = (gint8)strtol(line+13, NULL, 10); /* XXX - bad cast */
				if (tree) {
					ti = proto_tree_add_uint(line_tree, hf_ldss_compression,
								 tvb, offset+13, linelen-13, transfer_info->req->compression);
					PROTO_ITEM_SET_GENERATED(ti);
				}
			}
			else {
				proto_tree_add_expert(line_tree, pinfo, &ei_ldss_unrecognized_line, tvb, offset, linelen);
			}

			if (is_digest_line) {
				/* Sample digest-type/digest line:
				 * md5:0123456789ABCDEF\n */
				if (!already_dissected) {
					GByteArray *digest_bytes;

					digest_bytes = g_byte_array_new();
					hex_str_to_bytes(
						tvb_get_ptr(tvb, offset+digest_type_len, linelen-digest_type_len),
						digest_bytes, FALSE);

					if(digest_bytes->len >= DIGEST_LEN)
						digest_bytes->len = (DIGEST_LEN-1);
					/* Ensure the digest is zero-padded */
					transfer_info->file->digest = (guint8 *)wmem_alloc0(wmem_file_scope(), DIGEST_LEN);
					memcpy(transfer_info->file->digest, digest_bytes->data, digest_bytes->len);

					g_byte_array_free(digest_bytes, TRUE);
				}
				if (tree) {
					proto_item *tii = NULL;

					tii = proto_tree_add_uint(line_tree, hf_ldss_digest_type,
								 tvb, offset, digest_type_len, transfer_info->file->digest_type);
					PROTO_ITEM_SET_GENERATED(tii);
					tii = proto_tree_add_bytes(line_tree, hf_ldss_digest,
								  tvb, offset+digest_type_len, MIN(linelen-digest_type_len, DIGEST_LEN),
								  transfer_info->file->digest);
					PROTO_ITEM_SET_GENERATED(tii);
				}
			}

			offset = next_offset;
		}

		/* Link forwards to the response for this pull. */
		if (tree && transfer_info->resp_num != 0) {
			ti = proto_tree_add_uint(ldss_tree, hf_ldss_response_in,
						 tvb, 0, 0, transfer_info->resp_num);
			PROTO_ITEM_SET_GENERATED(ti);
		}

		transfer_info->req->num = pinfo->num;
		transfer_info->req->ts = pinfo->abs_ts;
	}
	/* Remaining packets are the file response */
	else {
		guint64 size;
		guint64 offset;
		guint8 compression;

		/* size, digest, compression come from the file request for a pull but
		 * they come from the broadcast for a push. Pushes don't bother
		 * with a file request - they just send the data. We have to get file
		 * info from the offer broadcast which triggered this transfer.
		 * If we cannot find the file request, default to the broadcast. */
		if (transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND &&
		    transfer_info->req != NULL) {
			transfer_info->file = transfer_info->req->file;
			size = transfer_info->req->size;
			offset = transfer_info->req->offset;
			compression = transfer_info->req->compression;
		}
		else {
			transfer_info->file = transfer_info->broadcast->file;
			size = transfer_info->broadcast->size;
			offset = transfer_info->broadcast->offset;
			compression = transfer_info->broadcast->compression;
		}

		/* Remaining data in this TCP connection is all file data.
		 * Always desegment if the size is 0 (ie. unknown)
		 */
		if (pinfo->can_desegment) {
			if (size == 0 || tvb_captured_length(tvb) < size) {
				pinfo->desegment_offset = 0;
				pinfo->desegment_len = DESEGMENT_UNTIL_FIN;
				return 0;
			}
		}

		/* OK. Now we have the whole file that was transferred. */
		transfer_info->resp_num = pinfo->num;
		transfer_info->resp_ts = pinfo->abs_ts;

		col_add_fstr(pinfo->cinfo, COL_INFO, "LDSS File Transfer (Sending file - %s)",
				     transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND
				     ? "pull"
				     : "push");

		if (tree) {
			ti = proto_tree_add_item(tree, proto_ldss,
						 tvb, 0, tvb_reported_length(tvb), ENC_NA);
			ldss_tree = proto_item_add_subtree(ti, ett_ldss_transfer);
			proto_tree_add_bytes_format(ldss_tree, hf_ldss_file_data,
						    tvb, 0, tvb_captured_length(tvb), NULL,
						    compression == COMPRESSION_GZIP
						    ? "Gzip compressed data: %d bytes"
						    : "File data: %d bytes",
						    tvb_captured_length(tvb));
#ifdef HAVE_ZLIB
			/* Be nice and uncompress the file data. */
			if (compression == COMPRESSION_GZIP) {
				tvbuff_t *uncomp_tvb;
				uncomp_tvb = tvb_child_uncompress(tvb, tvb, 0, tvb_captured_length(tvb));
				if (uncomp_tvb != NULL) {
					/* XXX: Maybe not a good idea to add a data_source for
					        what may very well be a large buffer since then
						the full uncompressed buffer will be shown in a tab
						in the hex bytes pane ?
						However, if we don't, bytes in an unrelated tab will
						be highlighted.
					*/
					add_new_data_source(pinfo, uncomp_tvb, "Uncompressed Data");
					proto_tree_add_bytes_format_value(ldss_tree, hf_ldss_file_data,
									  uncomp_tvb, 0, tvb_captured_length(uncomp_tvb),
									  NULL, "Uncompressed data: %d bytes",
									  tvb_captured_length(uncomp_tvb));
				}
			}
#endif
			ti = proto_tree_add_uint(ldss_tree, hf_ldss_digest_type,
						 tvb, 0, 0, transfer_info->file->digest_type);
			PROTO_ITEM_SET_GENERATED(ti);
			if (transfer_info->file->digest != NULL) {
				/* This is ugly. You can't add bytes of nonzero length and have
				 * filtering work correctly unless you give a valid location in
				 * the packet. This hack pretends the first 32 bytes of the packet
				 * are the digest, which they aren't: they're actually the first 32
				 * bytes of the file that was sent. */
				ti = proto_tree_add_bytes(ldss_tree, hf_ldss_digest,
							  tvb, 0, DIGEST_LEN, transfer_info->file->digest);
			}
			PROTO_ITEM_SET_GENERATED(ti);
			ti = proto_tree_add_uint64(ldss_tree, hf_ldss_size,
						   tvb, 0, 0, size);
			PROTO_ITEM_SET_GENERATED(ti);
			ti = proto_tree_add_uint64(ldss_tree, hf_ldss_offset,
						   tvb, 0, 0, offset);
			PROTO_ITEM_SET_GENERATED(ti);
			ti = proto_tree_add_uint(ldss_tree, hf_ldss_compression,
						 tvb, 0, 0, compression);
			PROTO_ITEM_SET_GENERATED(ti);
			/* Link to the request for a pull. */
			if (transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND &&
			    transfer_info->req != NULL &&
			    transfer_info->req->num != 0) {
				ti = proto_tree_add_uint(ldss_tree, hf_ldss_response_to,
							 tvb, 0, 0, transfer_info->req->num);
				PROTO_ITEM_SET_GENERATED(ti);
			}
		}
	}

	/* Print the pull response time */
	if (transfer_info->broadcast->message_id == MESSAGE_ID_WILLSEND &&
	    transfer_info->req != NULL &&
	    transfer_info->resp_num != 0) {
		nstime_t pull_response_time;
		nstime_delta(&pull_response_time, &transfer_info->resp_ts,
			     &transfer_info->req->ts);
		ti = proto_tree_add_time(ldss_tree, hf_ldss_transfer_response_time,
					 tvb, 0, 0, &pull_response_time);
		PROTO_ITEM_SET_GENERATED(ti);
	}

	/* Link the transfer back to the initiating broadcast. Response time is
	 * calculated as the time from broadcast to completed transfer. */
	ti = proto_tree_add_uint(ldss_tree, hf_ldss_initiated_by,
				 tvb, 0, 0, transfer_info->broadcast->num);
	PROTO_ITEM_SET_GENERATED(ti);

	if (transfer_info->resp_num != 0) {
		nstime_delta(&broadcast_response_time, &transfer_info->resp_ts,
			     &transfer_info->broadcast->ts);
		ti = proto_tree_add_time(ldss_tree, hf_ldss_transfer_completed_in,
					 tvb, 0, 0, &broadcast_response_time);
		PROTO_ITEM_SET_GENERATED(ti);
	}

	/* This conv got its addr2/port2 set by the TCP dissector because a TCP
	 * connection was established. Make a new one to handle future connections
	 * to the addr/port mentioned in the broadcast, because that socket is
	 * still open. */
	if (transfer_tcpinfo->seq == 1 &&
	    transfer_tcpinfo->lastackseq == 1) {

		prepare_ldss_transfer_conv(transfer_info->broadcast);
	}

	return tvb_captured_length(tvb);
}
Example #8
0
static void
dissect_imap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
  gboolean        is_request;
  proto_tree      *imap_tree, *reqresp_tree;
  proto_item      *ti, *hidden_item;
  gint            offset = 0;
  gint            uid_offset = 0;
  gint            folder_offset = 0;
  const guchar    *line;
  const guchar    *uid_line;
  const guchar    *folder_line;
  gint            next_offset;
  int             linelen;
  int             tokenlen;
  int             uid_tokenlen;
  int             folder_tokenlen;
  const guchar    *next_token;
  const guchar    *uid_next_token;
  const guchar    *folder_next_token;
  guchar          *tokenbuf;
  guchar          *command_token;
  int             iter;
  int             commandlen;
  conversation_t *conversation;
  imap_state_t   *session_state;

  conversation = find_or_create_conversation(pinfo);
  session_state = (imap_state_t *)conversation_get_proto_data(conversation, proto_imap);
  if (!session_state) {
    session_state = wmem_new0(wmem_file_scope(), imap_state_t);
    session_state->ssl_requested = FALSE;
    conversation_add_proto_data(conversation, proto_imap, session_state);
  }

  tokenbuf = (guchar *)wmem_alloc0(wmem_packet_scope(), MAX_BUFFER);
  command_token = (guchar *)wmem_alloc0(wmem_packet_scope(), MAX_BUFFER);
  commandlen = 0;
  folder_offset = 0;
  folder_tokenlen = 0;
  folder_line = NULL;
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "IMAP");


  if (pinfo->match_uint == pinfo->destport)
    is_request = TRUE;
  else
    is_request = FALSE;

  /*
   * Put the first line from the buffer into the summary
   * (but leave out the line terminator).
   */
  linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
  line = tvb_get_ptr(tvb, offset, linelen);

  col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s", is_request ? "Request" : "Response", format_text(line, linelen));

  {
    ti = proto_tree_add_item(tree, proto_imap, tvb, offset, -1, ENC_NA);
    imap_tree = proto_item_add_subtree(ti, ett_imap);

    hidden_item = proto_tree_add_boolean(imap_tree, hf_imap_isrequest, tvb, 0, 0, is_request);
    PROTO_ITEM_SET_HIDDEN(hidden_item);

    while(tvb_offset_exists(tvb, offset)) {

      /*
       * Find the end of each line
       *
       * Note that "tvb_find_line_end()" will return a value that is
       * not longer than what's in the buffer, so the "tvb_get_ptr()"
       * call won't throw an exception.
       */
      linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE);
      line = tvb_get_ptr(tvb, offset, linelen);

      /*
       * Put the line into the protocol tree.
       */
      ti = proto_tree_add_item(imap_tree, hf_imap_line, tvb, offset, next_offset - offset, ENC_ASCII|ENC_NA);

      reqresp_tree = proto_item_add_subtree(ti, ett_imap_reqresp);

      /*
       * Check that the line doesn't begin with '*', because that's a continuation line.
       * Otherwise if a tag is present then extract tokens.
       */
      if ( (line) && ((line[0] != '*') || (TRUE == is_request)) ) {
        /*
         * Show each line as tags + requests or replies.
         */

        /*
         * Extract the first token, and, if there is a first
         * token, add it as the request or reply tag.
         */
        tokenlen = get_token_len(line, line + linelen, &next_token);
        if (tokenlen != 0) {
          proto_tree_add_item(reqresp_tree, (is_request) ? hf_imap_request_tag : hf_imap_response_tag, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);

          offset += (gint) (next_token - line);
          linelen -= (int) (next_token - line);
          line = next_token;
        }

        /*
         * Extract second token, and, if there is a second
         * token, and it's not uid, add it as the request or reply command.
         */
        tokenlen = get_token_len(line, line + linelen, &next_token);
        if (tokenlen != 0) {
          for (iter = 0; iter < tokenlen && iter < MAX_BUFFER-1; iter++) {
            tokenbuf[iter] = g_ascii_tolower(line[iter]);
          }
          if (tree && is_request && strncmp(tokenbuf, "uid", tokenlen) == 0) {
            proto_tree_add_item(reqresp_tree, hf_imap_request_uid, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);
            /*
             * UID is a precursor to a command, if following the tag,
              * so move to next token to grab the actual command.
              */
            uid_offset = offset;
            uid_offset += (gint) (next_token - line);
            uid_line = next_token;
            uid_tokenlen = get_token_len(uid_line, uid_line + (linelen - tokenlen), &uid_next_token);
            if (tokenlen != 0) {
              proto_tree_add_item(reqresp_tree, hf_imap_request_command, tvb, uid_offset, uid_tokenlen, ENC_ASCII|ENC_NA);

              /*
               * Save command string to do specialized processing.
               */
              for (iter = 0; iter < uid_tokenlen && iter < MAX_BUFFER-1; iter++) {
                command_token[iter] = g_ascii_tolower(uid_line[iter]);
              }
              commandlen = uid_tokenlen;

              folder_offset = uid_offset;
              folder_offset += (gint) (uid_next_token - uid_line);
              folder_line = uid_next_token;
              folder_tokenlen = get_token_len(folder_line, folder_line + (linelen - tokenlen - uid_tokenlen), &folder_next_token);
            }
          } else {
            /*
             * Not a UID request so perform normal parsing.
             */
            proto_tree_add_item(reqresp_tree, (is_request) ? hf_imap_request_command : hf_imap_response_status, tvb, offset, tokenlen, ENC_ASCII|ENC_NA);

            if (is_request) {
              /*
               * Save command string to do specialized processing.
               */
              for (iter = 0; iter < tokenlen && iter < 256; iter++) {
                command_token[iter] = g_ascii_tolower(line[iter]);
              }
              commandlen = tokenlen;

              folder_offset = offset;
              folder_offset += (gint) (next_token - line);
              folder_line = next_token;
              folder_tokenlen = get_token_len(folder_line, folder_line + (linelen - tokenlen - 1), &folder_next_token);
            }
          }

          if (tree && commandlen > 0 && (
              strncmp(command_token, "select", commandlen) == 0 ||
              strncmp(command_token, "examine", commandlen) == 0 ||
              strncmp(command_token, "create", commandlen) == 0 ||
              strncmp(command_token, "delete", commandlen) == 0 ||
              strncmp(command_token, "rename", commandlen) == 0 ||
              strncmp(command_token, "subscribe", commandlen) == 0 ||
              strncmp(command_token, "unsubscribe", commandlen) == 0 ||
              strncmp(command_token, "status", commandlen) == 0 ||
              strncmp(command_token, "append", commandlen) == 0 ||
              strncmp(command_token, "search", commandlen) == 0)) {
            /*
             * These commands support folder as an argument,
             * so parse out the folder name.
             */
            if (folder_tokenlen != 0)
              proto_tree_add_item(reqresp_tree, hf_imap_request_folder, tvb, folder_offset, folder_tokenlen, ENC_ASCII|ENC_NA);
          }

          if (tree && is_request && (NULL != folder_line) && strncmp(command_token, "copy", commandlen) == 0) {
            /*
             * Handle the copy command separately since folder
             * is the second argument for this command.
             */
            folder_offset += (gint) (folder_next_token - folder_line);
            folder_line = folder_next_token;
            folder_tokenlen = get_token_len(folder_line, folder_line + (linelen - tokenlen), &folder_next_token);

            if (folder_tokenlen != 0)
              proto_tree_add_item(reqresp_tree, hf_imap_request_folder, tvb, folder_offset, folder_tokenlen, ENC_ASCII|ENC_NA);
          }

          /* If not yet switched to TLS, check for STARTTLS. */
          if (session_state->ssl_requested) {
            if (!is_request && session_state->ssl_requested &&
              strncmp(tokenbuf, "ok", tokenlen) == 0) {
              /* STARTTLS accepted, next reply will be TLS. */
              ssl_starttls_ack(ssl_handle, pinfo, imap_handle);
            }
            session_state->ssl_requested = FALSE;
          }
          if (is_request && commandlen > 0 &&
            strncmp(command_token, "starttls", commandlen) == 0) {
            /* If next response is OK, then TLS should be commenced. */
            session_state->ssl_requested = TRUE;
          }
        }

        /*
         * Add the rest of the line as request or reply data.
         */
        if (linelen != 0) {
          proto_tree_add_item(reqresp_tree, (is_request) ? hf_imap_request : hf_imap_response, tvb, offset, linelen, ENC_ASCII|ENC_NA);
        }

      }

      offset = next_offset; /* Skip over last line and \r\n at the end of it */
    }
  }
}
Example #9
0
static void
wmem_test_allocator(wmem_allocator_type_t type, wmem_verify_func verify,
        int iterations)
{
    int i;
    char *ptrs[MAX_SIMULTANEOUS_ALLOCS];
    wmem_allocator_t *allocator;

    allocator = wmem_allocator_force_new(type);

    if (verify) (*verify)(allocator);

    /* start with some fairly simple deterministic tests */

    wmem_test_allocator_det(allocator, verify, 8);

    wmem_test_allocator_det(allocator, verify, 64);

    wmem_test_allocator_det(allocator, verify, 512);

    for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
        ptrs[i] = wmem_alloc0_array(allocator, char, 32);
    }

    if (verify) (*verify)(allocator);
    wmem_free_all(allocator);
    wmem_gc(allocator);
    if (verify) (*verify)(allocator);

    /* now do some random fuzz-like tests */

    /* reset our ptr array */
    for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
        ptrs[i] = NULL;
    }

    /* Run enough iterations to fill the array 32 times */
    for (i=0; i<iterations; i++) {
        gint ptrs_index;
        gint new_size;

        /* returns value 0 <= x < MAX_SIMULTANEOUS_ALLOCS which is a valid
         * index into ptrs */
        ptrs_index = g_test_rand_int_range(0, MAX_SIMULTANEOUS_ALLOCS);

        if (ptrs[ptrs_index] == NULL) {
            /* if that index is unused, allocate some random amount of memory
             * between 0 and MAX_ALLOC_SIZE */
            new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE);

            ptrs[ptrs_index] = (char *) wmem_alloc0(allocator, new_size);
        }
        else if (g_test_rand_bit()) {
            /* the index is used, and our random bit has determined we will be
             * reallocating instead of freeing. Do so to some random size
             * between 0 and MAX_ALLOC_SIZE, then manually zero the
             * new memory */
            new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE);

            ptrs[ptrs_index] = (char *) wmem_realloc(allocator,
                    ptrs[ptrs_index], new_size);

            memset(ptrs[ptrs_index], 0, new_size);
        }
        else {
            /* the index is used, and our random bit has determined we will be
             * freeing instead of reallocating. Do so and NULL the pointer for
             * the next iteration. */
            wmem_free(allocator, ptrs[ptrs_index]);
            ptrs[ptrs_index] = NULL;
        }
        if (verify) (*verify)(allocator);
    }

    wmem_destroy_allocator(allocator);
}
Example #10
0
/* Code to actually dissect the packets */
static void
dissect_mtp3(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    mtp3_tap_rec_t* tap_rec = ep_new0(mtp3_tap_rec_t);
    gint heuristic_standard;
    guint8 si;

    /* Set up structures needed to add the protocol subtree and manage it */
    proto_item *mtp3_item = NULL, *gen_item;
    proto_tree *mtp3_tree = NULL;

    pref_mtp3_standard = mtp3_standard;

    mtp3_item = proto_tree_add_item(tree, proto_mtp3, tvb, 0, 0, ENC_NA);

    si = tvb_get_guint8(tvb, SIO_OFFSET) & SERVICE_INDICATOR_MASK;
    if (mtp3_heuristic_standard) {
	heuristic_standard = heur_mtp3_standard(tvb, pinfo, si);
	if (heuristic_standard == HEURISTIC_FAILED_STANDARD) {
	    gen_item = proto_tree_add_text(tree, tvb, 0, 0, "Could not determine Heuristic using %s", val_to_str_const(mtp3_standard, mtp3_standard_vals, "unknown"));
	} else {
	    gen_item = proto_tree_add_text(tree, tvb, 0, 0, "%s", val_to_str_const(heuristic_standard, mtp3_standard_vals, "unknown"));
	    mtp3_standard = heuristic_standard;

	    /* Register a frame-end routine to ensure mtp3_standard is set
	     * back even if an exception is thrown.
	     */
	    register_frame_end_routine(pinfo, reset_mtp3_standard);
	}
	PROTO_ITEM_SET_GENERATED(gen_item);
    }

    /* Make entries in Protocol column on summary display */
    switch(mtp3_standard) {
    case ITU_STANDARD:
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (Int. ITU)");
	proto_item_set_len(mtp3_item, ITU_HEADER_LENGTH);
	break;
    case ANSI_STANDARD:
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (ANSI)");
	proto_item_set_len(mtp3_item, ANSI_HEADER_LENGTH);
	break;
    case CHINESE_ITU_STANDARD:
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (Chin. ITU)");
	proto_item_set_len(mtp3_item, ANSI_HEADER_LENGTH);
	break;
    case JAPAN_STANDARD:
	col_set_str(pinfo->cinfo, COL_PROTOCOL, "MTP3 (Japan)");
	proto_item_set_len(mtp3_item, JAPAN_HEADER_LENGTH);
	break;
    };

    if (tree) {
	/* create display subtree for the protocol */
	mtp3_tree = proto_item_add_subtree(mtp3_item, ett_mtp3);
    }

    mtp3_addr_opc = (mtp3_addr_pc_t *)wmem_alloc0(pinfo->pool, sizeof(mtp3_addr_pc_t));
    mtp3_addr_dpc = (mtp3_addr_pc_t *)wmem_alloc0(pinfo->pool, sizeof(mtp3_addr_pc_t));

    /* Dissect the packet (even if !tree so can call sub-dissectors and update
     * the source and destination address columns) */
    dissect_mtp3_sio(tvb, mtp3_tree);
    dissect_mtp3_routing_label(tvb, pinfo, mtp3_tree);

    memcpy(&(tap_rec->addr_opc), mtp3_addr_opc, sizeof(mtp3_addr_pc_t));
    memcpy(&(tap_rec->addr_dpc), mtp3_addr_dpc, sizeof(mtp3_addr_pc_t));

    tap_rec->si_code = (tvb_get_guint8(tvb, SIO_OFFSET) & SERVICE_INDICATOR_MASK);
    tap_rec->size = tvb_length(tvb);

    tap_queue_packet(mtp3_tap, pinfo, tap_rec);

    dissect_mtp3_payload(tvb, pinfo, tree);

    mtp3_standard = pref_mtp3_standard;
}
Example #11
0
static gint ett_http = -1;
static int proto_http = -1;

static int hf_http_is_response = -1;
static int hf_http_request_method = -1;
static int hf_http_response_code = -1;
static int hf_http_transfer_encoding = -1;
static int hf_http_content_length = -1;
static int hf_http_media = -1;
static int hf_http_host = -1;
static int hf_http_request_uri = -1;

static dissector_handle_t http_handle;

static int dissect_http(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree, void* data _U_) {
    http_info_value_t* msgdata = wmem_alloc0(wmem_packet_scope(), sizeof(http_info_value_t));
    tvbparse_elem_t* reqresp;
    tpg_parser_data_t* tpg;
    proto_item* pi = proto_tree_add_item(tree,proto_http,tvb,0,-1,ENC_NA);
    proto_tree* pt = proto_item_add_subtree(pi,ett_http);

    tpg = tpg_start(pt,tvb,0,-1,http_tpg_data.wanted_http_sp, msgdata);

    if (( reqresp = TPG_GET(tpg,http_tpg_data.wanted_http_req_resp) )) {
        tvbparse_elem_t* hdr;

        while(( hdr = TPG_GET(tpg,http_tpg_data.wanted_http_header) ))
            ;

        if ( TPG_GET(tpg,http_tpg_data.wanted_http_crlf) ) {
            pi = proto_tree_add_boolean(pt,hf_http_is_response,tvb,0,0,msgdata->is_response);
Example #12
0
static void
dissect_ssh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{

	proto_tree	*ssh_tree = NULL;
	proto_item	*ti;
	conversation_t *conversation;
	int		last_offset, offset = 0;

	gboolean	is_response = (pinfo->destport != pinfo->match_uint),
				need_desegmentation;
	guint		version;

	struct ssh_flow_data *global_data=NULL;
	struct ssh_peer_data *peer_data;

	conversation = find_or_create_conversation(pinfo);

	global_data = (struct ssh_flow_data *)conversation_get_proto_data(conversation, proto_ssh);
	if (!global_data) {
		global_data = (struct ssh_flow_data *)wmem_alloc0(wmem_file_scope(), sizeof(struct ssh_flow_data));
		global_data->version=SSH_VERSION_UNKNOWN;
		global_data->kex_specific_dissector=ssh_dissect_kex_dh;
		global_data->peer_data[CLIENT_PEER_DATA].mac_length=-1;
		global_data->peer_data[SERVER_PEER_DATA].mac_length=-1;

		conversation_add_proto_data(conversation, proto_ssh, global_data);
	}

	peer_data = &global_data->peer_data[is_response];

	if (tree) {
		  ti = proto_tree_add_item(tree, proto_ssh, tvb, offset, -1, ENC_NA);
		  ssh_tree = proto_item_add_subtree(ti, ett_ssh);
	}

	version = global_data->version;

	switch(version) {
		case SSH_VERSION_UNKNOWN:
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSH");
			break;
		case SSH_VERSION_1:
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv1");
			break;
		case SSH_VERSION_2:
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "SSHv2");
			break;

	}

	col_clear(pinfo->cinfo, COL_INFO);

	while(tvb_reported_length_remaining(tvb, offset)> 0) {
		gboolean after_version_start = (peer_data->frame_version_start == 0 ||
			pinfo->fd->num >= peer_data->frame_version_start);
		gboolean before_version_end = (peer_data->frame_version_end == 0 ||
			pinfo->fd->num <= peer_data->frame_version_end);

		need_desegmentation = FALSE;
		last_offset = offset;

		peer_data->counter++;

		if (after_version_start && before_version_end &&
			  (tvb_strncaseeql(tvb, offset, "SSH-", 4) == 0)) {
			if (peer_data->frame_version_start == 0)
				peer_data->frame_version_start = pinfo->fd->num;

			offset = ssh_dissect_protocol(tvb, pinfo,
					global_data,
					offset, ssh_tree, is_response,
					&version, &need_desegmentation);

			if (!need_desegmentation) {
				peer_data->frame_version_end = pinfo->fd->num;
				global_data->version = version;
			}
		} else {
			switch(version) {

			case SSH_VERSION_UNKNOWN:
				offset = ssh_dissect_encrypted_packet(tvb, pinfo,
						&global_data->peer_data[is_response], offset, ssh_tree);
				break;

			case SSH_VERSION_1:
				offset = ssh_dissect_ssh1(tvb, pinfo, global_data,
						offset, ssh_tree, is_response,
						&need_desegmentation);
				break;

			case SSH_VERSION_2:
				offset = ssh_dissect_ssh2(tvb, pinfo, global_data,
						offset, ssh_tree, is_response,
						&need_desegmentation);
				break;
			}
		}

		if (need_desegmentation)
			return;
		if (offset <= last_offset)
			THROW(ReportedBoundsError);
	}

	col_prepend_fstr(pinfo->cinfo, COL_INFO, "%s: ", is_response ? "Server" : "Client");
}
int decompress_packet (const guint8 *in, gint in_length, guint8 *out, guint *out_length)
{
	class CsObjectInt csObject;
	int rt = 0, finished = false;
	SAP_BYTE *bufin = NULL, *bufin_pos = NULL, *bufout = NULL, *bufout_pos = NULL;
	SAP_INT bufin_length = 0, bufin_rest = 0, bufout_length = 0, bufout_rest = 0, data_length = 0, bytes_read = 0, bytes_decompressed = 0, total_decompressed = 0;

#ifdef DEBUG
	printf("sapdecompress.cpp: Decompressing (%d bytes, reported length of %d bytes)...\n", in_length, *out_length);
#endif

	/* Check for invalid inputs */
	if (in == NULL)
		return (CS_E_INVALID_ADDR);
	if (in_length <= 0)
		return (CS_E_IN_BUFFER_LEN);
	if (out == NULL)
		return (CS_E_INVALID_ADDR);
	if (*out_length <= 0)
		return (CS_E_OUT_BUFFER_LEN);

	/* Allocate buffers */
	bufin_length = bufin_rest = (SAP_INT)in_length;
	bufin = bufin_pos = (SAP_BYTE*) wmem_alloc0(wmem_packet_scope(), in_length);
	if (!bufin){
		return (CS_E_MEMORY_ERROR);
	}

	/* Copy the in parameter into the buffer */
	for (int i = 0; i < in_length; i++) {
		bufin[i] = (SAP_BYTE) in[i];
	}

	/* Initialize and obtain the reported uncompressed data length */
	rt = csObject.CsInitDecompr(bufin);
	if (rt != 0){
#ifdef DEBUG
		printf("sapdecompress.cpp: Initialization failed !\n");
#endif
		wmem_free(wmem_packet_scope(), bufin);
		*out_length = 0;
		return (rt);
	}

	/* Check the length in the header vs the reported one */
	data_length = csObject.CsGetLen(bufin);
	if (data_length != (SAP_INT)*out_length){
#ifdef DEBUG
		printf("sapdecompress.cpp: Length reported (%d) doesn't match with the one in the header (%d)\n", *out_length, data_length);
#endif
		wmem_free(wmem_packet_scope(), bufin);
		*out_length = 0;
		return (CS_E_OUT_BUFFER_LEN);
	}

	/* Advance the buffer pointer as we've already read the header */
	bufin_pos += CS_HEAD_SIZE;

#ifdef DEBUG
	printf("sapdecompress.cpp: Initialized, reported length in header: %d bytes\n", data_length);
#endif

	/* Allocate the output buffer. We use the reported output size
	 * as the output buffer size.
	 */
	bufout_length = bufout_rest = *out_length;
	bufout = bufout_pos = (SAP_BYTE*) wmem_alloc0(wmem_packet_scope(), bufout_length);
	if (!bufout){
		*out_length = 0;
		wmem_free(wmem_packet_scope(), bufin);
		return (CS_E_MEMORY_ERROR);
	}
	memset(bufout, 0, bufout_length);

#ifdef DEBUG_TRACE
	printf("sapdecompress.cpp: Input buffer %p (%d bytes), output buffer %p (%d bytes)\n", bufin, bufin_length, bufout, bufout_length);
#endif

	while (finished == false && bufin_rest > 0 && bufout_rest > 0) {

#ifdef DEBUG_TRACE
		printf("sapdecompress.cpp: Input position %p (rest %d bytes), output position %p\n", bufin_pos, bufin_rest, bufout_pos);
#endif
		rt = csObject.CsDecompr(bufin_pos, bufin_rest, bufout_pos, bufout_rest, 0, &bytes_read, &bytes_decompressed);

#ifdef DEBUG
		printf("sapdecompress.cpp: Return code %d (%s) (%d bytes read, %d bytes decompressed)\n", rt, decompress_error_string(rt), bytes_read, bytes_decompressed);
#endif

		/* Successful decompression, we've finished with the stream */
		if (rt == CS_END_OF_STREAM){
			finished = true;
		}
		/* Some error occurred */
		if (rt != CS_END_INBUFFER && rt != CS_END_OUTBUFFER){
			finished = true;
		}

		/* Advance the input buffer */
		bufin_pos += bytes_read;
		bufin_rest -= bytes_read;
		/* Advance the output buffer */
		bufout_pos += bytes_decompressed;
		bufout_rest -= bytes_decompressed;
		total_decompressed += bytes_decompressed;

	}

	/* Successful decompression */
	if (rt == CS_END_OF_STREAM) {
		*out_length = total_decompressed;

		/* Copy the buffer in the out parameter */
		for (int i = 0; i < total_decompressed; i++)
			(out)[i] = (char) bufout[i];

#ifdef DEBUG_TRACE
		    printf("sapdecompress.cpp: Out buffer:\n");
			hexdump(out, total_decompressed);
#endif

	}

	/* Free the buffers */
	wmem_free(wmem_packet_scope(), bufin); wmem_free(wmem_packet_scope(), bufout);

#ifdef DEBUG
	printf("sapdecompress.cpp: Out Length: %d\n", *out_length);
#endif

	return (rt);
};