/** * Parses a ccnb-encoded name * @param d is the decoder * @param components may be NULL, otherwise is filled in with the * Component boundary offsets * @returns the number of Components in the Name, or -1 if there is an error. */ int ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components) { int ncomp = 0; if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { if (components != NULL) components->n = 0; ccn_buf_advance(d); while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { if (components != NULL) ccn_indexbuf_append_element(components, d->decoder.token_index); ncomp += 1; ccn_buf_advance(d); if (ccn_buf_match_blob(d, NULL, NULL)) ccn_buf_advance(d); ccn_buf_check_close(d); } if (components != NULL) ccn_indexbuf_append_element(components, d->decoder.token_index); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.state < 0) return(-1); else return(ncomp); }
/* * utility, may need to be exported, to parse the buffer into a given slice * structure. */ static int slice_parse(struct ccns_slice *s, const unsigned char *p, size_t size) { int res = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); uintmax_t version; int op; int start; struct ccn_charbuf *clause = NULL; if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSlice)) return (-1); ccn_buf_advance(d); if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncVersion)) return (-1); ccn_buf_advance(d); ccn_parse_uintmax(d, &version); ccn_buf_check_close(d); if (version != SLICE_VERSION) return (-1); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) return(-1); ccn_charbuf_reset(s->topo); res = ccn_charbuf_append(s->topo, p + start, d->decoder.token_index - start); if (res < 0) return(-1); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) return(-1); ccn_charbuf_reset(s->prefix); res = ccn_charbuf_append(s->prefix, p + start, d->decoder.token_index - start); if (res < 0) return(-1); if (!ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSliceList)) return(-1); ccn_buf_advance(d); clause = ccn_charbuf_create(); if (clause == NULL) return(-1); while (ccn_buf_match_dtag(d, CCN_DTAG_SyncConfigSliceOp)) { ccn_buf_advance(d); op = ccn_parse_nonNegativeInteger(d); // op is a small integer ccn_buf_check_close(d); if (op != 0) break; ccn_charbuf_reset(clause); start = d->decoder.token_index; if (ccn_parse_Name(d, NULL) < 0) break; res = ccn_charbuf_append(clause, p + start, d->decoder.token_index - start); ccns_slice_add_clause(s, clause); } ccn_charbuf_destroy(&clause); ccn_buf_check_close(d); /* </SyncConfigSliceList> */ ccn_buf_check_close(d); /* </SyncConfigSlice> */ if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) return(-1); return(0); }
int ccn_parse_LinkAuthenticator(struct ccn_buf_decoder *d, struct ccn_parsed_Link *pl) { /* Implement with a single offset for the blob, CCN_PL_[BE]_PublisherDigest * and remember the DTAG value to indicate which type of digest it is */ if (ccn_buf_match_dtag(d, CCN_DTAG_LinkAuthenticator)) { ccn_buf_advance(d); // advance over DTAG token pl->offset[CCN_PL_B_LinkAuthenticator] = d->decoder.token_index; pl->offset[CCN_PL_B_PublisherID] = d->decoder.token_index; pl->offset[CCN_PL_B_PublisherDigest] = d->decoder.token_index; pl->offset[CCN_PL_E_PublisherDigest] = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest) || ccn_buf_match_dtag(d, CCN_DTAG_PublisherCertificateDigest) || ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerKeyDigest) || ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerCertificateDigest)) { pl->publisher_digest_type = d->decoder.numval; // remember the DTAG ccn_buf_advance(d); // over the DTAG token if (!ccn_buf_match_some_blob(d)) return (d->decoder.state = -__LINE__); pl->offset[CCN_PL_B_PublisherDigest] = d->decoder.token_index; ccn_buf_advance(d); // over the digest pl->offset[CCN_PL_E_PublisherDigest] = d->decoder.token_index; ccn_buf_check_close(d); // over the DTAG closer } if (d->decoder.state < 0) return (d->decoder.state); pl->offset[CCN_PL_E_PublisherID] = d->decoder.token_index; /* parse optional NameComponentCount nonNegativeInteger */ pl->offset[CCN_PL_B_NameComponentCount] = d->decoder.token_index; pl->name_component_count = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_NameComponentCount); pl->offset[CCN_PL_E_NameComponentCount] = d->decoder.token_index; /* parse optional Timestamp TimestampType */ pl->offset[CCN_PL_B_Timestamp] = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_Timestamp)) ccn_parse_required_tagged_timestamp(d, CCN_DTAG_Timestamp); pl->offset[CCN_PL_E_Timestamp] = d->decoder.token_index; /* parse optional Type ContentType */ pl->offset[CCN_PL_B_Type] = d->decoder.token_index; pl->type = ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA); pl->offset[CCN_PL_E_Type] = d->decoder.token_index; /* parse optional ContentDigest Base64BinaryType */ pl->offset[CCN_PL_B_ContentDigest] = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_ContentDigest, 32, 32); pl->offset[CCN_PL_E_ContentDigest] = d->decoder.token_index; ccn_buf_check_close(d); pl->offset[CCN_PL_E_LinkAuthenticator] = d->decoder.token_index; } else d->decoder.state = -__LINE__; if (!CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); return(0); }
/** * Append Components from a ccnb-encoded Name to a flatname * * The ccnb encoded input may be a ContentObject, Interest, Prefix, * or Component instead of simply a Name. * @param dst is the destination, which should hold a ccnb-encoded Name * @param ccnb points to first byte of Name * @param size is the number of bytes in ccnb * @param skip is the number of components at the front of flatname to skip * @param count is the maximum number of componebts to append, or -1 for all * @returns number of appended components, or -1 if there is an error. */ int ccn_flatname_append_from_ccnb(struct ccn_charbuf *dst, const unsigned char *ccnb, size_t size, int skip, int count) { int ans = 0; int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); int checkclose = 0; int res; if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) { ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) ccn_buf_advance_past_element(d); } if ((ccn_buf_match_dtag(d, CCN_DTAG_Name) || ccn_buf_match_dtag(d, CCN_DTAG_Prefix))) { checkclose = 1; ccn_buf_advance(d); } else if (count != 0) count = 1; while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { if (ans == count) return(ans); ccn_buf_advance(d); compsize = 0; if (ccn_buf_match_blob(d, &comp, &compsize)) ccn_buf_advance(d); ccn_buf_check_close(d); if (d->decoder.state < 0) return(-1); ncomp += 1; if (ncomp > skip) { res = ccn_flatname_append_component(dst, comp, compsize); if (res < 0) return(-1); ans++; } } if (checkclose) ccn_buf_check_close(d); if (d->decoder.state < 0) return (-1); return(ans); }
int ccn_ref_tagged_string(enum ccn_dtag dtag, const unsigned char *buf, size_t start, size_t stop, const unsigned char **presult, size_t *psize) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *result = NULL; size_t size = 0; if (stop < start) return(-1); d = ccn_buf_decoder_start(&decoder, buf + start, stop - start); if (ccn_buf_match_dtag(d, dtag)) { ccn_buf_advance(d); if (d->decoder.state >= 0 && CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) { result = d->buf + d->decoder.index; size = d->decoder.numval; ccn_buf_advance(d); } ccn_buf_check_close(d); } else return(-1); if (d->decoder.index != d->size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); if (presult) *presult = result; if (psize) *psize = size; return(0); }
int ccn_parse_PublisherID(struct ccn_buf_decoder *d, struct ccn_parsed_interest *pi) { int res = -1; int iskey = 0; unsigned pubstart = d->decoder.token_index; unsigned keystart = pubstart; unsigned keyend = pubstart; unsigned pubend = pubstart; iskey = ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest); if (iskey || ccn_buf_match_dtag(d, CCN_DTAG_PublisherCertificateDigest) || ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerKeyDigest) || ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerCertificateDigest)) { res = d->decoder.element_index; ccn_buf_advance(d); keystart = d->decoder.token_index; if (!ccn_buf_match_some_blob(d)) return (d->decoder.state = -__LINE__); ccn_buf_advance(d); keyend = d->decoder.token_index; ccn_buf_check_close(d); pubend = d->decoder.token_index; } if (d->decoder.state < 0) return (d->decoder.state); if (pi != NULL) { pi->offset[CCN_PI_B_PublisherID] = pubstart; pi->offset[CCN_PI_B_PublisherIDKeyDigest] = keystart; pi->offset[CCN_PI_E_PublisherIDKeyDigest] = iskey ? keyend : keystart; pi->offset[CCN_PI_E_PublisherID] = pubend; } return(res); }
static int ccn_parse_Signature(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x) { int res = -1; int i; struct ccn_parsed_ContentObject dummy; if (x == NULL) x = &dummy; for (i = CCN_PCO_B_Signature; i <= CCN_PCO_E_Signature; i++) { x->offset[i] = d->decoder.token_index; } if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) { res = d->decoder.element_index; ccn_buf_advance(d); x->offset[CCN_PCO_B_DigestAlgorithm] = d->decoder.token_index; ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_DigestAlgorithm); x->offset[CCN_PCO_E_DigestAlgorithm] = d->decoder.token_index; x->offset[CCN_PCO_B_Witness] = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 8, -1); x->offset[CCN_PCO_E_Witness] = d->decoder.token_index; x->offset[CCN_PCO_B_SignatureBits] = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 16, -1); x->offset[CCN_PCO_E_SignatureBits] = d->decoder.token_index; ccn_buf_check_close(d); x->offset[CCN_PCO_E_Signature] = d->decoder.token_index; } if (d->decoder.state < 0) return (d->decoder.state); return(res); }
/** * Parses a ccnb-encoded element expected to contain a UDATA string. * @param d is the decoder * @param dtag is the expected dtag value * @param store - on success, the string value is appended to store, * with null termination. * @returns the offset into the store buffer of the copied value, or -1 for error. * If a parse error occurs, d->decoder.state is set to a negative value. * If the element is not present, -1 is returned but no parse error * is indicated. */ int ccn_parse_tagged_string(struct ccn_buf_decoder *d, enum ccn_dtag dtag, struct ccn_charbuf *store) { const unsigned char *p = NULL; size_t size = 0; int res; if (ccn_buf_match_dtag(d, dtag)) { ccn_buf_advance(d); if (d->decoder.state >= 0 && CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) { res = store->length; p = d->buf + d->decoder.index; size = d->decoder.numval; ccn_buf_advance(d); } ccn_buf_check_close(d); if (d->decoder.state >= 0) { // XXX - should check for valid utf-8 data. res = store->length; if (size > 0) ccn_charbuf_append(store, p, size); ccn_charbuf_append_value(store, 0, 1); return(res); } } return(-1); }
int ccn_parse_ContentObject(const unsigned char *msg, size_t size, struct ccn_parsed_ContentObject *x, struct ccn_indexbuf *components) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size); int res; x->magic = 20090415; x->digest_bytes = 0; if (ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) { ccn_buf_advance(d); res = ccn_parse_Signature(d, x); x->offset[CCN_PCO_B_Name] = d->decoder.token_index; x->offset[CCN_PCO_B_Component0] = d->decoder.index; res = ccn_parse_Name(d, components); if (res < 0) d->decoder.state = -__LINE__; x->name_ncomps = res; x->offset[CCN_PCO_E_ComponentLast] = d->decoder.token_index - 1; x->offset[CCN_PCO_E_Name] = d->decoder.token_index; ccn_parse_SignedInfo(d, x); x->offset[CCN_PCO_B_Content] = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Content, 0, -1); x->offset[CCN_PCO_E_Content] = d->decoder.token_index; ccn_buf_check_close(d); x->offset[CCN_PCO_E] = d->decoder.index; } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); return(0); }
uintmax_t ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d, enum ccn_dtag dtag, int minlen, int maxlen) { uintmax_t value = 0; const unsigned char *p = NULL; size_t len = 0; int i; if (0 <= minlen && minlen <= maxlen && maxlen <= sizeof(value) && ccn_buf_match_dtag(d, dtag)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &p, &len)) ccn_buf_advance(d); ccn_buf_check_close(d); if (d->decoder.state < 0) return(value); if (minlen <= len && len <= maxlen) for (i = 0; i < len; i++) value = (value << 8) + p[i]; else d->decoder.state = -__LINE__; } else d->decoder.state = -__LINE__; return(value); }
int ccn_name_last_component_offset(const unsigned char *ccnb, size_t size) //CONET was static { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); int res = -1; if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { ccn_buf_advance(d); res = d->decoder.token_index; /* in case of 0 components */ while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { res = d->decoder.token_index; ccn_buf_advance(d); if (ccn_buf_match_blob(d, NULL, NULL)) ccn_buf_advance(d); ccn_buf_check_close(d); } ccn_buf_check_close(d); } return ((d->decoder.state >= 0) ? res : -1); }
int ccn_uri_append(struct ccn_charbuf *c, const unsigned char *ccnb, size_t size, int includescheme) { int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, ccnb, size); if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) { ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) ccn_buf_advance_past_element(d); } if (!ccn_buf_match_dtag(d, CCN_DTAG_Name)) return(-1); if (includescheme) ccn_charbuf_append_string(c, "ccnx:"); ccn_buf_advance(d); while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); compsize = 0; if (ccn_buf_match_blob(d, &comp, &compsize)) ccn_buf_advance(d); ccn_buf_check_close(d); if (d->decoder.state < 0) return(d->decoder.state); ncomp += 1; ccn_charbuf_append(c, "/", 1); ccn_uri_append_percentescaped(c, comp, compsize); } ccn_buf_check_close(d); if (d->decoder.state < 0) return (d->decoder.state); if (ncomp == 0) ccn_charbuf_append(c, "/", 1); return(ncomp); }
int ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d, enum ccn_dtag dtag) { int res = -1; if (ccn_buf_match_dtag(d, dtag)) { ccn_buf_advance(d); res = ccn_parse_nonNegativeInteger(d); ccn_buf_check_close(d); } if (d->decoder.state < 0) return (d->decoder.state); return(res); }
int ccn_compare_names(const unsigned char *a, size_t asize, const unsigned char *b, size_t bsize) { struct ccn_buf_decoder a_decoder; struct ccn_buf_decoder b_decoder; struct ccn_buf_decoder *aa = ccn_buf_decoder_start_at_components(&a_decoder, a, asize); struct ccn_buf_decoder *bb = ccn_buf_decoder_start_at_components(&b_decoder, b, bsize); const unsigned char *acp = NULL; const unsigned char *bcp = NULL; size_t acsize; size_t bcsize; int cmp = 0; int more_a; for (;;) { more_a = ccn_buf_match_dtag(aa, CCN_DTAG_Component); cmp = more_a - ccn_buf_match_dtag(bb, CCN_DTAG_Component); if (more_a == 0 || cmp != 0) break; ccn_buf_advance(aa); ccn_buf_advance(bb); acsize = bcsize = 0; if (ccn_buf_match_blob(aa, &acp, &acsize)) ccn_buf_advance(aa); if (ccn_buf_match_blob(bb, &bcp, &bcsize)) ccn_buf_advance(bb); cmp = acsize - bcsize; if (cmp != 0) break; cmp = memcmp(acp, bcp, acsize); if (cmp != 0) break; ccn_buf_check_close(aa); ccn_buf_check_close(bb); } return (cmp); }
int ccn_parse_Collection_next(struct ccn_buf_decoder *d, struct ccn_parsed_Link *link, struct ccn_indexbuf *components) { if (ccn_buf_match_dtag(d, CCN_DTAG_Link)) { return(ccn_parse_Link(d, link, components)); } else ccn_buf_check_close(d); if (d->decoder.state < 0) return(d->decoder.state); else return(0); }
static int ccn_parse_optional_Any_or_Bloom(struct ccn_buf_decoder *d) { int res; res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Bloom, 1, 1024+8); if (res >= 0) return(res); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_buf_check_close(d); res = 0; } if (d->decoder.state < 0) return (d->decoder.state); return(res); }
int ccn_parse_required_tagged_timestamp(struct ccn_buf_decoder *d, enum ccn_dtag dtag) { int res = -1; if (ccn_buf_match_dtag(d, dtag)) { res = d->decoder.element_index; ccn_buf_advance(d); ccn_parse_timestamp(d); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.state < 0) return (-1); return(res); }
int ccn_ref_tagged_BLOB(enum ccn_dtag tt, const unsigned char *buf, size_t start, size_t stop,const unsigned char **presult, size_t *psize) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; if (stop < start) return(-1); d = ccn_buf_decoder_start(&decoder, buf + start, stop - start); if (ccn_buf_match_dtag(d, tt)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, presult, psize)) ccn_buf_advance(d); ccn_buf_check_close(d); } else return(-1); if (d->decoder.index != d->size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); return(0); }
int ccn_parse_Exclude(struct ccn_buf_decoder *d) { int res = -1; if (ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) { res = d->decoder.element_index; ccn_buf_advance(d); ccn_parse_optional_Any_or_Bloom(d); while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1); ccn_parse_optional_Any_or_Bloom(d); } ccn_buf_check_close(d); } if (d->decoder.state < 0) return (d->decoder.state); return(res); }
int ccn_fetch_tagged_nonNegativeInteger(enum ccn_dtag tt, const unsigned char *buf, size_t start, size_t stop) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; int result = -1; if (stop < start) return(-1); d = ccn_buf_decoder_start(&decoder, buf + start, stop - start); if (ccn_buf_match_dtag(d, tt)) { ccn_buf_advance(d); result = ccn_parse_nonNegativeInteger(d); ccn_buf_check_close(d); } if (result < 0) return(-1); return(result); }
int ccn_parse_Link(struct ccn_buf_decoder *d, struct ccn_parsed_Link *link, struct ccn_indexbuf *components) { int ncomp = 0; int res; if (ccn_buf_match_dtag(d, CCN_DTAG_Link)) { if (components == NULL) { /* We need to have the component offsets. */ components = ccn_indexbuf_create(); if (components == NULL) return(-1); res = ccn_parse_Link(d, link, components); ccn_indexbuf_destroy(&components); return(res); } ccn_buf_advance(d); link->offset[CCN_PL_B_Name] = d->decoder.element_index; link->offset[CCN_PL_B_Component0] = d->decoder.index; ncomp = ccn_parse_Name(d, components); if (d->decoder.state < 0) { memset(link->offset, 0, sizeof(link->offset)); return(d->decoder.state); } link->offset[CCN_PL_E_ComponentLast] = d->decoder.token_index - 1; link->offset[CCN_PL_E_Name] = d->decoder.token_index; link->name_ncomps = ncomp; /* parse optional Label string */ link->offset[CCN_PL_B_Label] = d->decoder.token_index; res = ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_Label); link->offset[CCN_PL_E_Label] = d->decoder.token_index; /* parse optional LinkAuthenticator LinkAuthenticatorType */ if (ccn_buf_match_dtag(d, CCN_DTAG_LinkAuthenticator)) res = ccn_parse_LinkAuthenticator(d, link); ccn_buf_check_close(d); } else return (d->decoder.state = -__LINE__); if (d->decoder.state < 0) return (d->decoder.state); return(ncomp); }
int ccn_parse_required_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag) { int res = -1; if (ccn_buf_match_dtag(d, dtag)) { res = d->decoder.element_index; ccn_buf_advance(d); if (d->decoder.state >= 0 && CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) ccn_buf_advance(d); else d->decoder.state = -__LINE__; ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.state < 0) return (-1); return(res); }
static int ccn_parse_KeyName(struct ccn_buf_decoder *d, struct parsed_KeyName *x) { int res = -1; if (ccn_buf_match_dtag(d, CCN_DTAG_KeyName)) { res = d->decoder.element_index; ccn_buf_advance(d); x->Name = d->decoder.token_index; ccn_parse_Name(d, NULL); x->endName = d->decoder.token_index; x->PublisherID = ccn_parse_PublisherID(d, NULL); x->endPublisherID = d->decoder.token_index; ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.state < 0) return (d->decoder.state); return(res); }
int ccn_buf_advance_past_element(struct ccn_buf_decoder *d) { enum ccn_tt tt; int nest; if (d->decoder.state < 0) return(d->decoder.state); tt = CCN_GET_TT_FROM_DSTATE(d->decoder.state); if (tt == CCN_DTAG || tt == CCN_TAG) { nest = d->decoder.nest; ccn_buf_advance(d); while (d->decoder.state >= 0 && d->decoder.nest >= nest) ccn_buf_advance(d); /* The nest decrements before the closer is consumed */ ccn_buf_check_close(d); } else return(-1); if (d->decoder.state < 0) return(d->decoder.state); return (0); }
int ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag, int minlen, int maxlen) { int res = -1; size_t len = 0; if (ccn_buf_match_dtag(d, dtag)) { res = d->decoder.element_index; ccn_buf_advance(d); if (ccn_buf_match_some_blob(d)) { len = d->decoder.numval; ccn_buf_advance(d); } ccn_buf_check_close(d); if (len < minlen || (maxlen >= 0 && len > maxlen)) { d->decoder.state = -__LINE__; } } else d->decoder.state = -__LINE__; if (d->decoder.state < 0) return (d->decoder.state); return(res); }
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); }
PyObject * Signature_obj_from_ccn(PyObject *py_signature) { struct ccn_charbuf *signature; PyObject *py_obj_signature, *py_o; struct ccn_buf_decoder decoder, *d; size_t start, stop, size; const unsigned char *ptr; int r; assert(CCNObject_IsValid(SIGNATURE, py_signature)); signature = CCNObject_Get(SIGNATURE, py_signature); debug("Signature_from_ccn start, len=%zd\n", signature->length); // 1) Create python object py_obj_signature = PyObject_CallObject(g_type_Signature, NULL); if (!py_obj_signature) return NULL; // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_signature, "ccn_data", py_signature); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // Neither DigestAlgorithm nor Witness are included in the packet // from ccnput, so they are apparently both optional d = ccn_buf_decoder_start(&decoder, signature->buf, signature->length); if (!ccn_buf_match_dtag(d, CCN_DTAG_Signature)) { PyErr_Format(g_PyExc_CCNSignatureError, "Error finding" " CCN_DTAG_Signature (decoder state: %d)", d->decoder.state); goto error; } debug("Is a signature\n"); ccn_buf_advance(d); /* CCN_DTAG_DigestAlgorithm */ start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_DigestAlgorithm, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_DigestAlgorithm, d->buf, start, stop, &ptr, &size); if (r == 0) { debug("PyObject_SetAttrString digestAlgorithm\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "digestAlgorithm", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* CCN_DTAG_Witness */ start = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 1, -1); stop = d->decoder.token_index; debug("witness start %zd stop %zd\n", start, stop); r = ccn_ref_tagged_BLOB(CCN_DTAG_Witness, d->buf, start, stop, &ptr, &size); if (r == 0) { // The Witness is represented as a DER-encoded PKCS#1 DigestInfo, // which contains an AlgorithmIdentifier (an OID, together with any necessary parameters) // and a byte array (OCTET STRING) containing the digest information to be interpreted according to that OID. // http://www.ccnx.org/releases/latest/doc/technical/SignatureGeneration.html debug("PyObject_SetAttrString witness\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "witness", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } /* CCN_DTAG_SignatureBits */ start = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 1, -1); stop = d->decoder.token_index; r = ccn_ref_tagged_BLOB(CCN_DTAG_SignatureBits, d->buf, start, stop, &ptr, &size); if (r < 0) { PyErr_Format(g_PyExc_CCNSignatureError, "Error parsing" " CCN_DTAG_SignatureBits (decoder state %d)", d->decoder.state); goto error; } assert(r == 0); debug("PyObject_SetAttrString signatureBits\n"); py_o = PyBytes_FromStringAndSize((const char*) ptr, size); JUMP_IF_NULL(py_o, error); r = PyObject_SetAttrString(py_obj_signature, "signatureBits", py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); ccn_buf_check_close(d); if (d->decoder.state < 0) { PyErr_Format(g_PyExc_CCNSignatureError, "Signature decoding error" " (decoder state: %d, numval: %zd)", d->decoder.state, d->decoder.numval); goto error; } // 4) Return the created object debug("Signature_from_ccn ends\n"); return py_obj_signature; error: Py_DECREF(py_obj_signature); return NULL; }
static int ccn_parse_SignedInfo(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x) { x->offset[CCN_PCO_B_SignedInfo] = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) { ccn_buf_advance(d); x->offset[CCN_PCO_B_PublisherPublicKeyDigest] = d->decoder.token_index; ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64); x->offset[CCN_PCO_E_PublisherPublicKeyDigest] = d->decoder.token_index; x->offset[CCN_PCO_B_Timestamp] = d->decoder.token_index; ccn_parse_required_tagged_timestamp(d, CCN_DTAG_Timestamp); x->offset[CCN_PCO_E_Timestamp] = d->decoder.token_index; x->offset[CCN_PCO_B_Type] = d->decoder.token_index; x->type = CCN_CONTENT_DATA; x->type = ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA); x->offset[CCN_PCO_E_Type] = d->decoder.token_index; x->offset[CCN_PCO_B_FreshnessSeconds] = d->decoder.token_index; ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); x->offset[CCN_PCO_E_FreshnessSeconds] = d->decoder.token_index; x->offset[CCN_PCO_B_FinalBlockID] = d->decoder.token_index; ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1); x->offset[CCN_PCO_E_FinalBlockID] = d->decoder.token_index; x->offset[CCN_PCO_B_KeyLocator] = d->decoder.token_index; x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index; x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index; x->offset[CCN_PCO_B_KeyName_Name] = d->decoder.token_index; x->offset[CCN_PCO_E_KeyName_Name] = d->decoder.token_index; x->offset[CCN_PCO_B_KeyName_Pub] = d->decoder.token_index; x->offset[CCN_PCO_E_KeyName_Pub] = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) { ccn_buf_advance(d); x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index; if (ccn_buf_match_dtag(d, CCN_DTAG_Key)) { (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Key, 0, -1); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Certificate)) { (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Certificate, 0, -1); } else { struct parsed_KeyName keyname = {-1, -1, -1, -1}; if (ccn_parse_KeyName(d, &keyname) >= 0) { if (keyname.Name >= 0) { x->offset[CCN_PCO_B_KeyName_Name] = keyname.Name; x->offset[CCN_PCO_E_KeyName_Name] = keyname.endName; } if (keyname.PublisherID >= 0) { x->offset[CCN_PCO_B_KeyName_Pub] = keyname.PublisherID; x->offset[CCN_PCO_E_KeyName_Pub] = keyname.endPublisherID; } } } x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index; ccn_buf_check_close(d); } x->offset[CCN_PCO_E_KeyLocator] = d->decoder.token_index; ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; x->offset[CCN_PCO_E_SignedInfo] = d->decoder.token_index; if (d->decoder.state < 0) return (d->decoder.state); return(0); }
int ccn_parse_interest(const unsigned char *msg, size_t size, struct ccn_parsed_interest *interest, struct ccn_indexbuf *components) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size); int magic = 0; int ncomp = 0; int res; if (ccn_buf_match_dtag(d, CCN_DTAG_Interest) || ccn_buf_match_dtag(d, CCN_DTAG_PersistentInterest)) { if (components == NULL) { /* We need to have the component offsets. */ components = ccn_indexbuf_create(); if (components == NULL) return(-1); res = ccn_parse_interest(msg, size, interest, components); ccn_indexbuf_destroy(&components); return(res); } /*In case of persistent interest*/ if(ccn_buf_match_dtag(d, CCN_DTAG_PersistentInterest)) { interest->persistent = 1; } ccn_buf_advance(d); interest->offset[CCN_PI_B_Name] = d->decoder.element_index; interest->offset[CCN_PI_B_Component0] = d->decoder.index; ncomp = ccn_parse_Name(d, components); if (d->decoder.state < 0) { memset(interest->offset, 0, sizeof(interest->offset)); return(d->decoder.state); } interest->offset[CCN_PI_E_ComponentLast] = d->decoder.token_index - 1; interest->offset[CCN_PI_E_Name] = d->decoder.token_index; interest->prefix_comps = ncomp; interest->offset[CCN_PI_B_LastPrefixComponent] = components->buf[(ncomp > 0) ? (ncomp - 1) : 0]; interest->offset[CCN_PI_E_LastPrefixComponent] = components->buf[ncomp]; /* optional MinSuffixComponents, MaxSuffixComponents */ interest->min_suffix_comps = 0; interest->max_suffix_comps = 32767; interest->offset[CCN_PI_B_MinSuffixComponents] = d->decoder.token_index; res = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MinSuffixComponents); interest->offset[CCN_PI_E_MinSuffixComponents] = d->decoder.token_index; if (res >= 0) interest->min_suffix_comps = res; interest->offset[CCN_PI_B_MaxSuffixComponents] = d->decoder.token_index; res = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MaxSuffixComponents); interest->offset[CCN_PI_E_MaxSuffixComponents] = d->decoder.token_index; if (res >= 0) interest->max_suffix_comps = res; if (interest->max_suffix_comps < interest->min_suffix_comps) return (d->decoder.state = -__LINE__); /* optional PublisherID */ res = ccn_parse_PublisherID(d, interest); /* optional Exclude element */ interest->offset[CCN_PI_B_Exclude] = d->decoder.token_index; res = ccn_parse_Exclude(d); interest->offset[CCN_PI_E_Exclude] = d->decoder.token_index; /* optional ChildSelector */ interest->offset[CCN_PI_B_ChildSelector] = d->decoder.token_index; res = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_ChildSelector); if (res < 0) res = 0; interest->orderpref = res; interest->offset[CCN_PI_E_ChildSelector] = d->decoder.token_index; if (interest->orderpref > 5) return (d->decoder.state = -__LINE__); /* optional AnswerOriginKind */ interest->offset[CCN_PI_B_AnswerOriginKind] = d->decoder.token_index; interest->answerfrom = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_AnswerOriginKind); interest->offset[CCN_PI_E_AnswerOriginKind] = d->decoder.token_index; if (interest->answerfrom == -1) interest->answerfrom = CCN_AOK_DEFAULT; else if ((interest->answerfrom & CCN_AOK_NEW) != 0 && (interest->answerfrom & CCN_AOK_CS) == 0) return (d->decoder.state = -__LINE__); /* optional Scope */ interest->offset[CCN_PI_B_Scope] = d->decoder.token_index; interest->scope = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_Scope); interest->offset[CCN_PI_E_Scope] = d->decoder.token_index; if (interest->scope > 9) return (d->decoder.state = -__LINE__); if ((interest->answerfrom & CCN_AOK_EXPIRE) != 0 && interest->scope != 0) return (d->decoder.state = -__LINE__); /* optional InterestLifetime */ interest->offset[CCN_PI_B_InterestLifetime] = d->decoder.token_index; res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_InterestLifetime, 1, 8); if (res >= 0) magic |= 20100401; interest->offset[CCN_PI_E_InterestLifetime] = d->decoder.token_index; /* optional Nonce */ interest->offset[CCN_PI_B_Nonce] = d->decoder.token_index; res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Nonce, 4, 64); interest->offset[CCN_PI_E_Nonce] = d->decoder.token_index; /* Allow for no experimental stuff */ interest->offset[CCN_PI_B_OTHER] = d->decoder.token_index; interest->offset[CCN_PI_E_OTHER] = d->decoder.token_index; ccn_buf_check_close(d); interest->offset[CCN_PI_E] = d->decoder.index; } else return (d->decoder.state = -__LINE__); if (d->decoder.state < 0) return (d->decoder.state); if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) return (CCN_DSTATE_ERR_CODING); if (magic == 0) magic = 20090701; if (!(magic == 20090701 || magic == 20100401)) return (d->decoder.state = -__LINE__); interest->magic = magic; return (ncomp); }
static PyObject * ExclusionFilter_obj_from_ccn(PyObject *py_exclusion_filter) { PyObject *py_obj_ExclusionFilter, *py_components = NULL; PyObject *py_o; struct ccn_charbuf *exclusion_filter; int r; struct ccn_buf_decoder decoder, *d; size_t start, stop; assert(g_type_ExclusionFilter); debug("ExclusionFilter_from_ccn start\n"); exclusion_filter = CCNObject_Get(EXCLUSION_FILTER, py_exclusion_filter); // 1) Create python object py_obj_ExclusionFilter = PyObject_CallObject(g_type_ExclusionFilter, NULL); JUMP_IF_NULL(py_obj_ExclusionFilter, error); // 2) Set ccn_data to a cobject pointing to the c struct // and ensure proper destructor is set up for the c object. r = PyObject_SetAttrString(py_obj_ExclusionFilter, "ccn_data", py_exclusion_filter); JUMP_IF_NEG(r, error); // 3) Parse c structure and fill python attributes // using PyObject_SetAttrString // // self.components = None // # pyccn // self.ccn_data_dirty = False // self.ccn_data = None # backing charbuf py_components = PyList_New(0); JUMP_IF_NULL(py_components, error); r = PyObject_SetAttrString(py_obj_ExclusionFilter, "components", py_components); JUMP_IF_NEG(r, error); /* begin the actual parsing */ d = ccn_buf_decoder_start(&decoder, exclusion_filter->buf, exclusion_filter->length); r = ccn_buf_match_dtag(d, CCN_DTAG_Exclude); JUMP_IF_NEG(r, parse_error); ccn_buf_advance(d); r = ccn_buf_match_dtag(d, CCN_DTAG_Any); JUMP_IF_NEG(r, error); if (r) { ccn_buf_advance(d); ccn_buf_check_close(d); debug("got any: %d\n", r); py_o = Exclusion_Any_Obj(); JUMP_IF_NULL(py_o, error); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { start = d->decoder.token_index; r = ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1); JUMP_IF_NEG(r, error); stop = d->decoder.token_index; debug("got name\n"); py_o = Exclusion_Name_Obj(exclusion_filter->buf, start, stop); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); r = ccn_buf_match_dtag(d, CCN_DTAG_Any); if (r) { ccn_buf_advance(d); ccn_buf_check_close(d); debug("got *any*: %d\n", r); py_o = Exclusion_Any_Obj(); JUMP_IF_NULL(py_o, error); r = PyList_Append(py_components, py_o); Py_DECREF(py_o); JUMP_IF_NEG(r, error); } } ccn_buf_check_close(d); JUMP_IF_NEG(d->decoder.state, parse_error); // 4) Return the created object debug("ExclusionFilter_from_ccn ends\n"); return py_obj_ExclusionFilter; parse_error: PyErr_SetString(g_PyExc_CCNExclusionFilterError, "error parsing the data"); error: Py_XDECREF(py_components); Py_XDECREF(py_obj_ExclusionFilter); return NULL; }