コード例 #1
0
ファイル: ccnl-ext-crypto.c プロジェクト: DrummerB/ccn-lite
/**
 *
 * @param ccnl
 * @param content
 * @param content_len
 * @param sig
 * @param sig_len
 * @param callback function which should be called when crypto system returns
 *              for a new callback function you have to extend ccnl_crypto()!!!!
 * @return
 */
int
ccnl_crypto_verify(struct ccnl_relay_s *ccnl, char *content, int content_len,
        char *sig, int sig_len, char* callback, int sequnum)
{
    char *msg = 0;
    int len = 0, ret = 0;
    struct ccnl_buf_s *retbuf;
    //int plen;
    //unsigned char *buf;
    plen = 0;
    memset(buf,0,sizeof(buf));
    if(!ccnl->crypto_face) return ret;

    msg = (char *)ccnl_malloc(sizeof(char)*(content_len+sig_len)+3000);

    len = ccnl_crypto_create_ccnl_sign_verify_msg("verify", sequnum, content,
            content_len, sig, sig_len, msg, callback);

    if(len > CCNL_MAX_PACKET_SIZE){
        DEBUGMSG(DEBUG,"Ignored, packet size too large");
        return 0;
    }
    //send ccn_msg to crytoserver
    retbuf = ccnl_buf_new((char *)msg, len);
    ccnl_face_enqueue(ccnl, ccnl->crypto_face, retbuf);

    if(msg) ccnl_free(msg);
    return ret;
}
コード例 #2
0
// produces a full FRAG packet. It does not write, just read the fields in *fr
struct ccnl_buf_s*
ccnl_ccntlv_mkFrag(struct ccnl_frag_s *fr, unsigned int *consumed)
{
    size_t datalen;
    struct ccnl_buf_s *buf;
    struct ccnx_tlvhdr_ccnx2015_s *fp;
    uint16_t tmp;

    DEBUGMSG_PCNX(TRACE, "ccnl_ccntlv_mkFrag seqno=%u\n", fr->sendseq);

    datalen = fr->mtu - sizeof(*fp) - 4;
    if (datalen > (fr->bigpkt->datalen - fr->sendoffs)) {
        datalen = fr->bigpkt->datalen - fr->sendoffs;
    }
    if (datalen > UINT16_MAX) {
        return NULL;
    }

    buf = ccnl_buf_new(NULL, sizeof(*fp) + 4 + datalen);
    if (!buf) {
        return NULL;
    }
    fp = (struct ccnx_tlvhdr_ccnx2015_s*) buf->data;
    memset(fp, 0, sizeof(*fp));
    fp->version = CCNX_TLV_V1;
    fp->pkttype = CCNX_PT_Fragment;
    fp->hdrlen = sizeof(*fp);
    fp->pktlen = htons(sizeof(*fp) + 4 + datalen);

    tmp = htons(CCNX_TLV_TL_Fragment);
    memcpy(fp+1, &tmp, 2);
    tmp = htons((uint16_t) datalen);
    memcpy((char*)(fp+1) + 2, &tmp, 2);
    memcpy((char*)(fp+1) + 4, fr->bigpkt->data + fr->sendoffs, datalen);

    tmp = fr->sendseq & 0x03fff;
    if (datalen >= fr->bigpkt->datalen) {   // single
        tmp |= CCNL_BEFRAG_FLAG_SINGLE << 14;
    } else if (fr->sendoffs == 0) {          // start
        tmp |= CCNL_BEFRAG_FLAG_FIRST  << 14;
    } else if(datalen >= (fr->bigpkt->datalen - fr->sendoffs)) { // end
        tmp |= CCNL_BEFRAG_FLAG_LAST   << 14;
    } else {                                  // middle
        tmp |= CCNL_BEFRAG_FLAG_MID    << 14;
    }
    tmp = htons(tmp);
    memcpy(fp->fill, &tmp, 2);

    *consumed = datalen;
    return buf;
}
コード例 #3
0
// consumes the result stack, exports its content to a buffer
struct ccnl_buf_s*
Krivine_exportResultStack(struct ccnl_relay_s *ccnl,
                          struct configuration_s *config)
{
    char res[64000]; //TODO longer???
    int pos = 0;
    struct stack_s *stack;
    struct ccnl_content_s *cont;

    while ((stack = pop_or_resolve_from_result_stack(ccnl, config))) {
        if (stack->type == STACK_TYPE_PREFIX) {
            cont = ccnl_nfn_local_content_search(ccnl, config, stack->content);
            if (cont) {
                memcpy(res+pos, (char*)cont->pkt->content, cont->pkt->contlen);
                pos += cont->pkt->contlen;
            }
        } else if (stack->type == STACK_TYPE_PREFIXRAW) {
            cont = ccnl_nfn_local_content_search(ccnl, config, stack->content);
            if (cont) {
/*
                DEBUGMSG(DEBUG, "  PREFIXRAW packet: %p %d\n", (void*) cont->buf,
                         cont->buf ? cont->buf->datalen : -1);
*/
                memcpy(res+pos, (char*)cont->pkt->buf->data,
                       cont->pkt->buf->datalen);
                pos += cont->pkt->buf->datalen;
            }
        } else if (stack->type == STACK_TYPE_INT) {
            //h = ccnl_buf_new(NULL, 10);
            //sprintf((char*)h->data, "%d", *(int*)stack->content);
            //h->datalen = strlen((char*)h->data);
            pos += sprintf(res + pos, "%d", *(int*)stack->content);
        }
        ccnl_free(stack->content);
        ccnl_free(stack);
    }

    return ccnl_buf_new(res, pos);
}
コード例 #4
0
ファイル: ccnl-core.c プロジェクト: tanupoo/ccn-lite
int
ccnl_nonce_find_or_append(struct ccnl_relay_s *ccnl, struct ccnl_buf_s *nonce)
{
    struct ccnl_buf_s *n, *n2 = 0;
    int i;
    DEBUGMSG_CORE(TRACE, "ccnl_nonce_find_or_append\n");

    for (n = ccnl->nonces, i = 0; n; n = n->next, i++) {
        if (buf_equal(n, nonce))
            return -1;
        if (n->next)
            n2 = n;
    }
    n = ccnl_buf_new(nonce->data, nonce->datalen);
    if (n) {
        n->next = ccnl->nonces;
        ccnl->nonces = n;
        if (i >= CCNL_MAX_NONCES && n2) {
            ccnl_free(n2->next);
            n2->next = 0;
        }
    }
    return 0;
}
コード例 #5
0
// 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;
}
コード例 #6
0
int
ccnl_frag_RX_BeginEnd2015(RX_datagram callback, struct ccnl_relay_s *relay,
                          struct ccnl_face_s *from, int mtu,
                          unsigned int bits, unsigned int seqno,
                          unsigned char **data, int *datalen)
{
    struct ccnl_buf_s *buf = NULL;
    struct ccnl_frag_s *e;

    DEBUGMSG_EFRA(DEBUG, "ccnl_frag_RX_BeginEnd2015 (%d bytes), seqno=%d\n",
                  *datalen, seqno);

    if (!from) {
        DEBUGMSG_EFRA(WARNING, "RX_BeginEnd2015: no from value\n");
        return 0;
    }
    if (!from->frag)
        from->frag = ccnl_frag_new(CCNL_FRAG_BEGINEND2015, mtu);
    if (!from->frag) {
        DEBUGMSG_EFRA(WARNING, "no frag alloc\n");
        return 0;
    }
    if (from->frag->protocol != CCNL_FRAG_BEGINEND2015) {
        DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n");
        return 0;
    }

    e = from->frag;
    if (e->recvseq != seqno) {
        // should increase error counter here
        DEBUGMSG_EFRA(WARNING, "  >> seqnum mismatch: rcvd %d, expected %d\n",
                      seqno, e->recvseq);
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "  >> had to drop defrag buf\n");
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        e->recvseq = seqno;
    }

    switch(bits & (CCNL_BEFRAG_FLAG_MASK)) {
    case CCNL_BEFRAG_FLAG_SINGLE: // single packet
        DEBUGMSG_EFRA(VERBOSE, "  >> single fragment seqno=%d (%d bytes)\n",
                      seqno, *datalen);
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "    had to drop defrag buf\n");
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        e->recvseq++;
        // no need to copy the buffer:
        callback(relay, from, data, datalen);
        return 1;
    case CCNL_BEFRAG_FLAG_FIRST: // start of fragment sequence
        DEBUGMSG_EFRA(VERBOSE, "  >> start of fragment series\n");
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "    had to drop defrag buf\n");
            ccnl_free(e->defrag);
        }
        e->defrag = ccnl_buf_new(*data, *datalen);
        break;
    case CCNL_BEFRAG_FLAG_LAST: // end of fragment sequence
        DEBUGMSG_EFRA(VERBOSE, "  >> last fragment of a series\n");
        if (!e->defrag) {
            DEBUGMSG_EFRA(WARNING, "  >> no e->defrag?\n");
            break;
        }
        buf = ccnl_buf_new(NULL, e->defrag->datalen + *datalen);
        if (buf) {
            memcpy(buf->data, e->defrag->data, e->defrag->datalen);
            memcpy(buf->data + e->defrag->datalen, *data, *datalen);
        }
        ccnl_free(e->defrag);
        e->defrag = NULL;
        break;
    case CCNL_BEFRAG_FLAG_MID:  // fragment in the middle of a squence
    default:
        DEBUGMSG_EFRA(VERBOSE, "  >> fragment in the middle of a series\n");
        if (!e->defrag)
            break;
        buf = ccnl_buf_new(NULL, e->defrag->datalen + *datalen);
        if (buf) {
            memcpy(buf->data, e->defrag->data, e->defrag->datalen);
            memcpy(buf->data + e->defrag->datalen, *data, *datalen);
            ccnl_free(e->defrag);
            e->defrag = buf;
            buf = NULL;
        } else {
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        break;
    }
    *data += *datalen;
    *datalen = 0;
    e->recvseq++;

    if (buf) {
        unsigned char *frag = buf->data;
        int fraglen = buf->datalen;
        DEBUGMSG_EFRA(DEBUG, "  >> reassembled fragment is %d bytes\n",
                      buf->datalen);
        // FIXME: loop over multiple packets in this reassembled frame?
        callback(relay, from, &frag, &fraglen);
        ccnl_free(buf);
    }

    return 1;
}
コード例 #7
0
// processes a SEQENCED fragment. Once fully assembled we call the callback
void
ccnl_frag_RX_serialfragment(RX_datagram callback,
                            struct ccnl_relay_s *relay,
                            struct ccnl_face_s *from,
                            struct serialFragPDU_s *s)
{
    struct ccnl_buf_s *buf = NULL;
    struct ccnl_frag_s *e = from->frag;
    DEBUGMSG_EFRA(VERBOSE, "  frag %p protocol=%d, flags=%04x, seq=%d (%d)\n",
                  (void*)e, e->protocol, s->flags, s->ourseq, e->recvseq);

    if (e->recvseq != s->ourseq) {
        // should increase error counter here
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "  >> seqnum mismatch (%d/%d), dropped defrag buf\n",
                          s->ourseq, e->recvseq);
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        if (e->recvseq > s->ourseq) // old and dup fragment: ignore
            return;
    }
    switch(s->flags & (CCNL_DTAG_FRAG_FLAG_FIRST|CCNL_DTAG_FRAG_FLAG_LAST)) {
    case CCNL_DTAG_FRAG_FLAG_SINGLE: // single packet
        DEBUGMSG_EFRA(VERBOSE, "  >> single fragment (%d bytes)\n", s->contlen);
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "    had to drop defrag buf\n");
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        // no need to copy the buffer:
        callback(relay, from, &s->content, &s->contlen);
        return;
    case CCNL_DTAG_FRAG_FLAG_FIRST: // start of fragment sequence
        DEBUGMSG_EFRA(VERBOSE, "  >> start of fragment series\n");
        if (e->defrag) {
            DEBUGMSG_EFRA(WARNING, "    had to drop defrag buf\n");
            ccnl_free(e->defrag);
        }
        e->defrag = ccnl_buf_new(s->content, s->contlen);
        s->content += s->contlen;
        s->contlen = 0;
        break;
    case CCNL_DTAG_FRAG_FLAG_LAST: // end of fragment sequence
        DEBUGMSG_EFRA(VERBOSE, "  >> last fragment of a series\n");
        if (!e->defrag) {
            DEBUGMSG_EFRA(VERBOSE, "  >> no e->defrag?\n");
            break;
        }
        buf = ccnl_buf_new(NULL, e->defrag->datalen + s->contlen);
        if (buf) {
            memcpy(buf->data, e->defrag->data, e->defrag->datalen);
            memcpy(buf->data + e->defrag->datalen, s->content, s->contlen);
        }
        ccnl_free(e->defrag);
        e->defrag = NULL;
        s->content += s->contlen;
        s->contlen = 0;
        break;
    case CCNL_DTAG_FRAG_FLAG_MID:  // fragment in the middle of a squence
    default:
        DEBUGMSG_EFRA(VERBOSE, "  >> fragment in the middle of a series\n");
        if (!e->defrag) break;
        buf = ccnl_buf_new(NULL, e->defrag->datalen + s->contlen);
        if (buf) {
            memcpy(buf->data, e->defrag->data, e->defrag->datalen);
            memcpy(buf->data + e->defrag->datalen, s->content, s->contlen);
            ccnl_free(e->defrag);
            e->defrag = buf;
            buf = NULL;
        } else {
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
        s->content += s->contlen;
        s->contlen = 0;
        break;
    }
    // FIXME: we should only bump recvseq if s->ourseq is ahead, or 0
    e->recvseq = s->ourseq + 1;
    DEBUGMSG_EFRA(VERBOSE, ">>> seq from %d to %d (w=%d)\n", s->ourseq, e->recvseq,
                  s->ourseqwidth);

    if (buf) {
        unsigned char *frag = buf->data;
        int fraglen = buf->datalen;
        DEBUGMSG_EFRA(VERBOSE, "  >> reassembled fragment is %d bytes\n", buf->datalen);
        // FIXME: loop over multiple packets in this reassembled frame?
        callback(relay, from, &frag, &fraglen);
        ccnl_free(buf);
    }
}
コード例 #8
0
struct ccnl_buf_s*
ccnl_frag_getnextCCNx2013(struct ccnl_frag_s *fr, int *ifndx, sockunion *su)
{
    struct ccnl_buf_s *buf = 0;
    unsigned char header[256];
    int hdrlen, blobtaglen, flagoffs;
    unsigned int datalen;

    // switch among encodings of fragments here (ccnb, TLV, etc)

    hdrlen = ccnl_ccnb_mkHeader(header, CCNL_DTAG_FRAGMENT2013, CCN_TT_DTAG); // fragment

    hdrlen += ccnl_ccnb_mkHeader(header + hdrlen, CCNL_DTAG_FRAG2013_TYPE, CCN_TT_DTAG);
    hdrlen += ccnl_ccnb_mkHeader(header + hdrlen, 3, CCN_TT_BLOB);
    memcpy(header + hdrlen, CCNL_FRAG_TYPE_CCNx2013_VAL, 3); // "FHBH"
    header[hdrlen + 3] = '\0';
    hdrlen += 4;

    hdrlen += ccnl_ccnb_mkBinaryInt(header+hdrlen, CCNL_DTAG_FRAG2013_SEQNR, CCN_TT_DTAG,
                                    fr->sendseq, fr->sendseqwidth);

    hdrlen += ccnl_ccnb_mkBinaryInt(header+hdrlen, CCNL_DTAG_FRAG2013_FLAGS, CCN_TT_DTAG,
                                    0, fr->flagwidth);
    flagoffs = hdrlen - 2; // most significant byte of flag element

    // other optional fields would go here

    hdrlen += ccnl_ccnb_mkHeader(header+hdrlen, CCN_DTAG_CONTENT, CCN_TT_DTAG);

    blobtaglen = ccnl_ccnb_mkHeader(header + hdrlen, fr->mtu - hdrlen - 2, CCN_TT_BLOB);
    datalen = fr->mtu - hdrlen - blobtaglen - 2;
    if (datalen > (fr->bigpkt->datalen - fr->sendoffs))
        datalen = fr->bigpkt->datalen - fr->sendoffs;
    hdrlen += ccnl_ccnb_mkHeader(header + hdrlen, datalen, CCN_TT_BLOB);

    buf = ccnl_buf_new(NULL, hdrlen + datalen + 2);
    if (!buf)
        return NULL;
    memcpy(buf->data, header, hdrlen);
    memcpy(buf->data + hdrlen, fr->bigpkt->data + fr->sendoffs, datalen);
    buf->data[hdrlen + datalen] = '\0'; // end of content field
    buf->data[hdrlen + datalen + 1] = '\0'; // end of fragment

    // patch flag field:
    if (datalen >= fr->bigpkt->datalen) { // single
        buf->data[flagoffs] = CCNL_DTAG_FRAG_FLAG_SINGLE;
        ccnl_free(fr->bigpkt);
        fr->bigpkt = NULL;
    } else if (fr->sendoffs == 0) // start
        buf->data[flagoffs] = CCNL_DTAG_FRAG_FLAG_FIRST;
    else if(datalen >= (fr->bigpkt->datalen - fr->sendoffs)) { // end
        buf->data[flagoffs] = CCNL_DTAG_FRAG_FLAG_LAST;
        ccnl_free(fr->bigpkt);
        fr->bigpkt = NULL;
    } else
        buf->data[flagoffs] = CCNL_DTAG_FRAG_FLAG_MID;

    fr->sendoffs += datalen;
    fr->sendseq++;

    if (ifndx)
        *ifndx = fr->ifndx;
    if (su)
        memcpy(su, &fr->dest, sizeof(*su));

    return buf;
}
コード例 #9
0
struct ccnl_buf_s*
ccnl_frag_getnextSEQD2012(struct ccnl_frag_s *e, int *ifndx, sockunion *su)
{
    struct ccnl_buf_s *buf = 0;
    unsigned char header[256];
    int hdrlen = 0, blobtaglen, flagoffs;
    unsigned int datalen;

    DEBUGMSG_EFRA(TRACE, "ccnl_frag_getnextSEQD2012 e=%p, mtu=%d\n", (void*)e, e->mtu);
    DEBUGMSG_EFRA(TRACE, "  %d bytes to fragment, offset=%d\n",
                  e->bigpkt->datalen, e->sendoffs);

    hdrlen = ccnl_ccnb_mkHeader(header, CCNL_DTAG_FRAGMENT2012, CCN_TT_DTAG);
    hdrlen += ccnl_ccnb_mkBinaryInt(header + hdrlen, CCNL_DTAG_FRAG2012_FLAGS,
                                    CCN_TT_DTAG, 0, e->flagwidth);
    flagoffs = hdrlen - 2;
    hdrlen += ccnl_ccnb_mkBinaryInt(header + hdrlen, CCNL_DTAG_FRAG2012_YSEQN,
                                    CCN_TT_DTAG, e->recvseq, e->recvseqwidth);
    hdrlen += ccnl_ccnb_mkBinaryInt(header+hdrlen, CCNL_DTAG_FRAG2012_OLOSS, CCN_TT_DTAG,
                                    e->losscount, e->losscountwidth);

    hdrlen += ccnl_ccnb_mkBinaryInt(header + hdrlen, CCNL_DTAG_FRAG2012_SEQNR,
                                    CCN_TT_DTAG, e->sendseq, e->sendseqwidth);
    hdrlen += ccnl_ccnb_mkHeader(header+hdrlen, CCN_DTAG_CONTENT, CCN_TT_DTAG);
    blobtaglen = ccnl_ccnb_mkHeader(header+hdrlen, e->mtu - hdrlen - 2, CCN_TT_BLOB);

    datalen = e->mtu - hdrlen - blobtaglen - 2;
    if (datalen > (e->bigpkt->datalen - e->sendoffs))
        datalen = e->bigpkt->datalen - e->sendoffs;
    hdrlen += ccnl_ccnb_mkHeader(header + hdrlen, datalen, CCN_TT_BLOB);

    buf = ccnl_buf_new(NULL, hdrlen + datalen + 2);
    if (!buf)
        return NULL;
    memcpy(buf->data, header, hdrlen);
    memcpy(buf->data + hdrlen, e->bigpkt->data + e->sendoffs, datalen);
    buf->data[hdrlen + datalen] = '\0'; // end of content/any field
    buf->data[hdrlen + datalen + 1] = '\0'; // end of fragment/pdu

    if (datalen >= e->bigpkt->datalen) { // fits in a single fragment
        buf->data[flagoffs + e->flagwidth - 1] =
            CCNL_DTAG_FRAG_FLAG_FIRST | CCNL_DTAG_FRAG_FLAG_LAST;
        ccnl_free(e->bigpkt);
        e->bigpkt = NULL;
    } else if (e->sendoffs == 0) // this is the start fragment
        buf->data[flagoffs + e->flagwidth - 1] = CCNL_DTAG_FRAG_FLAG_FIRST;
    else if(datalen >= (e->bigpkt->datalen - e->sendoffs)) { // the end
        buf->data[flagoffs + e->flagwidth - 1] = CCNL_DTAG_FRAG_FLAG_LAST;
        ccnl_free(e->bigpkt);
        e->bigpkt = NULL;
    } else // in the middle
        buf->data[flagoffs + e->flagwidth - 1] = 0x00;

    e->sendoffs += datalen;
    e->sendseq++;

    DEBUGMSG_EFRA(TRACE, "  e->offset now %d\n", e->sendoffs);

    if (ifndx)
        *ifndx = e->ifndx;
    if (su)
        memcpy(su, &e->dest, sizeof(*su));
    return buf;
}
コード例 #10
0
// we use one extraction routine for both request and reply pkts
struct ccnl_pkt_s*
ccnl_iottlv_bytes2pkt(int pkttype, unsigned char *start,
                      unsigned char **data, int *datalen)
{
    struct ccnl_pkt_s *pkt;
    unsigned char *cp, tmp[10];
    int cplen, len2;
    unsigned int typ, len, state;

    DEBUGMSG_PIOT(DEBUG, "ccnl_iottlv_extract len=%d\n", *datalen);
    /*
    {
        int fd = open("s.bin", O_WRONLY|O_CREAT|O_TRUNC);
        write(fd, *data, *datalen);
        close(fd);
    }
    */

    pkt = (struct ccnl_pkt_s*) ccnl_calloc(1, sizeof(*pkt));
    if (!pkt)
        return NULL;
    pkt->suite = CCNL_SUITE_IOTTLV;
    pkt->val.final_block_id = -1;
    pkt->s.iottlv.ttl = -1;

#define IOTPS(C,L)   (((C)<<4)|(L))  // parse state: combines current state

    while (*datalen) {
        if (ccnl_iottlv_dehead(data, datalen, &typ, &len))
            goto Bail;

        state = IOTPS(pkttype, typ);
        DEBUGMSG_CFWD(TRACE, "  state = 0x%04x\n", state);
        switch (state) {
        case IOTPS(IOT_TLV_Request, IOT_TLV_R_OptHeader):
        case IOTPS(IOT_TLV_Reply, IOT_TLV_R_OptHeader):
        {
            cp = *data;
            cplen = len;
            while (cplen > 0 && !ccnl_iottlv_dehead(&cp, &cplen, &typ, (unsigned int *)&len2)) {
                if (typ == IOT_TLV_H_HopLim && len2 == 1) {
                    if (*cp > 0)
                        *cp -= 1;
                    pkt->s.iottlv.ttl = *cp;
                }
                cp += len2;
                cplen -= len2;
            }
            break;
        }

        case IOTPS(IOT_TLV_Request, IOT_TLV_R_Name):
        case IOTPS(IOT_TLV_Reply, IOT_TLV_R_Name):
            cp = *data;
            cplen = len;
            while (cplen > 0 && !ccnl_iottlv_dehead(&cp, &cplen, &typ, (unsigned int *)&len2)) {
                if (typ == IOT_TLV_N_PathName) {
                    if (!pkt->pfx)
                        pkt->pfx = ccnl_iottlv_parseHierarchicalName(cp, len2);
                    if (!pkt->pfx)
                        goto Bail;
                }
                cp += len2;
                cplen -= len2;
            }
            break;

        case IOTPS(IOT_TLV_Fragment, IOT_TLV_F_FlagsAndSeq): {
            uint16_t fragFields;
            if (len < 2) {
                DEBUGMSG_CFWD(DEBUG, "  no flags and seqno found (%d)\n", typ);
                goto Bail;
            }
            fragFields = ntohs(*(uint16_t*) *data);
            pkt->val.seqno = fragFields & 0x7ff;
            pkt->flags |= (fragFields >> 14) << 2;
            break;
        }

        case IOTPS(IOT_TLV_Request, IOT_TLV_R_Payload):
        case IOTPS(IOT_TLV_Reply, IOT_TLV_R_Payload):
            cp = *data;
            cplen = len;
            if (!ccnl_iottlv_dehead(&cp, &cplen, &typ, (unsigned int *)&len2)) {
                if (typ == IOT_TLV_PL_Data) {
                    pkt->content = cp;
                    pkt->contlen = len2;
		}
	    }
            break;

        case IOTPS(IOT_TLV_Fragment, IOT_TLV_F_Data):
            pkt->content = *data;
            pkt->contlen = len;
            break;
/*
#ifdef USE_FRAG
    if (ccnl_iottlv_peekType(*data, *datalen) == IOT_TLV_Fragment) {
        uint16_t tmp;
        unsigned int payloadlen;

        if (ccnl_iottlv_dehead(data, datalen, &typ, &len)) // IOT_TLV_Fragment
            return -1;
        if (ccnl_iottlv_dehead(data, datalen, &typ, &len))
            return -1;
        if (typ == IOT_TLV_F_OptFragHdr) { // skip it for the time being
            *data += len;
            *datalen -= len;
            if (ccnl_iottlv_dehead(data, datalen, &typ, &len))
                return -1;
        }
        if (typ != IOT_TLV_F_FlagsAndSeq || len < 2) {
            DEBUGMSG_CFWD(DEBUG, "  no flags and seqrn found (%d)\n", typ);
            return -1;
        }
        tmp = ntohs(*(uint16_t*) *data);
        *data += len;
        *datalen -= len;

        if (ccnl_iottlv_dehead(data, datalen, &typ, &payloadlen))
            return -1;
        if (typ != IOT_TLV_F_Payload) {
            DEBUGMSG_CFWD(DEBUG, "  no payload (%d)\n", typ);
            return -1;
        }
        *datalen -= payloadlen;
        ccnl_frag_RX_Sequenced2015(ccnl_iottlv_forwarder, relay, from,
                              relay->ifs[from->ifndx].mtu,
                              tmp >> 14, tmp & 0x7ff, data, (int*) &payloadlen);
        *datalen += payloadlen;

        DEBUGMSG_CFWD(TRACE, "  returning after fragment: %d bytes\n", *datalen);
        return 0;
    } else
#endif
*/
        default:
            fprintf(stderr, "  iottlv unknown state 0x%04x\n", state);
            break;
        }
        *data += len;
        *datalen -= len;
    }
    if (*datalen > 0)
        goto Bail;

// if we received a naked packet (without switch code), we need to add
// a switch code when creating the packet buffer
    if (*start != 0x80) {
        len = sizeof(tmp);
        len2 = ccnl_switch_prependCoding(CCNL_ENC_IOT2014, (int*) &len, tmp);
        if (len2 < 0) {
            DEBUGMSG(ERROR, "prending code should not return -1\n");
            len2 = 0;
        }
        start -= len2;
    } else
        len2 = 0;
    pkt->buf = ccnl_buf_new(start, *data - start);
    if (!pkt->buf)
        goto Bail;
    if (pkt->buf && len2)
        memcpy(pkt->buf->data, tmp + len, len2);

    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (pkt->content)
        pkt->content = pkt->buf->data + (pkt->content - start);
    if (pkt->pfx) {
        int i;
        for (i = 0; i < pkt->pfx->compcnt; i++)
            pkt->pfx->comp[i] = pkt->buf->data + (pkt->pfx->comp[i] - start);
        if (pkt->pfx->nameptr)
            pkt->pfx->nameptr = pkt->buf->data + (pkt->pfx->nameptr - start);
    }

    return pkt;
Bail:
    free_packet(pkt);
    return NULL;
}
コード例 #11
0
// 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;
}
コード例 #12
0
ファイル: ccnl-core.c プロジェクト: AnonMall/RIOT
struct ccnl_buf_s *
ccnl_extract_prefix_nonce_ppkd(unsigned char **data, int *datalen, int *scope,
                               int *aok, int *min, int *max, struct ccnl_prefix_s **prefix,
                               struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd,
                               unsigned char **content, int *contlen)
{
    unsigned char *start = *data - 2, *cp;
    int num, typ, len;
    struct ccnl_prefix_s *p;
    struct ccnl_buf_s *buf, *n = 0, *pub = 0;
    DEBUGMSG(99, "ccnl_extract_prefix\n");

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));

    if (!p) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        return NULL;
    }

    p->comp = (unsigned char **) ccnl_malloc(
                  CCNL_MAX_NAME_COMP * sizeof(unsigned char **));
    p->complen = (int *) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int));

    if (!p->comp || !p->complen) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        goto Bail;
    }

    while (dehead(data, datalen, &num, &typ) == 0) {
        if (num == 0 && typ == 0) {
            break;    // end
        }

        if (typ == CCN_TT_DTAG) {
            if (num == CCN_DTAG_NAME) {
                while (1) {
                    if (dehead(data, datalen, &num, &typ) != 0) {
                        goto Bail;
                    }

                    if (num == 0 && typ == 0) {
                        break;
                    }

                    if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT
                        && p->compcnt < CCNL_MAX_NAME_COMP) {
                        if (hunt_for_end(data, datalen, p->comp + p->compcnt,
                                         p->complen + p->compcnt) < 0) {
                            goto Bail;
                        }

                        p->compcnt++;
                    }
                    else {
                        if (consume(typ, num, data, datalen, 0, 0) < 0) {
                            goto Bail;
                        }
                    }
                }

                continue;
            }

            if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE
                || num == CCN_DTAG_MINSUFFCOMP
                || num == CCN_DTAG_MAXSUFFCOMP
                || num == CCN_DTAG_PUBPUBKDIGEST) {
                if (hunt_for_end(data, datalen, &cp, &len) < 0) {
                    goto Bail;
                }

                if (num == CCN_DTAG_SCOPE && len == 1 && scope) {
                    *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1;
                }

                if (num == CCN_DTAG_ANSWERORIGKIND && aok) {
                    *aok = data2uint(cp, len);
                }

                if (num == CCN_DTAG_MINSUFFCOMP && min) {
                    *min = data2uint(cp, len);
                }

                if (num == CCN_DTAG_MAXSUFFCOMP && max) {
                    *max = data2uint(cp, len);
                }

                if (num == CCN_DTAG_NONCE && !n) {
                    n = ccnl_buf_new(cp, len);
                }

                if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) {
                    pub = ccnl_buf_new(cp, len);
                }

                if (num == CCN_DTAG_EXCLUDE) {
                    DEBUGMSG(49, "warning: 'exclude' field ignored\n");
                }
                else {
                    continue;
                }
            }

            if (num == CCN_DTAG_CONTENT || num == CCN_DTAG_CONTENTOBJ) {
                if (consume(typ, num, data, datalen, content, contlen) < 0) {
                    goto Bail;
                }

                continue;
            }
        }

        if (consume(typ, num, data, datalen, 0, 0) < 0) {
            goto Bail;
        }
    }

    if (prefix) {
        p->comp[p->compcnt] = NULL;
        *prefix = p;
    }
    else {
        free_prefix(p);
    }

    if (nonce) {
        *nonce = n;
    }
    else {
        ccnl_free(n);
    }

    if (ppkd) {
        *ppkd = pub;
    }
    else {
        ccnl_free(pub);
    }

    buf = ccnl_buf_new(start, *data - start);

    if (!buf) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        goto Bail;
    }

    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (content) {
        *content = buf->data + (*content - start);
    }

    for (num = 0; num < p->compcnt; num++) {
        p->comp[num] = buf->data + (p->comp[num] - start);
    }

    return buf;
Bail:
    free_prefix(p);
    free_2ptr_list(n, pub);
    return NULL;
}
コード例 #13
0
ファイル: ccnl-core.c プロジェクト: AnonMall/RIOT
struct ccnl_buf_s *buf_dup(struct ccnl_buf_s *B)
{
    return (B) ? ccnl_buf_new(B->data, B->datalen) : NULL;
}
コード例 #14
0
ファイル: ccnl-ext-frag.c プロジェクト: Embedded-linux/RIOT
void ccnl_frag_RX_serialfragment(RX_datagram callback,
                                 struct ccnl_relay_s *relay, struct ccnl_face_s *from,
                                 struct serialFragPDU_s *s)
{
    struct ccnl_buf_s *buf = NULL;
    struct ccnl_frag_s *e = from->frag;
    DEBUGMSG(8, "  frag %p protocol=%d, flags=%04x, seq=%d (%d)\n", (void *) e,
             e->protocol, s->flags, s->ourseq, e->recvseq);

    if (e->recvseq != s->ourseq) {
        /* should increase error counter here */
        if (e->defrag) {
            DEBUGMSG(17, "  >> seqnum mismatch (%d/%d), dropped defrag buf\n",
                     s->ourseq, e->recvseq);
            ccnl_free(e->defrag);
            e->defrag = NULL;
        }
    }

    switch (s->flags & (CCNL_DTAG_FRAG_FLAG_FIRST | CCNL_DTAG_FRAG_FLAG_LAST)) {
        case CCNL_DTAG_FRAG_FLAG_SINGLE: /* single packet */
            DEBUGMSG(17, "  >> single fragment\n");

            if (e->defrag) {
                DEBUGMSG(18, "    had to drop defrag buf\n");
                ccnl_free(e->defrag);
                e->defrag = NULL;
            }

            /* no need to copy the buffer: */
            callback(relay, from, &s->content, &s->contlen);
            return;

        case CCNL_DTAG_FRAG_FLAG_FIRST: /* start of fragment sequence */
            DEBUGMSG(17, "  >> start of fragment series\n");

            if (e->defrag) {
                DEBUGMSG(18, "    had to drop defrag buf\n");
                ccnl_free(e->defrag);
            }

            e->defrag = ccnl_buf_new(s->content, s->contlen);
            break;

        case CCNL_DTAG_FRAG_FLAG_LAST: /* end of fragment sequence */
            DEBUGMSG(17, "  >> last fragment of a series\n");

            if (!e->defrag) {
                break;
            }

            buf = ccnl_buf_new(NULL, e->defrag->datalen + s->contlen);

            if (buf) {
                memcpy(buf->data, e->defrag->data, e->defrag->datalen);
                memcpy(buf->data + e->defrag->datalen, s->content, s->contlen);
            }

            ccnl_free(e->defrag);
            e->defrag = NULL;
            break;

        case CCNL_DTAG_FRAG_FLAG_MID:  /* fragment in the middle of a squence */
        default:
            DEBUGMSG(17, "  >> fragment in the middle of a series\n");

            if (!e->defrag) {
                break;
            }

            buf = ccnl_buf_new(NULL, e->defrag->datalen + s->contlen);

            if (buf) {
                memcpy(buf->data, e->defrag->data, e->defrag->datalen);
                memcpy(buf->data + e->defrag->datalen, s->content, s->contlen);
                ccnl_free(e->defrag);
                e->defrag = buf;
                buf = NULL;
            }
            else {
                ccnl_free(e->defrag);
                e->defrag = NULL;
            }

            break;
    }

    /* FIXME: we should only bump recvseq if s->ourseq is ahead, or 0 */
    e->recvseq = s->ourseq + 1;
    DEBUGMSG(1, ">>> seq from %d to %d (w=%d)\n", s->ourseq, e->recvseq,
             s->ourseqwidth);

    if (buf) {
        unsigned char *frag = buf->data;
        int fraglen = buf->datalen;
        DEBUGMSG(1, "  >> reassembled fragment is %d bytes\n", buf->datalen);
        callback(relay, from, &frag, &fraglen);
        ccnl_free(buf);
    }

    DEBUGMSG(1, "leaving function\n");
}
コード例 #15
0
// produces a full FRAG packet. It does not write, just read the fields in *fr
struct ccnl_buf_s*
ccnl_iottlv_mkFrag(struct ccnl_frag_s *fr, unsigned int *consumed)
{
    unsigned char test[20];
    int offset, hdrlen, len, len2;
    unsigned int datalen;
    struct ccnl_buf_s *buf;
    uint16_t tmp = 0;

    // test size, first
    datalen = fr->bigpkt->datalen - fr->sendoffs - 9;
    if (datalen > fr->mtu)
        datalen = fr->mtu;
    offset = sizeof(test);
    len = datalen +
             ccnl_iottlv_prependTL(IOT_TLV_F_Data, datalen, &offset, test);
    len += ccnl_iottlv_prependTL(IOT_TLV_F_FlagsAndSeq, 2, &offset, test) + 2;
    ccnl_iottlv_prependTL(IOT_TLV_Fragment, len, &offset, test);
    hdrlen = sizeof(test) - offset + 2 + 2; // adj for flagAndSeq, switch code

    // with real values:
    datalen = fr->bigpkt->datalen - fr->sendoffs;
    if (datalen > (fr->mtu - hdrlen))
        datalen = fr->mtu - hdrlen;

    buf = ccnl_buf_new(NULL, hdrlen + datalen); // 2 bytes for switch code
    if (!buf)
        return 0;
    offset = buf->datalen;
    len = ccnl_iottlv_prependBlob(IOT_TLV_F_Data,
                 fr->bigpkt->data + fr->sendoffs, datalen, &offset, buf->data);
    if (len <= 0) {
        ccnl_free(buf);
        return NULL;
    }

    // flags and sequence number
    if (datalen >= fr->bigpkt->datalen) { // single
        tmp |= CCNL_DTAG_FRAG_FLAG_SINGLE << 14;
    } else if (fr->sendoffs == 0) // start
        tmp |= CCNL_DTAG_FRAG_FLAG_FIRST << 14;
    else if(datalen >= (fr->bigpkt->datalen - fr->sendoffs)) { // end
        tmp |= CCNL_DTAG_FRAG_FLAG_LAST << 14;
    } else
        tmp |= CCNL_DTAG_FRAG_FLAG_MID << 14;
    tmp |= fr->sendseq & 0x07ff;
    tmp = htons(tmp);
    len2 = ccnl_iottlv_prependBlob(IOT_TLV_F_FlagsAndSeq, (unsigned char*)
                                   &tmp, sizeof(tmp), &offset, buf->data);
    if (len2 <= 0) {
        ccnl_free(buf);
        return NULL;
    }
    len += len2;
    // main header
    len2 = ccnl_iottlv_prependTL(IOT_TLV_Fragment, len, &offset, buf->data);
    if (len2 <= 0) {
        ccnl_free(buf);
        return NULL;
    }
    len += len2;

    // encoding switch:
    len2 = ccnl_switch_prependCoding(CCNL_ENC_IOT2014, &offset, buf->data);
    if (len2 < 0) {
        DEBUGMSG(ERROR, "  prending code should not return -1\n");
        ccnl_free(buf);
        return NULL;
    }
    len += len2;

    if (offset > 0) {
        DEBUGMSG(TRACE, "  iottlv fragment: shift by %d bytes\n", offset);
        memmove(buf->data, buf->data + offset, len);
        buf->datalen = len;
    }

    *consumed = datalen;
    return buf;
}
コード例 #16
0
ファイル: ccnl-ext-crypto.c プロジェクト: DrummerB/ccn-lite
int
ccnl_mgmt_crypto(struct ccnl_relay_s *ccnl, char *type, unsigned char *buf, int buflen)
{

   struct ccnl_face_s *from;
   DEBUGMSG(DEBUG,"ccnl_crypto type: %s\n", type);

   if(!strcmp(type, "verify")){
      int seqnum = 0;
      int verified = ccnl_crypto_extract_verify_reply(&buf, &buflen, &seqnum);
      unsigned char *msg, *msg2;
      char cmd[500];
      int len = ccnl_crypto_extract_msg(&buf, &buflen, &msg), len2 = 0;
      struct ccnl_face_s *from;
      //DEBUGMSG(DEBUG,"VERIFIED: %d, MSG_LEN: %d\n", verified, len);

      int scope=3, aok=3, minsfx=0, maxsfx=CCNL_MAX_NAME_COMP, contlen;
      struct ccnl_buf_s *buf1 = 0, *nonce=0, *ppkd=0;
      struct ccnl_prefix_s *p = 0;
      struct ccnl_buf_s *msg2_buf;
      unsigned char *content = 0;

      msg2 = (char *) ccnl_malloc(sizeof(char) * len + 200);
      len2 = ccnl_ccnb_mkHeader(msg2,CCN_DTAG_NAME, CCN_TT_DTAG);
      memcpy(msg2+len2, msg, len);
      len2 +=len;
      msg2[len2++] = 0;

      from = ccnl->faces;
      while(from){
          if(from->faceid == seqnum)
              break;
          from = from->next;
      }

      buf1 = ccnl_ccnb_extract(&msg2, &len2, &scope, &aok, &minsfx,
                         &maxsfx, &p, &nonce, &ppkd, &content, &contlen);

      if (p->complen[2] < sizeof(cmd)) {
            memcpy(cmd, p->comp[2], p->complen[2]);
            cmd[p->complen[2]] = '\0';
      } else
            strcpy(cmd, "cmd-is-too-long-to-display");
      msg2_buf = ccnl_buf_new((char *)msg2, len2);
      ccnl_mgmt_handle(ccnl, msg2_buf, p, from, cmd, verified);
      ccnl_free(msg2_buf);
   }else if(!strcmp(type, "sign")){
      char *sig = (char *) ccnl_malloc(sizeof(char)* CCNL_MAX_PACKET_SIZE);
      unsigned char *out;
      unsigned char *msg;
      int siglen = 0, seqnum = 0, len, len1;
      struct ccnl_buf_s *retbuf;

      ccnl_crypto_extract_sign_reply(&buf, &buflen, sig, &siglen, &seqnum);

      len = ccnl_crypto_extract_msg(&buf, &buflen, &msg);
      out = (char *) ccnl_malloc(sizeof(unsigned char)*len + sizeof(unsigned char)*siglen + 4096);

      len1 = ccnl_ccnb_mkHeader(out, CCN_DTAG_CONTENTOBJ, CCN_TT_DTAG);   // content
      if(siglen > 0) len1 += ccnl_crypto_add_signature(out+len1, sig, siglen);

      memcpy(out+len1, msg, len);
      len1 +=len;

      out[len1++] = 0; // end-of-interest
      from = ccnl->faces;
      while(from){
          if(from->faceid == seqnum)
              break;
          from = from->next;
      }

      retbuf = ccnl_buf_new((char *)out, len1);
      if(seqnum >= 0){
          ccnl_face_enqueue(ccnl, from, retbuf);
      }else{
          struct ccnl_prefix_s *prefix_a = 0;
          struct ccnl_content_s *c = 0;
          struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0;
          unsigned char *content = 0;
          char *ht = (char *) ccnl_malloc(sizeof(char)*20);
          int contlen;
          pkt = ccnl_ccnb_extract(&out, &len1, 0, 0, 0, 0,
                                  &prefix_a, &nonce, &ppkd, &content, &contlen);

          if (!pkt) {
               DEBUGMSG(WARNING, " parsing error\n"); goto Done;
          }
          if (prefix_a) {
              //DEBUGMSG(DEBUG, "%s", prefix_a->comp);
              //ccnl_free(prefix_a);
          }
          //prefix_a = (struct ccnl_prefix_s *)ccnl_malloc(sizeof(struct ccnl_prefix_s));
          prefix_a->compcnt = 2;
          prefix_a->comp = (unsigned char **) ccnl_malloc(sizeof(unsigned char*)*2);
          prefix_a->comp[0] = "mgmt";
          sprintf(ht, "seqnum-%d", -seqnum);
          prefix_a->comp[1] = ht;
          prefix_a->complen = (int *) ccnl_malloc(sizeof(int)*2);
          prefix_a->complen[0] = strlen("mgmt");
          prefix_a->complen[1] = strlen(ht);
          c = ccnl_content_new(ccnl, CCNL_SUITE_CCNB, &pkt, &prefix_a, &ppkd,
                                content, contlen);
          if (!c) goto Done;

          ccnl_content_serve_pending(ccnl, c);
          ccnl_content_add2cache(ccnl, c);
      }
      Done:
      ccnl_free(out);
   }
   return 0;
}
コード例 #17
0
ファイル: fwd-ccnb.c プロジェクト: truedat101/ccn-lite
struct ccnl_buf_s*
ccnl_ccnb_extract(unsigned char **data, int *datalen,
		  int *scope, int *aok, int *min, int *max,
		  struct ccnl_prefix_s **prefix,
		  struct ccnl_buf_s **nonce,
		  struct ccnl_buf_s **ppkd,
		  unsigned char **content, int *contlen)
{
    unsigned char *start = *data - 2 /* account for outer TAG hdr */, *cp;
    int num, typ, len;
    struct ccnl_prefix_s *p;
    struct ccnl_buf_s *buf, *n = 0, *pub = 0;
    DEBUGMSG(99, "ccnl_ccnb_extract\n");

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));
    if (!p) return NULL;
    p->comp = (unsigned char**) ccnl_malloc(CCNL_MAX_NAME_COMP *
					   sizeof(unsigned char**));
    p->complen = (int*) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int));
    if (!p->comp || !p->complen) goto Bail;

    while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) {
	if (num==0 && typ==0) break; // end
	if (typ == CCN_TT_DTAG) {
	    if (num == CCN_DTAG_NAME) {
		for (;;) {
		    if (ccnl_ccnb_dehead(data, datalen, &num, &typ) != 0)
			goto Bail;
		    if (num==0 && typ==0)
			break;
		    if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT &&
			p->compcnt < CCNL_MAX_NAME_COMP) {
			if (ccnl_ccnb_hunt_for_end(data, datalen, p->comp + p->compcnt,
				p->complen + p->compcnt) < 0) goto Bail;
			p->compcnt++;
		    } else {
			if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0)
			    goto Bail;
		    }
		}
		continue;
	    }
	    if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE ||
		num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP ||
					 num == CCN_DTAG_PUBPUBKDIGEST) {
		if (ccnl_ccnb_hunt_for_end(data, datalen, &cp, &len) < 0) goto Bail;
		if (num == CCN_DTAG_SCOPE && len == 1 && scope)
		    *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1;
		if (num == CCN_DTAG_ANSWERORIGKIND && aok)
		    *aok = ccnl_ccnb_data2uint(cp, len);
		if (num == CCN_DTAG_MINSUFFCOMP && min)
		    *min = ccnl_ccnb_data2uint(cp, len);
		if (num == CCN_DTAG_MAXSUFFCOMP && max)
		    *max = ccnl_ccnb_data2uint(cp, len);
		if (num == CCN_DTAG_NONCE && !n)
		    n = ccnl_buf_new(cp, len);
		if (num == CCN_DTAG_PUBPUBKDIGEST && !pub)
		    pub = ccnl_buf_new(cp, len);
		if (num == CCN_DTAG_EXCLUDE) {
		    DEBUGMSG(49, "warning: 'exclude' field ignored\n");
		} else
		    continue;
	    }
	    if (num == CCN_DTAG_CONTENT) {
		if (ccnl_ccnb_consume(typ, num, data, datalen, content, contlen) < 0)
		    goto Bail;
		continue;
	    }
	}
	if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail;
    }
    if (prefix)    *prefix = p;    else free_prefix(p);
    if (nonce)     *nonce = n;     else ccnl_free(n);
    if (ppkd)      *ppkd = pub;    else ccnl_free(pub);

    buf = ccnl_buf_new(start, *data - start);
    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (content)
	*content = buf->data + (*content - start);
    for (num = 0; num < p->compcnt; num++)
	    p->comp[num] = buf->data + (p->comp[num] - start);
    return buf;
Bail:
    free_prefix(p);
    free_2ptr_list(n, pub);
    return NULL;
}