int handle_ccn_content_obj(unsigned char **buf, int *len, int offset, FILE *stream){ int num, typ; if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; print_offset(offset); printf("<CONTENTOBJ>\n"); while(typ != 2){ ccnl_ccnb_dehead(buf, len, &num, &typ); } while(1) { switch(num) { case CCN_DTAG_NAME: handle_ccn_name(buf, len, offset+4, stream); break; case CCN_DTAG_SIGNATURE: handle_ccn_signature(buf, len, offset+4, stream); break; case CCN_DTAG_CONTENT: handle_ccn_content(buf, len, offset+4, stream); break; default: goto Bail; break; } if(ccnl_ccnb_dehead(buf, len, &num, &typ)) break; } Bail: print_offset(offset); printf("</CONTENTOBJ>\n"); return 0; }
static int ccnl_crypto_extract_sign_reply(unsigned char **buf, int *buflen, char *sig, int *sig_len, int *seqnum) { int ret = 0; int num, typ; char seqnumber_s[100]; int seqnubmer; int siglen = 0; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_SEQNO) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, seqnumber_s, sizeof(seqnumber_s)); seqnubmer = ccnl_crypto_strtoint(seqnumber_s); *seqnum = seqnubmer; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_SIGNATURE) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; siglen = num; ccnl_crypto_get_tag_content(buf, buflen, siglen, sig, CCNL_MAX_PACKET_SIZE); //ccnl_crypto_get_signature(buf, buflen, sig, siglen); *sig_len = siglen; ret = 1; Bail: return ret; }
static int ccnl_crypto_extract_verify_reply(unsigned char **buf, int *buflen, int *seqnum) { int verified = 0; int num, typ; char seqnumber_s[100], verified_s[100]; int seqnubmer, h; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_SEQNO) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, seqnumber_s, sizeof(seqnumber_s)); seqnubmer = ccnl_crypto_strtoint(seqnumber_s); *seqnum = seqnubmer; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCNL_DTAG_VERIFIED) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, verified_s, sizeof(verified_s)); h = ccnl_crypto_strtoint(verified_s); if(h == 1) { verified = 1; DEBUGMSG(DEBUG,"VERIFIED\n"); } Bail: return verified; }
int handle_ccn_debugrequest(unsigned char **buf, int *len, int offset, FILE *stream) { int num, typ; print_offset(offset); printf("<DEBUGREQUEST>\n"); while(1) { if(ccnl_ccnb_dehead(buf, len, &num, &typ)) goto Bail; switch(num) { case CCN_DTAG_ACTION: handle_ccn_action(buf, len, offset+4, stream); break; case CCNL_DTAG_DEBUGACTION: handle_ccn_debugaction(buf, len, offset+4, stream); break; default: goto Bail; } } Bail: print_offset(offset); printf("</DEBUGREQUEST>\n"); return 0; }
int handle_ccn_name(unsigned char **buf, int *len, int offset, FILE *stream){ int num, typ, i; if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; print_offset(offset); printf("<NAME>\n"); for(i = 0; i < 3; ++i) { if(num != CCN_DTAG_COMPONENT) return -1; handle_ccn_component_content(buf, len, offset+4, stream); if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; } print_offset(offset); printf("</NAME>\n"); return 0; }
int handle_ccn_debugreply(unsigned char **buf, int *len, int offset, FILE *stream) { int num, typ; print_offset(offset); printf("<DEBUGREPLY>\n"); while(1) { if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; switch(num) { case CCNL_DTAG_INTERFACE: handle_ccn_debugreply_content(buf, len, offset+4, "INTERFACE", stream); break; case CCN_DTAG_FACEINSTANCE: handle_ccn_debugreply_content(buf, len, offset+4, "FACEINSTANCE", stream); break; case CCN_DTAG_FWDINGENTRY: handle_ccn_debugreply_content(buf, len, offset+4, "FWDINGENTRY", stream); break; case CCN_DTAG_INTEREST: handle_ccn_debugreply_content(buf, len, offset+4, "INTEREST", stream); break; case CCN_DTAG_CONTENT: handle_ccn_debugreply_content(buf, len, offset+4, "CONTENT", stream); break; default: goto Bail; } } Bail: print_offset(offset); printf("</DEBUGREPLY>\n"); return 0; }
int ccnl_RX_ccnb(struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc = 0, num, typ; DEBUGMSG(6, "ccnl_RX_ccnb: %d bytes from face=%p (id=%d.%d)\n", *datalen, (void*)from, relay->id, from ? from->faceid : -1); while (rc >= 0 && *datalen > 0) { if (ccnl_ccnb_dehead(data, datalen, &num, &typ) || typ != CCN_TT_DTAG) return -1; switch (num) { case CCN_DTAG_INTEREST: case CCN_DTAG_CONTENTOBJ: rc = ccnl_ccnb_forwarder(relay, from, data, datalen); continue; #ifdef USE_FRAG case CCNL_DTAG_FRAGMENT2012: rc = ccnl_frag_RX_frag2012(ccnl_RX_ccnb, relay, from, data, datalen); continue; case CCNL_DTAG_FRAGMENT2013: rc = ccnl_frag_RX_CCNx2013(ccnl_RX_ccnb, relay, from, data, datalen); continue; #endif default: DEBUGMSG(15, " unknown datagram type %d\n", num); return -1; } } return rc; }
int handle_ccn_content(unsigned char **buf, int *len, int offset, FILE *stream){ int num, typ; if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; print_offset(offset); printf("<CONTENT>\n"); while(typ != 2){ ccnl_ccnb_dehead(buf, len, &num, &typ); } while(1) { switch(num) { case CCN_DTAG_NAME: handle_ccn_name(buf, len, offset+4, stream); break; case CCN_DTAG_INTEREST: break; case CCNL_DTAG_DEBUGREQUEST: handle_ccn_debugrequest(buf, len, offset+4, stream); break; case CCNL_DTAG_DEBUGREPLY: handle_ccn_debugreply(buf, len, offset+4, stream); break; case CCN_DTAG_FACEINSTANCE: handle_ccn_debugreply_content(buf, len, offset+4, "FACEINSTANCE", stream); break; case CCNL_DTAG_DEVINSTANCE: handle_ccn_debugreply_content(buf, len, offset+4, "DEVINSTANCE", stream); break; case CCNL_DTAG_PREFIX: handle_ccn_debugreply_content(buf, len, offset+4, "PREFIX", stream); break; case CCN_DTAG_ACTION: print_offset(offset + 4); print_tag_content_with_tag(buf, len, "ACTION", stream); break; default: //printf("%i,%i\n", num, typ); goto Bail; break; } if(ccnl_ccnb_dehead(buf, len, &num, &typ)) break; } Bail: print_offset(offset); printf("</CONTENT>\n"); return 0; }
int print_tag_content_with_tag(unsigned char **buf, int *len, char *tag, FILE *stream) { int num, typ; printf("<%s>", tag); ccnl_ccnb_dehead(buf, len, &num, &typ); print_tag_content(buf, len, stream); printf("</%s>\n", tag); return 0; }
static int ccnl_crypto_extract_msg(unsigned char **buf, int *buflen, unsigned char **msg){ int len = 0; int num, typ; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_CONTENTDIGEST) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; *msg = *buf; len = num; return len; Bail: DEBUGMSG(DEBUG, "Failed to extract msg\n"); return 0; }
int ccnb_isContent(unsigned char *buf, int len) { int num, typ; if (len < 0 || ccnl_ccnb_dehead(&buf, &len, &num, &typ)) return -1; if (typ != CCN_TT_DTAG || num != CCN_DTAG_CONTENTOBJ) return 0; return 1; }
int handle_ccn_action(unsigned char **buf, int *len, int offset, FILE *stream) { int num, typ; if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; print_offset(offset); printf("<ACTION>"); print_tag_content(buf,len,stream); printf("</ACTION>\n"); return 0; }
int handle_ccn_component_content(unsigned char **buf, int *len, int offset, FILE *stream) { int num, typ; print_offset(offset); printf("<COMPONENT>"); if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; print_tag_content(buf,len,stream); printf("</COMPONENT>\n"); return 0; }
int handle_ccn_packet(unsigned char *buf, int len, int offset, FILE *stream){ int num, typ; if(ccnl_ccnb_dehead(&buf, &len, &num, &typ)) return -1; switch(num) { case CCN_DTAG_CONTENTOBJ: return handle_ccn_content_obj(&buf, &len, offset, stream); break; case CCN_DTAG_INTEREST: break; } return 0; }
int handle_ccn_signature(unsigned char **buf, int *buflen, int offset, FILE *stream) { int num, typ, i; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) return -1; if (typ != CCN_TT_BLOB) return 0; print_offset(offset); printf("<SIGNATURE>"); for(i = 0; i < num; ++i){ printf("%c",(*buf)[i]); } printf("</SIGNATURE>\n"); *buflen -= (num+1); *buf += (num+1); return 0; }
int handle_ccn_debugreply_content(unsigned char **buf, int *len, int offset, char* tag, FILE *stream) { int num, typ; print_offset(offset); printf("<%s>\n", tag); while(1) { if(ccnl_ccnb_dehead(buf, len, &num, &typ)) return -1; switch(num) { case CCNL_DTAG_IFNDX: print_offset(offset+4); print_tag_content_with_tag(buf, len, "IFNDX", stream); break; case CCNL_DTAG_ADDRESS: print_offset(offset+4); print_tag_content_with_tag(buf, len, "ADDRESS", stream); break; case CCNL_DTAG_ETH: print_offset(offset+4); print_tag_content_with_tag(buf, len, "ETH", stream); break; case CCNL_DTAG_SOCK: print_offset(offset+4); print_tag_content_with_tag(buf, len, "SOCK", stream); break; case CCNL_DTAG_REFLECT: print_offset(offset+4); print_tag_content_with_tag(buf, len, "REFLECT", stream); break; case CCN_DTAG_FACEID: print_offset(offset+4); print_tag_content_with_tag(buf, len, "FACEID", stream); break; case CCNL_DTAG_SUITE: print_offset(offset+4); print_tag_content_with_tag(buf, len, "SUITE", stream); break; case CCNL_DTAG_NEXT: print_offset(offset+4); print_tag_content_with_tag(buf, len, "NEXT", stream); break; case CCNL_DTAG_PREV: print_offset(offset+4); print_tag_content_with_tag(buf, len, "PREV", stream); break; case CCNL_DTAG_FWD: print_offset(offset+4); print_tag_content_with_tag(buf, len, "FWD", stream); break; case CCNL_DTAG_FACEFLAGS: print_offset(offset+4); print_tag_content_with_tag(buf, len, "FACEFLAGS", stream); break; case CCNL_DTAG_IP: print_offset(offset+4); print_tag_content_with_tag(buf, len, "IP", stream); break; case CCNL_DTAG_UNIX: print_offset(offset+4); print_tag_content_with_tag(buf, len, "UNIX", stream); break; case CCNL_DTAG_PEER: print_offset(offset+4); print_tag_content_with_tag(buf, len, "PEER", stream); break; case CCNL_DTAG_FACE: print_offset(offset+4); print_tag_content_with_tag(buf, len, "FACE", stream); break; case CCNL_DTAG_INTERESTPTR: print_offset(offset+4); print_tag_content_with_tag(buf, len, "INTERESTPTR", stream); break; case CCNL_DTAG_LAST: print_offset(offset+4); print_tag_content_with_tag(buf, len, "LAST", stream); break; case CCNL_DTAG_MIN: print_offset(offset+4); print_tag_content_with_tag(buf, len, "MIN", stream); break; case CCNL_DTAG_MAX: print_offset(offset+4); print_tag_content_with_tag(buf, len, "MAX", stream); break; case CCNL_DTAG_RETRIES: print_offset(offset+4); print_tag_content_with_tag(buf, len, "RETRIES", stream); break; case CCNL_DTAG_PUBLISHER: print_offset(offset+4); print_tag_content_with_tag(buf, len, "PUBLISHER", stream); break; case CCNL_DTAG_CONTENTPTR: print_offset(offset+4); print_tag_content_with_tag(buf, len, "CONTENTPTR", stream); break; case CCNL_DTAG_LASTUSE: print_offset(offset+4); print_tag_content_with_tag(buf, len, "LASTUSE", stream); break; case CCNL_DTAG_SERVEDCTN: print_offset(offset+4); print_tag_content_with_tag(buf, len, "SERVEDCTN", stream); break; case CCN_DTAG_ACTION: print_offset(offset+4); print_tag_content_with_tag(buf, len, "ACTION", stream); break; case CCNL_DTAG_MACSRC: print_offset(offset+4); print_tag_content_with_tag(buf, len, "MACSRC", stream); break; case CCNL_DTAG_IP4SRC: print_offset(offset+4); print_tag_content_with_tag(buf, len, "IP4SRC", stream); break; case CCN_DTAG_IPPROTO: print_offset(offset+4); print_tag_content_with_tag(buf, len, "IPPROTO", stream); break; case CCN_DTAG_HOST: print_offset(offset+4); print_tag_content_with_tag(buf, len, "HOST", stream); break; case CCN_DTAG_PORT: print_offset(offset+4); print_tag_content_with_tag(buf, len, "PORT", stream); break; case CCNL_DTAG_FRAG: print_offset(offset+4); print_tag_content_with_tag(buf, len, "FRAG", stream); break; case CCNL_DTAG_MTU: print_offset(offset+4); print_tag_content_with_tag(buf, len, "MTU", stream); break; case CCNL_DTAG_DEVFLAGS: print_offset(offset+4); print_tag_content_with_tag(buf, len, "DEVFLAGS", stream); break; case CCNL_DTAG_DEVNAME: print_offset(offset+4); print_tag_content_with_tag(buf, len, "DEVNAME", stream); break; case CCN_DTAG_NAME: print_offset(offset+4); print_tag_content_with_tag(buf, len, "NAME", stream); break; case CCNL_DTAG_PREFIX: print_offset(offset+4); print_tag_content_with_tag(buf, len, "PREFIX", stream); break; default: goto Bail; } } Bail: print_offset(offset); printf("</%s>\n", tag); return 0; }
static int ccnl_crypto_extract_type_callback(unsigned char **buf, int *buflen, char *type, int max_type_length, char* callback, int max_callback_length) { int typ, num; char comp1[10]; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_CONTENTOBJ) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_NAME) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_COMPONENT) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, comp1, sizeof(comp1)); if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_COMPONENT) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, comp1, sizeof(comp1)); if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_CONTENT) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCNL_DTAG_CALLBACK) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, callback, max_callback_length); if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_DTAG || num != CCN_DTAG_TYPE) goto Bail; if(ccnl_ccnb_dehead(buf, buflen, &num, &typ)) goto Bail; if (typ != CCN_TT_BLOB) goto Bail; ccnl_crypto_get_tag_content(buf, buflen, num, type, max_type_length); return 1; Bail: return 0; }
int ccnl_frag_RX_CCNx2013(RX_datagram callback, struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int rc, num, typ, pdutypelen; unsigned char *pdutype = 0; struct serialFragPDU_s s; DEBUGMSG_EFRA(TRACE, "ccnl_frag_RX_CCNx2013 (%d bytes)\n", *datalen); serialFragPDU_init(&s); while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) { if (num==0 && typ==0) break; // end if (typ == CCN_TT_DTAG) { switch (num) { case CCNL_DTAG_FRAG2013_TYPE: if (ccnl_ccnb_hunt_for_end(data, datalen, &pdutype, &pdutypelen) || pdutypelen != 3) goto Bail; continue; case CCNL_DTAG_FRAG2013_SEQNR: getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq"); continue; case CCNL_DTAG_FRAG2013_FLAGS: getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags"); continue; case CCN_DTAG_CONTENT: // if (frag) // error: more than one content entry if (ccnl_ccnb_consume(typ, num, data, datalen, &s.content,&s.contlen) < 0) goto Bail; continue; // CCNL extensions: case CCN_DTAG_INTEREST: case CCN_DTAG_CONTENTOBJ: // rc = ccnl_ccnb_forwarder(relay, from, data, datalen); rc = callback(relay, from, data, datalen); if (rc < 0) return rc; continue; case CCNL_DTAG_FRAG2013_OLOSS: getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss"); continue; case CCNL_DTAG_FRAG2013_YSEQN: getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq"); continue; default: break; } } if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } if (!pdutype || !s.content ) { /* || (s.HAS&(HAS_FLAGS|HAS_OSEQ)) != (HAS_FLAGS|HAS_OSEQ) ) { */ DEBUGMSG_EFRA(WARNING, "* incomplete frag\n"); return 0; } if (memcmp(pdutype, CCNL_FRAG_TYPE_CCNx2013_VAL, 3) == 0) { // hop-by-hop if (from) { if (!from->frag) from->frag = ccnl_frag_new(CCNL_FRAG_CCNx2013, relay->ifs[from->ifndx].mtu); if (from->frag && from->frag->protocol == CCNL_FRAG_CCNx2013) ccnl_frag_RX_serialfragment(callback, relay, from, &s); else DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n"); } else ccnl_frag_RX_serialfragment(callback, relay, from, &s); } /* * echo "FMTE" | base64 -d | hexdump -v -e '/1 "@x%02x"'| tr @ '\\'; echo */ if (memcmp(pdutype, "\x14\xc4\xc4", 3) == 0) { // mid-to-end fragment // not implemented yet } return 0; Bail: DEBUGMSG_EFRA(WARNING, "* frag bailing\n"); return -1; }
int ccnl_frag_RX_frag2012(RX_datagram callback, struct ccnl_relay_s *relay, struct ccnl_face_s *from, unsigned char **data, int *datalen) { int num, typ; struct serialFragPDU_s s; DEBUGMSG_EFRA(TRACE, "ccnl_frag_RX_frag2012 (%d bytes)\n", *datalen); serialFragPDU_init(&s); while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) { if (num==0 && typ==0) break; // end if (typ == CCN_TT_DTAG) { switch(num) { case CCN_DTAG_CONTENT: DEBUGMSG_EFRA(TRACE, " frag content\n"); // if (s.content) // error: more than one content entry if (ccnl_ccnb_consume(typ, num, data, datalen, &s.content,&s.contlen) < 0) goto Bail; continue; case CCNL_DTAG_FRAG2012_FLAGS: getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags"); continue; case CCNL_DTAG_FRAG2012_SEQNR: getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq"); continue; case CCNL_DTAG_FRAG2012_OLOSS: getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss"); continue; case CCNL_DTAG_FRAG2012_YSEQN: getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq"); continue; default: break; } } if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } if (!s.content || s.HAS != 15) { DEBUGMSG_EFRA(WARNING, "* incomplete frag\n"); return 0; } if (from) { if (!from->frag) from->frag = ccnl_frag_new(CCNL_FRAG_SEQUENCED2012, relay->ifs[from->ifndx].mtu); if (from->frag && from->frag->protocol == CCNL_FRAG_SEQUENCED2012) ccnl_frag_RX_serialfragment(callback, relay, from, &s); else DEBUGMSG_EFRA(WARNING, "WRONG FRAG PROTOCOL\n"); } else ccnl_frag_RX_serialfragment(callback, relay, from, &s); return 0; Bail: DEBUGMSG_EFRA(WARNING, "* frag bailing\n"); return -1; }
struct ccnl_buf_s* ccnl_ccnb_extract(unsigned char **data, int *datalen, int *scope, int *aok, int *min, int *max, struct ccnl_prefix_s **prefix, struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd, unsigned char **content, int *contlen) { unsigned char *start = *data - 2 /* account for outer TAG hdr */, *cp; int num, typ, len; struct ccnl_prefix_s *p; struct ccnl_buf_s *buf, *n = 0, *pub = 0; DEBUGMSG(99, "ccnl_ccnb_extract\n"); p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s)); if (!p) return NULL; p->comp = (unsigned char**) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(unsigned char**)); p->complen = (int*) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int)); if (!p->comp || !p->complen) goto Bail; while (ccnl_ccnb_dehead(data, datalen, &num, &typ) == 0) { if (num==0 && typ==0) break; // end if (typ == CCN_TT_DTAG) { if (num == CCN_DTAG_NAME) { for (;;) { if (ccnl_ccnb_dehead(data, datalen, &num, &typ) != 0) goto Bail; if (num==0 && typ==0) break; if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT && p->compcnt < CCNL_MAX_NAME_COMP) { if (ccnl_ccnb_hunt_for_end(data, datalen, p->comp + p->compcnt, p->complen + p->compcnt) < 0) goto Bail; p->compcnt++; } else { if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } } continue; } if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE || num == CCN_DTAG_MINSUFFCOMP || num == CCN_DTAG_MAXSUFFCOMP || num == CCN_DTAG_PUBPUBKDIGEST) { if (ccnl_ccnb_hunt_for_end(data, datalen, &cp, &len) < 0) goto Bail; if (num == CCN_DTAG_SCOPE && len == 1 && scope) *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1; if (num == CCN_DTAG_ANSWERORIGKIND && aok) *aok = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_MINSUFFCOMP && min) *min = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_MAXSUFFCOMP && max) *max = ccnl_ccnb_data2uint(cp, len); if (num == CCN_DTAG_NONCE && !n) n = ccnl_buf_new(cp, len); if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) pub = ccnl_buf_new(cp, len); if (num == CCN_DTAG_EXCLUDE) { DEBUGMSG(49, "warning: 'exclude' field ignored\n"); } else continue; } if (num == CCN_DTAG_CONTENT) { if (ccnl_ccnb_consume(typ, num, data, datalen, content, contlen) < 0) goto Bail; continue; } } if (ccnl_ccnb_consume(typ, num, data, datalen, 0, 0) < 0) goto Bail; } if (prefix) *prefix = p; else free_prefix(p); if (nonce) *nonce = n; else ccnl_free(n); if (ppkd) *ppkd = pub; else ccnl_free(pub); buf = ccnl_buf_new(start, *data - start); // carefully rebase ptrs to new buf because of 64bit pointers: if (content) *content = buf->data + (*content - start); for (num = 0; num < p->compcnt; num++) p->comp[num] = buf->data + (p->comp[num] - start); return buf; Bail: free_prefix(p); free_2ptr_list(n, pub); return NULL; }