// executes (loops over) a Lambda expression: tries to run to termination,
// or returns after having emitted further remote lookup/reduction requests
// the return val is a buffer with the result stack's (concatenated) content
struct ccnl_buf_s*
Krivine_reduction(struct ccnl_relay_s *ccnl, char *expression,
                  int start_locally,
                  struct configuration_s **config,
                  struct ccnl_prefix_s *prefix, int suite)
{
    int steps = 0, halt = 0, restart = 1;
    int len = strlen("CLOSURE(HALT);RESOLVENAME()") + strlen(expression) + 1;
    char *dummybuf;

    DEBUGMSG(TRACE, "Krivine_reduction()\n");

    if (!*config && strlen(expression) == 0)
        return 0;
    dummybuf = ccnl_malloc(2000);
    if (!*config) {
        char *prog;
        struct environment_s *global_dict = NULL;

        prog = ccnl_malloc(len*sizeof(char));
        sprintf(prog, "CLOSURE(HALT);RESOLVENAME(%s)", expression);
        setup_global_environment(&global_dict);
        DEBUGMSG(DEBUG, "PREFIX %s\n", ccnl_prefix_to_path(prefix));
        *config = new_config(ccnl, prog, global_dict,
                             start_locally,
                             prefix, ccnl->km->configid, suite);
        DBL_LINKED_LIST_ADD(ccnl->km->configuration_list, (*config));
        restart = 0;
        --ccnl->km->configid;
    }
    DEBUGMSG(INFO, "Prog: %s\n", (*config)->prog);

    while ((*config)->prog && !halt) {
        char *oldprog = (*config)->prog;
        steps++;
        DEBUGMSG(DEBUG, "Step %d (%d/%d): %s\n", steps,
                 stack_len((*config)->argument_stack),
                 stack_len((*config)->result_stack), (*config)->prog);
        (*config)->prog = ZAM_term(ccnl, *config, &halt, dummybuf, &restart);
        ccnl_free(oldprog);
    }
    ccnl_free(dummybuf);

    if (halt < 0) { //HALT < 0 means pause computation
        DEBUGMSG(INFO,"Pause computation: %d\n", -(*config)->configid);
        return NULL;
    }

    //HALT > 0 means computation finished
    DEBUGMSG(INFO, "end-of-computation (%d/%d)\n",
             stack_len((*config)->argument_stack),
             stack_len((*config)->result_stack));
/*
    print_argument_stack((*config)->argument_stack);
    print_result_stack((*config)->result_stack);
*/

    return Krivine_exportResultStack(ccnl, *config);
}
struct ccnl_prefix_s *
ccnl_iottlv_parseHierarchicalName(unsigned char *data, int datalen)
{
    int len = datalen;
    unsigned int typ, len2;
    struct ccnl_prefix_s *p;

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));
    if (!p)
        return NULL;
    p->suite = CCNL_SUITE_IOTTLV;
    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)
        return NULL;

    p->nameptr = data;
    p->namelen = len;
    while (len > 0) {
        if (ccnl_iottlv_dehead(&data, &len, &typ, &len2))
            goto Bail;
        if (typ == IOT_TLV_PN_Component &&
                               p->compcnt < CCNL_MAX_NAME_COMP) {
            p->comp[p->compcnt] = data;
            p->complen[p->compcnt] = len2;
            p->compcnt++;
        }
        data += len2;
        len -= len2;
    }
    datalen -= p->namelen;
#ifdef USE_NFN
            if (p->compcnt > 0 && p->complen[p->compcnt-1] == 3 &&
                    !memcmp(p->comp[p->compcnt-1], "NFN", 3)) {
                p->nfnflags |= CCNL_PREFIX_NFN;
                p->compcnt--;
                if (p->compcnt > 0 && p->complen[p->compcnt-1] == 5 &&
                        !memcmp(p->comp[p->compcnt-1], "THUNK", 5)) {
                    p->nfnflags |= CCNL_PREFIX_THUNK;
                    p->compcnt--;
                }
            }
#endif

    return p;
  Bail:
    free_prefix(p);
    return NULL;
}
Example #3
0
int riot_send_msg(uint8_t *buf, uint16_t size, uint16_t to)
{
    DEBUGMSG(1, "this is a RIOT MSG based connection\n");
    DEBUGMSG(1, "size=%" PRIu16 " to=%" PRIu16 "\n", size, to);

    uint8_t *buf2 = ccnl_malloc(sizeof(riot_ccnl_msg_t) + size);
    if (!buf2) {
        DEBUGMSG(1, "  malloc failed...dorpping msg!\n");
        return 0;
    }

    riot_ccnl_msg_t *rmsg = (riot_ccnl_msg_t *) buf2;
    rmsg->payload = buf2 + sizeof(riot_ccnl_msg_t);
    rmsg->size = size;

    memcpy(rmsg->payload, buf, size);

    msg_t m;
    m.type = CCNL_RIOT_MSG;
    m.content.ptr = (char *) rmsg;
    DEBUGMSG(1, "sending msg to pid=%" PRIkernel_pid "\n", to);
    msg_send(&m, to);

    return size;
}
Example #4
0
/**
 *
 * @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;
}
Example #5
0
char*
ccnl_lambdaParseVar(char **cpp)
{
    char *p;
    int len, string = 0;

    p = *cpp;
    if (*p && *p == '\''){ // Parse a String between ''
        string = 1;
        p++;
        while(*p != '\''){
            p++;
        }
    }
    else{
        while (*p && (isalnum(*p) || *p == '_' || *p == '=' || *p == '/' || *p == '.')){
           p++;
        }
    }
    len = p - *cpp + string;
    p = ccnl_malloc(len+1);
    if (!p)
        return 0;
    memcpy(p, *cpp, len);
    p[len] = '\0';
    *cpp += len;
    return p;
}
Example #6
0
static int
ccnl_crypto_create_ccnl_sign_verify_msg(char *typ, int txid, char *content, int content_len,
        char *sig, int sig_len, char *msg, char *callback)
{
    int len = 0, len2 = 0, len3 = 0;
    char *component_buf, *contentobj_buf;
    char h[100];

    component_buf = ccnl_malloc(sizeof(char)*(content_len)+2000);
    contentobj_buf = ccnl_malloc(sizeof(char)*(content_len)+1000);

    len = ccnl_ccnb_mkHeader(msg, CCN_DTAG_INTEREST, CCN_TT_DTAG);   // interest
    len += ccnl_ccnb_mkHeader(msg+len, CCN_DTAG_NAME, CCN_TT_DTAG);  // name

    len += ccnl_ccnb_mkStrBlob(msg+len, CCN_DTAG_COMPONENT, CCN_TT_DTAG, "ccnx");
    len += ccnl_ccnb_mkStrBlob(msg+len, CCN_DTAG_COMPONENT, CCN_TT_DTAG, "crypto");

    // prepare FACEINSTANCE
    len3 += ccnl_ccnb_mkStrBlob(component_buf+len3, CCNL_DTAG_CALLBACK, CCN_TT_DTAG, callback);
    len3 += ccnl_ccnb_mkStrBlob(component_buf+len3, CCN_DTAG_TYPE, CCN_TT_DTAG, typ);
    memset(h, 0, 100);
    sprintf(h, "%d", txid);
    len3 += ccnl_ccnb_mkStrBlob(component_buf+len3, CCN_DTAG_SEQNO, CCN_TT_DTAG, h);
    if(!strcmp(typ, "verify"))
        len3 += ccnl_ccnb_mkBlob(component_buf+len3, CCN_DTAG_SIGNATURE, CCN_TT_DTAG,  // content
                   (char*) sig, sig_len);
    len3 += ccnl_ccnb_mkBlob(component_buf+len3, CCN_DTAG_CONTENTDIGEST, CCN_TT_DTAG,  // content
                   (char*) content, content_len);

    // prepare CONTENTOBJ with CONTENT
    len2 = ccnl_ccnb_mkHeader(contentobj_buf, CCN_DTAG_CONTENTOBJ, CCN_TT_DTAG);   // contentobj
    len2 += ccnl_ccnb_mkBlob(contentobj_buf+len2, CCN_DTAG_CONTENT, CCN_TT_DTAG,  // content
                   (char*) component_buf, len3);
    contentobj_buf[len2++] = 0; // end-of-contentobj

    // add CONTENTOBJ as the final name component
    len += ccnl_ccnb_mkBlob(msg+len, CCN_DTAG_COMPONENT, CCN_TT_DTAG,  // comp
                  (char*) contentobj_buf, len2);

    msg[len++] = 0; // end-of-name
    msg[len++] = 0; // end-o

    ccnl_free(component_buf);
    ccnl_free(contentobj_buf);

    return len;
}
Example #7
0
struct ccnl_prefix_s*
ccnl_prefix_new(int suite, int cnt)
{
    struct ccnl_prefix_s *p;

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));
    if (!p)
        return NULL;
    p->comp = (unsigned char**) ccnl_malloc(cnt * sizeof(unsigned char*));
    p->complen = (int*) ccnl_malloc(cnt * sizeof(int));
    if (!p->comp || !p->complen) {
        free_prefix(p);
        return NULL;
    }
    p->compcnt = cnt;
    p->suite = suite;
    p->chunknum = NULL;

    return p;
}
Example #8
0
struct ccnl_nonce_s *ccnl_nonce_new(struct ccnl_buf_s *that)
{
    struct ccnl_nonce_s *n = (struct ccnl_nonce_s *) ccnl_malloc(sizeof(struct ccnl_nonce_s));

    n->buf = buf_dup(that);
    ccnl_get_timeval(&n->created);

    n->next = NULL;
    n->prev = NULL;

    return n;
}
Example #9
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;
}
Example #10
0
int
ccnl_prefix_appendCmp(struct ccnl_prefix_s *prefix, unsigned char *cmp,
                      int cmplen)
{
    int lastcmp = prefix->compcnt, i;
    int *oldcomplen = prefix->complen;
    unsigned char **oldcomp = prefix->comp;
    unsigned char *oldbytes = prefix->bytes;

    int prefixlen = 0;

    if (prefix->compcnt + 1 > CCNL_MAX_NAME_COMP)
        return -1;
    for (i = 0; i < lastcmp; i++) {
        prefixlen += prefix->complen[i];
    }

    prefix->compcnt++;
    prefix->comp = (unsigned char**) ccnl_malloc(prefix->compcnt * sizeof(unsigned char*));
    prefix->complen = (int*) ccnl_malloc(prefix->compcnt * sizeof(int));
    prefix->bytes = (unsigned char*) ccnl_malloc(prefixlen + cmplen);

    memcpy(prefix->bytes, oldbytes, prefixlen);
    memcpy(prefix->bytes + prefixlen, cmp, cmplen);

    prefixlen = 0;
    for (i = 0; i < lastcmp; i++) {
        prefix->comp[i] = &prefix->bytes[prefixlen];
        prefix->complen[i] = oldcomplen[i];
        prefixlen += oldcomplen[i];
    }
    prefix->comp[lastcmp] = &prefix->bytes[prefixlen];
    prefix->complen[lastcmp] = cmplen;

    ccnl_free(oldcomp);
    ccnl_free(oldcomplen);
    ccnl_free(oldbytes);

    return 0;
}
Example #11
0
struct ccnl_buf_s*
ccnl_buf_new(void *data, int len)
{
    struct ccnl_buf_s *b = ccnl_malloc(sizeof(*b) + len);

    if (!b)
        return NULL;
    b->next = NULL;
    b->datalen = len;
    if (data)
        memcpy(b->data, data, len);
    return b;
}
Example #12
0
struct ccnl_buf_s*
ccnl_buf_new(void *data, size_t len)
{
    struct ccnl_buf_s *b = (struct ccnl_buf_s*) ccnl_malloc(sizeof(*b) + len);

    if (!b) {
        return NULL;
    }
    b->next = NULL;
    b->datalen = len;
    if (data) {
        memcpy(b->data, data, len);
    }
    return b;
}
Example #13
0
char*
op_builtin_add(struct ccnl_relay_s *ccnl, struct configuration_s *config,
               int *restart, int *halt, char *prog, char *pending,
               struct stack_s **stack)
{
    int i1=0, i2=0, *h;

    DEBUGMSG(DEBUG, "---to do: OP_ADD <%s> pending: %s\n", prog+7, pending);
    pop2int();
    h = ccnl_malloc(sizeof(int));
    *h = i1 + i2;
    push_to_stack(stack, h, STACK_TYPE_INT);

    return pending ? ccnl_strdup(pending) : NULL;
}
// executes a ZAM instruction, returns the term to continue working on
char*
ZAM_term(struct ccnl_relay_s *ccnl, struct configuration_s *config,
        int *halt, char *dummybuf, int *restart)
{
//    struct ccnl_lambdaTerm_s *t;
//    char *pending, *p, *cp, *prog = config->prog;
//    int len;

    char *prog = config->prog;
    struct builtin_s *bp;
    char *arg, *contd;
    int tok;

    //pop closure
    if (!prog || strlen(prog) == 0) {
         if (config->result_stack) {
             prog = ccnl_malloc(strlen((char*)config->result_stack->content)+1);
             strcpy(prog, config->result_stack->content);
             return prog;
         }
         DEBUGMSG(DEBUG, "no result returned\n");
         return NULL;
    }

    tok = ZAM_nextToken(prog, &arg, &contd);

    // TODO: count opening/closing parentheses when hunting for ';' ?
/*
    pending = strchr(prog, ';');
    p = strchr(prog, '(');
*/

    switch (tok) {
    case ZAM_ACCESS:
    {
        struct closure_s *closure = search_in_environment(config->env, arg);
        DEBUGMSG(DEBUG, "---to do: access <%s>\n", arg);
        if (!closure) {
            // TODO: is the following needed? Above search should have
            // visited global_dict, already!
            closure = search_in_environment(config->global_dict, arg);
            if (!closure) {
                DEBUGMSG(WARNING, "?? could not lookup var %s\n", arg);
                ccnl_free(arg);
                return NULL;
            }
        }
        ccnl_free(arg);
        closure = new_closure(ccnl_strdup(closure->term), closure->env);
        push_to_stack(&config->argument_stack, closure, STACK_TYPE_CLOSURE);
        return ccnl_strdup(contd);
    }
    case ZAM_APPLY:
    {
        struct stack_s *fct = pop_from_stack(&config->argument_stack);
        struct stack_s *par = pop_from_stack(&config->argument_stack);
        struct closure_s *fclosure, *aclosure;
        char *code;
        DEBUGMSG(DEBUG, "---to do: apply\n");

        if (!fct || !par)
            return NULL;
        fclosure = (struct closure_s *) fct->content;
        aclosure = (struct closure_s *) par->content;
        if (!fclosure || !aclosure)
            return NULL;
        ccnl_free(fct);
        ccnl_free(par);

        code = aclosure->term;
        if (config->env)
            ccnl_nfn_releaseEnvironment(&config->env);
        config->env = aclosure->env;
        ccnl_free(aclosure);
        push_to_stack(&config->argument_stack, fclosure, STACK_TYPE_CLOSURE);

        if (contd)
            sprintf(dummybuf, "%s;%s", code, contd);
        else
            strcat(dummybuf, code);
        ccnl_free(code);
        return ccnl_strdup(dummybuf);
    }
    case ZAM_CALL:
    {
        struct stack_s *h = pop_or_resolve_from_result_stack(ccnl, config);
        int i, offset, num_params = *(int *)h->content;
        char name[5];

        DEBUGMSG(DEBUG, "---to do: CALL <%s>\n", arg);
        ccnl_free(h->content);
        ccnl_free(h);
        sprintf(dummybuf, "CLOSURE(FOX);RESOLVENAME(@op(");
	// ... @x(@y y x 2 op)));TAILAPPLY";
        offset = strlen(dummybuf);
        for (i = 0; i < num_params; ++i) {
            sprintf(name, "x%d", i);
            offset += sprintf(dummybuf+offset, "@%s(", name);
        }
        for (i = num_params - 1; i >= 0; --i) {
            sprintf(name, "x%d", i);
            offset += sprintf(dummybuf+offset, " %s", name);
        }
        offset += sprintf(dummybuf + offset, " %d", num_params);
        offset += sprintf(dummybuf+offset, " op");
        for (i = 0; i < num_params+2; ++i)
            offset += sprintf(dummybuf + offset, ")");
        if (contd)
            sprintf(dummybuf + offset, ";%s", contd);
        return ccnl_strdup(dummybuf);
    }
    case ZAM_CLOSURE:
    {
        struct closure_s *closure;
        DEBUGMSG(DEBUG, "---to do: closure <%s> (contd=%s)\n", arg, contd);

        if (!config->argument_stack && !strncmp(arg, "RESOLVENAME(", 12)) {
            char v[500], *c;
            int len;
            c = strchr(arg+12, ')');
            if (!c)
                goto normal;
            len = c - (arg+12);
            memcpy(v, arg+12, len);
            v[len] = '\0';
            closure = search_in_environment(config->env, v);
            if (!closure)
                goto normal;
            if (!strcmp(closure->term, arg)) {
                DEBUGMSG(WARNING, "** detected tail recursion case %s/%s\n",
                         closure->term, arg);
            } else
                goto normal;
        } else {
normal:
            closure = new_closure(arg, config->env);
            //configuration->env = NULL;//FIXME new environment?
            push_to_stack(&config->argument_stack, closure, STACK_TYPE_CLOSURE);
            arg = NULL;
        }
        if (contd) {
            ccnl_free(arg);
            return ccnl_strdup(contd);
        }
        DEBUGMSG(ERROR, "** not implemented, see line %d\n", __LINE__);
        return arg;
    }
    case ZAM_FOX:
        return ZAM_fox(ccnl, config, restart, halt, prog, arg, contd);
    case ZAM_GRAB:
    {
        struct stack_s *stack = pop_from_stack(&config->argument_stack);
        DEBUGMSG(DEBUG, "---to do: grab <%s>\n", arg);
        add_to_environment(&config->env, arg, stack->content);
        ccnl_free(stack);
        return ccnl_strdup(contd);
    }
    case ZAM_HALT:
        ccnl_nfn_freeStack(config->argument_stack);
        //ccnl_nfn_freeStack(config->result_stack);
        config->argument_stack = /*config->result_stack =*/ NULL;
        *halt = 1;
        return ccnl_strdup(contd);
    case ZAM_RESOLVENAME:
        return ZAM_resolvename(config, dummybuf, arg, contd);
    case ZAM_TAILAPPLY:
    {
        struct stack_s *stack = pop_from_stack(&config->argument_stack);
        struct closure_s *closure = (struct closure_s *) stack->content;
        char *code = closure->term;
        DEBUGMSG(DEBUG, "---to do: tailapply\n");

        ccnl_free(stack);
        if (contd) //build new term
            sprintf(dummybuf, "%s;%s", code, contd);
        else
            strcpy(dummybuf, code);
        if (config->env)
            ccnl_nfn_releaseEnvironment(&config->env);
        config->env = closure->env; //set environment from closure
        ccnl_free(code);
        ccnl_free(closure);
        return ccnl_strdup(dummybuf);
    }
    case ZAM_UNKNOWN:
        break;
    default:
        DEBUGMSG(DEBUG, "builtin: %s (%s/%s)\n", bifs[-tok - 1].name, prog, contd);
        return bifs[-tok - 1].fct(ccnl, config, restart, halt, prog,
                                  contd, &config->result_stack);
    }

    ccnl_free(arg);

    // iterate through all extension operations
    for (bp = op_extensions; bp; bp = bp->next)
        if (!strncmp(prog, bp->name, strlen(bp->name)))
            return (bp->fct)(ccnl, config, restart, halt, prog,
                             contd, &config->result_stack);

    DEBUGMSG(INFO, "unknown (built-in) command <%s>\n", prog);

    return NULL;
}
// 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 #16
0
char*
op_builtin_find(struct ccnl_relay_s *ccnl, struct configuration_s *config,
                int *restart, int *halt, char *prog, char *pending,
                struct stack_s **stack)
{
    int local_search = 0;
    struct stack_s *h;
    char *cp = NULL;
    struct ccnl_prefix_s *prefix;
    struct ccnl_content_s *c = NULL;

    if (*restart) {
        DEBUGMSG(DEBUG, "---to do: OP_FIND restart\n");
        *restart = 0;
        local_search = 1;
    } else {
        DEBUGMSG(DEBUG, "---to do: OP_FIND <%s> <%s>\n", prog+7, pending);
        h = pop_from_stack(&config->result_stack);
        //    if (h->type != STACK_TYPE_PREFIX)  ...
        config->fox_state->num_of_params = 1;
        config->fox_state->params = ccnl_malloc(sizeof(struct ccnl_stack_s *));
        config->fox_state->params[0] = h;
        config->fox_state->it_routable_param = 0;
    }
    prefix = config->fox_state->params[0]->content;

    //check if result is now available
    //loop by reentering (with local_search) after timeout of the interest...
    DEBUGMSG(DEBUG, "FIND: Checking if result was received\n");
    c = ccnl_nfn_local_content_search(ccnl, config, prefix);
    if (!c) {
        struct ccnl_prefix_s *copy;
        struct ccnl_interest_s *interest;
        if (local_search) {
            DEBUGMSG(INFO, "FIND: no content\n");
            return NULL;
        }
        //Result not in cache, search over the network
        //        struct ccnl_interest_s *interest = mkInterestObject(ccnl, config, prefix);
        copy = ccnl_prefix_dup(prefix);
        interest = ccnl_nfn_query2interest(ccnl, &copy, config);
        DEBUGMSG(DEBUG, "FIND: sending new interest from Face ID: %d\n",
                 interest->from->faceid);
        if (interest)
            ccnl_interest_propagate(ccnl, interest);
        //wait for content, return current program to continue later
        *halt = -1; //set halt to -1 for async computations
        return ccnl_strdup(prog);
    }

    DEBUGMSG(INFO, "FIND: result was found ---> handle it (%s), prog=%s, pending=%s\n", ccnl_prefix_to_path(prefix), prog, pending);
#ifdef USE_NACK
/*
    if (!strncmp((char*)c->content, ":NACK", 5)) {
        DEBUGMSG(DEBUG, "NACK RECEIVED, going to next parameter\n");
        ++config->fox_state->it_routable_param;
        
        return prog ? ccnl_strdup(prog) : NULL;
    }
*/
#endif
    prefix = ccnl_prefix_dup(prefix);
    push_to_stack(&config->result_stack, prefix, STACK_TYPE_PREFIX);

    if (pending) {
        DEBUGMSG(DEBUG, "Pending: %s\n", pending);

        cp = ccnl_strdup(pending);
    }
    return cp;
}
Example #17
0
char*
op_builtin_nstrans(struct ccnl_relay_s *ccnl, struct configuration_s *config,
                   int *restart, int *halt, char *prog, char *pending,
                   struct stack_s **stack)
{
    char *cp = NULL;
    struct stack_s *s1, *s2;

    DEBUGMSG(DEBUG, "---to do: OP_NSTRANS\n");

    s1 = pop_or_resolve_from_result_stack(ccnl, config);
    if (!s1) {
        *halt = -1;
        return prog;
    }
    s2 = pop_or_resolve_from_result_stack(ccnl, config);
    if (!s2) {
        ccnl_nfn_freeStack(s1);
        *halt = -1;
        return prog;
    }

    if (s2->type == STACK_TYPE_CONST && s1->type == STACK_TYPE_PREFIX) {
        struct ccnl_prefix_s *p = (struct ccnl_prefix_s*) s1->content;
        struct const_s *con = (struct const_s *) s2->content;
        int suite = -1;
        DEBUGMSG(DEBUG, "  original packet format: %s\n", con->str);

        if (!strcmp(con->str, "ccnb"))
            suite = CCNL_SUITE_CCNB;
        else if (!strcmp(con->str, "ccnx2014"))
            suite = CCNL_SUITE_CCNTLV;
        else if (!strcmp(con->str, "ndn2013"))
            suite = CCNL_SUITE_NDNTLV;

        if (suite < 0)
            goto out;
        DEBUGMSG(DEBUG, " >> changing PREFIX suite from %d to %d\n",
                 p->suite, suite);

        p->nfnflags = 0;
        p->suite = suite;
        push_to_stack(stack, s1->content, STACK_TYPE_PREFIX);

        ccnl_free(s1);
        s1 = NULL;

        if (pending) {
            cp = ccnl_malloc(strlen(pending)+1);
            strcpy(cp, pending);
        }
    } else {
out:
        *halt = -1;
        cp = prog;
    }
    if (s1)
        ccnl_nfn_freeStack(s1);
    ccnl_nfn_freeStack(s2);

    return cp;
}
Example #18
0
void
ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path)
{
    DIR *dir;
    struct dirent *de;
    int datalen;

    DEBUGMSG(99, "ccnl_populate_cache %s\n", path);

    dir = opendir(path);
    if (!dir)
	return;
    while ((de = readdir(dir))) {
	if (!fnmatch("*.ccnb", de->d_name, FNM_NOESCAPE)) {
	    char fname[1000];
	    struct stat s;
	    strcpy(fname, path);
	    strcat(fname, "/");
	    strcat(fname, de->d_name);
	    if (stat(fname, &s)) {
		perror("stat");
	    } else {
		struct ccnl_buf_s *buf = 0;
		int fd;
		DEBUGMSG(6, "loading file %s, %d bytes\n",
			 de->d_name, (int) s.st_size);

		fd = open(fname, O_RDONLY);
		if (!fd) {
		    perror("open");
		    continue;
		}
               
		buf = (struct ccnl_buf_s *) ccnl_malloc(sizeof(*buf) +
							s.st_size);
		datalen = read(fd, buf->data, s.st_size);
		close(fd);
		if (datalen == s.st_size && datalen >= 2 &&
			    buf->data[0] == 0x04 && buf->data[1] == 0x82) {
		    struct ccnl_prefix_s *prefix = 0;
		    struct ccnl_content_s *c = 0;
		    struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0;
		    unsigned char *content, *data = buf->data + 2;
		    int contlen;

		    buf->datalen = datalen;
		    datalen -= 2;
		    pkt = ccnl_extract_prefix_nonce_ppkd(&data, &datalen, 0, 0,
			      0, 0, &prefix, &nonce, &ppkd, &content, &contlen);
		    if (!pkt) {
			DEBUGMSG(6, "  parsing error\n"); goto Done;
		    }
		    if (!prefix) {
			DEBUGMSG(6, "  no prefix error\n"); goto Done;
		    }
		    c = ccnl_content_new(ccnl, &pkt, &prefix, &ppkd,
					 content, contlen);
		    if (!c)
			goto Done;
		    ccnl_content_add2cache(ccnl, c);
		    c->flags |= CCNL_CONTENT_FLAGS_STATIC;
Done:
		    free_prefix(prefix);
		    ccnl_free(buf);
		    ccnl_free(pkt);
		    ccnl_free(nonce);
		    ccnl_free(ppkd);
		} else {
		    DEBUGMSG(6, "  not a content object\n");
		    ccnl_free(buf);
		}
	    }
	}
    }
}
int
main(int argc, char *argv[])
{
    // char *private_key_path = 0;
    //    char *witness = 0;
    unsigned char out[65*1024];
    char *publisher = 0;
    char *infname = 0, *outdirname = 0, *outfname;
    int f, fout, contentlen = 0, opt, plen;
    //    int suite = CCNL_SUITE_DEFAULT;
    int suite = CCNL_SUITE_CCNTLV;
    int chunk_size = CCNL_MAX_CHUNK_SIZE;
    struct ccnl_prefix_s *name;

    while ((opt = getopt(argc, argv, "hc:f:i:o:p:k:w:s:v:")) != -1) {
        switch (opt) {
        case 'c':
            chunk_size = atoi(optarg);
            if (chunk_size > CCNL_MAX_CHUNK_SIZE) {
                DEBUGMSG(WARNING, "max chunk size is %d (%d is to large), using max chunk size\n", CCNL_MAX_CHUNK_SIZE, chunk_size);
                chunk_size = CCNL_MAX_CHUNK_SIZE;
            }
            break;
        case 'f':
            outfname = optarg;
            break;
        case 'i':
            infname = optarg;
            break;
        case 'o':
            outdirname = optarg;
            break;
/*
        case 'k':
            private_key_path = optarg;
            break;
        case 'w':
            witness = optarg;
            break;
*/
        case 'p':
            publisher = optarg;
            plen = unescape_component(publisher);
            if (plen != 32) {
            DEBUGMSG(ERROR,
             "publisher key digest has wrong length (%d instead of 32)\n",
             plen);
            exit(-1);
            }
            break;
        case 's':
            suite = ccnl_str2suite(optarg);
            break;
        case 'v':
#ifdef USE_LOGGING
            if (isdigit(optarg[0]))
                debug_level = atoi(optarg);
            else
                debug_level = ccnl_debug_str2level(optarg);
#endif
            break;
        case 'h':
        default:
Usage:
        fprintf(stderr,
        "Creates a chunked content object stream for the input data and writes them to stdout.\n"
        "usage: %s [options] URL\n"
        "  -c SIZE          size for each chunk (max %d)\n"
        "  -f FNAME         filename of the chunks when using -o\n"
        "  -i FNAME         input file (instead of stdin)\n"
        "  -o DIR           output dir (instead of stdout), filename default is cN, otherwise specify -f\n"
        "  -p DIGEST        publisher fingerprint\n"
        "  -s SUITE         (ccnb, ccnx2015, cisco2015, iot2014, ndn2013)\n"
#ifdef USE_LOGGING
        "  -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n"
#endif
        ,
        argv[0],
        CCNL_MAX_CHUNK_SIZE);
        exit(1);
        }
    }

    if (!ccnl_isSuite(suite))
        goto Usage;

    // mandatory url
    if (!argv[optind])
        goto Usage;

    char *url_orig = argv[optind];
    char url[strlen(url_orig)];
    optind++;

    // optional nfn
    char *nfnexpr = argv[optind];

    int status;
    struct stat st_buf;
    if(outdirname) {
        // Check if outdirname is a directory and open it as a file
        status = stat(outdirname, &st_buf);
        if (status != 0) {
            // DEBUGMSG (ERROR, "Error (%d) when opening file %s\n", errno, outdirname);
            DEBUGMSG(ERROR, "Error (%d) when opening output dir %s (probaby does not exist)\n", errno, outdirname);
            goto Usage;
        }
        if (S_ISREG (st_buf.st_mode)) {
            // DEBUGMSG (ERROR, "Error: %s is a file and not a directory.\n", argv[optind]);
            DEBUGMSG(ERROR, "Error: output dir %s is a file and not a directory.\n", outdirname);
            goto Usage;
        }
    }
    if(infname) {
        // Check if outdirname is a directory and open it as a file
        status = stat(infname, &st_buf);
        if (status != 0) {
            // DEBUGMSG (ERROR, "Error (%d) when opening file %s\n", errno, outdirname);
            DEBUGMSG(ERROR, "Error (%d) when opening input file %s (probaby does not exist)\n", errno, infname);
            goto Usage;
        }
        if (S_ISDIR (st_buf.st_mode)) {
            // DEBUGMSG (ERROR, "Error: %s is a file and not a directory.\n", argv[optind]);
            DEBUGMSG(ERROR, "Error: input file %s is a directory and not a file.\n", infname);
            goto Usage;
        }
        f = open(infname, O_RDONLY);
        if (f < 0) {
            perror("file open:");
        }
    } else {
      f = 0;
    }

    char default_file_name[2] = "c";
    if (!outfname) {
        outfname = default_file_name;
    } else if(!outdirname) {
        DEBUGMSG(WARNING, "filename -f without -o output dir does nothing\n");
    }

    char *chunk_buf;
    chunk_buf = ccnl_malloc(chunk_size * sizeof(unsigned char));
    int chunk_len, is_last = 0, offs = -1;
    unsigned int chunknum = 0;

    char outpathname[255];
    char fileext[10];
    switch (suite) {
        case CCNL_SUITE_CCNB:
            strcpy(fileext, "ccnb");
            break;
        case CCNL_SUITE_CCNTLV:
            strcpy(fileext, "ccntlv");
            break;
        case CCNL_SUITE_CISTLV:
            strcpy(fileext, "cistlv");
            break;
        case CCNL_SUITE_IOTTLV:
            strcpy(fileext, "iottlv");
            break;
        case CCNL_SUITE_NDNTLV:
            strcpy(fileext, "ndntlv");
            break;
        default:
            DEBUGMSG(ERROR, "fileext for suite %d not implemented\n", suite);
    }

    chunk_len = 1;
    chunk_len = read(f, chunk_buf, chunk_size);
    while (!is_last && chunk_len > 0) {

        if (chunk_len < chunk_size) {
            is_last = 1;
        }

        strcpy(url, url_orig);
        offs = CCNL_MAX_PACKET_SIZE;
        name = ccnl_URItoPrefix(url, suite, nfnexpr, &chunknum);

        switch (suite) {
        case CCNL_SUITE_CCNTLV:
            contentlen = ccnl_ccntlv_prependContentWithHdr(name,
                            (unsigned char *)chunk_buf, chunk_len,
                            is_last ? &chunknum : NULL,
                            NULL, // int *contentpos
                            &offs, out);
            break;
        case CCNL_SUITE_CISTLV:
            contentlen = ccnl_cistlv_prependContentWithHdr(name,
                                                           (unsigned char *)chunk_buf, chunk_len,
                                                           is_last ? &chunknum : NULL,
                                                           &offs,
                                                           NULL, // int *contentpos
                                                           out);
            break;
        case CCNL_SUITE_IOTTLV:
            ccnl_iottlv_prependReply(name, (unsigned char *) chunk_buf,
                                     chunk_len, &offs, NULL,
                                     is_last ? &chunknum : NULL, out);
            ccnl_switch_prependCoding(CCNL_ENC_IOT2014, &offs, out);
            contentlen = CCNL_MAX_PACKET_SIZE - offs;
            break;
        case CCNL_SUITE_NDNTLV:
            contentlen = ccnl_ndntlv_prependContent(name,
                                 (unsigned char *) chunk_buf, chunk_len,
                                 NULL, is_last ? &chunknum : NULL,
                                 &offs, out);
            break;
        default:
            DEBUGMSG(ERROR, "produce for suite %i is not implemented\n", suite);
            goto Error;
            break;
        }

        if (outdirname) {
            sprintf(outpathname, "%s/%s%d.%s", outdirname, outfname, chunknum, fileext);
//            DEBUGMSG(INFO, "%s/%s%d.%s\n", outdirname, outfname, chunknum, fileext);

            DEBUGMSG(INFO, "writing chunk %d to file %s\n", chunknum, outpathname);

            fout = creat(outpathname, 0666);
            write(fout, out + offs, contentlen);
            close(fout);
        } else {
            DEBUGMSG(INFO, "writing chunk %d\n", chunknum);
            fwrite(out + offs, sizeof(unsigned char),contentlen, stdout);
        }

        chunknum++;
        if (!is_last) {
            chunk_len = read(f, chunk_buf, chunk_size);
        }
    }

    close(f);
    ccnl_free(chunk_buf);
    return 0;

Error:
    close(f);
    ccnl_free(chunk_buf);
    return -1;
}
Example #20
0
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;
}
Example #21
0
// TODO: This function should probably be moved to another file to indicate that it should only be used by application level programs
// and not in the ccnl core. Chunknumbers for NDNTLV are only a convention and there no specification on the packet encoding level.
int
ccnl_prefix_addChunkNum(struct ccnl_prefix_s *prefix, unsigned int chunknum)
{
    if (chunknum >= 0xff) {
      DEBUGMSG_CPFX(WARNING, "addChunkNum is only implemented for "
               "chunknum smaller than 0xff (%d)\n", chunknum);
        return -1;
    }

    switch(prefix->suite) {
#ifdef USE_SUITE_NDNTLV
        case CCNL_SUITE_NDNTLV: {
            unsigned char cmp[2];
            cmp[0] = NDN_Marker_SegmentNumber;
            // TODO: this only works for chunknums smaller than 255
            cmp[1] = chunknum;
            if(ccnl_prefix_appendCmp(prefix, cmp, 2) < 0)
                return -1;
            if (prefix->chunknum)
                ccnl_free(prefix->chunknum);
            prefix->chunknum = ccnl_malloc(sizeof(int));
            *prefix->chunknum = chunknum;
        }
        break;
#endif

#ifdef USE_SUITE_CCNTLV
        case CCNL_SUITE_CCNTLV: {
            unsigned char cmp[5];
            cmp[0] = 0;
            // TODO: this only works for chunknums smaller than 255
            cmp[1] = CCNX_TLV_N_Chunk;
            cmp[2] = 0;
            cmp[3] = 1;
            cmp[4] = chunknum;
            if(ccnl_prefix_appendCmp(prefix, cmp, 5) < 0)
                return -1;
            if (prefix->chunknum)
                ccnl_free(prefix->chunknum);
            prefix->chunknum = ccnl_malloc(sizeof(int));
            *prefix->chunknum = chunknum;
        }
        break;
#endif

#ifdef USE_SUITE_CISTLV
        case CCNL_SUITE_CISTLV: {
            unsigned char cmp[5];
            // TODO: this only works for chunknums smaller than 255
            cmp[0] = 0;
            cmp[1] = CISCO_TLV_NameSegment;
            cmp[2] = 0;
            cmp[3] = 1;
            cmp[4] = chunknum;
            if (ccnl_prefix_appendCmp(prefix, cmp, 5) < 0)
                return -1;
            if (prefix->chunknum)
                ccnl_free(prefix->chunknum);
            prefix->chunknum = ccnl_malloc(sizeof(int));
            *prefix->chunknum = chunknum;
        }
        break;
#endif

        default:
            DEBUGMSG_CPFX(WARNING,
                     "add chunk number not implemented for suite %d\n",
                     prefix->suite);
            return -1;
    }

    return 0;
}
Example #22
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;
}
void
ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path)
{
    DIR *dir;
    struct dirent *de;

    dir = opendir(path);
    if (!dir) {
        DEBUGMSG(ERROR, "could not open directory %s\n", path);
        return;
    }

    DEBUGMSG(INFO, "populating cache from directory %s\n", path);

    while ((de = readdir(dir))) {
        char fname[1000];
        struct stat s;
        struct ccnl_buf_s *buf = 0; // , *nonce=0, *ppkd=0, *pkt = 0;
        struct ccnl_content_s *c = 0;
        int fd, datalen, suite, skip;
        unsigned char *data;
        (void) data; // silence compiler warning (if any USE_SUITE_* is not set)
#if defined(USE_SUITE_IOTTLV) || defined(USE_SUITE_NDNTLV)
        unsigned int typ;
        int len;
#endif
        struct ccnl_pkt_s *pk;

        if (de->d_name[0] == '.')
            continue;

        strcpy(fname, path);
        strcat(fname, "/");
        strcat(fname, de->d_name);

        if (stat(fname, &s)) {
            perror("stat");
            continue;
        }
        if (S_ISDIR(s.st_mode))
            continue;

        DEBUGMSG(INFO, "loading file %s, %d bytes\n", de->d_name,
                 (int) s.st_size);

        fd = open(fname, O_RDONLY);
        if (!fd) {
            perror("open");
            continue;
        }

        buf = (struct ccnl_buf_s *) ccnl_malloc(sizeof(*buf) + s.st_size);
        if (buf)
            datalen = read(fd, buf->data, s.st_size);
        else
            datalen = -1;
        close(fd);

        if (!buf || datalen != s.st_size || datalen < 2) {
            DEBUGMSG(WARNING, "size mismatch for file %s, %d/%d bytes\n",
                     de->d_name, datalen, (int) s.st_size);
            continue;
        }
        buf->datalen = datalen;
        suite = ccnl_pkt2suite(buf->data, datalen, &skip);

        pk = NULL;
        switch (suite) {
#ifdef USE_SUITE_CCNB
        case CCNL_SUITE_CCNB: {
            unsigned char *start;

            data = start = buf->data + skip;
            datalen -= skip;

            if (data[0] != 0x04 || data[1] != 0x82)
                goto notacontent;
            data += 2;
            datalen -= 2;

            pk = ccnl_ccnb_bytes2pkt(start, &data, &datalen);
            break;
        }
#endif
#ifdef USE_SUITE_CCNTLV
        case CCNL_SUITE_CCNTLV: {
            int hdrlen;
            unsigned char *start;

            data = start = buf->data + skip;
            datalen -=  skip;

            hdrlen = ccnl_ccntlv_getHdrLen(data, datalen);
            data += hdrlen;
            datalen -= hdrlen;

            pk = ccnl_ccntlv_bytes2pkt(start, &data, &datalen);
            break;
        }
#endif
#ifdef USE_SUITE_CISTLV
        case CCNL_SUITE_CISTLV: {
            int hdrlen;
            unsigned char *start;

            data = start = buf->data + skip;
            datalen -=  skip;

            hdrlen = ccnl_cistlv_getHdrLen(data, datalen);
            data += hdrlen;
            datalen -= hdrlen;

            pk = ccnl_cistlv_bytes2pkt(start, &data, &datalen);
            break;
        }
#endif
#ifdef USE_SUITE_IOTTLV
        case CCNL_SUITE_IOTTLV: {
            unsigned char *olddata;

            data = olddata = buf->data + skip;
            datalen -= skip;
            if (ccnl_iottlv_dehead(&data, &datalen, &typ, &len) ||
                                                       typ != IOT_TLV_Reply)
                goto notacontent;
            pk = ccnl_iottlv_bytes2pkt(typ, olddata, &data, &datalen);
            break;
        }
#endif
#ifdef USE_SUITE_NDNTLV
        case CCNL_SUITE_NDNTLV: {
            unsigned char *olddata;

            data = olddata = buf->data + skip;
            datalen -= skip;
            if (ccnl_ndntlv_dehead(&data, &datalen, (int*) &typ, &len) ||
                                                         typ != NDN_TLV_Data)
                goto notacontent;
            pk = ccnl_ndntlv_bytes2pkt(typ, olddata, &data, &datalen);
            break;
        }
#endif
        default:
            DEBUGMSG(WARNING, "unknown packet format (%s)\n", de->d_name);
            goto Done;
        }
        if (!pk) {
            DEBUGMSG(DEBUG, "  parsing error in %s\n", de->d_name);
            goto Done;
        }
        c = ccnl_content_new(ccnl, &pk);
        if (!c) {
            DEBUGMSG(WARNING, "could not create content (%s)\n", de->d_name);
            goto Done;
        }
        ccnl_content_add2cache(ccnl, c);
        c->flags |= CCNL_CONTENT_FLAGS_STATIC;
Done:
        free_packet(pk);
        ccnl_free(buf);
        continue;
#if defined(USE_SUITE_CCNB) || defined(USE_SUITE_IOTTLV) || defined(USE_SUITE_NDNTLV)
notacontent:
        DEBUGMSG(WARNING, "not a content object (%s)\n", de->d_name);
        ccnl_free(buf);
#endif
    }

    closedir(dir);
}
Example #24
0
int
main(int argc, char *argv[])
{
    // char *private_key_path = 0;
    //    char *witness = 0;
    uint8_t out[65*1024];
    char *publisher = 0;
    char *infname = 0, *outdirname = 0, *outfname = 0;
    size_t contentlen = 0, plen;
    int f, fout, opt;
    //    int suite = CCNL_SUITE_DEFAULT;
    int suite = CCNL_SUITE_CCNTLV;
    size_t chunk_size = CCNL_MAX_CHUNK_SIZE;
    struct ccnl_prefix_s *name;
    ccnl_data_opts_u data_opts;

    while ((opt = getopt(argc, argv, "hc:f:i:o:p:k:w:s:v:")) != -1) {
        switch (opt) {
        case 'c':
            chunk_size = (size_t) strtol(optarg, (char **) NULL, 10);
            if (chunk_size > CCNL_MAX_CHUNK_SIZE) {
                DEBUGMSG(WARNING, "max chunk size is %d (%zu is to large), using max chunk size\n", CCNL_MAX_CHUNK_SIZE, chunk_size);
                chunk_size = CCNL_MAX_CHUNK_SIZE;
            }
            break;
        case 'f':
            outfname = optarg;
            break;
        case 'i':
            infname = optarg;
            break;
        case 'o':
            outdirname = optarg;
            break;
/*
        case 'k':
            private_key_path = optarg;
            break;
        case 'w':
            witness = optarg;
            break;
*/
        case 'p':
            publisher = optarg;
            plen = unescape_component(publisher);
            if (plen != 32) {
                DEBUGMSG(ERROR, "publisher key digest has wrong length (%zu instead of 32)\n",
                         plen);
                exit(-1);
            }
            break;
        case 's':
            suite = ccnl_str2suite(optarg);
            break;
        case 'v':
#ifdef USE_LOGGING
            if (isdigit(optarg[0]))
                debug_level =  (int)strtol(optarg, (char **)NULL, 10);
            else
                debug_level = ccnl_debug_str2level(optarg);
#endif
            break;
        case 'h':
        default:
Usage:
        fprintf(stderr,
        "Creates a chunked content object stream for the input data and writes them to stdout.\n"
        "usage: %s [options] URL\n"
        "  -c SIZE          size for each chunk (max %d)\n"
        "  -f FNAME         filename of the chunks when using -o\n"
        "  -i FNAME         input file (instead of stdin)\n"
        "  -o DIR           output dir (instead of stdout), filename default is cN, otherwise specify -f\n"
        "  -p DIGEST        publisher fingerprint\n"
        "  -s SUITE         (ccnb, ccnx2015, ndn2013)\n"
#ifdef USE_LOGGING
        "  -v DEBUG_LEVEL (fatal, error, warning, info, debug, verbose, trace)\n"
#endif
        ,
        argv[0],
        CCNL_MAX_CHUNK_SIZE);
        exit(1);
        }
    }

    if (!ccnl_isSuite(suite)) {
        goto Usage;
    }

    // mandatory url
    if (!argv[optind]) {
        goto Usage;
    }

    char *url_orig = argv[optind];
    char url[strlen(url_orig)];
    optind++;

    int status;
    struct stat st_buf;
    if (outdirname) {
        // Check if outdirname is a directory and open it as a file
        status = stat(outdirname, &st_buf);
        if (status != 0) {
            // DEBUGMSG (ERROR, "Error (%d) when opening file %s\n", errno, outdirname);
            DEBUGMSG(ERROR, "Error (%d) when opening output dir %s (probaby does not exist)\n", errno, outdirname);
            goto Usage;
        }
        if (S_ISREG (st_buf.st_mode)) {
            // DEBUGMSG (ERROR, "Error: %s is a file and not a directory.\n", argv[optind]);
            DEBUGMSG(ERROR, "Error: output dir %s is a file and not a directory.\n", outdirname);
            goto Usage;
        }
    }
    if (infname) {
        // Check if outdirname is a directory and open it as a file
        status = stat(infname, &st_buf);
        if (status != 0) {
            // DEBUGMSG (ERROR, "Error (%d) when opening file %s\n", errno, outdirname);
            DEBUGMSG(ERROR, "Error (%d) when opening input file %s (probaby does not exist)\n", errno, infname);
            goto Usage;
        }
        if (S_ISDIR (st_buf.st_mode)) {
            // DEBUGMSG (ERROR, "Error: %s is a file and not a directory.\n", argv[optind]);
            DEBUGMSG(ERROR, "Error: input file %s is a directory and not a file.\n", infname);
            goto Usage;
        }
        f = open(infname, O_RDONLY);
        if (f < 0) {
            perror("file open:");
        }
    } else {
        f = 0;
    }

    char default_file_name[2] = "c";
    if (!outfname) {
        outfname = default_file_name;
    } else if(!outdirname) {
        DEBUGMSG(WARNING, "filename -f without -o output dir does nothing\n");
    }

    uint8_t *chunk_buf;
    chunk_buf = ccnl_malloc(chunk_size * sizeof(uint8_t));
    if (!chunk_buf) {
        DEBUGMSG(ERROR, "Error: Failed to allocate memory\n");
        exit(1);
    }
    size_t chunk_len;
    ssize_t s_chunk_len;
    int8_t is_last = 0;
    size_t offs;
    uint32_t chunknum = 0;

    char outpathname[255];
    char fileext[10];
    switch (suite) {
        case CCNL_SUITE_CCNB:
            strcpy(fileext, "ccnb");
            break;
        case CCNL_SUITE_CCNTLV:
            strcpy(fileext, "ccntlv");
            break;
        case CCNL_SUITE_NDNTLV:
            strcpy(fileext, "ndntlv");
            break;
        default:
            DEBUGMSG(ERROR, "fileext for suite %d not implemented\n", suite);
    }

    
    FILE *fp = fopen(infname, "r");
    fseek(fp, 0L, SEEK_END);
    long sz = ftell(fp);
    size_t isz;
    if (sz < 0) {
        DEBUGMSG(ERROR, "Error reading input file offset; error: %d\n", errno);
        exit(1);
    }
    if ((unsigned long) sz > SIZE_MAX) {
        DEBUGMSG(ERROR, "Input file offset exceeds bounds: %ld", sz);
        exit(1);
    }
    isz = (size_t) sz;
    rewind(fp);
    fclose(fp);

    size_t lastchunknum_s = (isz / chunk_size);
    if (lastchunknum_s > UINT32_MAX) {
        DEBUGMSG(ERROR, "lastchunknum exceeds bounds: %zu", lastchunknum_s);
        exit(1);
    }
    uint32_t lastchunknum = (uint32_t) lastchunknum_s;
    if (sz % chunk_size == 0) {
        --lastchunknum;
    }

    s_chunk_len = read(f, chunk_buf, chunk_size);
    if (s_chunk_len < 0) {
        DEBUGMSG(ERROR, "Error reading input file; error: %d\n", errno);
        exit(1);
    }
    chunk_len = (size_t) s_chunk_len;
    while (!is_last && chunk_len > 0) {

        if (chunk_len < chunk_size) {
            is_last = 1;
        }

        strcpy(url, url_orig);
        offs = CCNL_MAX_PACKET_SIZE;
        name = ccnl_URItoPrefix(url, suite, &chunknum);

        switch (suite) {
        case CCNL_SUITE_CCNTLV:
            if (ccnl_ccntlv_prependContentWithHdr(name, chunk_buf, chunk_len, &lastchunknum,
                                                  //is_last ? &chunknum : NULL,
                                                  NULL, // int *contentpos
                                                  &offs, out, &contentlen)) {
                goto Error;
            }
            break;
        case CCNL_SUITE_NDNTLV:
            data_opts.ndntlv.finalblockid = lastchunknum;
            if (ccnl_ndntlv_prependContent(name, chunk_buf, chunk_len, NULL,
                                           &(data_opts.ndntlv),// is_last ? &chunknum : NULL,
                                           &offs, out, &contentlen)) {
                goto Error;
            }
            break;
        default:
            DEBUGMSG(ERROR, "produce for suite %i is not implemented\n", suite);
            goto Error;
            break;
        }

        if (outdirname) {
            sprintf(outpathname, "%s/%s%d.%s", outdirname, outfname, chunknum, fileext);

            DEBUGMSG(INFO, "writing chunk %d to file %s\n", chunknum, outpathname);

            fout = creat(outpathname, 0666);
            write(fout, out + offs, contentlen);
            close(fout);
        } else {
            DEBUGMSG(INFO, "writing chunk %d\n", chunknum);
            fwrite(out + offs, sizeof(unsigned char),contentlen, stdout);
        }

        chunknum++;
        if (!is_last) {
            s_chunk_len = read(f, chunk_buf, chunk_size);
            if (s_chunk_len < 0) {
                DEBUGMSG(ERROR, "Error reading input file; error: %d\n", errno);
                exit(1);
            }
            chunk_len = (size_t) s_chunk_len;
        }
    }

    close(f);
    ccnl_free(chunk_buf);
    return 0;

Error:
    close(f);
    ccnl_free(chunk_buf);
    return -1;
}
char*
ZAM_resolvename(struct configuration_s *config, char *dummybuf,
                char *arg, char *contd)
{
    struct ccnl_lambdaTerm_s *t;
    char res[1000], *cp = arg;
    int len;

    DEBUGMSG(DEBUG, "---to do: resolveNAME <%s>\n", arg);

    //function definition
    if (!strncmp(cp, "let", 3)) {
        int i, end = 0, cp2len, namelength, lambdalen;
        char *h, *cp2, *name, *lambda_expr, *resolveterm;

        DEBUGMSG(DEBUG, " fct definition: %s\n", cp);
        strcpy(res, cp+3);
        for (i = 0; i < strlen(res); ++i) {
            if (!strncmp(res+i, "endlet", 6)) {
                end = i;
                break;
            }
        }
        cp2len = strlen(res+end) + strlen("RESOLVENAME()");
        h = strchr(cp, '=');
        namelength = h - cp;

        lambda_expr = ccnl_malloc(strlen(h));
        name = ccnl_malloc(namelength);
        cp2 = ccnl_malloc(cp2len);

        memset(cp2, 0, cp2len);
        memset(name, 0, namelength);
        memset(lambda_expr, 0, strlen(h));

        sprintf(cp2, "RESOLVENAME(%s)", res+end+7); //add 7 to overcome endlet
        memcpy(name, cp+3, namelength-3); //copy name without let and endlet
        trim(name);

        lambdalen = strlen(h)-strlen(cp2)+11-6;
        memcpy(lambda_expr, h+1, lambdalen); //copy lambda expression without =
        trim(lambda_expr);
        resolveterm = ccnl_malloc(strlen("RESOLVENAME()")+strlen(lambda_expr));
        sprintf(resolveterm, "RESOLVENAME(%s)", lambda_expr);

        add_to_environment(&config->env, name, new_closure(resolveterm, NULL));

        ccnl_free(cp);
        return strdup(contd);
    }

    //check if term can be made available, if yes enter it as a var
    //try with searching in global env for an added term!

    t = ccnl_lambdaStrToTerm(0, &cp, NULL);
    ccnl_free(arg);

    if (term_is_var(t)) {
        char *end = 0;
        cp = t->v;
        if (isdigit(*cp)) {
            // is disgit...
            int *integer = ccnl_malloc(sizeof(int));
            *integer = strtol(cp, &end, 0);
            if (end && *end)
                end = 0;
            if (end)
                push_to_stack(&config->result_stack, integer, STACK_TYPE_INT);
            else
                ccnl_free(integer);
        } else if (*cp == '\'') { // quoted name (constant)
            //determine size
            struct const_s *con = ccnl_nfn_krivine_str2const(cp);
            push_to_stack(&config->result_stack, con, STACK_TYPE_CONST);
            end = (char*)1;
        } else if (iscontentname(cp)) { // is content...
            struct ccnl_prefix_s *prefix;
            prefix = ccnl_URItoPrefix(cp, config->suite, NULL, NULL);
            push_to_stack(&config->result_stack, prefix, STACK_TYPE_PREFIX);
            end = (char*)1;
        }
        if (end) {
            if (contd)
                sprintf(res, "TAILAPPLY;%s", contd);
            else
                sprintf(res, "TAILAPPLY");
        } else {
            if (contd)
                sprintf(res, "ACCESS(%s);TAILAPPLY;%s", t->v, contd);
            else
                sprintf(res, "ACCESS(%s);TAILAPPLY", t->v);
        }
        ccnl_lambdaFreeTerm(t);
        return ccnl_strdup(res);
    }
    if (term_is_lambda(t)) {
        char *var;
        var = t->v;
        ccnl_lambdaTermToStr(dummybuf, t->m, 0);
        if (contd)
            sprintf(res, "GRAB(%s);RESOLVENAME(%s);%s", var, dummybuf, contd);
        else
            sprintf(res, "GRAB(%s);RESOLVENAME(%s)", var, dummybuf);
        ccnl_lambdaFreeTerm(t);
        return ccnl_strdup(res);
    }
    if (term_is_app(t)) {
        ccnl_lambdaTermToStr(dummybuf, t->n, 0);
        len = sprintf(res, "CLOSURE(RESOLVENAME(%s));", dummybuf);
        ccnl_lambdaTermToStr(dummybuf, t->m, 0);
        len += sprintf(res+len, "RESOLVENAME(%s)", dummybuf);
        if (contd)
            len += sprintf(res+len, ";%s", contd);
        ccnl_lambdaFreeTerm(t);
        return ccnl_strdup(res);
    }
    return NULL;
}
Example #26
0
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;
}
Example #27
0
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;
}
Example #28
0
void
ccnl_populate_cache(struct ccnl_relay_s *ccnl, char *path, int suite)
{
    DIR *dir;
    struct dirent *de;
    int datalen;
    char *suffix;

    DEBUGMSG(99, "ccnl_populate_cache %s\n", path);

    switch (suite) {
#ifdef USE_SUITE_CCNB
    case CCNL_SUITE_CCNB:
	suffix = "*.ccnb"; break;
#endif
#ifdef USE_SUITE_NDNTLV
    case CCNL_SUITE_NDNTLV:
	suffix = "*.ndntlv"; break;
#endif
    default:
	fprintf(stderr, "unknown suite and encoding, cannot populate cache.\n");
	return;
    }

    dir = opendir(path);
    if (!dir)
	return;
    while ((de = readdir(dir))) {
	if (!fnmatch(suffix, de->d_name, FNM_NOESCAPE)) {
	    char fname[1000];
	    struct stat s;
	    strcpy(fname, path);
	    strcat(fname, "/");
	    strcat(fname, de->d_name);
	    if (stat(fname, &s)) {
		perror("stat");
	    } else {
		struct ccnl_buf_s *buf = 0;
		int fd;
		DEBUGMSG(6, "loading file %s, %d bytes\n",
			 de->d_name, (int) s.st_size);

		fd = open(fname, O_RDONLY);
		if (!fd) {
		    perror("open");
		    continue;
		}
               
		buf = (struct ccnl_buf_s *) ccnl_malloc(sizeof(*buf) +
							s.st_size);
		datalen = read(fd, buf->data, s.st_size);
		close(fd);
		if (datalen == s.st_size && datalen >= 2) {
		    struct ccnl_prefix_s *prefix = 0;
		    struct ccnl_content_s *c = 0;
		    struct ccnl_buf_s *nonce=0, *ppkd=0, *pkt = 0;
		    unsigned char *content, *data;
		    int contlen, typ, len;

		    buf->datalen = datalen;
		    switch (suite) {
#ifdef USE_SUITE_CCNB
		    case CCNL_SUITE_CCNB:
			if (buf->data[0] != 0x04 || buf->data[1] != 0x82)
			    goto notacontent;
			data = buf->data + 2;
			datalen -= 2;
			pkt = ccnl_ccnb_extract(&data, &datalen, 0, 0, 0, 0,
				&prefix, &nonce, &ppkd, &content, &contlen);
			break;
#endif
#ifdef USE_SUITE_NDNTLV
		    case CCNL_SUITE_NDNTLV:
			data = buf->data;
			if (ccnl_ndntlv_dehead(&data, &datalen, &typ, &len) ||
			    typ != NDN_TLV_Data)
			    goto notacontent;
			pkt = ccnl_ndntlv_extract(data - buf->data,
						  &data, &datalen, 0, 0, 0, 0,
				&prefix, &nonce, &ppkd, &content, &contlen);
			break;
#endif
		    default:
			goto Done;
		    }
		    if (!pkt) {
			DEBUGMSG(6, "  parsing error\n"); goto Done;
		    }
		    if (!prefix) {
			DEBUGMSG(6, "  no prefix error\n"); goto Done;
		    }
		    c = ccnl_content_new(ccnl, suite, &pkt, &prefix,
					 &ppkd, content, contlen);
		    if (!c)
			goto Done;
		    ccnl_content_add2cache(ccnl, c);
		    c->flags |= CCNL_CONTENT_FLAGS_STATIC;
Done:
		    free_prefix(prefix);
		    ccnl_free(buf);
		    ccnl_free(pkt);
		    ccnl_free(nonce);
		    ccnl_free(ppkd);
		} else {
notacontent:
		    DEBUGMSG(6, "  not a content object\n");
		    ccnl_free(buf);
		}
	    }
	}
    }
}
Example #29
0
int
ccnl_http_status(struct ccnl_relay_s *ccnl, struct ccnl_http_s *http)
{
    static char txt[64000];
    char *hdr =
        "HTTP/1.1 200 OK\n\r"
        "Content-Type: text/html; charset=utf-8\n\r"
        "Connection: close\n\r\n\r", *cp;
    int len = strlen(hdr), i, j, cnt;
    time_t t;
    struct utsname uts;
    struct ccnl_face_s *f;
    struct ccnl_forward_s *fwd;
    struct ccnl_interest_s *ipt;
    struct ccnl_buf_s *bpt;

    strcpy(txt, hdr);
    len += sprintf(txt+len,
                   "<html><head><title>ccn-lite-relay status</title>\n"
                   "<style type=\"text/css\">\n"
                   "body {font-family: sans-serif;}\n"
                   "</style>\n"
                   "</head><body>\n");
    len += sprintf(txt+len, "\n<table borders=0>\n<tr><td>"
                   "<a href=\"\">[refresh]</a>&nbsp;&nbsp;<td>"
                   "ccn-lite-relay Status Page &nbsp;&nbsp;");
    uname(&uts);
    len += sprintf(txt+len, "node <strong>%s (%d)</strong>\n",
                   uts.nodename, getpid());
    t = time(NULL);
    cp = ctime(&t);
    cp[strlen(cp)-1] = 0;
    len += sprintf(txt+len, "<tr><td><td><font size=-1>%s &nbsp;&nbsp;", cp);
    cp = ctime(&ccnl->startup_time);
    cp[strlen(cp)-1] = 0;
    len += sprintf(txt+len, " (started %s)</font>\n</table>\n", cp);

    len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>"
                   "<tr><td><em>Forwarding Table</em></table><ul>\n");
    for (fwd = ccnl->fib, cnt = 0; fwd; fwd = fwd->next, cnt++);
    if (cnt > 0) {
        struct ccnl_forward_s **fwda;
        fwda = (struct ccnl_forward_s**) ccnl_malloc(cnt * sizeof(fwd));
        for (fwd = ccnl->fib, i = 0; fwd; fwd = fwd->next, i++)
            fwda[i] = fwd;
        qsort(fwda, cnt, sizeof(fwd), ccnl_cmpfib);
        for (i = 0; i < cnt; i++) {
            char fname[10];
            sprintf(fname, "f%d", fwda[i]->face->faceid);
            len += sprintf(txt+len,
                           "<li>via %4s: <font face=courier>%s</font>\n",
                           fname, ccnl_prefix_to_path(fwda[i]->prefix));
        }
        ccnl_free(fwda);
    }
    len += sprintf(txt+len, "</ul>\n");

    len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>"
                   "<tr><td><em>Faces</em></table><ul>\n");
    for (f = ccnl->faces, cnt = 0; f; f = f->next, cnt++);
    if (cnt > 0) {
        struct ccnl_face_s **fa;
        fa = (struct ccnl_face_s**) ccnl_malloc(cnt * sizeof(f));
        for (f = ccnl->faces, i = 0; f; f = f->next, i++)
            fa[i] = f;
        qsort(fa, cnt, sizeof(f), ccnl_cmpfaceid);
        for (i = 0; i < cnt; i++) {
            len += sprintf(txt+len,
                           "<li><strong>f%d</strong> (via i%d) &nbsp;"
                           "peer=<font face=courier>%s</font> &nbsp;ttl=",
                           fa[i]->faceid, fa[i]->ifndx,
                           ccnl_addr2ascii(&(fa[i]->peer)));
            if (fa[i]->flags & CCNL_FACE_FLAGS_STATIC)
                len += sprintf(txt+len, "static");
            else
                len += sprintf(txt+len, "%.1fsec",
                        fa[i]->last_used + CCNL_FACE_TIMEOUT - CCNL_NOW());
            for (j = 0, bpt = fa[i]->outq; bpt; bpt = bpt->next, j++);
            len += sprintf(txt+len, " &nbsp;qlen=%d\n", j);
        }
        ccnl_free(fa);
    }
    len += sprintf(txt+len, "</ul>\n");

    len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>"
                   "<tr><td><em>Interfaces</em></table><ul>\n");
    for (i = 0; i < ccnl->ifcount; i++) {
        len += sprintf(txt+len, "<li><strong>i%d</strong>&nbsp;&nbsp;"
                       "addr=<font face=courier>%s</font>&nbsp;&nbsp;"
                       "qlen=%d/%d\n",
                       i, ccnl_addr2ascii(&ccnl->ifs[i].addr),
                       ccnl->ifs[i].qlen, CCNL_MAX_IF_QLEN);
    }
    len += sprintf(txt+len, "</ul>\n");

    len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>"
                   "<tr><td><em>Misc stats</em></table><ul>\n");
    for (cnt = 0, bpt = ccnl->nonces; bpt; bpt = bpt->next, cnt++);
    len += sprintf(txt+len, "<li>Nonces: %d\n", cnt);
    for (cnt = 0, ipt = ccnl->pit; ipt; ipt = ipt->next, cnt++);
    len += sprintf(txt+len, "<li>Pending interests: %d\n", cnt);
    len += sprintf(txt+len, "<li>Content chunks: %d (max=%d)\n",
                   ccnl->contentcnt, ccnl->max_cache_entries);
    len += sprintf(txt+len, "</ul>\n");

    len += sprintf(txt+len, "\n<p><table borders=0 width=100%% bgcolor=#e0e0ff>"
                   "<tr><td><em>Config</em></table><table borders=0>\n");
    len += sprintf(txt+len, "<tr><td>content.timeout:"
                   "<td align=right> %d<td>\n", CCNL_CONTENT_TIMEOUT);
    len += sprintf(txt+len, "<tr><td>face.timeout:"
                   "<td align=right> %d<td>\n", CCNL_FACE_TIMEOUT);
    len += sprintf(txt+len, "<tr><td>interest.maxretransmit:"
                   "<td align=right> %d<td>\n", CCNL_MAX_INTEREST_RETRANSMIT);
    len += sprintf(txt+len, "<tr><td>interest.timeout:"
                   "<td align=right> %d<td>\n", CCNL_INTEREST_TIMEOUT);
    len += sprintf(txt+len, "<tr><td>nonces.max:"
                   "<td align=right> %d<td>\n", CCNL_MAX_NONCES);

    len += sprintf(txt+len, "<tr><td>compile.featureset:<td><td> %s\n",
                   compile_string());
    len += sprintf(txt+len, "<tr><td>compile.time:"
                   "<td><td>%s %s\n", __DATE__, __TIME__);
    len += sprintf(txt+len, "<tr><td>compile.ccnl_core_version:"
                   "<td><td>%s\n", CCNL_VERSION);
    len += sprintf(txt+len, "</table>\n");

    len += sprintf(txt+len, "\n<p><hr></body></html>\n");

    http->out = (unsigned char*) txt;
    http->outoffs = 0;
    http->outlen = len;

    return 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;
}