Example #1
0
static gboolean
val_from_unparsed(fvalue_t *fv, char *s, gboolean allow_partial_value _U_, LogFunc logfunc)
{
	fvalue_t *fv_bytes;
	tvbuff_t *new_tvb;
	guint8 *private_data;

	/* Free up the old value, if we have one */
	value_free(fv);

	/* Does this look like a byte string? */
	fv_bytes = fvalue_from_unparsed(FT_BYTES, s, TRUE, NULL);
	if (fv_bytes) {
		/* Make a tvbuff from the bytes */
		private_data = (guint8 *)g_memdup(fv_bytes->value.bytes->data,
				fv_bytes->value.bytes->len);
		new_tvb = tvb_new_real_data(private_data,
				fv_bytes->value.bytes->len,
				fv_bytes->value.bytes->len);

		/* Let the tvbuff know how to delete the data. */
		tvb_set_free_cb(new_tvb, free_tvb_data);

		/* And let us know that we need to free the tvbuff */
		fv->tvb_is_private = TRUE;
		fv->value.tvb = new_tvb;
		return TRUE;
	}

	/* Treat it as a string. */
	return val_from_string(fv, s, logfunc);
}
Example #2
0
/*
 * ByteArray_tvb(name)
 */
WSLUA_CONSTRUCTOR ByteArray_tvb (lua_State *L) {
	/* Creates a new Tvb from a bytearray (it gets added to the current frame too) */
#define WSLUA_ARG_ByteArray_tvb_NAME 2 /* The name to be given to the new data-source. */
    ByteArray ba = checkByteArray(L,1);
    const gchar* name = luaL_optstring(L,WSLUA_ARG_ByteArray_tvb_NAME,"Unnamed") ;
    guint8* data;
    Tvb tvb;

    if (!ba) return 0;

    if (!lua_tvb) {
        luaL_error(L,"Tvbs can only be created and used in dissectors");
        return 0;
    }

    data = (guint8 *)g_memdup(ba->data, ba->len);

    tvb = (Tvb)g_malloc(sizeof(struct _wslua_tvb));
    tvb->ws_tvb = tvb_new_real_data(data, ba->len,ba->len);
    tvb->expired = FALSE;
    tvb->need_free = TRUE;
    tvb_set_free_cb(tvb->ws_tvb, g_free);

    add_new_data_source(lua_pinfo, tvb->ws_tvb, name);
    PUSH_TVB(L,tvb);
    WSLUA_RETURN(1); /* The created Tvb. */
}
int main(int argc, char **argv)
{
    frame_data fd;
    char src[] = {1,2,3,4}, dst[] = {5,6,7,8};
    unsigned int i;
    void (*tests[])(void) = {
        test_simple_fragment_add_seq,
        test_fragment_add_seq_partial_reassembly,
        test_fragment_add_dcerpc_dg,
        test_fragment_add_seq_check,
        test_fragment_add_seq_check_1,
        test_fragment_add_seq_802_11_0,
        test_fragment_add_seq_802_11_1,
        test_simple_fragment_add_seq_next,
        test_missing_data_fragment_add_seq_next,
        test_missing_data_fragment_add_seq_next_2,
        test_missing_data_fragment_add_seq_next_3
    };

    /* we don't use our params */
    argc=argc;
    argv=argv;

    /* initialise stuff */
    ep_init_chunk();
    tvbuff_init();
    reassemble_init();

    /* a tvbuff for testing with */
    data = g_malloc(DATA_LEN);
    /* make sure it's full of stuff */
    for(i=0; i<DATA_LEN; i++) {
        data[i]=i & 0xFF;
    }
    tvb = tvb_new_real_data(data, DATA_LEN, DATA_LEN*2);

    /* other test stuff */
    pinfo.fd = &fd;
    fd.flags.visited = 0;
    SET_ADDRESS(&pinfo.src,AT_IPv4,4,src);
    SET_ADDRESS(&pinfo.dst,AT_IPv4,4,dst);

    /*************************************************************************/
    for(i=0; i < sizeof(tests)/sizeof(tests[0]); i++ ) {
        /* re-init the fragment tables */
        fragment_table_init(&fragment_table);
        ASSERT(fragment_table != NULL);

        reassembled_table_init(&reassembled_table);
        ASSERT(reassembled_table != NULL);

        pinfo.fd->flags.visited = FALSE;

        tests[i]();
    }

    printf(failure?"FAILURE\n":"SUCCESS\n");
    return failure;
}
Example #4
0
static int
dissect_bmc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
    guint8 message_type;
    guint8 *p_rev, *reversing_buffer;
    gint offset = 0;
    gint i, len;
    proto_item *ti;
    proto_tree *bmc_tree;
    tvbuff_t *bit_reversed_tvb;

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

    ti = proto_tree_add_item(tree, proto_bmc, tvb, 0, -1, ENC_NA);
    bmc_tree = proto_item_add_subtree(ti, ett_bmc);

    /* Needs bit-reversing. Create a new buffer, copy the message to it and bit-reverse */
    len = tvb_length(tvb);
    reversing_buffer = se_alloc(len);
    memcpy(reversing_buffer, tvb_get_ptr(tvb, offset, -1), len);
    
    p_rev = reversing_buffer;
    /* Entire message is bit reversed */
    for (i=0; i<len; i++, p_rev++)
        *p_rev = BIT_SWAP(*p_rev);

    /* Make this new buffer part of the display and provide a way to dispose of it */
    bit_reversed_tvb = tvb_new_real_data(reversing_buffer, len, len);
    tvb_set_child_real_data_tvbuff(tvb, bit_reversed_tvb);
    add_new_data_source(pinfo, bit_reversed_tvb, "Bit-reversed Data");

    message_type = tvb_get_guint8(bit_reversed_tvb, offset);
    proto_tree_add_item(bmc_tree, hf_bmc_message_type, bit_reversed_tvb, offset, 1, ENC_BIG_ENDIAN);
    offset++;
    col_add_fstr(pinfo->cinfo, COL_INFO, "%s", val_to_str(message_type, message_type_vals,"Reserved 0x%02x"));

    switch (message_type) {
        case MESSAGE_TYPE_CBS_MESSAGE:
            offset = dissect_bmc_cbs_message(bit_reversed_tvb, pinfo, bmc_tree);
            break;

        case MESSAGE_TYPE_SCHEDULE_MESSAGE:
            offset = dissect_bmc_schedule_message(bit_reversed_tvb, pinfo, bmc_tree);
            break;

        case MESSAGE_TYPE_CBS41_MESSAGE:
            offset = dissect_bmc_cbs41_message(bit_reversed_tvb, pinfo, bmc_tree);
            break;

        default:
            break;
    }
    
    return offset;
}
Example #5
0
tvbuff_t *
tvb_new_proxy(tvbuff_t *backing)
{
	tvbuff_t *tvb;
	
	if (backing)
		tvb = tvb_new_with_subset(backing, backing->reported_length, 0, backing->length);
	else
		tvb = tvb_new_real_data(NULL, 0, 0);

	tvb->ds_tvb = tvb;

	return tvb;
}
Example #6
0
static void dissect_gwtb_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	gwtb_info_t *info_ptr = (gwtb_info_t*) p_get_proto_data(pinfo->fd, proto_gwtb, 0);
	tvbuff_t *next_tvb;
	proto_item *gwtb_item = NULL;
	proto_tree *gwtb_tree = NULL;
	guint32 offset = 0;
	guint32 length = tvb_length(tvb);
	guint16 size;

	if (!info_ptr->data) {
		info_ptr->auth = FALSE;
		info_ptr->data = (guchar*) se_alloc(length);
		tvb_memcpy(tvb, info_ptr->data, offset, length);
		crypt_rc4(info_ptr->rc4, info_ptr->data, length);
	}

	next_tvb = tvb_new_real_data(info_ptr->data, length, length);
	tvb_set_child_real_data_tvbuff(tvb, next_tvb);
	add_new_data_source(pinfo, next_tvb, "Data");
	length = tvb_length(next_tvb);

	if (check_col(pinfo->cinfo, COL_PROTOCOL))
		col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_TAG_GWTB);

	if (check_col(pinfo->cinfo, COL_INFO)) {
		col_clear(pinfo->cinfo, COL_INFO);
		col_add_fstr(pinfo->cinfo, COL_INFO, "%d > %d - %s", 
			pinfo->srcport, 
			pinfo->destport, 
				(pinfo->match_port == pinfo->destport || TCP_PORT_GWTB == pinfo->destport) ? "Request" : "Response"
		);
	}

	if (tree) { /* we are being asked for details */
		while(offset < length) {
			gwtb_item = proto_tree_add_item(tree, proto_gwtb, next_tvb, offset, length-offset, FALSE);
			gwtb_tree = proto_item_add_subtree(gwtb_item, ett_gwtb);

			size = tvb_get_ntohs(next_tvb, offset);

			proto_tree_add_item(gwtb_tree, hf_length, next_tvb, offset, FRAME_HEADER_LEN, FALSE);
			offset += FRAME_HEADER_LEN;

			proto_tree_add_item(gwtb_tree, hf_string, next_tvb, offset, size, FALSE);
			offset += size;
		}
	}
}
Example #7
0
static gboolean dissect_xml_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
	if (pref_heuristic_media || pref_heuristic_tcp || pref_heuristic_udp) {
		if (tvbparse_peek(tvbparse_init(tvb,0,-1,NULL,want_ignore), want_heur)) {
			dissect_xml(tvb, pinfo, tree);
			return TRUE;
		} else if (pref_heuristic_unicode) {
			const guint8 *data = tvb_get_ephemeral_faked_unicode(tvb, 0, tvb_length(tvb)/2, TRUE);
			tvbuff_t *unicode_tvb = tvb_new_real_data(data, tvb_length(tvb)/2, tvb_length(tvb)/2);
			if (tvbparse_peek(tvbparse_init(unicode_tvb,0,-1,NULL,want_ignore), want_heur)) {
				dissect_xml(unicode_tvb, pinfo, tree);
				return TRUE;
			}
		}
	}
	return FALSE;
}
static tvbuff_t *
tvb_unmasked(tvbuff_t *tvb, packet_info *pinfo, const guint offset, guint payload_length, const guint8 *masking_key)
{

  gchar        *data_unmask;
  guint         i;
  const guint8 *data_mask;
  guint         unmasked_length = payload_length > MAX_UNMASKED_LEN ? MAX_UNMASKED_LEN : payload_length;

  data_unmask = (gchar *)wmem_alloc(pinfo->pool, unmasked_length);
  data_mask   = tvb_get_ptr(tvb, offset, unmasked_length);
  /* Unmasked(XOR) Data... */
  for(i=0; i < unmasked_length; i++) {
    data_unmask[i] = data_mask[i] ^ masking_key[i%4];
  }

  return tvb_new_real_data(data_unmask, unmasked_length, payload_length);
}
Example #9
0
tvbuff_t *
tvb_unmasked(tvbuff_t *tvb, const int offset, int payload_length, const guint8 *masking_key)
{

  gchar *data_unmask;
  tvbuff_t  *tvb_unmask    = NULL;
  int i;
  const guint8 *data_mask;
  int unmasked_length = payload_length > MAX_UNMASKED_LEN ? MAX_UNMASKED_LEN : payload_length;

  data_unmask = g_malloc(unmasked_length);
  data_mask = tvb_get_ptr(tvb, offset, unmasked_length);
  /* Unmasked(XOR) Data... */
  for(i=0; i < unmasked_length; i++){
    data_unmask[i] = data_mask[i] ^ masking_key[i%4];
  }

  tvb_unmask = tvb_new_real_data(data_unmask, unmasked_length, unmasked_length);
  tvb_set_free_cb(tvb_unmask, g_free);
  return tvb_unmask;
}
Example #10
0
static gboolean
val_from_string(fvalue_t *fv, char *s, LogFunc logfunc _U_)
{
	tvbuff_t *new_tvb;
	guint8 *private_data;

	/* Free up the old value, if we have one */
	value_free(fv);

	/* Make a tvbuff from the string. We can drop the
	 * terminating NUL. */
	private_data = (guint8 *)g_memdup(s, (guint)strlen(s));
	new_tvb = tvb_new_real_data(private_data,
			(guint)strlen(s), (gint)strlen(s));

	/* Let the tvbuff know how to delete the data. */
	tvb_set_free_cb(new_tvb, free_tvb_data);

	/* And let us know that we need to free the tvbuff */
	fv->tvb_is_private = TRUE;
	fv->value.tvb = new_tvb;
	return TRUE;
}
Example #11
0
static fragment_head *
force_reassemble_seq(reassembly_table *table, packet_info *pinfo, guint32 id)
{
	fragment_head *fd_head;
	fragment_item *fd_i;
	fragment_item *last_fd;
	guint32 dfpos, size, packet_lost, burst_lost, seq_num;
	guint8 *data;

	fd_head = fragment_get(table, pinfo, id, NULL);

	/* have we already seen this frame ?*/
	if (pinfo->fd->flags.visited) {
		if (fd_head != NULL && fd_head->flags & FD_DEFRAGMENTED) {
			return fd_head;
		} else {
			return NULL;
		}
	}

	if (fd_head==NULL){
		/* we must have it to continue */
		return NULL;
	}

	/* check for packet lost and count the burst of packet lost */
	packet_lost = 0;
	burst_lost = 0;
	seq_num = 0;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
		if (seq_num != fd_i->offset) {
			packet_lost += fd_i->offset - seq_num;
			if ( (fd_i->offset - seq_num) > burst_lost ) {
				burst_lost = fd_i->offset - seq_num;
			}
		}
		seq_num = fd_i->offset + 1;
	}

	/* we have received an entire packet, defragment it and
	 * free all fragments
	 */
	size=0;
	last_fd=NULL;
	for(fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(!last_fd || last_fd->offset!=fd_i->offset){
	    size+=fd_i->len;
	  }
	  last_fd=fd_i;
	}

	data = (guint8 *) g_malloc(size);
	fd_head->tvb_data = tvb_new_real_data(data, size, size);
	fd_head->len = size;		/* record size for caller	*/

	/* add all data fragments */
	dfpos = 0;
	last_fd=NULL;
	for (fd_i=fd_head->next;fd_i && fd_i->len + dfpos <= size;fd_i=fd_i->next) {
	  if (fd_i->len) {
	    if(!last_fd || last_fd->offset!=fd_i->offset){
	      memcpy(data+dfpos,tvb_get_ptr(fd_i->tvb_data,0,fd_i->len),fd_i->len);
	      dfpos += fd_i->len;
	    } else {
	      /* duplicate/retransmission/overlap */
	      fd_i->flags    |= FD_OVERLAP;
	      fd_head->flags |= FD_OVERLAP;
	      if( (last_fd->len!=fd_i->datalen)
		  || tvb_memeql(last_fd->tvb_data, 0, tvb_get_ptr(fd_i->tvb_data, 0, last_fd->len), last_fd->len) ){
			fd_i->flags    |= FD_OVERLAPCONFLICT;
			fd_head->flags |= FD_OVERLAPCONFLICT;
	      }
	    }
	  }
	  last_fd=fd_i;
	}

	/* we have defragmented the pdu, now free all fragments*/
	for (fd_i=fd_head->next;fd_i;fd_i=fd_i->next) {
	  if(fd_i->tvb_data){
	    tvb_free(fd_i->tvb_data);
	    fd_i->tvb_data=NULL;
	  }
	}

	/* mark this packet as defragmented */
	fd_head->flags |= FD_DEFRAGMENTED;
	fd_head->reassembled_in=pinfo->fd->num;

	col_append_fstr(pinfo->cinfo, COL_INFO, " (t4-data Reassembled: %d pack lost, %d pack burst lost)", packet_lost, burst_lost);

	p_t38_packet_conv_info->packet_lost = packet_lost;
	p_t38_packet_conv_info->burst_lost = burst_lost;

	return fd_head;
}
static int
dissect_corosynec_totemnet_with_decryption(tvbuff_t *tvb,
                                           packet_info *pinfo, proto_tree *parent_tree,
                                           gboolean check_crypt_type,
                                           const gchar* key_for_trial)
{
  unsigned char  keys[48];
  sober128_prng     keygen_prng_state;
  sober128_prng     stream_prng_state;
  unsigned char *hmac_key       = &keys[32];
  unsigned char *cipher_key     = &keys[16];
  unsigned char *initial_vector = &keys[0];
  unsigned char  digest_comparison[SHA1_DIGEST_LEN];

  int            io_len;
  guint8        *io_base;

#define PRIVATE_KEY_LEN_MAX 256
  gchar          private_key[PRIVATE_KEY_LEN_MAX];
  gsize          private_key_len;
  unsigned char* hash_digest;
  unsigned char* salt;

  io_len = tvb_reported_length(tvb) - (check_crypt_type? 1: 0);
  if (io_len < SHA1_DIGEST_LEN + SALT_SIZE) {
    return 0;
  }

  io_base = (guint8 *)tvb_memdup(pinfo->pool, tvb, 0, io_len + (check_crypt_type? 1: 0));
  if (check_crypt_type &&
      ( io_base[io_len] != TOTEM_CRYPTO_SOBER )) {
    return 0;
  }

  hash_digest = io_base;
  salt        = io_base + SHA1_DIGEST_LEN;


  memset(private_key, 0, sizeof(private_key));

  private_key_len = (strlen(key_for_trial)+4) & 0xFC;
  if (private_key_len > PRIVATE_KEY_LEN_MAX)
    private_key_len = PRIVATE_KEY_LEN_MAX;
  g_strlcpy(private_key, key_for_trial, private_key_len);

  /*
   * Generate MAC, CIPHER, IV keys from private key
   */
  memset (keys, 0, sizeof(keys));
  sober128_start (&keygen_prng_state);
  sober128_add_entropy(private_key,
                                  (unsigned long)private_key_len, &keygen_prng_state);
  sober128_add_entropy (salt, SALT_SIZE, &keygen_prng_state);
  sober128_read (keys, sizeof (keys), &keygen_prng_state);

  /*
   * Setup stream cipher
   */
  sober128_start (&stream_prng_state);
  sober128_add_entropy (cipher_key, 16, &stream_prng_state);
  sober128_add_entropy (initial_vector, 16, &stream_prng_state);

  /*
   * Authenticate contents of message
   */
  sha1_hmac(hmac_key, 16,
            io_base + SHA1_DIGEST_LEN, io_len - SHA1_DIGEST_LEN,
            digest_comparison);

  if (memcmp (digest_comparison, hash_digest, SHA1_DIGEST_LEN) != 0)
      return 0;

  /*
   * Decrypt the contents of the message with the cipher key
   */

  sober128_read (io_base + SHA1_DIGEST_LEN + SALT_SIZE,
                            io_len - (SHA1_DIGEST_LEN + SALT_SIZE),
                            &stream_prng_state);


  /*
   * Dissect the decrypted data
   */
  {
    tvbuff_t *decrypted_tvb;
    tvbuff_t *next_tvb;


    decrypted_tvb = tvb_new_real_data(io_base, io_len, io_len);

    tvb_set_child_real_data_tvbuff(tvb, decrypted_tvb);
    add_new_data_source(pinfo, decrypted_tvb, "Decrypted Data");


    dissect_corosync_totemnet_security_header(decrypted_tvb, pinfo, parent_tree,
                                              check_crypt_type, key_for_trial);

    next_tvb = tvb_new_subset(decrypted_tvb,
                              SHA1_DIGEST_LEN + SALT_SIZE,
                              io_len - (SHA1_DIGEST_LEN + SALT_SIZE),
                              io_len - (SHA1_DIGEST_LEN + SALT_SIZE));

    return call_dissector(corosync_totemsrp_handle, next_tvb, pinfo, parent_tree) + SHA1_DIGEST_LEN + SALT_SIZE;
  }
}
Example #13
0
tvbuff_t *
tvb_uncompress(tvbuff_t *tvb, const int offset, int comprlen)
{
	gint       err;
	guint      bytes_out      = 0;
	guint8    *compr;
	guint8    *uncompr        = NULL;
	tvbuff_t  *uncompr_tvb    = NULL;
	z_streamp  strm;
	Bytef     *strmbuf;
	guint      inits_done     = 0;
	gint       wbits          = MAX_WBITS;
	guint8    *next;
	guint      bufsiz;
#ifdef TVB_Z_DEBUG
	guint      inflate_passes = 0;
	guint      bytes_in       = tvb_captured_length_remaining(tvb, offset);
#endif

	if (tvb == NULL || comprlen <= 0) {
		return NULL;
	}

	compr = (guint8 *)tvb_memdup(NULL, tvb, offset, comprlen);
	if (compr == NULL) {
		return NULL;
	}

	/*
	 * Assume that the uncompressed data is at least twice as big as
	 * the compressed size.
	 */
	bufsiz = tvb_captured_length_remaining(tvb, offset) * 2;
	bufsiz = CLAMP(bufsiz, TVB_Z_MIN_BUFSIZ, TVB_Z_MAX_BUFSIZ);

#ifdef TVB_Z_DEBUG
	ws_debug_printf("bufsiz: %u bytes\n", bufsiz);
#endif

	next = compr;

	strm            = g_new0(z_stream, 1);
	strm->next_in   = next;
	strm->avail_in  = comprlen;

	strmbuf         = (Bytef *)g_malloc0(bufsiz);
	strm->next_out  = strmbuf;
	strm->avail_out = bufsiz;

	err = inflateInit2(strm, wbits);
	inits_done = 1;
	if (err != Z_OK) {
		inflateEnd(strm);
		g_free(strm);
		wmem_free(NULL, compr);
		g_free(strmbuf);
		return NULL;
	}

	while (1) {
		memset(strmbuf, '\0', bufsiz);
		strm->next_out  = strmbuf;
		strm->avail_out = bufsiz;

		err = inflate(strm, Z_SYNC_FLUSH);

		if (err == Z_OK || err == Z_STREAM_END) {
			guint bytes_pass = bufsiz - strm->avail_out;

#ifdef TVB_Z_DEBUG
			++inflate_passes;
#endif

			if (uncompr == NULL) {
				/*
				 * This is ugly workaround for bug #6480
				 * (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6480)
				 *
				 * g_memdup(..., 0) returns NULL (g_malloc(0) also)
				 * when uncompr is NULL logic below doesn't create tvb
				 * which is later interpreted as decompression failed.
				 */
				uncompr = (guint8 *)((bytes_pass || err != Z_STREAM_END) ?
						g_memdup(strmbuf, bytes_pass) :
						g_strdup(""));
			} else {
				guint8 *new_data = (guint8 *)g_malloc0(bytes_out + bytes_pass);

				memcpy(new_data, uncompr, bytes_out);
				memcpy(new_data + bytes_out, strmbuf, bytes_pass);

				g_free(uncompr);
				uncompr = new_data;
			}

			bytes_out += bytes_pass;

			if (err == Z_STREAM_END) {
				inflateEnd(strm);
				g_free(strm);
				g_free(strmbuf);
				break;
			}
		} else if (err == Z_BUF_ERROR) {
			/*
			 * It's possible that not enough frames were captured
			 * to decompress this fully, so return what we've done
			 * so far, if any.
			 */
			inflateEnd(strm);
			g_free(strm);
			g_free(strmbuf);

			if (uncompr != NULL) {
				break;
			} else {
				wmem_free(NULL, compr);
				return NULL;
			}

		} else if (err == Z_DATA_ERROR && inits_done == 1
			&& uncompr == NULL && comprlen >= 2 &&
			(*compr  == 0x1f) && (*(compr + 1) == 0x8b)) {
			/*
			 * inflate() is supposed to handle both gzip and deflate
			 * streams automatically, but in reality it doesn't
			 * seem to handle either (at least not within the
			 * context of an HTTP response.)  We have to try
			 * several tweaks, depending on the type of data and
			 * version of the library installed.
			 */

			/*
			 * Gzip file format.  Skip past the header, since the
			 * fix to make it work (setting windowBits to 31)
			 * doesn't work with all versions of the library.
			 */
			Bytef *c = compr + 2;
			Bytef  flags = 0;

			/* we read two bytes already (0x1f, 0x8b) and
			   need at least Z_DEFLATED, 1 byte flags, 4
			   bytes MTIME, 1 byte XFL, 1 byte OS */
			if (comprlen < 10 || *c != Z_DEFLATED) {
				inflateEnd(strm);
				g_free(strm);
				wmem_free(NULL, compr);
				g_free(strmbuf);
				return NULL;
			}

			c++;
			flags = *c;
			c++;

			/* Skip past the MTIME (4 bytes),
			   XFL, and OS fields (1 byte each). */
			c += 6;

			if (flags & (1 << 2)) {
				/* An Extra field is present. It
				   consists of 2 bytes xsize and xsize
				   bytes of data.
				   Read byte-by-byte (least significant
				   byte first) to make sure we abort
				   cleanly when the xsize is truncated
				   after the first byte. */
				guint16 xsize = 0;

				if (c-compr < comprlen) {
					xsize += *c;
					c++;
				}
				if (c-compr < comprlen) {
					xsize += *c << 8;
					c++;
				}

				c += xsize;
			}

			if (flags & (1 << 3)) {
				/* A null terminated filename */

				while ((c - compr) < comprlen && *c != '\0') {
					c++;
				}

				c++;
			}

			if (flags & (1 << 4)) {
				/* A null terminated comment */

				while ((c - compr) < comprlen && *c != '\0') {
					c++;
				}

				c++;
			}


			if (c - compr > comprlen) {
				inflateEnd(strm);
				g_free(strm);
				wmem_free(NULL, compr);
				g_free(strmbuf);
				return NULL;
			}
			/* Drop gzip header */
			comprlen -= (int) (c - compr);
			next = c;

			inflateReset(strm);
			strm->next_in   = next;
			strm->avail_in  = comprlen;

			inflateEnd(strm);
			inflateInit2(strm, wbits);
			inits_done++;
		} else if (err == Z_DATA_ERROR && uncompr == NULL &&
			inits_done <= 3) {

			/*
			 * Re-init the stream with a negative
			 * MAX_WBITS. This is necessary due to
			 * some servers (Apache) not sending
			 * the deflate header with the
			 * content-encoded response.
			 */
			wbits = -MAX_WBITS;

			inflateReset(strm);

			strm->next_in   = next;
			strm->avail_in  = comprlen;

			inflateEnd(strm);
			memset(strmbuf, '\0', bufsiz);
			strm->next_out  = strmbuf;
			strm->avail_out = bufsiz;

			err = inflateInit2(strm, wbits);

			inits_done++;

			if (err != Z_OK) {
				g_free(strm);
				g_free(strmbuf);
				wmem_free(NULL, compr);
				g_free(uncompr);

				return NULL;
			}
		} else {
			inflateEnd(strm);
			g_free(strm);
			g_free(strmbuf);

			if (uncompr == NULL) {
				wmem_free(NULL, compr);
				return NULL;
			}

			break;
		}
	}

#ifdef TVB_Z_DEBUG
	ws_debug_printf("inflate() total passes: %u\n", inflate_passes);
	ws_debug_printf("bytes  in: %u\nbytes out: %u\n\n", bytes_in, bytes_out);
#endif

	if (uncompr != NULL) {
		uncompr_tvb =  tvb_new_real_data((guint8*) uncompr, bytes_out, bytes_out);
		tvb_set_free_cb(uncompr_tvb, g_free);
	}
	wmem_free(NULL, compr);
	return uncompr_tvb;
}
Example #14
0
static tvbuff_t *
dissect_pft_fec_detailed(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
  guint32 findex,
  guint32 fcount,
  guint16 seq,
  gint offset,
  guint16 plen,
  gboolean fec _U_,
  guint16 rsk,
  guint16 rsz,
  fragment_data *fdx
)
{
  guint16 decoded_size;
  guint32 c_max;
  guint32 rx_min;
  gboolean first, last;
  tvbuff_t *new_tvb=NULL;

  if (fcount > MAX_FRAGMENTS) {
    if (tree)
      proto_tree_add_text(tree, tvb , 0, -1, "[Reassembly of %d fragments not attempted]", fcount);
    return NULL;
  }

  first = findex == 0;
  last = fcount == (findex+1);
  decoded_size = fcount*plen;
  c_max = fcount*plen/(rsk+PFT_RS_P);  /* rounded down */
  rx_min = c_max*rsk/plen;
  if(rx_min*plen<c_max*rsk)
    rx_min++;
  if (fdx)
    new_tvb = process_reassembled_data (tvb, offset, pinfo,
                                        "Reassembled DCP (ETSI)",
                                        fdx, &dcp_frag_items,
                                        NULL, tree);
  else {
    guint fragments=0;
    guint32 *got;
    fragment_data *fd;
    fragment_data *fd_head;

    if(tree)
      proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d",
                           fcount, fragments, rx_min
        );
    got = ep_alloc(fcount*sizeof(guint32));

    /* make a list of the findex (offset) numbers of the fragments we have */
    fd = fragment_get(pinfo, seq, dcp_fragment_table);
    for (fd_head = fd; fd_head != NULL; fd_head = fd_head->next) {
      if(fd_head->data) {
        got[fragments++] = fd_head->offset; /* this is the findex of the fragment */
      }
    }
    /* put a sentinel at the end */
    got[fragments++] = fcount;
    /* have we got enough for Reed Solomon to try to correct ? */
    if(fragments>=rx_min) { /* yes, in theory */
      guint i,current_findex;
      fragment_data *frag=NULL;
      guint8 *dummy_data = (guint8*) ep_alloc0 (plen);
      tvbuff_t *dummytvb = tvb_new_real_data(dummy_data, plen, plen);
      /* try and decode with missing fragments */
      if(tree)
          proto_tree_add_text (tree, tvb, 0, -1, "want %d, got %d need %d",
                               fcount, fragments, rx_min
            );
      /* fill the fragment table with empty fragments */
      current_findex = 0;
      for(i=0; i<fragments; i++) {
        guint next_fragment_we_have = got[i];
        if (next_fragment_we_have > MAX_FRAGMENTS) {
          if (tree)
            proto_tree_add_text(tree, tvb , 0, -1, "[Reassembly of %d fragments not attempted]", next_fragment_we_have);
          return NULL;
        }
        for(; current_findex<next_fragment_we_have; current_findex++) {
          frag = fragment_add_seq_check (dummytvb, 0, pinfo, seq,
                                         dcp_fragment_table, dcp_reassembled_table, 
                                         current_findex, plen, (current_findex+1!=fcount));
        }
        current_findex++; /* skip over the fragment we have */
      }
      if(frag)
        new_tvb = process_reassembled_data (tvb, offset, pinfo,
                                            "Reassembled DCP (ETSI)",
                                            frag, &dcp_frag_items,
                                            NULL, tree);
    }
  }
  if(new_tvb) {
    gboolean decoded = TRUE;
    tvbuff_t *dtvb = NULL;
    const guint8 *input = tvb_get_ptr(new_tvb, 0, -1);
    guint16 reassembled_size = tvb_length(new_tvb);
    guint8 *deinterleaved = (guint8*) g_malloc (reassembled_size);
    guint8 *output = (guint8*) g_malloc (decoded_size);
    rs_deinterleave(input, deinterleaved, plen, fcount);

    dtvb = tvb_new_child_real_data(tvb, deinterleaved, reassembled_size, reassembled_size);
    add_new_data_source(pinfo, dtvb, "Deinterleaved");
    tvb_set_free_cb(dtvb, g_free);

    decoded = rs_correct_data(deinterleaved, output, c_max, rsk, rsz);
    if(tree)
      proto_tree_add_boolean (tree, hf_edcp_rs_ok, tvb, offset, 2, decoded);

    new_tvb = tvb_new_child_real_data(dtvb, output, decoded_size, decoded_size);
    add_new_data_source(pinfo, new_tvb, "RS Error Corrected Data");
    tvb_set_free_cb(new_tvb, g_free);
  }
  return new_tvb;
}
Example #15
0
static void
dissect_rtmpt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
	proto_tree	*rtmpt_tree = NULL;
	proto_tree	*rtmptroot_tree = NULL;
	proto_item	*ti = NULL;
	gint        offset = 0;

	struct tcpinfo* tcpinfo = pinfo->private_data;

	guint8  iCommand = -1;
	guint32 iLength = 1;
	guint16 iHeaderType = 4;
	guint16 iHeaderLength;
	guint8  iID;
	guint   rtmp_index;

	conversation_t * current_conversation;
	rtmpt_conversation_data_t * conversation_data;
	rtmpt_packet_data_t * packet_data;

	rtmpt_chunk_data_t *current_chunk_data = NULL;
	rtmpt_chunk_data_t *initial_chunk_data = NULL;

	tvbuff_t*   amf_tvb;

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

	if (NULL != current_conversation)
	{
		conversation_data = (rtmpt_conversation_data_t*)conversation_get_proto_data(current_conversation, proto_rtmpt);
		if (NULL == conversation_data)
		{
			conversation_data = se_alloc(sizeof(rtmpt_conversation_data_t));
			memset((void*)conversation_data, 0, sizeof(rtmpt_conversation_data_t));
			conversation_add_proto_data(current_conversation, proto_rtmpt, conversation_data);
			conversation_data->current_chunks = g_hash_table_new(g_direct_hash, g_direct_equal);
			conversation_data->previous_frame_number = -1;
			conversation_data->current_chunk_size = RTMPT_DEFAULT_CHUNK_SIZE;
			conversation_data->is_rtmpe = 0;
		}

		packet_data = p_get_proto_data(pinfo->fd, proto_rtmpt);
		if (NULL == packet_data)
		{
			packet_data = se_alloc(sizeof(rtmpt_packet_data_t));
			memset((void*)packet_data, 0, sizeof(rtmpt_packet_data_t));
			p_add_proto_data(pinfo->fd, proto_rtmpt, packet_data);
			packet_data->initial_chunks = g_hash_table_new(g_direct_hash, g_direct_equal);
			packet_data->initial_chunk_size = conversation_data->current_chunk_size;
		}


		if (conversation_data->is_rtmpe == 1)
		{
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMPE");
			return;
		}
		else
		{
			col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTMP");
		}

		if (conversation_data->previous_frame_number != (guint) pinfo->fd->num)
		{
			conversation_data->current_chunk_size = packet_data->initial_chunk_size;
		}

		col_set_writable(pinfo->cinfo, TRUE);
		col_clear(pinfo->cinfo, COL_INFO);

		conversation_data->previous_frame_number = pinfo->fd->num;
		if (tvb_length_remaining(tvb, offset) >= 1)
		{
			if (tcpinfo->lastackseq == RTMPT_HANDSHAKE_OFFSET_1 && tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_1)
			{
				iCommand =  RTMPT_TYPE_HANDSHAKE_1;
			}
			else if (tcpinfo->lastackseq == RTMPT_HANDSHAKE_OFFSET_2 && tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_1) iCommand =  RTMPT_TYPE_HANDSHAKE_2;
			else if (tcpinfo->seq == RTMPT_HANDSHAKE_OFFSET_2
			         && tvb_length(tvb) == RTMPT_HANDSHAKE_LENGTH_3) iCommand = RTMPT_TYPE_HANDSHAKE_3;
			else
			{
				iID = tvb_get_guint8(tvb, offset + 0);
				iHeaderType = iID >> 6;
				rtmp_index = iID & 0x3F;

				current_chunk_data = g_hash_table_lookup(conversation_data->current_chunks, GUINT_TO_POINTER(rtmp_index));
				initial_chunk_data = g_hash_table_lookup(packet_data->initial_chunks, GUINT_TO_POINTER(rtmp_index));

				if (iHeaderType <= 2) iLength = tvb_get_ntoh24(tvb, offset + 4);
				if (iHeaderType <= 1)
				{
					iCommand = tvb_get_guint8(tvb, offset + 7);
					if (NULL == current_chunk_data)
					{
						current_chunk_data = se_alloc(sizeof(rtmpt_chunk_data_t));
						memset((void*)current_chunk_data, 0, sizeof(rtmpt_chunk_data_t));
						g_hash_table_insert(conversation_data->current_chunks, GUINT_TO_POINTER(rtmp_index), current_chunk_data);
					}

					current_chunk_data->data_type = iCommand;
					current_chunk_data->last_length = iLength;
					current_chunk_data->frame_modified = pinfo->fd->num;
				}
				else
				{
					/* must get the command type from the previous entries in the hash table */
					/* try to use the current_chunk_data unless it is from a different frame */
					if (NULL != current_chunk_data && NULL != initial_chunk_data)
					{
						/* we have precedent data (we should)*/
						if (current_chunk_data->frame_modified != pinfo->fd->num)
						{
							iCommand = initial_chunk_data->data_type;
							iLength = initial_chunk_data->length_remaining;
							current_chunk_data->frame_modified = pinfo->fd->num;
							current_chunk_data->data_type = iCommand;
							current_chunk_data->last_length = iLength;
							current_chunk_data->dechunk_buffer = initial_chunk_data->dechunk_buffer;
						}
						else
						{
							iCommand = current_chunk_data->data_type;
							iLength = current_chunk_data->length_remaining;
						}

						if (iLength > conversation_data->current_chunk_size)
						{
							iLength = conversation_data->current_chunk_size;
						}
					}
				}
			}

			iHeaderLength = rtmpt_header_length_from_type(iHeaderType);


			if (check_col(pinfo->cinfo, COL_INFO))
			{
				col_append_sep_fstr(pinfo->cinfo, COL_INFO, " | ", "%s", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)"));
				col_set_fence(pinfo->cinfo, COL_INFO);
			}

			if (tree)
			{
				ti = proto_tree_add_item(tree, proto_rtmpt, tvb, offset, -1, FALSE);
				proto_item_append_text(ti, " (%s)", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)"));
				rtmptroot_tree = proto_item_add_subtree(ti, ett_rtmpt);

				ti = proto_tree_add_text(rtmptroot_tree, tvb, offset, iHeaderLength, RTMPT_TEXT_RTMP_HEADER);
				proto_item_append_text(ti, " (%s)", val_to_str(iCommand, rtmpt_opcode_vals, "Unknown (0x%01x)"));
				rtmpt_tree = proto_item_add_subtree(ti, ett_rtmpt_header);

				if (iHeaderType <= 3) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_objid, tvb, offset + 0, 1, FALSE);
				if (iHeaderType <= 2) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_timestamp, tvb, offset + 1, 3, FALSE);
				if (iHeaderType <= 1) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_body_size, tvb, offset + 4, 3, FALSE);
				if (iHeaderType <= 1) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_function, tvb, offset + 7, 1, FALSE);
				if (iHeaderType <= 0) proto_tree_add_item(rtmpt_tree, hf_rtmpt_header_source, tvb, offset + 8, 4, TRUE);

				if (iCommand == RTMPT_TYPE_HANDSHAKE_1)
				{
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1, 1536, FALSE);
				}
				else if (iCommand == RTMPT_TYPE_HANDSHAKE_2)
				{
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1, 1536, FALSE);
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 1537, 1536, FALSE);
				}
				else if (iCommand == RTMPT_TYPE_HANDSHAKE_3)
				{
					proto_tree_add_item(rtmpt_tree, hf_rtmpt_handshake_data, tvb, 0, -1, FALSE);
				}
				else if (iCommand == RTMPT_TYPE_CHUNK_SIZE)
				{
					conversation_data->current_chunk_size = tvb_get_ntohl (tvb, offset + iHeaderLength);
				}

				offset = iHeaderLength;
				if (tvb_length_remaining(tvb, offset))
				{
					ti = proto_tree_add_text(rtmptroot_tree, tvb, offset, -1, RTMPT_TEXT_RTMP_BODY);
				}


				if (iCommand == RTMPT_TYPE_INVOKE || iCommand == RTMPT_TYPE_NOTIFY)
				{
					guint iChunkSize = tvb_length_remaining(tvb, iHeaderLength);
					/* we have data which will be AMF */
					/* we should add it to a new tvb */
					if (NULL != current_chunk_data)
					{
						if (NULL == current_chunk_data->dechunk_buffer)
						{
							/* we have to create a new tvbuffer */
							current_chunk_data->dechunk_buffer = tvb_new_composite();
						}
						if (!(current_chunk_data->dechunk_buffer->initialized))
						{
							/* add the existing data to the new buffer */
							tvb_composite_append(current_chunk_data->dechunk_buffer,
							                     tvb_new_real_data(tvb_memdup(tvb, iHeaderLength, iChunkSize), iChunkSize, iChunkSize));

							if (current_chunk_data->length_remaining <= 0)
							{
								guint amf_length;
								guint8* amf_data;

								tvb_composite_finalize(current_chunk_data->dechunk_buffer);

								amf_length = tvb_length(current_chunk_data->dechunk_buffer);

								if (amf_length == 0)
								{
									return;
								}


								amf_data = tvb_memdup(current_chunk_data->dechunk_buffer, 0, amf_length);

								amf_tvb = tvb_new_real_data(amf_data, tvb_length_remaining(current_chunk_data->dechunk_buffer, 0), tvb_length_remaining(current_chunk_data->dechunk_buffer, 0));

								add_new_data_source(pinfo, amf_tvb, "Dechunked AMF data");
								ti = proto_tree_add_item(tree, proto_rtmpt, amf_tvb, 0, -1, FALSE);
								rtmpt_tree = proto_item_add_subtree(ti, ett_rtmpt_body);
								proto_tree_set_appendix(rtmpt_tree, amf_tvb, 0, tvb_length_remaining(amf_tvb, 0));
								proto_item_append_text(rtmpt_tree, " (%s)", "AMF Data");
								dissect_rtmpt_amf(amf_tvb, rtmpt_tree);
								current_chunk_data->dechunk_buffer = NULL;
							}
						}
					}
				}
			}
		}
	}
Example #16
0
	g_free(data);
}

static gboolean
val_from_string(fvalue_t *fv, const char *s, gchar **err_msg _U_)
{
	tvbuff_t *new_tvb;
	guint8 *private_data;

	/* Free up the old value, if we have one */
	value_free(fv);

	/* Make a tvbuff from the string. We can drop the
	 * terminating NUL. */
	private_data = (guint8 *)g_memdup(s, (guint)strlen(s));
	new_tvb = tvb_new_real_data(private_data,
			(guint)strlen(s), (gint)strlen(s));

	/* Let the tvbuff know how to delete the data. */
	tvb_set_free_cb(new_tvb, free_tvb_data);

	/* And let us know that we need to free the tvbuff */
	fv->tvb_is_private = TRUE;
	fv->value.tvb = new_tvb;
	return TRUE;
}

static gboolean
val_from_unparsed(fvalue_t *fv, const char *s, gboolean allow_partial_value _U_, gchar **err_msg)
{
	fvalue_t *fv_bytes;
	tvbuff_t *new_tvb;