Ejemplo n.º 1
0
int
coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu) {
  coap_opt_t *opt;

  assert(data);
  assert(pdu);

  if (pdu->max_size < length) {
    debug("insufficient space to store parsed PDU\n");
    return 0;
  }

  if (length < COAP_HDR_SIZE) {
    debug("discarded invalid PDU\n");
  }

#ifdef WITH_LWIP
  LWIP_ASSERT("coap_pdu_parse with unexpected addresses", data == pdu->hdr);
  LWIP_ASSERT("coap_pdu_parse with unexpected length", length == pdu->length);
#else

  pdu->hdr->version = data[0] >> 6;
  pdu->hdr->type = (data[0] >> 4) & 0x03;
  pdu->hdr->token_length = data[0] & 0x0f;
  pdu->hdr->code = data[1];
#endif
  pdu->data = NULL;

  /* sanity checks */
  if (pdu->hdr->code == 0) {
    if (length != COAP_HDR_SIZE || pdu->hdr->token_length) {
      debug("coap_pdu_parse: empty message is not empty\n");
      goto discard;
    }
  }

  if (length < sizeof(coap_hdr_t) + pdu->hdr->token_length
      || pdu->hdr->token_length > 8) {
    debug("coap_pdu_parse: invalid Token\n");
    goto discard;
  }

#ifndef WITH_LWIP
  /* Copy message id in network byte order, so we can easily write the
   * response back to the network. */
  memcpy(&pdu->hdr->id, data + 2, 2);

  /* append data (including the Token) to pdu structure */
  memcpy(pdu->hdr + 1, data + COAP_HDR_SIZE, length - COAP_HDR_SIZE);
  pdu->length = (unsigned short)length;

  /* Finally calculate beginning of data block and thereby check integrity
   * of the PDU structure. */
#endif

  /* skip header + token */
  length -= (pdu->hdr->token_length + COAP_HDR_SIZE);
  opt = (unsigned char *)(pdu->hdr + 1) + pdu->hdr->token_length;

  while (length && *opt != COAP_PAYLOAD_START) {
    if (!next_option_safe(&opt, (size_t *)&length)) {
      debug("coap_pdu_parse: drop\n");
      goto discard;
    }
  }

  /* end of packet or start marker */
  if (length) {
    assert(*opt == COAP_PAYLOAD_START);
    opt++; length--;

    if (!length) {
      debug("coap_pdu_parse: message ending in payload start marker\n");
      goto discard;
    }

    debug("set data to %p (pdu ends at %p)\n", (unsigned char *)opt,
	  (unsigned char *)pdu->hdr + pdu->length);
    pdu->data = (unsigned char *)opt;
  }

  return 1;

 discard:
  return 0;
}
Ejemplo n.º 2
0
int coap_pdu_parse(unsigned char *data, size_t length, coap_pdu_t *pdu)
{
    coap_opt_t *opt;

    assert(data);
    assert(pdu);

    if (pdu->max_size < length)
    {
        debug("insufficient space to store parsed PDU\n");
        printf("[COAP] insufficient space to store parsed PDU\n");
        return 0;
    }

    if (length < sizeof(coap_hdr_t))
    {
        debug("discarded invalid PDU\n");
    }

    pdu->hdr->version = data[0] >> 6;
    pdu->hdr->type = (data[0] >> 4) & 0x03;
    pdu->hdr->token_length = data[0] & 0x0f;
    pdu->hdr->code = data[1];
    /*
     printf("[COAP] pdu - version : %d\n", pdu->hdr->version);
     printf("[COAP] pdu - type : %d\n", pdu->hdr->type);
     printf("[COAP] pdu - token_length : %d\n", pdu->hdr->token_length);
     printf("[COAP] pdu - code : %d\n", pdu->hdr->code);
     */
    pdu->data = NULL;

    /* sanity checks */
    if (pdu->hdr->code == 0)
    {
        if (length != sizeof(coap_hdr_t) || pdu->hdr->token_length)
        {
            debug("coap_pdu_parse: empty message is not empty\n");
            goto discard;
        }
    }

    if (length < sizeof(coap_hdr_t) + pdu->hdr->token_length || pdu->hdr->token_length > 8)
    {
        debug("coap_pdu_parse: invalid Token\n");
        goto discard;
    }

    /* Copy message id in network byte order, so we can easily write the
     * response back to the network. */
    memcpy(&pdu->hdr->id, data + 2, 2);

    //printf("[COAP] pdu - id : %d\n", pdu->hdr->id);

    /* append data (including the Token) to pdu structure */
    memcpy(pdu->hdr + 1, data + sizeof(coap_hdr_t), length - sizeof(coap_hdr_t));
    pdu->length = length;

    /* Finally calculate beginning of data block and thereby check integrity
     * of the PDU structure. */

    /* skip header + token */
    length -= (pdu->hdr->token_length + sizeof(coap_hdr_t));
    opt = (unsigned char *) (pdu->hdr + 1) + pdu->hdr->token_length;

    while (length && *opt != COAP_PAYLOAD_START)
    {
        coap_option_t option;
        memset(&option, 0, sizeof(coap_option_t));
        if (!next_option_safe(&opt, (size_t *) &length, &option))
        {
            debug("coap_pdu_parse: drop\n");
            goto discard;
        }
    }

    /* end of packet or start marker */
    if (length)
    {
        assert(*opt == COAP_PAYLOAD_START);
        opt++;
        length--;

        if (!length)
        {
            debug("coap_pdu_parse: message ending in payload start marker\n");
            goto discard;
        }

        debug(
            "set data to %p (pdu ends at %p)\n", (unsigned char *)opt, (unsigned char *)pdu->hdr + pdu->length);
        pdu->data = (unsigned char *) opt;
        //printf("[COAP] pdu - data : %s\n", pdu->data);
    }

    return 1;

discard:
    return 0;
}