Exemple #1
0
int count_frames(unsigned char *packet, int len)
{
    int sz = packet[0]&0x7;

    if (sz == 0)
        return 1;
    else if (sz == 1 || sz == 4)
        return 2;
    else if (sz == 2 || sz == 5)
        return 3;
    else if (sz == 3)
    {
        /* Many packets, same size */
        int count, payload;
        int flen = decode_length(packet+1, len-1);
        if (flen<=0)
            return -1;
        payload = len - 2;
        if (flen>=252)
            payload--;
        count = payload/flen;
        if (count*flen==payload)
            return count;
        else
            return -1;
    } else /* if (sz == 6 || sz == 7) */
    {
        /* Many packets, different sizes */
        int count = 0;
        int pos = 1;
        int bytes = 1;
        int extra = 0;
        if (sz==7)
            extra = 1;
        while (bytes < len)
        {
            int tmp=extra+1;
            int flen = decode_length(packet+pos, len-bytes);
            if (flen==-1)
                return -1;
            if (flen >= 252)
                tmp = 2;
            pos += tmp;
            bytes += tmp+flen;
            count++;
        }
        if (bytes != len)
            return -1;
        else
            return count;
    }
}
static int decode_open_type(uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets)
{
	int octet_cnt;
	int octet_idx;
	int stat;
	int i;
	const uint8_t **pbuf;

	for (octet_idx = 0, *p_num_octets = 0;  ;  octet_idx += octet_cnt) {
		if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
			return -1;
		if (octet_cnt > 0) {
			*p_num_octets += octet_cnt;

			pbuf = &p_object[octet_idx];
			i = 0;
			/* Make sure the buffer contains at least the number of bits requested */
			if ((*len + octet_cnt) > limit)
				return -1;

			*pbuf = &buf[*len];
			*len += octet_cnt;
		}
		if (stat == 0)
			break;
	}
	return 0;
}
Exemple #3
0
static inline grub_uint32_t
skip_data_ref_object (const grub_uint8_t *ptr, const grub_uint8_t *end)
{
  grub_dprintf ("acpi", "data type = 0x%x\n", *ptr);
  switch (*ptr)
    {
    case GRUB_ACPI_OPCODE_PACKAGE:
    case GRUB_ACPI_OPCODE_BUFFER:
      return 1 + decode_length (ptr + 1, 0);
    case GRUB_ACPI_OPCODE_ZERO:
    case GRUB_ACPI_OPCODE_ONES:
    case GRUB_ACPI_OPCODE_ONE:
      return 1;
    case GRUB_ACPI_OPCODE_BYTE_CONST:
      return 2;
    case GRUB_ACPI_OPCODE_WORD_CONST:
      return 3;
    case GRUB_ACPI_OPCODE_DWORD_CONST:
      return 5;
    case GRUB_ACPI_OPCODE_STRING_CONST:
      {
	const grub_uint8_t *ptr0 = ptr;
	for (ptr++; ptr < end && *ptr; ptr++);
	if (ptr == end)
	  return 0;
	return ptr - ptr0 + 1;
      }
    default:
      if (*ptr == '^' || *ptr == '\\' || *ptr == '_'
	  || (*ptr >= 'A' && *ptr <= 'Z'))
	return skip_name_string (ptr, end);
      grub_printf ("Unknown opcode 0x%x\n", *ptr);
      return 0;
    }
}
Exemple #4
0
static inline grub_uint32_t
skip_ext_op (const grub_uint8_t *ptr, const grub_uint8_t *end)
{
  const grub_uint8_t *ptr0 = ptr;
  int add;
  grub_dprintf ("acpi", "Extended opcode: 0x%x\n", *ptr);
  switch (*ptr)
    {
    case GRUB_ACPI_EXTOPCODE_MUTEX:
      ptr++;
      ptr += skip_name_string (ptr, end);
      ptr++;
      break;
    case GRUB_ACPI_EXTOPCODE_OPERATION_REGION:
      ptr++;
      ptr += skip_name_string (ptr, end);
      ptr++;
      ptr += add = skip_data_ref_object (ptr, end);
      if (!add)
	return 0;
      ptr += add = skip_data_ref_object (ptr, end);
      if (!add)
	return 0;
      break;
    case GRUB_ACPI_EXTOPCODE_FIELD_OP:
    case GRUB_ACPI_EXTOPCODE_INDEX_FIELD_OP:
      ptr++;
      ptr += decode_length (ptr, 0);
      break;
    default:
      grub_printf ("Unexpected extended opcode: 0x%x\n", *ptr);
      return 0;
    }
  return ptr - ptr0;
}
Exemple #5
0
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t ** p_object, int *p_num_octets)
{
	int octet_cnt;
#if 0
	int octet_idx;
	int stat;
	const uint8_t **pbuf;

	*p_num_octets = 0;
	for (octet_idx = 0;; octet_idx += octet_cnt) {
		if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
			return -1;
		if (octet_cnt > 0) {
			*p_num_octets += octet_cnt;

			pbuf = &p_object[octet_idx];
			/* Make sure the buffer contains at least the number of bits requested */
			if ((*len + octet_cnt) > limit)
				return -1;

			/* Was told the buffer was large enough, but in reality it didn't exist. FS-5202 */
			if ( buf[*len] == 0 )
			  return -1;

			*pbuf = &buf[*len];
			*len += octet_cnt;
		}
		if (stat == 0)
			break;
	}
#else
	/* We do not deal with fragments, so there is no point in looping through them. Just say that something
       fragmented is bad. */
	if (decode_length(buf, limit, len, &octet_cnt) != 0)
		return -1;
	*p_num_octets = octet_cnt;
	if (octet_cnt > 0) {
		/* Make sure the buffer contains at least the number of bits requested */
		if ((*len + octet_cnt) > limit)
			return -1;
		*p_object = &buf[*len];
		*len += octet_cnt;
	}
#endif
	return 0;
}
void dynamic_inflate(reader_t *reader)
{
	size_t hlit = read_HLIT(reader) + 257;
	size_t hdist = read_HDIST(reader) + 1;
	size_t hclen = read_HCLEN(reader) + 4;

	/*printf("hclen = %d, hlit = %d, hdist = %d\n", hclen, hlit, hdist);*/

	huffman_code litlen_codes[hlit];
	huffman_code offset_codes[hdist];
	read_alphabets(reader, 
				   litlen_codes, hlit, 
				   offset_codes, hdist, 
				   hclen);

	io *io_s;
	init_io(&io_s);
	byte bytes[LEN_MAX];
	size_t litlen;
	bool is_end_of_block = false;
	size_t block_size = 0;
	while (!is_end_of_block) {
		litlen = read_next_huffman_code(reader, litlen_codes, hlit);
		block_size++;
		if (litlen < END_OF_BLOCK)
			write_byte(io_s, litlen);
		else if (litlen == END_OF_BLOCK)
			is_end_of_block = true;
		else {
			two_bytes length = decode_length(reader, litlen);
			two_bytes offcode = read_next_huffman_code(reader, 
													   offset_codes, 
													   hdist);
		    two_bytes distance = decode_distance(reader, offcode);
			get_cyclic_queue(io_s->output, bytes, length, distance);
			write_bytes(io_s, bytes, length);
			block_size = block_size - 1 + length;
		}
	}
	/*printf("block_size = %d\n", block_size);*/

	write_to_output(io_s, reader->output);
	delete_io(&io_s);
}
Exemple #7
0
static int decode_open_type(uint8_t *buf, unsigned int limit, unsigned int *len, const uint8_t **p_object, unsigned int *p_num_octets)
{
	unsigned int octet_cnt = 0;

	if (decode_length(buf, limit, len, &octet_cnt) != 0)
		return -1;

	if (octet_cnt > 0) {
		/* Make sure the buffer contains at least the number of bits requested */
		if ((*len + octet_cnt) > limit)
			return -1;

		*p_num_octets = octet_cnt;
		*p_object = &buf[*len];
		*len += octet_cnt;
	}

	return 0;
}
Exemple #8
0
static int
get_sleep_type (grub_uint8_t *table, grub_uint8_t *end)
{
  grub_uint8_t *ptr, *prev = table;
  int sleep_type = -1;
  
  ptr = table + sizeof (struct grub_acpi_table_header);
  while (ptr < end && prev < ptr)
    {
      int add;
      prev = ptr;
      grub_dprintf ("acpi", "Opcode 0x%x\n", *ptr);
      grub_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table));
      switch (*ptr)
	{
	case GRUB_ACPI_OPCODE_EXTOP:
	  ptr++;
	  ptr += add = skip_ext_op (ptr, end);
	  if (!add)
	    return -1;
	  break;
	case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD:
	case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD:
	  {
	    ptr += 5;
	    ptr += add = skip_data_ref_object (ptr, end);
	    if (!add)
	      return -1;
	    ptr += 4;
	    break;
	  }
	case GRUB_ACPI_OPCODE_NAME:
	  ptr++;
	  if (memcmp (ptr, "_S5_", 4) == 0 || memcmp (ptr, "\\_S5_", 4) == 0)
	    {
	      int ll;
	      grub_uint8_t *ptr2 = ptr;
	      grub_dprintf ("acpi", "S5 found\n");
	      ptr2 += skip_name_string (ptr, end);
	      if (*ptr2 != 0x12)
		{
		  grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
		  return -1;
		}
	      ptr2++;
	      decode_length (ptr2, &ll);
	      ptr2 += ll;
	      ptr2++;
	      switch (*ptr2)
		{
		case GRUB_ACPI_OPCODE_ZERO:
		  sleep_type = 0;
		  break;
		case GRUB_ACPI_OPCODE_ONE:
		  sleep_type = 1;
		  break;
		case GRUB_ACPI_OPCODE_BYTE_CONST:
		  sleep_type = ptr2[1];
		  break;
		default:
		  grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
		  return -1;
		}
	    }
	  ptr += add = skip_name_string (ptr, end);
	  if (!add)
	    return -1;
	  ptr += add = skip_data_ref_object (ptr, end);
	  if (!add)
	    return -1;
	  break;
	case GRUB_ACPI_OPCODE_SCOPE:
	case GRUB_ACPI_OPCODE_IF:
	case GRUB_ACPI_OPCODE_METHOD:
	  {
	    ptr++;
	    ptr += decode_length (ptr, 0);
	    break;
	  }
	default:
	  grub_printf ("Unknown opcode 0x%x\n", *ptr);
	  return -1;	  
	}
    }

  grub_dprintf ("acpi", "TYP = %d\n", sleep_type);
  return sleep_type;
}
Exemple #9
0
/* Section 21.4.3.1 MAC-RESOURCE */
int macpdu_decode_resource(struct tetra_resrc_decoded *rsd, const uint8_t *bits)
{
	const uint8_t *cur = bits + 4;

	rsd->encryption_mode = bits_to_uint(cur, 2); cur += 2;
	rsd->rand_acc_flag = *cur++;
	rsd->macpdu_length = decode_length(bits_to_uint(cur, 6)); cur += 6;
	rsd->addr.type = bits_to_uint(cur, 3); cur += 3;
	switch (rsd->addr.type) {
	case ADDR_TYPE_NULL:
		return 0;
		break;
	case ADDR_TYPE_SSI:
	case ADDR_TYPE_USSI:
	case ADDR_TYPE_SMI:
		rsd->addr.ssi = bits_to_uint(cur, 24);
		break;
	case ADDR_TYPE_EVENT_LABEL:
		rsd->addr.event_label = bits_to_uint(cur, 10);
		break;
	case ADDR_TYPE_SSI_EVENT:
	case ADDR_TYPE_SMI_EVENT:
		rsd->addr.ssi = bits_to_uint(cur, 24);
		rsd->addr.event_label = bits_to_uint(cur+24, 10);
		break;
	case ADDR_TYPE_SSI_USAGE:
		rsd->addr.ssi = bits_to_uint(cur, 24);
		rsd->addr.usage_marker = bits_to_uint(cur+24, 6);
		break;
	default:
		return -EINVAL;
		break;
	}
	cur += addr_len_by_type[rsd->addr.type];
	/* no intermediate napping in pi/4 */
	rsd->power_control_pres = *cur++;
	if (rsd->power_control_pres)
		cur += 4;
	rsd->slot_granting.pres = *cur++;
	if (rsd->slot_granting.pres) {
#if 0
		/* check for multiple slot granting flag (can only exist in QAM) */
		if (*cur++) {
			cur += 0; //FIXME;
		} else {
#endif
			rsd->slot_granting.nr_slots =
				decode_nr_slots(bits_to_uint(cur, 4));
			cur += 4;
			rsd->slot_granting.delay = bits_to_uint(cur, 4);
			cur += 4;
#if 0
		}
#endif
	}
	rsd->chan_alloc_pres = *cur++;
	/* FIXME: If encryption is enabled, Channel Allocation is encrypted !!! */
	if (rsd->chan_alloc_pres)
		cur += decode_chan_alloc(&rsd->cad, cur);
	/* FIXME: TM-SDU */

	return cur - bits;
}
Exemple #10
0
static int
get_sleep_type (grub_uint8_t *table, grub_uint8_t *ptr, grub_uint8_t *end,
		grub_uint8_t *scope, int scope_len)
{
  grub_uint8_t *prev = table;
  
  if (!ptr)
    ptr = table + sizeof (struct grub_acpi_table_header);
  while (ptr < end && prev < ptr)
    {
      int add;
      prev = ptr;
      grub_dprintf ("acpi", "Opcode 0x%x\n", *ptr);
      grub_dprintf ("acpi", "Tell %x\n", (unsigned) (ptr - table));
      switch (*ptr)
	{
	case GRUB_ACPI_OPCODE_EXTOP:
	  ptr++;
	  ptr += add = skip_ext_op (ptr, end);
	  if (!add)
	    return -1;
	  break;
	case GRUB_ACPI_OPCODE_CREATE_WORD_FIELD:
	case GRUB_ACPI_OPCODE_CREATE_BYTE_FIELD:
	  {
	    ptr += 5;
	    ptr += add = skip_data_ref_object (ptr, end);
	    if (!add)
	      return -1;
	    ptr += 4;
	    break;
	  }
	case GRUB_ACPI_OPCODE_NAME:
	  ptr++;
	  if ((!scope || grub_memcmp (scope, "\\", scope_len) == 0) &&
	      (grub_memcmp (ptr, "_S5_", 4) == 0 || grub_memcmp (ptr, "\\_S5_", 4) == 0))
	    {
	      int ll;
	      grub_uint8_t *ptr2 = ptr;
	      grub_dprintf ("acpi", "S5 found\n");
	      ptr2 += skip_name_string (ptr, end);
	      if (*ptr2 != 0x12)
		{
		  grub_printf ("Unknown opcode in _S5: 0x%x\n", *ptr2);
		  return -1;
		}
	      ptr2++;
	      decode_length (ptr2, &ll);
	      ptr2 += ll;
	      ptr2++;
	      switch (*ptr2)
		{
		case GRUB_ACPI_OPCODE_ZERO:
		  return 0;
		case GRUB_ACPI_OPCODE_ONE:
		  return 1;
		case GRUB_ACPI_OPCODE_BYTE_CONST:
		  return ptr2[1];
		default:
		  grub_printf ("Unknown data type in _S5: 0x%x\n", *ptr2);
		  return -1;
		}
	    }
	  ptr += add = skip_name_string (ptr, end);
	  if (!add)
	    return -1;
	  ptr += add = skip_data_ref_object (ptr, end);
	  if (!add)
	    return -1;
	  break;
	case GRUB_ACPI_OPCODE_SCOPE:
	  {
	    int scope_sleep_type;
	    int ll;
	    grub_uint8_t *name;
	    int name_len;

	    ptr++;
	    add = decode_length (ptr, &ll);
	    name = ptr + ll;
	    name_len = skip_name_string (name, ptr + add);
	    if (!name_len)
	      return -1;
	    scope_sleep_type = get_sleep_type (table, name + name_len,
					       ptr + add, name, name_len);
	    if (scope_sleep_type != -2)
	      return scope_sleep_type;
	    ptr += add;
	    break;
	  }
	case GRUB_ACPI_OPCODE_IF:
	case GRUB_ACPI_OPCODE_METHOD:
	  {
	    ptr++;
	    ptr += decode_length (ptr, 0);
	    break;
	  }
	default:
	  grub_printf ("Unknown opcode 0x%x\n", *ptr);
	  return -1;	  
	}
    }

  return -2;
}