char * get_orig_router_from_info_content_name(struct ccn_charbuf * content_name) { int start,end; start=0; struct ccn_indexbuf *comps=ccn_indexbuf_create(); ccn_name_split (content_name, comps); end=check_for_name_component_in_name(content_name,comps,"nlsr"); struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_name_init(temp); ccn_name_append_components( temp, content_name->buf, comps->buf[start], comps->buf[end]); struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, temp->buf, temp->length, 0); char *orig_router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1, sizeof(char)); memcpy(orig_router,ccn_charbuf_as_string(temp1), strlen(ccn_charbuf_as_string(temp1))); orig_router[strlen(orig_router)]='\0'; ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&temp1); ccn_indexbuf_destroy(&comps); return orig_router; }
int sync_cb(struct ccns_handle *h, struct ccn_charbuf *lhash, struct ccn_charbuf *rhash, struct ccn_charbuf *name) { char *hexL; char *hexR; struct ccn_charbuf *uri = ccn_charbuf_create(); ccn_uri_append(uri, name->buf, name->length, 1); if (lhash == NULL || lhash->length == 0) { hexL = strdup("none"); } else hexL = hex_string(lhash->buf, lhash->length); if (rhash == NULL || rhash->length == 0) { hexR = strdup("none"); } else hexR = hex_string(rhash->buf, rhash->length); printf("%s %s %s\n", ccn_charbuf_as_string(uri), hexL, hexR); fflush(stdout); free(hexL); free(hexR); ccn_charbuf_destroy(&uri); return(0); }
static void collect_forwarding_html(struct ccnd_handle *h, struct ccn_charbuf *b) { struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ struct ccn_forwarding *f; int res; struct ccn_charbuf *name = ccn_charbuf_create(); ccn_charbuf_putf(b, "<h4>Forwarding</h4>" NL); ccn_charbuf_putf(b, "<ul>"); hashtb_start(h->nameprefix_tab, e); for (; e->data != NULL; hashtb_next(e)) { struct nameprefix_entry *ipe = e->data; ccn_name_init(name); res = ccn_name_append_components(name, e->key, 0, e->keysize); if (res < 0) abort(); if (0) { ccn_charbuf_putf(b, " <li>"); ccn_uri_append(b, name->buf, name->length, 1); ccn_charbuf_putf(b, "</li>" NL); } for (f = ipe->forwarding; f != NULL; f = f->next) { if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) { ccn_name_init(name); ccn_name_append_components(name, e->key, 0, e->keysize); ccn_charbuf_putf(b, " <li>"); ccn_uri_append(b, name->buf, name->length, 1); ccn_charbuf_putf(b, " <b>face:</b> %u" " <b>flags:</b> 0x%x" " <b>expires:</b> %d", f->faceid, f->flags & CCN_FORW_PUBMASK, f->expires); ccn_charbuf_putf(b, "</li>" NL); } } } hashtb_end(e); ccn_charbuf_destroy(&name); ccn_charbuf_putf(b, "</ul>"); }
char * get_orig_router_from_lsa_name(struct ccn_charbuf * content_name) { int start=0; size_t comp_size; const unsigned char *second_last_comp; char *second_comp_type; char *sep="."; char *rem; struct ccn_indexbuf *components=ccn_indexbuf_create(); struct ccn_charbuf *name=ccn_charbuf_create(); ccn_name_from_uri(name,nlsr->slice_prefix); ccn_name_split (name, components); start=components->n-2; ccn_charbuf_destroy(&name); ccn_indexbuf_destroy(&components); struct ccn_indexbuf *comps=ccn_indexbuf_create(); ccn_name_split (content_name, comps); ccn_name_comp_get( content_name->buf, comps, comps->n-1-2, &second_last_comp, &comp_size); second_comp_type=strtok_r((char *)second_last_comp, sep, &rem); if ( strcmp( second_comp_type, "lsId" ) == 0 ){ ccn_name_chop(content_name,comps,-3); } else{ ccn_name_chop(content_name,comps,-2); } struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_name_init(temp); ccn_name_append_components( temp, content_name->buf, comps->buf[start+1], comps->buf[comps->n - 1]); struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, temp->buf, temp->length, 0); char *orig_router=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1, sizeof(char)); memcpy(orig_router,ccn_charbuf_as_string(temp1), strlen(ccn_charbuf_as_string(temp1))); orig_router[strlen(orig_router)]='\0'; ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&temp1); ccn_indexbuf_destroy(&comps); return orig_router; }
/** * Base loop for the background CCN task * * This is the main execution loop for the background task responsible for * interacting with the CCN network. It is from this point that many of the above methods are * called to work the inbound messages from ccnx as well as sending out the data messages. * * \param data the task context information setup by the parent sink element thread */ static void ccn_event_thread (void *data) { Gstccnxsink *me = (Gstccnxsink *) data; struct ccn_charbuf *filtName; struct ccn_charbuf *temp; int res = 0; GST_DEBUG ("CCNxSink event: *** event thread starting"); temp = ccn_charbuf_create (); filtName = ccn_charbuf_create (); /* A closure is what defines what to do when an inbound interest arrives */ if ((me->ccn_closure = calloc (1, sizeof (struct ccn_closure))) == NULL) { GST_ELEMENT_ERROR (me, RESOURCE, READ, (NULL), ("closure alloc failed")); return; } /* We setup the closure to contain the sink element context reference, and also tell it what function to call */ me->ccn_closure->data = me; me->ccn_closure->p = new_interests; me->timeouts = 0; ccn_charbuf_append (filtName, me->name->buf, me->name->length); /* This call will set up a handler for interests we expect to get from clients */ // hDump(DUMP_ADDR(filtName->buf), DUMP_SIZE(filtName->length)); ccn_set_interest_filter (me->ccn, filtName, me->ccn_closure); GST_DEBUG ("CCNxSink event: interest filter registered\n"); /* Some debugging information */ temp->length = 0; ccn_uri_append (temp, me->name->buf, me->name->length, TRUE); GST_DEBUG ("CCNxSink event: using uri: %s\n", ccn_charbuf_as_string (temp)); /* Now that the interest is registered, we loop around waiting for something to do */ /* We pass control to ccnx for a while so it can work with any incoming or outgoing data */ /* and then we check our fifo queue for work to do. That's about it! */ /* We check to see if any problems have caused our ccnd connection to fail, and we reconnect */ while (res >= 0) { GST_DEBUG ("CCNxSink event: *** looping"); res = ccn_run (me->ccn, 50); check_fifo (me); if (res < 0 && ccn_get_connection_fd (me->ccn) == -1) { GST_DEBUG ("CCNxSink event: need to reconnect..."); /* Try reconnecting, after a bit of delay */ msleep ((30 + (getpid () % 30)) * 1000); res = ccn_connect (me->ccn, ccndHost ()); } } GST_DEBUG ("CCNxSink event: *** event thread ending"); }
static void collect_forwarding_xml(struct ccnd_handle *h, struct ccn_charbuf *b) { struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ struct ccn_forwarding *f; int res; struct ccn_charbuf *name = ccn_charbuf_create(); ccn_charbuf_putf(b, "<forwarding>"); hashtb_start(h->nameprefix_tab, e); for (; e->data != NULL; hashtb_next(e)) { struct nameprefix_entry *ipe = e->data; for (f = ipe->forwarding, res = 0; f != NULL && !res; f = f->next) { if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) res = 1; } if (res) { ccn_name_init(name); ccn_name_append_components(name, e->key, 0, e->keysize); ccn_charbuf_putf(b, "<fentry>"); ccn_charbuf_putf(b, "<prefix>"); ccn_uri_append(b, name->buf, name->length, 1); ccn_charbuf_putf(b, "</prefix>"); for (f = ipe->forwarding; f != NULL; f = f->next) { if ((f->flags & (CCN_FORW_ACTIVE | CCN_FORW_PFXO)) != 0) { ccn_charbuf_putf(b, "<dest>" "<faceid>%u</faceid>" "<flags>%x</flags>" "<expires>%d</expires>" "</dest>", f->faceid, f->flags & CCN_FORW_PUBMASK, f->expires); } } ccn_charbuf_putf(b, "</fentry>"); } } hashtb_end(e); ccn_charbuf_destroy(&name); ccn_charbuf_putf(b, "</forwarding>"); }
/** * Produce a ccnd debug trace entry. * Output is produced by calling ccnd_msg. * @param h the ccnd handle * @param lineno caller's source line number (usually __LINE__) * @param msg a short text tag to identify the entry * @param face handle of associated face; may be NULL * @param ccnb points to ccnb-encoded Interest or ContentObject * @param ccnb_size is in bytes */ void ccnd_debug_ccnb(struct ccnd_handle *h, int lineno, const char *msg, struct face *face, const unsigned char *ccnb, size_t ccnb_size) { struct ccn_charbuf *c; struct ccn_parsed_interest pi; const unsigned char *nonce = NULL; size_t nonce_size = 0; size_t i; if (h != NULL && h->debug == 0) return; c = ccn_charbuf_create(); ccn_charbuf_putf(c, "debug.%d %s ", lineno, msg); if (face != NULL) ccn_charbuf_putf(c, "%u ", face->faceid); ccn_uri_append(c, ccnb, ccnb_size, 1); ccn_charbuf_putf(c, " (%u bytes)", (unsigned)ccnb_size); if (ccn_parse_interest(ccnb, ccnb_size, &pi, NULL) >= 0) { const char *p = ""; ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi.offset[CCN_PI_B_Nonce], pi.offset[CCN_PI_E_Nonce], &nonce, &nonce_size); if (nonce_size > 0) { ccn_charbuf_putf(c, " "); if (nonce_size == 12) p = "CCC-P-F-T-NN"; for (i = 0; i < nonce_size; i++) ccn_charbuf_putf(c, "%s%02X", (*p) && (*p++)=='-' ? "-" : "", nonce[i]); } } ccnd_msg(h, "%s", ccn_charbuf_as_string(c)); ccn_charbuf_destroy(&c); }
/** * Like ccn_uri_append(), but accepts a flatname instead of ccnb */ int ccn_uri_append_flatname(struct ccn_charbuf *uri, const unsigned char *flatname, size_t size, int includescheme) { struct ccn_charbuf *ccnb = NULL; int res; ccnb = ccn_charbuf_create(); if (ccnb == NULL) return(-1); res = ccn_name_init(ccnb); if (res < 0) goto Bail; res = ccn_name_append_flatname(ccnb, flatname, size, 0, -1); if (res < 0) goto Bail; res = ccn_uri_append(uri, ccnb->buf, ccnb->length, includescheme); Bail: ccn_charbuf_destroy(&ccnb); return(res); }
void get_name_part(struct name_prefix *name_part,struct ccn_charbuf * interest_ccnb, struct ccn_indexbuf *interest_comps, int offset) { int lsa_position=0; struct ccn_indexbuf *components=ccn_indexbuf_create(); struct ccn_charbuf *name=ccn_charbuf_create(); ccn_name_from_uri(name,nlsr->slice_prefix); ccn_name_split (name, components); lsa_position=components->n-2; ccn_charbuf_destroy(&name); struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_name_init(temp); ccn_name_append_components( temp, interest_ccnb->buf, interest_comps->buf[lsa_position+1], interest_comps->buf[interest_comps->n - 1]); struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, temp->buf, temp->length, 0); name_part->name=(char *)calloc(strlen(ccn_charbuf_as_string(temp1))+1, sizeof(char)); memcpy(name_part->name,ccn_charbuf_as_string(temp1), strlen(ccn_charbuf_as_string(temp1))); name_part->name[strlen(ccn_charbuf_as_string(temp1))]='\0'; name_part->length=strlen(ccn_charbuf_as_string(temp1))+1; ccn_charbuf_destroy(&temp1); ccn_charbuf_destroy(&temp); ccn_indexbuf_destroy(&components); if ( nlsr->debugging ) printf("Name Part: %s \n",name_part->name); }
PUBLIC void ccnr_uri_listen(struct ccnr_handle *ccnr, struct ccn *ccn, const char *uri, ccn_handler p, intptr_t intdata) { struct ccn_charbuf *name; struct ccn_charbuf *uri_modified = NULL; struct ccn_closure *closure; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t offset; name = ccn_charbuf_create(); ccn_name_from_uri(name, uri); comps = ccn_indexbuf_create(); if (ccn_name_split(name, comps) < 0) abort(); if (ccn_name_comp_get(name->buf, comps, 1, &comp, &comp_size) >= 0) { if (comp_size == 32 && 0 == memcmp(comp, CCNR_ID_TEMPL, 32)) { /* Replace placeholder with our ccnr_id */ offset = comp - name->buf; memcpy(name->buf + offset, ccnr->ccnr_id, 32); uri_modified = ccn_charbuf_create(); ccn_uri_append(uri_modified, name->buf, name->length, 1); uri = (char *)uri_modified->buf; } } closure = calloc(1, sizeof(*closure)); closure->p = p; closure->data = ccnr; closure->intdata = intdata; ccn_set_interest_filter(ccn, name, closure); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&uri_modified); ccn_indexbuf_destroy(&comps); }
enum ccn_upcall_res andana_client_encap_interest( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { int res; enum ccn_upcall_res upcall_res = CCN_UPCALL_RESULT_ERR; struct andana_client *client = selfp->data; struct ccn_proxy *proxy = client->proxy; size_t orig_name_ncomps; struct ccn_charbuf *orig_name = NULL; struct ccn_indexbuf *orig_name_comps = NULL; struct ccn_charbuf *new_name = NULL; struct ccn_indexbuf *new_name_comps = NULL; struct hashtb_enumerator ee; struct hashtb_enumerator *e = ⅇ switch (kind) { case CCN_UPCALL_INTEREST: DEBUG_PRINT("Received Interest\n"); break; case CCN_UPCALL_FINAL: DEBUG_PRINT("Encap: callback final\n"); return(CCN_UPCALL_RESULT_OK); default: return(CCN_UPCALL_RESULT_ERR); } /* Extract Name from Interest */ orig_name_ncomps = ccn_util_extract_name(info->interest_ccnb, info->interest_comps, &orig_name, &orig_name_comps); /* * Need to check this Interest doesn't match what we send out. * Otherwise, we'll just keep encapsulating the same thing over and over. */ int num_matching_comps = ccn_util_name_match(client->proxy->prefix, client->proxy->prefix_comps, orig_name, orig_name_comps); if (num_matching_comps == client->proxy->prefix_ncomps) { DEBUG_PRINT("Interest matches %d of %d components, ignoring interest\n", num_matching_comps, (int)client->proxy->prefix_ncomps); #ifdef PROXYDEBUG ccn_util_println_pc_fmt(orig_name->buf, orig_name->length); DEBUG_PRINT("Name has %lu comps\n", orig_name_comps->n-1); ccn_util_println_pc_fmt(client->proxy->prefix->buf, client->proxy->prefix->length); DEBUG_PRINT("Name has %lu comps\n", client->proxy->prefix_comps->n-1); #endif goto MatchBail; } else { DEBUG_PRINT("Interest matches %d of %d components\n", num_matching_comps, (int)client->proxy->prefix_ncomps); } /* Create a new name encapsulated & encrypted name */ // new_name_comps = ccn_indexbuf_create(); ccn_name_append(orig_name, info->interest_ccnb, info->pi->offset[CCN_PI_E]); ccn_indexbuf_destroy(&orig_name_comps); struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = &decoder; ccn_buf_decoder_start(d, orig_name->buf, orig_name->length); orig_name_comps = ccn_indexbuf_create(); res = ccn_parse_Name(d, orig_name_comps); if (res <= 0) { DEBUG_PRINT("%d %s error parsing encapsulated name\n", __LINE__, __func__); goto MatchBail; } res = andana_path_encrypt_encap(client->path, orig_name, orig_name_comps, &new_name, &new_name_comps); if (res <= 0) { DEBUG_PRINT("%d %s error encapsulating and encrypting name\n", __LINE__, __func__); goto EncryptBail; } /* Remember the new name so we know how to decrypt & decapsulate it later */ hashtb_start(client->name_to_path, e); res = hashtb_seek(e, new_name->buf, new_name->length, 0); if (res == HT_NEW_ENTRY) { } else if (res == HT_OLD_ENTRY) { DEBUG_PRINT("Interest recording found old entry\n"); upcall_res = CCN_UPCALL_RESULT_OK; goto LookupBail; } else { DEBUG_PRINT("Error in Interest insertion\n"); goto LookupBail; } /* Send out new Interest */ #ifdef PROXYDEBUG struct ccn_charbuf *c = ccn_charbuf_create(); ccn_uri_append(c, new_name->buf, new_name->length, 1); DEBUG_PRINT("name = %s\n", ccn_charbuf_as_string(c)); ccn_charbuf_destroy(&c); #endif res = ccn_express_interest(proxy->handle, new_name, proxy->content_handler, NULL); if(res != 0) { DEBUG_PRINT("express interest res = %d\n",res); } else { struct andana_path **path_ptr = e->data; *path_ptr = andana_path_copy(client->path); upcall_res = CCN_UPCALL_RESULT_INTEREST_CONSUMED; } LookupBail: hashtb_end(e); EncryptBail: ccn_charbuf_destroy(&new_name); ccn_indexbuf_destroy(&new_name_comps); MatchBail: ccn_charbuf_destroy(&orig_name); ccn_indexbuf_destroy(&orig_name_comps); return(upcall_res); }
int main (int argc, char *argv[]) { struct ccn_charbuf *buffer = ccn_charbuf_create(); struct ccn_charbuf *signed_info = ccn_charbuf_create(); struct ccn_skeleton_decoder dd = {0}; ssize_t res; char *outname = NULL; int fd; int result = 0; char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length: 448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", "Quaer #%2d zjduer badone", "", NULL}; char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", "/d/e/f", "/zero/length/content", NULL}; struct path * cur_path = NULL; struct ccn_keystore *keystore = ccn_keystore_create(); char *home = getenv("HOME"); char *keystore_suffix = "/.ccnx/.ccnx_keystore"; char *keystore_name = NULL; int i; if (argc == 3 && strcmp(argv[1], "-o") == 0) { outname = argv[2]; } else { printf("Usage: %s -o <outfilename>\n", argv[0]); exit(1); } if (home == NULL) { printf("Unable to determine home directory for keystore\n"); exit(1); } keystore_name = calloc(1, strlen(home) + strlen(keystore_suffix) + 1); strcat(keystore_name, home); strcat(keystore_name, keystore_suffix); if (0 != ccn_keystore_init(keystore, keystore_name, "Th1s1sn0t8g00dp8ssw0rd.")) { printf("Failed to initialize keystore\n"); exit(1); } printf("Creating signed_info\n"); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ccn_keystore_public_key_digest(keystore), /*publisher_key_id_size*/ccn_keystore_public_key_digest_length(keystore), /*datetime*/NULL, /*type*/CCN_CONTENT_GONE, /*freshness*/ 42, /*finalblockid*/NULL, /*keylocator*/NULL); if (res < 0) { printf("Failed to create signed_info!\n"); } res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length); if (!(res == signed_info->length && dd.state == 0)) { printf("Failed to decode signed_info! Result %d State %d\n", (int)res, dd.state); result = 1; } memset(&dd, 0, sizeof(dd)); printf("Done with signed_info\n"); printf("Encoding sample message data length %d\n", (int)strlen(contents[0])); cur_path = path_create(paths[0]); if (encode_message(buffer, cur_path, contents[0], strlen(contents[0]), signed_info, ccn_keystore_private_key(keystore))) { printf("Failed to encode message!\n"); } else { printf("Encoded sample message length is %d\n", (int)buffer->length); res = ccn_skeleton_decode(&dd, buffer->buf, buffer->length); if (!(res == buffer->length && dd.state == 0)) { printf("Failed to decode! Result %d State %d\n", (int)res, dd.state); result = 1; } if (outname != NULL) { fd = open(outname, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU); if (fd == -1) perror(outname); res = write(fd, buffer->buf, buffer->length); close(fd); } if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) != 0) { result = 1; } printf("Expect signature verification failure: "); if (buffer->length >= 20) buffer->buf[buffer->length - 20] += 1; if (decode_message(buffer, cur_path, contents[0], strlen(contents[0]), ccn_keystore_public_key(keystore)) == 0) { result = 1; } } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); printf("Done with sample message\n"); /* Now exercise as unit tests */ for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) { printf("Unit test case %d\n", i); cur_path = path_create(paths[i]); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_private_key(keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) { printf("Failed decode\n"); result = 1; } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); } /* Test the uri encode / decode routines */ init_all_chars_percent_encoded(); const char *uri_tests[] = { "_+4", "ccnx:/this/is/a/test", "", "ccnx:/this/is/a/test", ".+4", "../test2?x=2", "?x=2", "ccnx:/this/is/a/test2", "_-X", "../should/error", "", "", "_+2", "/missing/scheme", "", "ccnx:/missing/scheme", ".+0", "../../../../../././#/", "#/", "ccnx:/", ".+1", all_chars_percent_encoded, "", all_chars_percent_encoded_canon, "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon, ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....", "_-X", "/%3G?bad-pecent-encode", "", "", "_-X", "/%3?bad-percent-encode", "", "", "_-X", "/%#bad-percent-encode", "", "", "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri", NULL, NULL, NULL, NULL }; const char **u; struct ccn_charbuf *uri_out = ccn_charbuf_create(); buffer = ccn_charbuf_create(); for (u = uri_tests; *u != NULL; u += 4, i++) { printf("Unit test case %d\n", i); if (u[0][0] != '.') buffer->length = 0; res = ccn_name_from_uri(buffer, u[1]); if (!expected_res(res, u[0][1])) { printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (res > strlen(u[1])) { printf("Failed: ccn_name_from_uri long res %d\n", (int)res); result = 1; } else if (0 != strcmp(u[1] + res, u[2])) { printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res); result = 1; } uri_out->length = 0; res = ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (!expected_res(res, u[0][2])) { printf("Failed: ccn_uri_append wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (uri_out->length != strlen(u[3])) { printf("Failed: ccn_uri_append produced wrong number of characters\n"); result = 1; } ccn_charbuf_reserve(uri_out, 1)[0] = 0; if (0 != strcmp((const char *)uri_out->buf, u[3])) { printf("Failed: ccn_uri_append produced wrong output\n"); printf("Expected: %s\n", u[3]); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } } } } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); printf("Name marker tests\n"); do { const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81"; const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE"; const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF"; const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_chop(buffer, NULL, 100); if (res != -1) { printf("Failed: ccn_name_chop did not produce error \n"); result = 1; } res = ccn_name_chop(buffer, NULL, 4); if (res != 4) { printf("Failed: ccn_name_chop got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) { printf("Failed: ccn_name_chop botch\n"); printf("Expected: %s\n", expected_chopped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_next_sibling(buffer); if (res != 4) { printf("Failed: ccn_name_next_sibling got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_name_next_sibling(buffer); uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, 1); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped2_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); printf("Message digest tests\n"); do { printf("Unit test case %d\n", i++); struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256); if (dg == NULL) { printf("Failed: ccn_digest_create returned NULL\n"); result = 1; break; } printf("Unit test case %d\n", i++); const unsigned char expected_digest[] = { 0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0 }; unsigned char actual_digest[sizeof(expected_digest)] = {0}; const char *data = "Content-centric"; if (ccn_digest_size(dg) != sizeof(expected_digest)) { printf("Failed: wrong digest size\n"); result = 1; break; } printf("Unit test case %d\n", i++); ccn_digest_init(dg); res = ccn_digest_update(dg, data, strlen(data)); if (res != 0) printf("Warning: check res %d\n", (int)res); printf("Unit test case %d\n", i++); res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest)); if (res != 0) printf("Warning: check res %d\n", (int)res); if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) { printf("Failed: wrong digest\n"); result = 1; break; } } while (0); printf("Really basic PRNG test\n"); do { unsigned char r1[42]; unsigned char r2[42]; printf("Unit test case %d\n", i++); ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */ ccn_random_bytes(r1, sizeof(r1)); memcpy(r2, r1, sizeof(r2)); ccn_random_bytes(r2, sizeof(r2)); if (0 == memcmp(r1, r2, sizeof(r2))) { printf("Failed: badly broken PRNG\n"); result = 1; break; } } while (0); printf("Bloom filter tests\n"); do { unsigned char seed1[4] = "1492"; const char *a[13] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen" }; struct ccn_bloom *b1 = NULL; struct ccn_bloom *b2 = NULL; int j, k, t1, t2; unsigned short us; printf("Unit test case %d\n", i++); b1 = ccn_bloom_create(13, seed1); for (j = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0; j < 13; j++) ccn_bloom_insert(b1, a[j], strlen(a[j])); for (j = 0; j < 13; j++) if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" not found when it should have been\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0, k = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1))) k++; if (k > 0) { printf("Mmm, found %d false positives\n", k); if (k > 2) { result = 1; break; } } unsigned char seed2[5] = "aqfb\0"; for (; seed2[3] <= 'f'; seed2[3]++) { printf("Unit test case %d (%4s) ", i++, seed2); b2 = ccn_bloom_create(13, seed2); for (j = 0; j < 13; j++) ccn_bloom_insert(b2, a[j], strlen(a[j])); for (j = 0, k = 0, us = ~0; us > 0; us--) { t1 = ccn_bloom_match(b1, &us, sizeof(us)); t2 = ccn_bloom_match(b2, &us, sizeof(us)); j += (t1 | t2); k += (t1 & t2); } printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1)); if (k > 12) { printf("Failed: Bloom seeding may not be effective\n"); result = 1; } ccn_bloom_destroy(&b2); } ccn_bloom_destroy(&b1); } while (0); printf("ccn_sign_content() tests\n"); do { struct ccn *h = ccn_create(); struct ccn_charbuf *co = ccn_charbuf_create(); struct ccn_signing_params sparm = CCN_SIGNING_PARAMS_INIT; struct ccn_parsed_ContentObject pco = {0}; struct ccn_charbuf *name = ccn_charbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/data/%00%42"); res = ccn_sign_content(h, co, name, NULL, "DATA", 4); if (res != 0) { printf("Failed: res == %d\n", (int)res); result = 1; } sparm.template_ccnb = ccn_charbuf_create(); res = ccn_parse_ContentObject(co->buf, co->length, &pco, NULL); if (res != 0) { printf("Failed: ccn_parse_ContentObject res == %d\n", (int)res); result = 1; break; } ccn_charbuf_append(sparm.template_ccnb, co->buf + pco.offset[CCN_PCO_B_SignedInfo], pco.offset[CCN_PCO_E_SignedInfo] - pco.offset[CCN_PCO_B_SignedInfo]); sparm.sp_flags = CCN_SP_TEMPL_TIMESTAMP; printf("Unit test case %d\n", i++); res = ccn_sign_content(h, co, name, &sparm, "DATA", 4); if (res != 0) { printf("Failed: res == %d\n", (int)res); result = 1; } printf("Unit test case %d\n", i++); sparm.sp_flags = -1; res = ccn_sign_content(h, co, name, &sparm, "DATA", 4); if (res != -1) { printf("Failed: res == %d\n", (int)res); result = 1; } ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&sparm.template_ccnb); ccn_charbuf_destroy(&co); ccn_destroy(&h); } while (0); printf("link tests\n"); do { struct ccn_charbuf *l = ccn_charbuf_create(); struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_parsed_Link pl = {0}; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; struct ccn_indexbuf *comps = ccn_indexbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/link/name"); ccnb_append_Link(l, name, "label", NULL); d = ccn_buf_decoder_start(&decoder, l->buf, l->length); res = ccn_parse_Link(d, &pl, comps); if (res != 3 /* components in name */) { printf("Failed: ccn_parse_Link res == %d\n", (int)res); result = 1; } } while (0); exit(result); }
enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *c = NULL; struct ccn_charbuf *comp = NULL; struct ccn_charbuf *uri = NULL; struct ccn_charbuf *templ = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; struct ccn_indexbuf *comps = NULL; int matched_comps = 0; int res; int i; struct upcalldata *data = selfp->data; if (data->magic != 856372) abort(); if (kind == CCN_UPCALL_FINAL) return(CCN_UPCALL_RESULT_OK); if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(CCN_UPCALL_RESULT_REEXPRESS); if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) { if ((data->option & MUST_VERIFY) != 0) return(CCN_UPCALL_RESULT_VERIFY); } else if (kind != CCN_UPCALL_CONTENT) abort(); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; comps = info->content_comps; matched_comps = info->pi->prefix_comps; c = ccn_charbuf_create(); uri = ccn_charbuf_create(); templ = ccn_charbuf_create(); /* note that comps->n is 1 greater than the number of explicit components */ if (matched_comps > comps->n) { ccn_uri_append(c, ccnb, ccnb_size, 1); fprintf(stderr, "How did this happen? %s\n", ccn_charbuf_as_string(uri)); exit(1); } data->counter[0]++; /* Recover the same prefix as before */ ccn_name_init(c); res = ccn_name_append_components(c, info->interest_ccnb, info->interest_comps->buf[0], info->interest_comps->buf[matched_comps]); if (res < 0) abort(); comp = ccn_charbuf_create(); ccn_name_init(comp); if (matched_comps + 1 == comps->n) { /* Reconstruct the implicit ContentObject digest component */ ccn_digest_ContentObject(ccnb, info->pco); ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes); } else if (matched_comps < comps->n) { ccn_name_append_components(comp, ccnb, comps->buf[matched_comps], comps->buf[matched_comps + 1]); } res = ccn_uri_append(uri, comp->buf, comp->length, 0); if (res < 0 || uri->length < 1) fprintf(stderr, "*** Error: ccnls line %d res=%d\n", __LINE__, res); else { if (uri->length == 1) ccn_charbuf_append(uri, ".", 1); printf("%s%s\n", ccn_charbuf_as_string(uri) + 1, kind == CCN_UPCALL_CONTENT ? " [verified]" : " [unverified]"); } ccn_charbuf_append_tt(templ, CCN_DTAG_Interest, CCN_DTAG); ccn_charbuf_append(templ, c->buf, c->length); /* Name */ if (matched_comps == comps->n) { /* The interest supplied the digest component */ ccn_charbuf_destroy(&comp); /* * We can't rely on the Exclude filter to keep from seeing this, so * say that we need at least one more name component. */ ccn_charbuf_append_tt(templ, CCN_DTAG_MinSuffixComponents, CCN_DTAG); ccn_charbuf_append_tt(templ, 1, CCN_UDATA); ccn_charbuf_append(templ, "1", 1); ccn_charbuf_append_closer(templ); /* </MinSuffixComponents> */ } else { data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0])); data->excl[data->n_excl++] = comp; comp = NULL; } qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare); ccn_charbuf_append_tt(templ, CCN_DTAG_Exclude, CCN_DTAG); for (i = 0; i < data->n_excl; i++) { comp = data->excl[i]; if (comp->length < 4) abort(); ccn_charbuf_append(templ, comp->buf + 1, comp->length - 2); } comp = NULL; ccn_charbuf_append_closer(templ); /* </Exclude> */ ccnb_tagged_putf(templ, CCN_DTAG_AnswerOriginKind, "%d", CCN_AOK_CS); if (data->scope > -1) ccnb_tagged_putf(templ, CCN_DTAG_Scope, "%d", data->scope); ccn_charbuf_append_closer(templ); /* </Interest> */ if (templ->length > data->warn) { fprintf(stderr, "*** Interest packet is %d bytes\n", (int)templ->length); data->warn = data->warn * 8 / 5; } ccn_express_interest(info->h, c, selfp, templ); ccn_charbuf_destroy(&templ); ccn_charbuf_destroy(&c); ccn_charbuf_destroy(&uri); return(CCN_UPCALL_RESULT_OK); }
/* * This upcall gets called for each piece of incoming content that * matches one of our interests. We need to issue a new interest that * excludes another component at the current level, and perhaps also * and interest to start exploring the next level. Thus if the matched * interest is * /a/b/c exclude {d,e,f,i,j,k} * and we get * /a/b/c/g/h * we would issue a new interest * /a/b/c exclude {d,e,f,g,i,j,k} * to continue exploring the current level, plus a simple interest * /a/b/c/g * to start exploring the next level as well. * * This does end up fetching each piece of content multiple times, once for * each level in the name. The repeated requests will be answered from the local * content store, though, and so should not generate extra network traffic. * There is a lot of unanswerable interest generated, though. * * To prevent the interests from becoming too huge, we may need to split them. * Thus if the first new interest above were deemed too large, we could instead * issue the two interests * /a/b/c exclude {d,e,f,g,*} * /a/b/c exclude {*,g,i,j,k} * where * stands for a Bloom filter that excludes anything. Note the * repetition of g to ensure that these two interests cover disjoint portions * of the hierarchy. We need to keep track of the endpoint conditions * as well as the excluded set in our upcall data. * When a split happens, we need a new closure to track it, as we do when * we start exploring a new level. */ static enum ccn_upcall_res incoming_content( struct ccn_closure *selfp, enum ccn_upcall_kind kind, struct ccn_upcall_info *info) { struct ccn_charbuf *c = NULL; struct ccn_charbuf *comp = NULL; struct ccn_charbuf *uri = NULL; const unsigned char *ccnb = NULL; size_t ccnb_size = 0; struct ccn_indexbuf *comps = NULL; int matched_comps = 0; int res; int i; struct ccn_traversal *data = get_my_data(selfp); if (kind == CCN_UPCALL_FINAL) { for (i = 0; i < data->n_excl; i++) ccn_charbuf_destroy(&(data->excl[i])); if (data->excl != NULL) free(data->excl); free(data); free(selfp); return(0); } if (kind == CCN_UPCALL_INTEREST_TIMED_OUT) return(0); if (kind == CCN_UPCALL_CONTENT_BAD) return(0); if (kind == CCN_UPCALL_CONTENT_UNVERIFIED) { if ((data->flags & MUST_VERIFY) != 0) return(CCN_UPCALL_RESULT_VERIFY); } if (kind != CCN_UPCALL_CONTENT && kind != CCN_UPCALL_CONTENT_UNVERIFIED) abort(); ccnb = info->content_ccnb; ccnb_size = info->pco->offset[CCN_PCO_E]; comps = info->content_comps; matched_comps = info->pi->prefix_comps; c = ccn_charbuf_create(); uri = ccn_charbuf_create(); if (matched_comps + 1 > comps->n) { ccn_uri_append(c, ccnb, ccnb_size, 1); fprintf(stderr, "How did this happen? %s\n", ccn_charbuf_as_string(uri)); exit(1); } data->counter[0]++; /* Tell main that something new came in */ /* Recover the same prefix as before */ ccn_name_init(c); ccn_name_append_components(c, ccnb, comps->buf[0], comps->buf[matched_comps]); comp = ccn_charbuf_create(); ccn_name_init(comp); if (matched_comps + 1 == comps->n) { /* Reconstruct the implicit content digest component */ ccn_digest_ContentObject(ccnb, info->pco); ccn_name_append(comp, info->pco->digest, info->pco->digest_bytes); } else { ccn_name_append_components(comp, ccnb, comps->buf[matched_comps], comps->buf[matched_comps + 1]); } data->excl = realloc(data->excl, (data->n_excl + 1) * sizeof(data->excl[0])); data->excl[data->n_excl++] = comp; comp = NULL; qsort(data->excl, data->n_excl, sizeof(data->excl[0]), &namecompare); res = express_my_interest(info->h, selfp, c); if (res == -1) { struct ccn_closure *high = split_my_excludes(selfp); if (high == NULL) abort(); express_my_interest(info->h, selfp, c); express_my_interest(info->h, high, c); } /* Explore the next level, if there is one. */ if (matched_comps + 2 < comps->n) { struct ccn_traversal *newdat = NULL; struct ccn_closure *cl; newdat = calloc(1, sizeof(*newdat)); newdat->magic = 68955871; newdat->warn = 1492; newdat->counter = data->counter; newdat->flags = data->flags & ~(EXCLUDE_LOW | EXCLUDE_HIGH); newdat->n_excl = 0; newdat->excl = NULL; cl = calloc(1, sizeof(*cl)); cl->p = &incoming_content; cl->data = newdat; ccn_name_init(c); ccn_name_append_components(c, ccnb, comps->buf[0], comps->buf[matched_comps + 1]); express_my_interest(info->h, cl, c); } else { res = ccn_uri_append(uri, info->content_ccnb, info->pco->offset[CCN_PCO_E], 1); if (res < 0) fprintf(stderr, "*** Error: ccn_traverse line %d res=%d\n", __LINE__, res); else printf("%s\n", ccn_charbuf_as_string(uri)); } ccn_charbuf_destroy(&c); ccn_charbuf_destroy(&uri); return(0); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherIDKeyDigest? */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "Exclude"); exclude_tree = proto_item_add_subtree(titem, ett_exclude); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* Nonce */ /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
int main(int argc, char *argv[]) { struct ccn_charbuf *buffer; struct ccn_charbuf *signed_info = ccn_charbuf_create(); struct ccn_skeleton_decoder dd = {0}; ssize_t res; char *outname = NULL; int result = 0; char * contents[] = {"INVITE sip:[email protected] SIP/2.0\nVia: SIP/2.0/UDP 127.0.0.1:5060;rport;branch=z9hG4bK519044721\nFrom: <sip:[email protected]>;tag=2105643453\nTo: Test User <sip:[email protected]>\nCall-ID: [email protected]\nCSeq: 20 INVITE\nContact: <sip:[email protected]:5060>\nMax-Forwards: 70\nUser-Agent: Linphone-1.7.1/eXosip\nSubject: Phone call\nExpires: 120\nAllow: INVITE, ACK, CANCEL, BYE, OPTIONS, REFER, SUBSCRIBE, NOTIFY, MESSAGE\nContent-Type: application/sdp\nContent-Length: 448\n\nv=0\no=jthornto 123456 654321 IN IP4 127.0.0.1\ns=A conversation\nc=IN IP4 127.0.0.1\nt=0 0\nm=audio 7078 RTP/AVP 111 110 0 3 8 101\na=rtpmap:111 speex/16000/1\na=rtpmap:110 speex/8000/1\na=rtpmap:0 PCMU/8000/1\na=rtpmap:3 GSM/8000/1\na=rtpmap:8 PCMA/8000/1\na=rtpmap:101 telephone-event/8000\na=fmtp:101 0-11\nm=video 9078 RTP/AVP 97 98 99\na=rtpmap:97 theora/90000\na=rtpmap:98 H263-1998/90000\na=fmtp:98 CIF=1;QCIF=1\na=rtpmap:99 MP4V-ES/90000\n", "Quaer #%2d zjduer badone", "", NULL}; char * paths[] = { "/sip/protocol/parc.com/domain/foo/principal/invite/verb/[email protected]/id", "/d/e/f", "/zero/length/content", NULL}; struct path * cur_path = NULL; struct ccn_keystore *keystore = ccn_keystore_create(); struct ccn_keystore *aes_keystore = ccn_aes_keystore_create(); char *keystore_name = NULL; char *keystore_password = NULL; char *aes_keystore_name = NULL; unsigned char keybuf[32]; int i; while ((i = getopt(argc, argv, "a:k:p:o:")) != -1) { switch (i) { case 'a': aes_keystore_name = optarg; break; case 'k': keystore_name = optarg; break; case 'p': keystore_password = optarg; break; case 'o': outname = optarg; break; default: printf("Usage: %s [-k <keystore>] [-o <outfilename>]\n", argv[0]); exit(1); } } if (keystore_name == NULL) keystore_name = "test.keystore"; if (aes_keystore_name == NULL) aes_keystore_name = "test.aeskeystore"; if (keystore_password == NULL) keystore_password = "******"; res = ccn_keystore_init(keystore, keystore_name, keystore_password); if (res != 0) { printf ("Initializing keystore in %s\n", keystore_name); res = ccn_keystore_file_init(keystore_name, keystore_password, "ccnxuser", 0, 3650); if (res != 0) { fprintf (stderr, "Cannot create keystore [%s]", keystore_name); return res; } res = ccn_keystore_init(keystore, keystore_name, keystore_password); if (res != 0) { printf("Failed to initialize keystore\n"); exit(1); } } res = ccn_aes_keystore_init(aes_keystore, aes_keystore_name, keystore_password); if (res != 0) { printf ("Initializing AES keystore in %s\n", aes_keystore_name); ccn_generate_symmetric_key(keybuf, 256); res = ccn_aes_keystore_file_init(aes_keystore_name, keystore_password, keybuf, 256); if (res != 0) { fprintf (stderr, "Cannot create keystore [%s]", keystore_name); return res; } res = ccn_aes_keystore_init(aes_keystore, aes_keystore_name, keystore_password); if (res != 0) { printf("Failed to initialize keystore\n"); exit(1); } } printf("Creating signed_info\n"); res = ccn_signed_info_create(signed_info, /*pubkeyid*/ccn_keystore_key_digest(keystore), /*publisher_key_id_size*/ccn_keystore_key_digest_length(keystore), /*timestamp*/NULL, /*type*/CCN_CONTENT_GONE, /*freshness*/ 42, /*finalblockid*/NULL, /*keylocator*/NULL); if (res < 0) { printf("Failed to create signed_info!\n"); } res = ccn_skeleton_decode(&dd, signed_info->buf, signed_info->length); if (!(res == signed_info->length && dd.state == 0)) { printf("Failed to decode signed_info! Result %d State %d\n", (int)res, dd.state); result = 1; } memset(&dd, 0, sizeof(dd)); printf("Done with signed_info\n"); result = encode_sample_test(ccn_keystore_key(keystore), ccn_keystore_public_key(keystore), ccn_keystore_digest_algorithm(keystore), paths, contents, signed_info, outname); if (! result) { result = encode_sample_test(ccn_keystore_key(aes_keystore), ccn_keystore_key(aes_keystore), ccn_keystore_digest_algorithm(aes_keystore), paths, contents, signed_info, outname); } /* Now exercise as unit tests */ for (i = 0; paths[i] != NULL && contents[i] != NULL; i++) { printf("Unit test case %d\n", i); cur_path = path_create(paths[i]); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_key(keystore), ccn_keystore_digest_algorithm(keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_public_key(keystore))) { printf("Failed decode\n"); result = 1; } ccn_charbuf_destroy(&buffer); buffer = ccn_charbuf_create(); if (encode_message(buffer, cur_path, contents[i], strlen(contents[i]), signed_info, ccn_keystore_key(aes_keystore), ccn_keystore_digest_algorithm(aes_keystore))) { printf("Failed encode\n"); result = 1; } else if (decode_message(buffer, cur_path, contents[i], strlen(contents[i]), ccn_keystore_key(aes_keystore))) { printf("Failed decode\n"); result = 1; } path_destroy(&cur_path); ccn_charbuf_destroy(&buffer); } /* Test the uri encode / decode routines */ init_all_chars_percent_encoded(); init_all_chars_mixed_encoded(); const char *uri_tests[] = { "_+4", "ccnx:/this/is/a/test", "", "ccnx:/this/is/a/test", ".+4", "../test2?x=2", "?x=2", "ccnx:/this/is/a/test2", "_-X", "../should/error", "", "", "_+2", "/missing/scheme", "", "ccnx:/missing/scheme", ".+0", "../../../../../././#/", "#/", "ccnx:/", ".+1", all_chars_percent_encoded, "", all_chars_percent_encoded_canon, "_+1", all_chars_percent_encoded_canon, "", all_chars_percent_encoded_canon, ".+4", "ccnx:/.../.%2e./...././.....///?...", "?...", "ccnx:/.../.../..../.....", "_-X", "/%3G?bad-pecent-encode", "", "", "_-X", "/%3?bad-percent-encode", "", "", "_-X", "/%#bad-percent-encode", "", "", "_+3", "ccnx://[email protected]:42/ignore/host/part of uri", "", "ccnx:/ignore/host/part%20of%20uri", NULL, NULL, NULL, NULL }; const char **u; struct ccn_charbuf *uri_out = ccn_charbuf_create(); buffer = ccn_charbuf_create(); for (u = uri_tests; *u != NULL; u += 4, i++) { printf("Unit test case %d\n", i); if (u[0][0] != '.') buffer->length = 0; res = ccn_name_from_uri(buffer, u[1]); if (!expected_res(res, u[0][1])) { printf("Failed: ccn_name_from_uri wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (res > strlen(u[1])) { printf("Failed: ccn_name_from_uri long res %d\n", (int)res); result = 1; } else if (0 != strcmp(u[1] + res, u[2])) { printf("Failed: ccn_name_from_uri expecting leftover '%s', got '%s'\n", u[2], u[1] + res); result = 1; } uri_out->length = 0; res = ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (!expected_res(res, u[0][2])) { printf("Failed: ccn_uri_append wrong res %d\n", (int)res); result = 1; } if (res >= 0) { if (uri_out->length != strlen(u[3])) { printf("Failed: ccn_uri_append produced wrong number of characters\n"); result = 1; } ccn_charbuf_reserve(uri_out, 1)[0] = 0; if (0 != strcmp((const char *)uri_out->buf, u[3])) { printf("Failed: ccn_uri_append produced wrong output\n"); printf("Expected: %s\n", u[3]); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } } } } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); printf("Name marker tests\n"); do { const char *expected_uri = "ccnx:/example.com/.../%01/%FE/%01%02%03%04%05%06%07%08/%FD%10%10%10%10%1F%FF/%00%81"; const char *expected_chopped_uri = "ccnx:/example.com/.../%01/%FE"; const char *expected_bumped_uri = "ccnx:/example.com/.../%01/%FF"; const char *expected_bumped2_uri = "ccnx:/example.com/.../%01/%00%00"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_chop(buffer, NULL, 100); if (res != -1) { printf("Failed: ccn_name_chop did not produce error \n"); result = 1; } res = ccn_name_chop(buffer, NULL, 4); if (res != 4) { printf("Failed: ccn_name_chop got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_chopped_uri)) { printf("Failed: ccn_name_chop botch\n"); printf("Expected: %s\n", expected_chopped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } res = ccn_name_next_sibling(buffer); if (res != 4) { printf("Failed: ccn_name_next_sibling got wrong length\n"); result = 1; } uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_name_next_sibling(buffer); uri_out->length = 0; ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_PERCENTESCAPE | CCN_URI_INCLUDESCHEME); if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_bumped2_uri)) { printf("Failed: ccn_name_next_sibling botch\n"); printf("Expected: %s\n", expected_bumped2_uri); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); do { const char *expected_uri_mixed = "ccnx:/example.com/.../%01/%FE/=0102030405060708/=FD101010101FFF/=0081"; printf("Unit test case %d\n", i++); buffer = ccn_charbuf_create(); uri_out = ccn_charbuf_create(); res = ccn_name_init(buffer); res |= ccn_name_append_str(buffer, "example.com"); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 1); res |= ccn_name_append_numeric(buffer, 0xFE, 0); res |= ccn_name_append_numeric(buffer, CCN_MARKER_NONE, 0x0102030405060708ULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_VERSION, 0x101010101FFFULL); res |= ccn_name_append_numeric(buffer, CCN_MARKER_SEQNUM, 129); res |= ccn_uri_append(uri_out, buffer->buf, buffer->length, CCN_URI_MIXEDESCAPE | CCN_URI_INCLUDESCHEME); if (res < 0) { printf("Failed: name marker tests had negative res\n"); result = 1; } if (0 != strcmp(ccn_charbuf_as_string(uri_out), expected_uri_mixed)) { printf("Failed: name marker tests produced wrong output\n"); printf("Expected: %s\n", expected_uri_mixed); printf(" Actual: %s\n", (const char *)uri_out->buf); result = 1; } ccn_charbuf_destroy(&buffer); ccn_charbuf_destroy(&uri_out); } while (0); printf("Empty component encoding test\n"); do { struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_charbuf *expected_encoding = ccn_charbuf_create(); /* manually create an encoding of <Name><Component/></Name> to ensure * that the regular encoders do not create a 0-length blob as part of * the empty component. */ ccnb_element_begin(expected_encoding, CCN_DTAG_Name); ccnb_element_begin(expected_encoding, CCN_DTAG_Component); ccnb_element_end(expected_encoding); ccnb_element_end(expected_encoding); ccn_name_from_uri(name, "ccnx:/..."); if (expected_encoding->length != name->length) { printf("Failed: encoding length %u but expected %u\n", (unsigned) name->length, (unsigned)expected_encoding->length); result = 1; } for (i = 0; i < expected_encoding->length; i++) { if (expected_encoding->buf[i] != name->buf[i]) { printf("Failed: encoding mismatch at %d, got %d but expected %d\n", i, name->buf[i], expected_encoding->buf[i]); result = 1; } } } while (0); printf("Timestamp tests\n"); do { intmax_t sec; int nsec; int r; int f; struct ccn_charbuf *a[2]; int t0 = 1363899678; printf("Unit test case %d\n", i++); /* Run many increasing inputs and make sure the output is in order. */ a[0] = ccn_charbuf_create(); a[1] = ccn_charbuf_create(); ccnb_append_timestamp_blob(a[1], CCN_MARKER_NONE, t0 - 1, 0); for (f = 0, nsec = 0, sec = t0; sec < t0 + 20; nsec += 122099) { while (nsec >= 1000000000) { sec++; nsec -= 1000000000; } ccn_charbuf_reset(a[f]); r = ccnb_append_timestamp_blob(a[f], CCN_MARKER_NONE, sec, nsec); if (r != 0 || a[f]->length != 7 || memcmp(a[1-f]->buf, a[f]->buf, 6) > 0) { printf("Failed ccnb_append_timestamp_blob(...,%jd,%d)\n", sec, nsec); result = 1; } f = 1 - f; } ccn_charbuf_destroy(&a[0]); ccn_charbuf_destroy(&a[1]); } while (0); printf("Message digest tests\n"); do { printf("Unit test case %d\n", i++); struct ccn_digest *dg = ccn_digest_create(CCN_DIGEST_SHA256); if (dg == NULL) { printf("Failed: ccn_digest_create returned NULL\n"); result = 1; break; } printf("Unit test case %d\n", i++); const unsigned char expected_digest[] = { 0xb3, 0x82, 0xcd, 0xb0, 0xe9, 0x5d, 0xf7, 0x3b, 0xe7, 0xdc, 0x19, 0x81, 0x3a, 0xfd, 0xdf, 0x89, 0xfb, 0xd4, 0xd4, 0xa0, 0xdb, 0x11, 0xa6, 0xba, 0x24, 0x16, 0x5b, 0xad, 0x9d, 0x90, 0x72, 0xb0 }; unsigned char actual_digest[sizeof(expected_digest)] = {0}; const char *data = "Content-centric"; if (ccn_digest_size(dg) != sizeof(expected_digest)) { printf("Failed: wrong digest size\n"); result = 1; break; } printf("Unit test case %d\n", i++); ccn_digest_init(dg); res = ccn_digest_update(dg, data, strlen(data)); if (res != 0) printf("Warning: check res %d\n", (int)res); printf("Unit test case %d\n", i++); res = ccn_digest_final(dg, actual_digest, sizeof(expected_digest)); if (res != 0) printf("Warning: check res %d\n", (int)res); if (0 != memcmp(actual_digest, expected_digest, sizeof(expected_digest))) { printf("Failed: wrong digest\n"); result = 1; break; } } while (0); printf("Really basic PRNG test\n"); do { unsigned char r1[42]; unsigned char r2[42]; printf("Unit test case %d\n", i++); ccn_add_entropy(&i, sizeof(i), 0); /* Not much entropy, really. */ ccn_random_bytes(r1, sizeof(r1)); memcpy(r2, r1, sizeof(r2)); ccn_random_bytes(r2, sizeof(r2)); if (0 == memcmp(r1, r2, sizeof(r2))) { printf("Failed: badly broken PRNG\n"); result = 1; break; } } while (0); printf("Bloom filter tests\n"); do { unsigned char seed1[4] = "1492"; const char *a[13] = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen" }; struct ccn_bloom *b1 = NULL; struct ccn_bloom *b2 = NULL; int j, k, t1, t2; unsigned short us; printf("Unit test case %d\n", i++); b1 = ccn_bloom_create(13, seed1); for (j = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" matched empty Bloom filter\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0; j < 13; j++) ccn_bloom_insert(b1, a[j], strlen(a[j])); for (j = 0; j < 13; j++) if (!ccn_bloom_match(b1, a[j], strlen(a[j]))) break; if (j < 13) { printf("Failed: \"%s\" not found when it should have been\n", a[j]); result = 1; break; } printf("Unit test case %d\n", i++); for (j = 0, k = 0; j < 13; j++) if (ccn_bloom_match(b1, a[j]+1, strlen(a[j]+1))) k++; if (k > 0) { printf("Mmm, found %d false positives\n", k); if (k > 2) { result = 1; break; } } unsigned char seed2[5] = "aqfb\0"; for (; seed2[3] <= 'f'; seed2[3]++) { printf("Unit test case %d (%4s) ", i++, seed2); b2 = ccn_bloom_create(13, seed2); for (j = 0; j < 13; j++) ccn_bloom_insert(b2, a[j], strlen(a[j])); for (j = 0, k = 0, us = ~0; us > 0; us--) { t1 = ccn_bloom_match(b1, &us, sizeof(us)); t2 = ccn_bloom_match(b2, &us, sizeof(us)); j += (t1 | t2); k += (t1 & t2); } printf("either=%d both=%d wiresize=%d\n", j, k, ccn_bloom_wiresize(b1)); if (k > 12) { printf("Failed: Bloom seeding may not be effective\n"); result = 1; } ccn_bloom_destroy(&b2); } ccn_bloom_destroy(&b1); } while (0); printf("ccn_sign_content() tests\n"); do { struct ccn *h = ccn_create(); int res; res = unit_tests_for_signing(h, &i, 0); if (res == 1) result = 1; printf("Unit test case %d\n", i++); ccn_destroy(&h); } while (0); do { struct ccn *h = ccn_create(); int res; res = ccn_load_default_key(h, aes_keystore_name, keystore_password); if (res < 0) { result = 1; printf("Failed: res == %d\n", (int)res); } else res = unit_tests_for_signing(h, &i, 1); if (res == 1) result = 1; printf("Unit test case %d\n", i++); ccn_destroy(&h); } while (0); printf("link tests\n"); printf("link tests\n"); do { struct ccn_charbuf *l = ccn_charbuf_create(); struct ccn_charbuf *name = ccn_charbuf_create(); struct ccn_parsed_Link pl = {0}; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; struct ccn_indexbuf *comps = ccn_indexbuf_create(); printf("Unit test case %d\n", i++); ccn_name_from_uri(name, "ccnx:/test/link/name"); ccnb_append_Link(l, name, "label", NULL); d = ccn_buf_decoder_start(&decoder, l->buf, l->length); res = ccn_parse_Link(d, &pl, comps); if (res != 3 /* components in name */) { printf("Failed: ccn_parse_Link res == %d\n", (int)res); result = 1; } } while (0); exit(result); }
int verify_key(const unsigned char *ccnb, struct ccn_parsed_ContentObject *pco, int content_type){ if ( nlsr->debugging ) printf("verify key called\n"); int ret=-1; //int res; if ( contain_key_name(ccnb, pco) == 1){ struct ccn_charbuf *key_name=get_key_name(ccnb, pco); struct ccn_charbuf *key_uri = ccn_charbuf_create(); ccn_uri_append(key_uri, key_name->buf, key_name->length, 0); if ( nlsr->debugging ) printf("Key Name from Incoming Content: %s\n",ccn_charbuf_as_string(key_uri)); int key_type=get_key_type_from_key_name(key_name); if ( nlsr->debugging ) printf("Key Type: %d \n",key_type); struct ccn_charbuf *result = ccn_charbuf_create(); struct ccn_parsed_ContentObject temp_pco = {0}; int get_flags = 0; get_flags |= CCN_GET_NOKEYWAIT; int counter = 0; while(ccn_get(nlsr->ccn, key_name, NULL, 500, result, &temp_pco, NULL, get_flags) < 0 && counter < 3) counter++; int chk_verify=ccn_verify_content(nlsr->ccn,ccnb,pco); if ( chk_verify == 0 ){ if ( nlsr->debugging ) printf("Content verification Successful :)\n"); if ( counter == 3){ if ( nlsr->debugging ) printf("Could not retrieve key by name !!!\n"); } else{ if ( key_type == ROOT_KEY ){ ret=0; } else{ if ( nlsr->isStrictHierchicalKeyCheck ){ int key_name_test=check_key_name_hierarchy(ccnb, pco, key_type, content_type); if ( key_name_test == 1){ ret=verify_key(result->buf,&temp_pco,content_type); } } else{ ret=verify_key(result->buf,&temp_pco,content_type); } } } } ccn_charbuf_destroy(&result); ccn_charbuf_destroy(&key_uri); ccn_charbuf_destroy(&key_name); return ret; } return ret; }
int check_key_name_hierarchy(const unsigned char *ccnb, struct ccn_parsed_ContentObject *pco, int key_type, int content_type){ printf("check_key_name_hierarchy called\n"); if (key_type == UNKNOWN_KEY ){ return 1; } int res; struct ccn_charbuf *key_name=get_key_name(ccnb, pco); struct ccn_charbuf *key_uri = ccn_charbuf_create(); ccn_uri_append(key_uri, key_name->buf, key_name->length, 0); printf("Key Name: %s\n",ccn_charbuf_as_string(key_uri)); ccn_charbuf_destroy(&key_uri); struct ccn_charbuf *content_name=ccn_charbuf_create(); res=ccn_charbuf_append(content_name, ccnb + pco->offset[CCN_PCO_B_Name], pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name]); struct ccn_charbuf *content_uri = ccn_charbuf_create(); ccn_uri_append(content_uri, content_name->buf, content_name->length, 0); printf("Content Name: %s\n",ccn_charbuf_as_string(content_uri)); ccn_charbuf_destroy(&content_uri); if ( key_type == NLSR_KEY){ char *orig_router_key_name=get_orig_router_from_key_name(key_name,0,0); char *orig_router_content_name; if ( content_type == 1 ){ orig_router_content_name=get_orig_router_from_lsa_name(content_name); } else if ( content_type == 0 ){ orig_router_content_name=get_orig_router_from_info_content_name(content_name); } printf("Orig Router (Key Name):%s\n",orig_router_key_name); printf("Orig Router (Content Name):%s\n",orig_router_content_name); if (strcmp(orig_router_key_name,orig_router_content_name) == 0 ){ free(orig_router_key_name); free(orig_router_content_name); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == ROUTING_KEY){ char *orig_router_key_name=get_orig_router_from_key_name(key_name,1,0); char *orig_router_content_name=get_orig_router_from_key_name(content_name,1,1); printf("Orig Router (Key Name):%s\n",orig_router_key_name); printf("Orig Router (Content Name):%s\n",orig_router_content_name); if (strcmp(orig_router_key_name,orig_router_content_name) == 0 ){ free(orig_router_key_name); free(orig_router_content_name); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == OPERATOR_KEY){ struct ccn_indexbuf *key_name_comps; key_name_comps = ccn_indexbuf_create(); res = ccn_name_split(key_name, key_name_comps); int last_indx=check_for_tag_component_in_name(key_name,key_name_comps,"O.N.Start"); char *site_key_prefix_key=get_name_segments_from_name(key_name,0,last_indx); printf("Site key prefix(key Name):%s\n",site_key_prefix_key); ccn_indexbuf_destroy(&key_name_comps); struct ccn_indexbuf *content_name_comps; content_name_comps = ccn_indexbuf_create(); res = ccn_name_split(content_name, content_name_comps); int last_indx_rtr=check_for_tag_component_in_name(content_name,content_name_comps,"R.N.Start"); char *site_key_prefix_content=get_name_segments_from_name(key_name,0,last_indx_rtr); printf("Site key prefix(Content Name):%s\n",site_key_prefix_content); ccn_indexbuf_destroy(&content_name_comps); if( strcmp(site_key_prefix_key,site_key_prefix_content) == 0 ){ free(site_key_prefix_key); free(site_key_prefix_content); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == SITE_KEY){ struct ccn_indexbuf *key_name_comps; key_name_comps = ccn_indexbuf_create(); res = ccn_name_split(key_name, key_name_comps); int last_indx=check_for_tag_component_in_name(key_name,key_name_comps,"M.K"); char *site_key_prefix_key=get_name_segments_from_name(key_name,0,last_indx); printf("Site key prefix(key Name):%s\n",site_key_prefix_key); ccn_indexbuf_destroy(&key_name_comps); struct ccn_indexbuf *content_name_comps; content_name_comps = ccn_indexbuf_create(); res = ccn_name_split(content_name, content_name_comps); int last_indx_rtr=check_for_tag_component_in_name(content_name,content_name_comps,"O.N.Start"); char *site_key_prefix_content=get_name_segments_from_name(key_name,0,last_indx_rtr); printf("Site key prefix(Content Name):%s\n",site_key_prefix_content); ccn_indexbuf_destroy(&content_name_comps); if( strcmp(site_key_prefix_key,site_key_prefix_content) == 0 ){ free(site_key_prefix_key); free(site_key_prefix_content); ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } } if ( key_type == ROOT_KEY){ ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 1; } ccn_charbuf_destroy(&key_name); ccn_charbuf_destroy(&content_name); return 0; }
int sign_content_with_user_defined_keystore(struct ccn_charbuf *content_name, struct ccn_charbuf *resultbuf, const void *data, size_t data_size, char *keystore_path, char *keystore_passphrase, char *key_repo_name, char *site_name, char *router_name){ if ( nlsr->debugging ) printf("sign_content_with_user_defined_keystore called\n"); int res; struct ccn_charbuf * pubid_out=ccn_charbuf_create(); struct ccn_charbuf * keyname; struct ccn_keystore *keystore = NULL; keystore=ccn_keystore_create(); res=ccn_keystore_init(keystore, keystore_path,keystore_passphrase ); if ( res < 0 ){ if ( nlsr->debugging ) printf("Error in initiating keystore :(\n"); ccn_keystore_destroy(&keystore); return -1; } res=ccn_load_private_key (nlsr->ccn, keystore_path, keystore_passphrase, pubid_out); if(res < 0 ){ if ( nlsr->debugging ) printf("Error in loading keystore :( \n"); ccn_charbuf_destroy(&pubid_out); return -1; } char *baseuri=(char *)calloc(strlen(key_repo_name)+strlen(site_name)+ strlen(router_name)+strlen("/%C1.R.N.Start")+5,sizeof(char)); memcpy(baseuri,key_repo_name,strlen(key_repo_name)+1); if ( site_name[0] != '/') memcpy(baseuri+strlen(baseuri),"/",1); memcpy(baseuri+strlen(baseuri),site_name,strlen(site_name)+1); memcpy(baseuri+strlen(baseuri),"/%C1.R.N.Start",strlen("/%C1.R.N.Start")); memcpy(baseuri+strlen(baseuri),router_name,strlen(router_name)+1); baseuri[strlen(baseuri)]='\0'; keyname=ccn_charbuf_create(); if(keyname == NULL ){ ccn_charbuf_destroy(&pubid_out); free(baseuri); return -1; } ccn_name_from_uri(keyname,baseuri); if ( res < 0 ){ if ( nlsr->debugging ) printf("Bad URI format: %s\n",baseuri); ccn_charbuf_destroy(&pubid_out); ccn_charbuf_destroy(&keyname); free(baseuri); return -1; } ccn_name_append_str(keyname,"nlsr"); struct ccn_charbuf *keyid = ccn_charbuf_create(); ccn_charbuf_append_value(keyid, CCN_MARKER_CONTROL, 1); ccn_charbuf_append_string(keyid, ".M.K"); ccn_charbuf_append_value(keyid, 0, 1); ccn_charbuf_append_charbuf(keyid, pubid_out); ccn_name_append(keyname, keyid->buf, keyid->length); struct ccn_charbuf *uri = ccn_charbuf_create(); ccn_uri_append(uri, keyname->buf, keyname->length, 0); if ( nlsr->debugging ) printf("Key Name Included when processing content: %s\n", ccn_charbuf_as_string(uri)); ccn_charbuf_destroy(&uri); struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; sp.type = CCN_CONTENT_DATA; sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG); ccn_charbuf_append(sp.template_ccnb, keyname->buf, keyname->length); ccn_charbuf_append_closer(sp.template_ccnb); // KeyName closer ccn_charbuf_append_closer(sp.template_ccnb); // KeyLocator closer ccn_charbuf_append_closer(sp.template_ccnb); // SignedInfo closer sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR; sp.sp_flags |= CCN_SP_FINAL_BLOCK; sp.freshness = 60; if (pubid_out->length != sizeof(sp.pubid)){ if ( nlsr->debugging ) printf("Size of pubid and sp.pubid is not equal"); ccn_charbuf_destroy(&keyname); ccn_charbuf_destroy(&pubid_out); free(baseuri); return -1; } memcpy(sp.pubid, pubid_out->buf, pubid_out->length); res=ccn_sign_content(nlsr->ccn,resultbuf,content_name,&sp,data,data_size); if( res < 0 ){ if ( nlsr->debugging ) printf("Content signing error \n"); ccn_charbuf_destroy(&sp.template_ccnb); ccn_charbuf_destroy(&keyid); ccn_charbuf_destroy(&keyname); ccn_charbuf_destroy(&pubid_out); free(baseuri); return -1; } ccn_charbuf_destroy(&sp.template_ccnb); ccn_charbuf_destroy(&keyid); ccn_charbuf_destroy(&keyname); ccn_charbuf_destroy(&pubid_out); free(baseuri); return 0; }
/* * Dissector that returns: * * The amount of data in the protocol's PDU, if it was able to * dissect all the data; * * 0, if the tvbuff doesn't contain a PDU for that protocol; * * The negative of the amount of additional data needed, if * we need more data (e.g., from subsequent TCP segments) to * dissect the entire PDU. */ static int dissect_ccn(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint tvb_size = 0; proto_tree *ccn_tree; proto_item *ti = NULL; const unsigned char *ccnb; struct ccn_skeleton_decoder skel_decoder; struct ccn_skeleton_decoder *sd; struct ccn_charbuf *c; int packet_type = 0; int packet_type_length = 0; /* a couple of basic checks to rule out packets that are definitely not ours */ tvb_size = tvb_length(tvb); if (tvb_size < CCN_MIN_PACKET_SIZE || tvb_get_guint8(tvb, 0) == 0) return (0); sd = &skel_decoder; memset(sd, 0, sizeof(*sd)); sd->state |= CCN_DSTATE_PAUSE; ccnb = ep_tvb_memdup(tvb, 0, tvb_size); ccn_skeleton_decode(sd, ccnb, tvb_size); if (sd->state < 0) return (0); if (CCN_GET_TT_FROM_DSTATE(sd->state) == CCN_DTAG) { packet_type = sd->numval; packet_type_length = sd->index; } else { return (0); } memset(sd, 0, sizeof(*sd)); ccn_skeleton_decode(sd, ccnb, tvb_size); if (!CCN_FINAL_DSTATE(sd->state)) { pinfo->desegment_offset = 0; pinfo->desegment_len = DESEGMENT_ONE_MORE_SEGMENT; return (-1); /* what should this be? */ } /* Make it visible that we're taking this packet */ if (check_col(pinfo->cinfo, COL_PROTOCOL)) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "CCN"); } /* Clear out stuff in the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_clear(pinfo->cinfo, COL_INFO); } c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, tvb_size, 1); /* Add the packet type and CCN URI to the info column */ if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x")); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, ccn_charbuf_as_string(c)); } if (tree == NULL) { ccn_charbuf_destroy(&c); return (sd->index); } ti = proto_tree_add_protocol_format(tree, proto_ccn, tvb, 0, -1, "Content-centric Networking Protocol, %s, %s", val_to_str(packet_type, VALS(ccn_dtag_dict.dict), "Unknown (0x%02x"), ccn_charbuf_as_string(c)); ccn_tree = proto_item_add_subtree(ti, ett_ccn); ccn_charbuf_destroy(&c); ti = proto_tree_add_uint(ccn_tree, hf_ccn_type, tvb, 0, packet_type_length, packet_type); switch (packet_type) { case CCN_DTAG_ContentObject: if (0 > dissect_ccn_contentobject(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; case CCN_DTAG_Interest: if (0 > dissect_ccn_interest(ccnb, sd->index, tvb, pinfo, ccn_tree)) return (0); break; } return (sd->index); }
int sync_cb(struct ccns_name_closure *nc, struct ccn_charbuf *lhash, struct ccn_charbuf *rhash, struct ccn_charbuf *name) { nlsr_lock(); int res; struct ccn_charbuf *content_name; struct ccn_indexbuf *content_comps; struct ccn_indexbuf *name_comps; content_comps = ccn_indexbuf_create(); res = ccn_name_split(name, content_comps); if ( res < 0 ) return 0; if (content_comps->n < 2) return 0; content_name = ccn_charbuf_create(); ccn_name_init(content_name); res = ccn_name_append_components( content_name, name->buf, content_comps->buf[0], content_comps->buf[content_comps->n - 1]); if ( res < 0) return 0; // for debugging struct ccn_charbuf *temp=ccn_charbuf_create(); ccn_uri_append(temp, content_name->buf, content_name->length, 0); if ( nlsr->debugging ) printf("Name before chopping: %s \n",ccn_charbuf_as_string(temp)); ccn_charbuf_destroy(&temp); name_comps = ccn_indexbuf_create(); res=ccn_name_split (content_name, name_comps); if (res < 0) return 0; if ( nlsr->debugging ) { printf("Number of components in name = %d \n",res); printf("Number of components in name as indexbuf->n = %d \n", (int)name_comps->n); } ccn_name_chop(content_name, name_comps, -3); if ( nlsr->debugging ) printf("Number of components in name as indexbuf->n after chopping= %d \n" , (int)name_comps->n); //for debugging struct ccn_charbuf *temp1=ccn_charbuf_create(); ccn_uri_append(temp1, content_name->buf, content_name->length, 0); if ( nlsr->debugging ) printf("Name after chopping: %s \n",ccn_charbuf_as_string(temp1)); ccn_charbuf_destroy(&temp1); //main method that processes contents from the sync process_content_from_sync(content_name, name_comps); ccn_charbuf_destroy(&content_name); ccn_indexbuf_destroy(&content_comps); ccn_indexbuf_destroy(&name_comps); nlsr_unlock(); return(0); }
static int dissect_ccn_contentobject(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *signature_tree; proto_tree *name_tree; proto_tree *signedinfo_tree; proto_tree *content_tree; proto_item *titem; struct ccn_parsed_ContentObject co; struct ccn_parsed_ContentObject *pco = &co; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; size_t blob_size; const unsigned char *blob; int l; unsigned int i; double dt; nstime_t timestamp; int res; comps = ccn_indexbuf_create(); res = ccn_parse_ContentObject(ccnb, ccnb_size, pco, comps); if (res < 0) return (-1); /* Signature */ l = pco->offset[CCN_PCO_E_Signature] - pco->offset[CCN_PCO_B_Signature]; titem = proto_tree_add_item(tree, hf_ccn_signature, tvb, pco->offset[CCN_PCO_B_Signature], l, FALSE); signature_tree = proto_item_add_subtree(titem, ett_signature); /* DigestAlgorithm */ l = pco->offset[CCN_PCO_E_DigestAlgorithm] - pco->offset[CCN_PCO_B_DigestAlgorithm]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, ccnb, pco->offset[CCN_PCO_B_DigestAlgorithm], pco->offset[CCN_PCO_E_DigestAlgorithm], &blob, &blob_size); titem = proto_tree_add_item(signature_tree, hf_ccn_signaturedigestalg, tvb, blob - ccnb, blob_size, FALSE); } /* Witness */ l = pco->offset[CCN_PCO_E_Witness] - pco->offset[CCN_PCO_B_Witness]; if (l > 0) { /* add the witness item to the signature tree */ } /* Signature bits */ l = pco->offset[CCN_PCO_E_SignatureBits] - pco->offset[CCN_PCO_B_SignatureBits]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, ccnb, pco->offset[CCN_PCO_B_SignatureBits], pco->offset[CCN_PCO_E_SignatureBits], &blob, &blob_size); titem = proto_tree_add_bytes(signature_tree, hf_ccn_signaturebits, tvb, blob - ccnb, blob_size, blob); } /* /Signature */ /* Name */ l = pco->offset[CCN_PCO_E_Name] - pco->offset[CCN_PCO_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pco->offset[CCN_PCO_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); /* Name Components */ for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* /Name */ /* SignedInfo */ l = pco->offset[CCN_PCO_E_SignedInfo] - pco->offset[CCN_PCO_B_SignedInfo]; titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_SignedInfo], l, "SignedInfo"); signedinfo_tree = proto_item_add_subtree(titem, ett_signedinfo); /* PublisherPublicKeyDigest */ l = pco->offset[CCN_PCO_E_PublisherPublicKeyDigest] - pco->offset[CCN_PCO_B_PublisherPublicKeyDigest]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_PublisherPublicKeyDigest, ccnb, pco->offset[CCN_PCO_B_PublisherPublicKeyDigest], pco->offset[CCN_PCO_E_PublisherPublicKeyDigest], &blob, &blob_size); titem = proto_tree_add_bytes(signedinfo_tree, hf_ccn_publisherpublickeydigest, tvb, blob - ccnb, blob_size, blob); } /* Timestamp */ l = pco->offset[CCN_PCO_E_Timestamp] - pco->offset[CCN_PCO_B_Timestamp]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Timestamp, ccnb, pco->offset[CCN_PCO_B_Timestamp], pco->offset[CCN_PCO_E_Timestamp], &blob, &blob_size); dt = 0.0; for (i = 0; i < blob_size; i++) dt = dt * 256.0 + (double)blob[i]; dt /= 4096.0; timestamp.secs = dt; /* truncates */ timestamp.nsecs = (dt - (double) timestamp.secs) * 1000000000.0; titem = proto_tree_add_time(signedinfo_tree, hf_ccn_timestamp, tvb, blob - ccnb, blob_size, ×tamp); } /* Type */ l = pco->offset[CCN_PCO_E_Type] - pco->offset[CCN_PCO_B_Type]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_Type, ccnb, pco->offset[CCN_PCO_B_Type], pco->offset[CCN_PCO_E_Type], &blob, &blob_size); titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, tvb, blob - ccnb, blob_size, pco->type); } else { titem = proto_tree_add_int(signedinfo_tree, hf_ccn_contenttype, NULL, 0, 0, pco->type); } /* FreshnessSeconds */ l = pco->offset[CCN_PCO_E_FreshnessSeconds] - pco->offset[CCN_PCO_B_FreshnessSeconds]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds], &blob, &blob_size); i = ccn_fetch_tagged_nonNegativeInteger(CCN_DTAG_FreshnessSeconds, ccnb, pco->offset[CCN_PCO_B_FreshnessSeconds], pco->offset[CCN_PCO_E_FreshnessSeconds]); titem = proto_tree_add_uint(signedinfo_tree, hf_ccn_freshnessseconds, tvb, blob - ccnb, blob_size, i); } /* FinalBlockID */ l = pco->offset[CCN_PCO_E_FinalBlockID] - pco->offset[CCN_PCO_B_FinalBlockID]; if (l > 0) { res = ccn_ref_tagged_BLOB(CCN_DTAG_FinalBlockID, ccnb, pco->offset[CCN_PCO_B_FinalBlockID], pco->offset[CCN_PCO_E_FinalBlockID], &blob, &blob_size); titem = proto_tree_add_item(signedinfo_tree, hf_ccn_finalblockid, tvb, blob - ccnb, blob_size, FALSE); } /* TODO: KeyLocator */ /* /SignedInfo */ /* Content */ l = pco->offset[CCN_PCO_E_Content] - pco->offset[CCN_PCO_B_Content]; res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, ccnb, pco->offset[CCN_PCO_B_Content], pco->offset[CCN_PCO_E_Content], &blob, &blob_size); titem = proto_tree_add_text(tree, tvb, pco->offset[CCN_PCO_B_Content], l, "Content: %d bytes", blob_size); if (blob_size > 0) { content_tree = proto_item_add_subtree(titem, ett_content); titem = proto_tree_add_item(content_tree, hf_ccn_contentdata, tvb, blob - ccnb, blob_size, FALSE); } return (ccnb_size); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *bloom; size_t bloom_size = 0; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; double lifetime; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); if (res < 0) return (res); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherPublicKeyDigest */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { c = ccn_charbuf_create(); d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l); if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) { ccn_charbuf_destroy(&c); return(-1); } ccn_charbuf_append_string(c, "Exclude: "); ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); comp_size = 0; if (ccn_buf_match_blob(d, &comp, &comp_size)) ccn_buf_advance(d); ccn_uri_append_percentescaped(c, comp, comp_size); ccn_charbuf_append_string(c, " "); ccn_buf_check_close(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } } titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "%s", ccn_charbuf_as_string(c)); exclude_tree = proto_item_add_subtree(titem, ett_exclude); ccn_charbuf_destroy(&c); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* InterestLifetime */ l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); lifetime = 0.0; for (i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double)blob[i]; lifetime /= 4096.0; titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime); } /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
int main(int argc, char **argv) { int opt; int res; char *prog = argv[0]; struct ccn *h; struct ccns_slice *slice; struct ccn_charbuf *prefix = ccn_charbuf_create(); struct ccn_charbuf *topo = ccn_charbuf_create(); struct ccn_charbuf *clause = ccn_charbuf_create(); struct ccn_charbuf *slice_name = ccn_charbuf_create(); struct ccn_charbuf *slice_uri = ccn_charbuf_create(); enum { CREATE = 0, DELETE = 1 } cmd = CREATE; unsigned verbose = 0; unsigned i; if (prefix == NULL || topo == NULL || clause == NULL || slice_name == NULL || slice_uri == NULL) { fprintf(stderr, "Unable to allocate required memory.\n"); exit(1); } while ((opt = getopt(argc, argv, "vh")) != -1) { switch (opt) { case 'v': verbose = 1; break; default: case 'h': usage(prog); break; } } argc -= optind; argv += optind; if (argc < 3) usage(prog); if (strcmp(argv[0], "create") == 0) cmd = CREATE; else if (strcmp(argv[0], "delete") == 0) cmd = DELETE; else usage(prog); slice = ccns_slice_create(); ccn_charbuf_reset(topo); if (0 > ccn_name_from_uri(topo, argv[1])) usage(prog); ccn_charbuf_reset(prefix); if (0 > ccn_name_from_uri(prefix, argv[2])) usage(prog); if (0 > ccns_slice_set_topo_prefix(slice, topo, prefix)) usage(prog); for (i = 3; i < argc; i++) { ccn_charbuf_reset(clause); if (0 > ccn_name_from_uri(clause, argv[i])) usage(prog); else if (0 > ccns_slice_add_clause(slice, clause)) usage(prog); } h = ccn_create(); res = ccn_connect(h, NULL); if (0 > res) { fprintf(stderr, "Unable to connect to ccnd.\n"); exit(1); } switch(cmd) { case CREATE: res = ccns_write_slice(h, slice, slice_name); break; case DELETE: ccns_slice_name(slice_name, slice); res = ccns_delete_slice(h, slice_name); break; } if (verbose || res < 0) { ccn_uri_append(slice_uri, slice_name->buf, slice_name->length, 1); printf("%s slice %s %s\n", cmd == CREATE ? "create" : "delete", ccn_charbuf_as_string(slice_uri), (res < 0) ? "failed" : "succeeded"); } ccns_slice_destroy(&slice); ccn_destroy(&h); ccn_charbuf_destroy(&prefix); ccn_charbuf_destroy(&topo); ccn_charbuf_destroy(&clause); ccn_charbuf_destroy(&slice_name); ccn_charbuf_destroy(&slice_uri); exit(res); }
int main(int argc, char **argv) { const char *progname = argv[0]; struct ccn *ccn = NULL; struct ccn_charbuf *name = NULL; struct ccn_charbuf *pname = NULL; struct ccn_charbuf *temp = NULL; struct ccn_charbuf *extopt = NULL; long expire = -1; int versioned = 0; size_t blocksize = 8*1024; int status = 0; int res; ssize_t read_res; unsigned char *buf = NULL; enum ccn_content_type content_type = CCN_CONTENT_DATA; struct ccn_closure in_interest = {.p=&incoming_interest}; const char *postver = NULL; const char *key_uri = NULL; int force = 0; int verbose = 0; int timeout = -1; int setfinal = 0; int prefixcomps = -1; int fd; struct ccn_signing_params sp = CCN_SIGNING_PARAMS_INIT; while ((res = getopt(argc, argv, "e:fhk:lvV:p:t:w:x:")) != -1) { switch (res) { case 'e': if (extopt == NULL) extopt = ccn_charbuf_create(); fd = open(optarg, O_RDONLY); if (fd < 0) { perror(optarg); exit(1); } for (;;) { read_res = read(fd, ccn_charbuf_reserve(extopt, 64), 64); if (read_res <= 0) break; extopt->length += read_res; } if (read_res < 0) perror(optarg); close(fd); break; case 'f': force = 1; break; case 'l': setfinal = 1; // set FinalBlockID to last comp of name break; case 'k': key_uri = optarg; break; case 'p': prefixcomps = atoi(optarg); if (prefixcomps < 0) usage(progname); break; case 'x': expire = atol(optarg); if (expire <= 0) usage(progname); break; case 'v': verbose = 1; break; case 'V': versioned = 1; postver = optarg; if (0 == memcmp(postver, "%00", 3)) setfinal = 1; break; case 'w': timeout = atol(optarg); if (timeout <= 0) usage(progname); timeout *= 1000; break; case 't': if (0 == strcasecmp(optarg, "DATA")) { content_type = CCN_CONTENT_DATA; break; } if (0 == strcasecmp(optarg, "ENCR")) { content_type = CCN_CONTENT_ENCR; break; } if (0 == strcasecmp(optarg, "GONE")) { content_type = CCN_CONTENT_GONE; break; } if (0 == strcasecmp(optarg, "KEY")) { content_type = CCN_CONTENT_KEY; break; } if (0 == strcasecmp(optarg, "LINK")) { content_type = CCN_CONTENT_LINK; break; } if (0 == strcasecmp(optarg, "NACK")) { content_type = CCN_CONTENT_NACK; break; } content_type = atoi(optarg); if (content_type > 0 && content_type <= 0xffffff) break; fprintf(stderr, "Unknown content type %s\n", optarg); /* FALLTHRU */ default: case 'h': usage(progname); break; } } argc -= optind; argv += optind; if (argv[0] == NULL) usage(progname); name = ccn_charbuf_create(); res = ccn_name_from_uri(name, argv[0]); if (res < 0) { fprintf(stderr, "%s: bad ccn URI: %s\n", progname, argv[0]); exit(1); } if (argv[1] != NULL) fprintf(stderr, "%s warning: extra arguments ignored\n", progname); /* Preserve the original prefix, in case we add versioning, * but trim it down if requested for the interest filter registration */ pname = ccn_charbuf_create(); ccn_charbuf_append(pname, name->buf, name->length); if (prefixcomps >= 0) { res = ccn_name_chop(pname, NULL, prefixcomps); if (res < 0) { fprintf(stderr, "%s: unable to trim name to %d component%s.\n", progname, prefixcomps, prefixcomps == 1 ? "" : "s"); exit(1); } } /* Connect to ccnd */ ccn = ccn_create(); if (ccn_connect(ccn, NULL) == -1) { perror("Could not connect to ccnd"); exit(1); } /* Read the actual user data from standard input */ buf = calloc(1, blocksize); read_res = read_full(0, buf, blocksize); if (read_res < 0) { perror("read"); read_res = 0; status = 1; } /* Tack on the version component if requested */ if (versioned) { res = ccn_create_version(ccn, name, CCN_V_REPLACE | CCN_V_NOW | CCN_V_HIGH, 0, 0); if (res < 0) { fprintf(stderr, "%s: ccn_create_version() failed\n", progname); exit(1); } if (postver != NULL) { res = ccn_name_from_uri(name, postver); if (res < 0) { fprintf(stderr, "-V %s: invalid name suffix\n", postver); exit(0); } } } temp = ccn_charbuf_create(); /* Ask for a FinalBlockID if appropriate. */ if (setfinal) sp.sp_flags |= CCN_SP_FINAL_BLOCK; if (res < 0) { fprintf(stderr, "Failed to create signed_info (res == %d)\n", res); exit(1); } /* Set content type */ sp.type = content_type; /* Set freshness */ if (expire >= 0) { if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccnb_tagged_putf(sp.template_ccnb, CCN_DTAG_FreshnessSeconds, "%ld", expire); sp.sp_flags |= CCN_SP_TEMPL_FRESHNESS; ccn_charbuf_append_closer(sp.template_ccnb); } /* Set key locator, if supplied */ if (key_uri != NULL) { struct ccn_charbuf *c = ccn_charbuf_create(); res = ccn_name_from_uri(c, key_uri); if (res < 0) { fprintf(stderr, "%s is not a valid ccnx URI\n", key_uri); exit(1); } if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyLocator, CCN_DTAG); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_KeyName, CCN_DTAG); ccn_charbuf_append(sp.template_ccnb, c->buf, c->length); ccn_charbuf_append_closer(sp.template_ccnb); ccn_charbuf_append_closer(sp.template_ccnb); sp.sp_flags |= CCN_SP_TEMPL_KEY_LOCATOR; ccn_charbuf_append_closer(sp.template_ccnb); ccn_charbuf_destroy(&c); } if (extopt != NULL && extopt->length > 0) { if (sp.template_ccnb == NULL) { sp.template_ccnb = ccn_charbuf_create(); ccn_charbuf_append_tt(sp.template_ccnb, CCN_DTAG_SignedInfo, CCN_DTAG); } else if (sp.template_ccnb->length > 0) { sp.template_ccnb->length--; } ccnb_append_tagged_blob(sp.template_ccnb, CCN_DTAG_ExtOpt, extopt->buf, extopt->length); sp.sp_flags |= CCN_SP_TEMPL_EXT_OPT; ccn_charbuf_append_closer(sp.template_ccnb); } /* Create the signed content object, ready to go */ temp->length = 0; res = ccn_sign_content(ccn, temp, name, &sp, buf, read_res); if (res != 0) { fprintf(stderr, "Failed to encode ContentObject (res == %d)\n", res); exit(1); } if (read_res == blocksize) { read_res = read_full(0, buf, 1); if (read_res == 1) { fprintf(stderr, "%s: warning - truncated data\n", argv[0]); status = 1; } } free(buf); buf = NULL; if (force) { /* At user request, send without waiting to see an interest */ res = ccn_put(ccn, temp->buf, temp->length); if (res < 0) { fprintf(stderr, "ccn_put failed (res == %d)\n", res); exit(1); } } else { in_interest.data = temp; /* Set up a handler for interests */ res = ccn_set_interest_filter(ccn, pname, &in_interest); if (res < 0) { fprintf(stderr, "Failed to register interest (res == %d)\n", res); exit(1); } res = ccn_run(ccn, timeout); if (in_interest.intdata == 0) { if (verbose) fprintf(stderr, "Nobody's interested\n"); exit(1); } } if (verbose) { struct ccn_charbuf *uri = ccn_charbuf_create(); uri->length = 0; ccn_uri_append(uri, name->buf, name->length, 1); printf("wrote %s\n", ccn_charbuf_as_string(uri)); ccn_charbuf_destroy(&uri); } ccn_destroy(&ccn); ccn_charbuf_destroy(&name); ccn_charbuf_destroy(&pname); ccn_charbuf_destroy(&temp); ccn_charbuf_destroy(&sp.template_ccnb); ccn_charbuf_destroy(&extopt); exit(status); }