int _ccnl_content(int argc, char **argv) { char *body = (char*) _default_content; int arg_len = strlen(_default_content) + 1; int offs = CCNL_MAX_PACKET_SIZE; if (argc < 2) { _content_usage(argv[0]); return -1; } if (argc > 2) { char buf[BUF_SIZE]; memset(buf, ' ', BUF_SIZE); char *buf_ptr = buf; for (int i = 2; (i < argc) && (buf_ptr < (buf + BUF_SIZE)); i++) { arg_len = strlen(argv[i]); if ((buf_ptr + arg_len) > (buf + BUF_SIZE)) { arg_len = (buf + BUF_SIZE) - buf_ptr; } strncpy(buf_ptr, argv[i], arg_len); buf_ptr += arg_len + 1; } *buf_ptr = '\0'; body = buf; arg_len = strlen(body); } int suite = CCNL_SUITE_NDNTLV; struct ccnl_prefix_s *prefix = ccnl_URItoPrefix(argv[1], suite, NULL, NULL); arg_len = ccnl_ndntlv_prependContent(prefix, (unsigned char*) body, arg_len, NULL, NULL, &offs, _out); unsigned char *olddata; unsigned char *data = olddata = _out + offs; int len; unsigned typ; if (ccnl_ndntlv_dehead(&data, &arg_len, (int*) &typ, &len) || typ != NDN_TLV_Data) { return -1; } struct ccnl_content_s *c = 0; struct ccnl_pkt_s *pk = ccnl_ndntlv_bytes2pkt(typ, olddata, &data, &arg_len); c = ccnl_content_new(&ccnl_relay, &pk); /* Remove the following line later */ ccnl_relay.max_cache_entries = 10; ccnl_content_add2cache(&ccnl_relay, c); c->flags |= CCNL_CONTENT_FLAGS_STATIC; return 0; }
int ndntlv_isData(unsigned char *buf, int len) { int typ; int vallen; if (len < 0 || ccnl_ndntlv_dehead(&buf, &len, (int*) &typ, &vallen)) return -1; if (typ != NDN_TLV_Data) return 0; return 1; }
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); } } } } }
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); }
int ccnl_extractDataAndChunkInfo(unsigned char **data, int *datalen, int suite, struct ccnl_prefix_s **prefix, unsigned int *lastchunknum, unsigned char **content, int *contentlen) { struct ccnl_pkt_s *pkt = NULL; switch (suite) { #ifdef USE_SUITE_CCNTLV case CCNL_SUITE_CCNTLV: { int hdrlen; unsigned char *start = *data; if (ccntlv_isData(*data, *datalen) < 0) { DEBUGMSG(WARNING, "Received non-content-object\n"); return -1; } hdrlen = ccnl_ccntlv_getHdrLen(*data, *datalen); if (hdrlen < 0) return -1; *data += hdrlen; *datalen -= hdrlen; pkt = ccnl_ccntlv_bytes2pkt(start, data, datalen); break; } #endif #ifdef USE_SUITE_CISTLV case CCNL_SUITE_CISTLV: { int hdrlen; unsigned char *start = *data; if (cistlv_isData(*data, *datalen) < 0) { DEBUGMSG(WARNING, "Received non-content-object\n"); return -1; } hdrlen = ccnl_cistlv_getHdrLen(*data, *datalen); if (hdrlen < 0) return -1; *data += hdrlen; *datalen -= hdrlen; pkt = ccnl_cistlv_bytes2pkt(start, data, datalen); break; } #endif #ifdef USE_SUITE_NDNTLV case CCNL_SUITE_NDNTLV: { unsigned int typ, len; unsigned char *start = *data; if (ccnl_ndntlv_dehead(data, datalen, &typ, &len)) { DEBUGMSG(WARNING, "could not dehead\n"); return -1; } if (typ != NDN_TLV_Data) { DEBUGMSG(WARNING, "received non-content-object packet with type %d\n", typ); return -1; } pkt = ccnl_ndntlv_bytes2pkt(typ, start, data, datalen); break; } #endif default: DEBUGMSG(WARNING, "extractDataAndChunkInfo: suite %d not implemented\n", suite); return -1; } if (!pkt) { DEBUGMSG(WARNING, "extract(%s): parsing error or no prefix\n", ccnl_suite2str(suite)); return -1; } *prefix = ccnl_prefix_dup(pkt->pfx); *lastchunknum = pkt->val.final_block_id; *content = pkt->content; *contentlen = pkt->contlen; free_packet(pkt); return 0; }