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;
}
示例#2
0
// return 1 for Reply, 0 for Request, -1 if invalid
int iottlv_isReply(unsigned char *buf, int len)
{
    int enc = 1, suite;
    unsigned int typ;
    int vallen;

    while (!ccnl_switch_dehead(&buf, &len, &enc));
    suite = ccnl_enc2suite(enc);
    if (suite != CCNL_SUITE_IOTTLV)
        return -1;
    DEBUGMSG(DEBUG, "suite ok\n");
    if (len < 1 || ccnl_iottlv_dehead(&buf, &len, &typ, &vallen) < 0)
        return -1;
    DEBUGMSG(DEBUG, "typ=%d, len=%d\n", typ, vallen);
    if (typ == IOT_TLV_Reply)
        return 1;
    if (typ == IOT_TLV_Request)
        return 0;
    return -1;
}
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);
}
// 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;
}