/* * 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); }
struct ccn_charbuf* CcnbOR_read(CcnbOR self) { if (NBS_error(self->nbs)) { self->error = true; return NULL; } uint8_t* buf = (uint8_t*)malloc(2048); size_t readSize = NBS_read(self->nbs, buf, 2048, NULL); if (readSize == 0) { free(buf); return NULL; } ssize_t consumeSize = ccn_skeleton_decode(self->rd, buf, readSize); if (self->rd->state < 0) self->error = true; else ccn_charbuf_append(self->cbuf, buf, consumeSize); if (consumeSize < readSize) NBS_pushback(self->nbs, buf, consumeSize, readSize - consumeSize, NULL); else free(buf); if (CCN_FINAL_DSTATE(self->rd->state)) { struct ccn_charbuf* cbuf = self->cbuf; self->cbuf = ccn_charbuf_create(); CcnbOR_clear(self); return cbuf; } return NULL; }
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); }
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_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); }
int ccn_dhcp_content_parse(const unsigned char *p, size_t size, struct ccn_dhcp_entry *tail) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); int i; int count; struct ccn_dhcp_entry *de = tail; if (ccn_buf_match_dtag(d, CCN_DTAG_Entry)) { ccn_buf_advance(d); count = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_Count); for (i = 0; i < count; i ++) { struct ccn_charbuf *store = ccn_charbuf_create(); size_t start; size_t end; int host_off = -1; int port_off = -1; de->next = calloc(1, sizeof(*de)); de = de->next; memset(de, 0, sizeof(*de)); de->store = store; de->next = NULL; if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { de->name_prefix = ccn_charbuf_create(); start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(de->name_prefix, p + start, end - start); } else de->name_prefix = NULL; host_off = ccn_parse_tagged_string(d, CCN_DTAG_Host, store); port_off = ccn_parse_tagged_string(d, CCN_DTAG_Port, store); char *b = (char *)store->buf; char *h = b + host_off; char *p = b + port_off; if (host_off >= 0) memcpy((void *)de->address, h, strlen(h)); if (port_off >= 0) memcpy((void *)de->port, p, strlen(p)); } } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_dhcp_content_destroy(tail->next); return count; }
bool CcnbMsg_verifyIntegrity(CcnbMsg self) { struct ccn_skeleton_decoder rdecoder; struct ccn_skeleton_decoder *rd = &rdecoder; size_t dres; size_t encapSize = CcnbMsg_getEncapSize(self); memset(rd, 0, sizeof(rdecoder)); dres = ccn_skeleton_decode(rd, CcnbMsg_getEncap(self), encapSize); return CCN_FINAL_DSTATE(rd->state) && dres == encapSize; }
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_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); }
/* * 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); }
struct ccn_strategy_selection * ccn_strategy_selection_parse(const unsigned char *p, size_t size) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); struct ccn_strategy_selection *result; struct ccn_charbuf *store = NULL; const unsigned char *val = NULL; size_t sz; size_t start; size_t end; int action_off = -1; int ccnd_id_off = -1; int strategyid_off = -1; int parameters_off = -1; result = calloc(1, sizeof(*result)); if (result == NULL) return(NULL); result->name_prefix = ccn_charbuf_create(); result->store = store = ccn_charbuf_create(); if (result->name_prefix == NULL || result->store == NULL) { ccn_strategy_selection_destroy(&result); return(NULL); } if (ccn_buf_match_dtag(d, CCN_DTAG_StrategySelection)) { ccn_buf_advance(d); action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store); if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(result->name_prefix, p + start, end - start); } else ccn_charbuf_destroy(&result->name_prefix); if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &val, &sz)) { ccn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ccn_buf_check_close(d); if (d->decoder.state >= 0) { ccnd_id_off = store->length; ccn_charbuf_append(store, val, sz); result->ccnd_id_size = sz; } } strategyid_off = ccn_parse_tagged_string(d, CCN_DTAG_StrategyID, store); parameters_off = ccn_parse_tagged_string(d, CCN_DTAG_StrategyParameters, store); result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_strategy_selection_destroy(&result); else { const char *b = (const char *)result->store->buf; result->action = (action_off == -1) ? NULL : b + action_off; result->ccnd_id = (ccnd_id_off == -1) ? NULL : result->store->buf + ccnd_id_off; result->strategyid = (strategyid_off == -1) ? NULL : b + strategyid_off; result->parameters = (parameters_off == -1) ? NULL : b + parameters_off; } return(result); }
int r_init_map_and_process_file(struct ccnr_handle *h, struct ccn_charbuf *filename, int add_content) { int res = 0; int dres; struct stat statbuf; unsigned char *mapped_file = MAP_FAILED; unsigned char *msg; size_t size; int fd = -1; struct content_entry *content; struct ccn_skeleton_decoder *d; struct fdholder *fdholder; fd = r_io_open_repo_data_file(h, ccn_charbuf_as_string(filename), 0); if (fd == -1) // Normal exit return(1); res = fstat(fd, &statbuf); if (res != 0) { ccnr_msg(h, "stat failed for %s (fd=%d), %s (errno=%d)", ccn_charbuf_as_string(filename), fd, strerror(errno), errno); res = -errno; goto Bail; } if (statbuf.st_size == 0) goto Bail; mapped_file = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0); if (mapped_file == MAP_FAILED) { ccnr_msg(h, "mmap failed for %s (fd=%d), %s (errno=%d)", ccn_charbuf_as_string(filename), fd, strerror(errno), errno); res = -errno; goto Bail; } fdholder = r_io_fdholder_from_fd(h, fd); d = &fdholder->decoder; msg = mapped_file; size = statbuf.st_size; while (d->index < size) { dres = ccn_skeleton_decode(d, msg + d->index, size - d->index); if (!CCN_FINAL_DSTATE(d->state)) break; if (add_content) { content = process_incoming_content(h, fdholder, msg + d->index - dres, dres, NULL); if (content != NULL) r_store_commit_content(h, content); } } if (d->index != size || !CCN_FINAL_DSTATE(d->state)) { ccnr_msg(h, "protocol error on fdholder %u (state %d), discarding %d bytes", fdholder->filedesc, d->state, (int)(size - d->index)); res = -1; goto Bail; } Bail: if (mapped_file != MAP_FAILED) munmap(mapped_file, statbuf.st_size); r_io_shutdown_client_fd(h, fd); return (res); }
/** * Parse a ccnb-ecoded FaceInstance into an internal representation * * The space used for the various strings is held by the charbuf. * A client may replace the strings with other pointers, but then * assumes responsibilty for managing those pointers. * @returns pointer to newly allocated structure describing the face, or * NULL if there is an error. */ struct ccn_face_instance * ccn_face_instance_parse(const unsigned char *p, size_t size) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); struct ccn_charbuf *store = ccn_charbuf_create(); struct ccn_face_instance *result; const unsigned char *val; size_t sz; int action_off = -1; int ccnd_id_off = -1; int host_off = -1; int port_off = -1; int mcast_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ccn_charbuf_destroy(&store); return(NULL); } result->store = store; if (ccn_buf_match_dtag(d, CCN_DTAG_FaceInstance)) { ccn_buf_advance(d); action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store); if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &val, &sz)) { ccn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ccn_buf_check_close(d); if (d->decoder.state >= 0) { ccnd_id_off = store->length; ccn_charbuf_append(store, val, sz); result->ccnd_id_size = sz; } } result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID); result->descr.ipproto = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_IPProto); host_off = ccn_parse_tagged_string(d, CCN_DTAG_Host, store); port_off = ccn_parse_tagged_string(d, CCN_DTAG_Port, store); mcast_off = ccn_parse_tagged_string(d, CCN_DTAG_MulticastInterface, store); result->descr.mcast_ttl = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_MulticastTTL); result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state)) ccn_face_instance_destroy(&result); else { char *b = (char *)store->buf; result->action = (action_off == -1) ? NULL : b + action_off; result->ccnd_id = (ccnd_id_off == -1) ? NULL : store->buf + ccnd_id_off; result->descr.address = (host_off == -1) ? NULL : b + host_off; result->descr.port = (port_off == -1) ? NULL : b + port_off; result->descr.source_address = (mcast_off == -1) ? NULL : b + mcast_off; } return(result); }
struct ccn_forwarding_entry * ccn_forwarding_entry_parse(const unsigned char *p, size_t size) { struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, p, size); struct ccn_charbuf *store = ccn_charbuf_create(); struct ccn_forwarding_entry *result; const unsigned char *val; size_t sz; size_t start; size_t end; int action_off = -1; int ccnd_id_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ccn_charbuf_destroy(&store); return(NULL); } if (ccn_buf_match_dtag(d, CCN_DTAG_ForwardingEntry)) { ccn_buf_advance(d); action_off = ccn_parse_tagged_string(d, CCN_DTAG_Action, store); if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) { result->name_prefix = ccn_charbuf_create(); start = d->decoder.token_index; ccn_parse_Name(d, NULL); end = d->decoder.token_index; ccn_charbuf_append(result->name_prefix, p + start, end - start); } else result->name_prefix = NULL; if (ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &val, &sz)) { ccn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ccn_buf_check_close(d); if (d->decoder.state >= 0) { ccnd_id_off = store->length; ccn_charbuf_append(store, val, sz); result->ccnd_id_size = sz; } } result->faceid = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FaceID); result->flags = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_ForwardingFlags); result->lifetime = ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds); ccn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state) || store->length > sizeof(result->store)) ccn_forwarding_entry_destroy(&result); else { char *b = (char *)result->store; memcpy(b, store->buf, store->length); result->action = (action_off == -1) ? NULL : b + action_off; result->ccnd_id = (ccnd_id_off == -1) ? NULL : result->store + ccnd_id_off; } ccn_charbuf_destroy(&store); return(result); }