Example #1
0
struct ccnl_prefix_s*
ccnl_prefix_dup(struct ccnl_prefix_s *prefix)
{
    int i = 0, len;
    struct ccnl_prefix_s *p;

    if (!prefix)
        return NULL;
    p = ccnl_prefix_new(prefix->suite, prefix->compcnt);
    if (!p)
        return p;

    p->compcnt = prefix->compcnt;
    p->chunknum = prefix->chunknum;
#ifdef USE_NFN
    p->nfnflags = prefix->nfnflags;
#endif

    for (i = 0, len = 0; i < prefix->compcnt; i++)
        len += prefix->complen[i];
    p->bytes = (unsigned char*) ccnl_malloc(len);
    if (!p->bytes) {
        free_prefix(p);
        return NULL;
    }

    for (i = 0, len = 0; i < prefix->compcnt; i++) {
        p->complen[i] = prefix->complen[i];
        p->comp[i] = p->bytes + len;
        memcpy(p->bytes + len, prefix->comp[i], p->complen[i]);
        len += p->complen[i];
    }

    if (prefix->chunknum) {
        p->chunknum = ccnl_malloc(sizeof(int));
        *p->chunknum = *prefix->chunknum;
    }

    return p;
}
// We use one extraction procedure for both interest and data pkts.
// This proc assumes that the packet header was already processed and consumed
struct ccnl_pkt_s*
ccnl_ccntlv_bytes2pkt(unsigned char *start, unsigned char **data, int *datalen)
{
    struct ccnl_pkt_s *pkt;
    int i, len;
    unsigned int typ, oldpos;
    struct ccnl_prefix_s *p;
#ifdef USE_HMAC256
    int validAlgoIsHmac256 = 0;
#endif

    DEBUGMSG_PCNX(TRACE, "ccnl_ccntlv_bytes2pkt len=%d\n", *datalen);

    pkt = (struct ccnl_pkt_s*) ccnl_calloc(1, sizeof(*pkt));
    if (!pkt)
        return NULL;

    pkt->pfx = p = ccnl_prefix_new(CCNL_SUITE_CCNTLV, CCNL_MAX_NAME_COMP);
    if (!p) {
        ccnl_free(pkt);
        return NULL;
    }
    p->compcnt = 0;

#ifdef USE_HMAC256
    pkt->hmacStart = *data;
#endif
    // We ignore the TL types of the message for now:
    // content and interests are filled in both cases (and only one exists).
    // Validation info is now collected
    if (ccnl_ccntlv_dehead(data, datalen, &typ, (unsigned int*) &len) || (int) len > *datalen)
        goto Bail;

    pkt->type = typ;
    pkt->suite = CCNL_SUITE_CCNTLV;
    pkt->val.final_block_id = -1;

    // XXX this parsing is not safe for all input data - needs more bound
    // checks, as some packets with wrong L values can bring this to crash
    oldpos = *data - start;
    while (ccnl_ccntlv_dehead(data, datalen, &typ, (unsigned int*) &len) == 0) {
        unsigned char *cp = *data, *cp2;
        int len2 = len;
        int len3;

        if ( (int)len > *datalen)
            goto Bail;
        switch (typ) {
        case CCNX_TLV_M_Name:
            p->nameptr = start + oldpos;
            while (len2 > 0) {
                cp2 = cp;
                if (ccnl_ccntlv_dehead(&cp, &len2, &typ, (unsigned int*) &len3) || (int)len>*datalen)
                    goto Bail;

                switch (typ) {
                case CCNX_TLV_N_Chunk:
                    // We extract the chunknum to the prefix but keep it
                    // in the name component for now. In the future we
                    // possibly want to remove the chunk segment from the
                    // name components and rely on the chunknum field in
                    // the prefix.
                  p->chunknum = (int*) ccnl_malloc(sizeof(int));

                    if (ccnl_ccnltv_extractNetworkVarInt(cp, len3,
                                                         (unsigned int*) p->chunknum) < 0) {
                        DEBUGMSG_PCNX(WARNING, "Error in NetworkVarInt for chunk\n");
                        goto Bail;
                    }
                    if (p->compcnt < CCNL_MAX_NAME_COMP) {
                        p->comp[p->compcnt] = cp2;
                        p->complen[p->compcnt] = cp - cp2 + len3;
                        p->compcnt++;
                    } // else out of name component memory: skip
                    break;
                case CCNX_TLV_N_NameSegment:
                    if (p->compcnt < CCNL_MAX_NAME_COMP) {
                        p->comp[p->compcnt] = cp2;
                        p->complen[p->compcnt] = cp - cp2 + len3;
                        p->compcnt++;
                    } // else out of name component memory: skip
                    break;
                case CCNX_TLV_N_Meta:
                    if (ccnl_ccntlv_dehead(&cp, &len2, &typ, (unsigned int*) &len3) ||
                        (int)len > *datalen) {
                        DEBUGMSG_PCNX(WARNING, "error when extracting CCNX_TLV_M_MetaData\n");
                        goto Bail;
                    }
                    break;
                default:
                    break;
                }
                cp += len3;
                len2 -= len3;
            }
            p->namelen = *data - p->nameptr;
#ifdef USE_NFN
            if (p->compcnt > 0 && p->complen[p->compcnt-1] == 7 &&
                    !memcmp(p->comp[p->compcnt-1], "\x00\x01\x00\x03NFN", 7)) {
                p->nfnflags |= CCNL_PREFIX_NFN;
                p->compcnt--;
            }
#endif
            break;
        case CCNX_TLV_M_ENDChunk:
            if (ccnl_ccnltv_extractNetworkVarInt(cp, len,
                              (unsigned int*) &(pkt->val.final_block_id)) < 0) {
                DEBUGMSG_PCNX(WARNING, "error when extracting CCNX_TLV_M_ENDChunk\n");
                goto Bail;
            }
            break;
        case CCNX_TLV_M_Payload:
            pkt->content = *data;
            pkt->contlen = len;
            break;
#ifdef USE_HMAC256
        case CCNX_TLV_TL_ValidationAlgo:
            cp = *data;
            len2 = len;
            if (ccnl_ccntlv_dehead(&cp, &len2, &typ, (unsigned*) &len3) || len>*datalen)
                goto Bail;
            if (typ == CCNX_VALIDALGO_HMAC_SHA256) {
                // ignore keyId and other algo dependent data ... && len3 == 0)
                validAlgoIsHmac256 = 1;
            }
            break;
        case CCNX_TLV_TL_ValidationPayload:
            if (pkt->hmacStart && validAlgoIsHmac256 && len == 32) {
                pkt->hmacLen = *data - pkt->hmacStart - 4;
                pkt->hmacSignature = *data;
            }
            break;
#endif
        default:
            break;
        }
        *data += len;
        *datalen -= len;
        oldpos = *data - start;
    }
    if (*datalen > 0)
        goto Bail;

    pkt->pfx = p;
    pkt->buf = ccnl_buf_new(start, *data - start);
    if (!pkt->buf)
        goto Bail;
    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (pkt->content)
        pkt->content = pkt->buf->data + (pkt->content - start);
    for (i = 0; i < p->compcnt; i++)
        p->comp[i] = pkt->buf->data + (p->comp[i] - start);
    if (p->nameptr)
        p->nameptr = pkt->buf->data + (p->nameptr - start);
#ifdef USE_HMAC256
    pkt->hmacStart = pkt->buf->data + (pkt->hmacStart - start);
    pkt->hmacSignature = pkt->buf->data + (pkt->hmacSignature - start);
#endif

    return pkt;
Bail:
    free_packet(pkt);
    return NULL;
}
Example #3
0
// turn an URI into an internal prefix (watch out: this modifies the uri string)
struct ccnl_prefix_s *
ccnl_URItoPrefix(char* uri, int suite, char *nfnexpr, unsigned int *chunknum)
{
    struct ccnl_prefix_s *p;
    char *compvect[CCNL_MAX_NAME_COMP];
    unsigned int complens[CCNL_MAX_NAME_COMP];
    int cnt, i, len, tlen;

    DEBUGMSG_CPFX(TRACE, "ccnl_URItoPrefix(suite=%s, uri=%s, nfn=%s)\n",
             ccnl_suite2str(suite), uri, nfnexpr);

    if (strlen(uri))
        cnt = ccnl_URItoComponents(compvect, complens, uri);
    else
        cnt = 0;

    if (nfnexpr && *nfnexpr)
        cnt += 1;

    p = ccnl_prefix_new(suite, cnt);
    if (!p)
        return NULL;

    for (i = 0, len = 0; i < cnt; i++) {
        if (i == (cnt-1) && nfnexpr && *nfnexpr)
            len += strlen(nfnexpr);
        else
            len += complens[i];//strlen(compvect[i]);
    }
#ifdef USE_SUITE_CCNTLV
    if (suite == CCNL_SUITE_CCNTLV)
        len += cnt * 4; // add TL size
#endif
#ifdef USE_SUITE_CISTLV
    if (suite == CCNL_SUITE_CISTLV)
        len += cnt * 4; // add TL size
#endif

    p->bytes = (unsigned char*) ccnl_malloc(len);
    if (!p->bytes) {
        free_prefix(p);
        return NULL;
    }

    for (i = 0, len = 0, tlen = 0; i < cnt; i++) {
        int isnfnfcomp = i == (cnt-1) && nfnexpr && *nfnexpr;
        char *cp = isnfnfcomp ? nfnexpr : (char*) compvect[i];

        if (isnfnfcomp)
            tlen = strlen(nfnexpr);
        else
            tlen = complens[i];

        p->comp[i] = p->bytes + len;
        tlen = ccnl_pkt_mkComponent(suite, p->comp[i], cp, tlen);
        p->complen[i] = tlen;
        len += tlen;
    }

    p->compcnt = cnt;
#ifdef USE_NFN
    if (nfnexpr && *nfnexpr)
        p->nfnflags |= CCNL_PREFIX_NFN;
#endif

    if(chunknum) {
        p->chunknum = ccnl_malloc(sizeof(int));
        *p->chunknum = *chunknum;
    }

    return p;
}
// we use one extraction routine for both interest and data pkts
struct ccnl_pkt_s*
ccnl_cistlv_bytes2pkt(unsigned char *start, unsigned char **data, int *datalen)
{
    struct ccnl_pkt_s *pkt;
    int i;
    unsigned int len, typ, oldpos;
    struct ccnl_prefix_s *p;

    DEBUGMSG(DEBUG, "extracting CISTLV packet (%d, %d bytes)\n",
             (int)(*data - start), *datalen);

    pkt = (struct ccnl_pkt_s*) ccnl_calloc(1, sizeof(*pkt));
    if (!pkt)
        return NULL;

    pkt->pfx = p = ccnl_prefix_new(CCNL_SUITE_CISTLV, CCNL_MAX_NAME_COMP);
    if (!p) {
        ccnl_free(pkt);
        return NULL;
    }
    p->compcnt = 0;

    // We ignore the TL types of the message for now
    // content and interests are filled in both cases (and only one exists)
    // validation is ignored
    if (ccnl_cistlv_dehead(data, datalen, &typ, &len))
        goto Bail;
    pkt->type = typ;
    pkt->suite = CCNL_SUITE_CISTLV;
    pkt->val.final_block_id = -1;

    oldpos = *data - start;
    while (ccnl_cistlv_dehead(data, datalen, &typ, &len) == 0) {
        unsigned char *cp = *data, *cp2;
        int len2 = len;
        unsigned int len3;

        switch (typ) {
        case CISCO_TLV_Name:
            p->nameptr = start + oldpos;
            while (len2 > 0) {
                cp2 = cp;
                if (ccnl_cistlv_dehead(&cp, &len2, &typ, &len3))
                    goto Bail;

                if (typ == CISCO_TLV_NameSegment) {
                    // We extract the chunknum to the prefix but keep it in the name component for now
                    // In the future we possibly want to remove the chunk segment from the name components
                    // and rely on the chunknum field in the prefix.
                  p->chunknum = (unsigned int*) ccnl_malloc(sizeof(int));

                    if (ccnl_cistlv_extractNetworkVarInt(cp,
                                                         len2, p->chunknum) < 0) {
                        DEBUGMSG(WARNING, "Error in NetworkVarInt for chunk\n");
                        goto Bail;
                    }
                    if (p->compcnt < CCNL_MAX_NAME_COMP) {
                        p->comp[p->compcnt] = cp2;
                        p->complen[p->compcnt] = cp - cp2 + len3;
                        p->compcnt++;
                    } // else out of name component memory: skip
                } else if (typ == CISCO_TLV_NameComponent) {
                    if (p->compcnt < CCNL_MAX_NAME_COMP) {
                        p->comp[p->compcnt] = cp2;
                        p->complen[p->compcnt] = cp - cp2 + len3;
                        p->compcnt++;
                    } // else out of name component memory: skip
                }
                cp += len3;
                len2 -= len3;
            }
            p->namelen = *data - p->nameptr;
#ifdef USE_NFN
            if (p->compcnt > 0 && p->complen[p->compcnt-1] == 7 &&
                    !memcmp(p->comp[p->compcnt-1], "\x00\x01\x00\x03NFN", 7)) {
                p->nfnflags |= CCNL_PREFIX_NFN;
                p->compcnt--;
                if (p->compcnt > 0 && p->complen[p->compcnt-1] == 9 &&
                   !memcmp(p->comp[p->compcnt-1], "\x00\x01\x00\x05THUNK", 9)) {
                    p->nfnflags |= CCNL_PREFIX_THUNK;
                    p->compcnt--;
                }
            }
#endif
            break;
        case CISCO_TLV_FinalSegmentID:
            if (ccnl_cistlv_extractNetworkVarInt(cp, len2,
                               (unsigned int*) &pkt->val.final_block_id) < 0) {
                    DEBUGMSG(WARNING, "error when extracting CISCO_TLV_FinalSegmentID\n");
                    goto Bail;
            }
            break;
        case CISCO_TLV_ContentData:
            pkt->content = *data;
            pkt->contlen = len;
            break;
        default:
            break;
        }
        *data += len;
        *datalen -= len;
        oldpos = *data - start;
    }
    if (*datalen > 0)
        goto Bail;

    pkt->pfx = p;
    pkt->buf = ccnl_buf_new(start, *data - start);
    if (!pkt->buf)
        goto Bail;
    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (pkt->content)
        pkt->content = pkt->buf->data + (pkt->content - start);
    for (i = 0; i < p->compcnt; i++)
        p->comp[i] = pkt->buf->data + (p->comp[i] - start);
    if (p->nameptr)
        p->nameptr = pkt->buf->data + (p->nameptr - start);

    return pkt;
Bail:
    free_packet(pkt);
    return NULL;
}