/** * Parse a ndnb-encoded Header */ struct ndn_header * ndn_header_parse(const unsigned char *p, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, p, size); struct ndn_header *result; const unsigned char *blob; size_t blobsize; int res = 0; result = calloc(1, sizeof(*result)); if (result == NULL) return (NULL); if (ndn_buf_match_dtag(d, NDN_DTAG_Header)) { ndn_buf_advance(d); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_Start, &result->start); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_Count, &result->count); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_BlockSize, &result->block_size); res |= ndn_parse_tagged_required_uintmax(d, NDN_DTAG_Length, &result->length); if (res != 0) { free(result); return (NULL); } if (ndn_buf_match_dtag(d, NDN_DTAG_ContentDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &blob, &blobsize)) { result->content_digest = ndn_charbuf_create(); ndn_charbuf_append(result->content_digest, blob, blobsize); ndn_buf_advance(d); } ndn_buf_check_close(d); } if (ndn_buf_match_dtag(d, NDN_DTAG_RootDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &blob, &blobsize)) { result->root_digest = ndn_charbuf_create(); ndn_charbuf_append(result->root_digest, blob, blobsize); ndn_buf_advance(d); } ndn_buf_check_close(d); } ndn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !NDN_FINAL_DSTATE(d->decoder.state)) { ndn_header_destroy(&result); } return (result); }
/** * Extract a pointer to and size of component at * given index i. The first component is index 0. * @returns 0, or -1 for error. */ int ndn_name_comp_get(const unsigned char *data, const struct ndn_indexbuf *indexbuf, unsigned int i, const unsigned char **comp, size_t *size) { int len; struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d; /* indexbuf should have an extra value marking end of last component, so we need to use last 2 values */ if (indexbuf->n < 2 || i > indexbuf->n - 2) { /* There isn't a component at this index */ return(-1); } len = indexbuf->buf[i + 1]-indexbuf->buf[i]; d = ndn_buf_decoder_start(&decoder, data + indexbuf->buf[i], len); if (ndn_buf_match_dtag(d, NDN_DTAG_Component)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, comp, size)) return(0); *comp = d->buf + d->decoder.index; *size = 0; ndn_buf_check_close(d); if (d->decoder.state >= 0) return(0); } return(-1); }
int ndn_uri_append(struct ndn_charbuf *c, const unsigned char *ndnb, size_t size, int flags) { int ncomp = 0; const unsigned char *comp = NULL; size_t compsize = 0; struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, ndnb, size); if (ndn_buf_match_dtag(d, NDN_DTAG_Interest) || ndn_buf_match_dtag(d, NDN_DTAG_ContentObject)) { ndn_buf_advance(d); if (ndn_buf_match_dtag(d, NDN_DTAG_Signature)) ndn_buf_advance_past_element(d); } if (!ndn_buf_match_dtag(d, NDN_DTAG_Name)) return(-1); if (flags & NDN_URI_INCLUDESCHEME) ndn_charbuf_append_string(c, "ndn:"); ndn_buf_advance(d); while (ndn_buf_match_dtag(d, NDN_DTAG_Component)) { ndn_buf_advance(d); compsize = 0; if (ndn_buf_match_blob(d, &comp, &compsize)) ndn_buf_advance(d); ndn_buf_check_close(d); if (d->decoder.state < 0) return(d->decoder.state); ncomp += 1; ndn_charbuf_append(c, "/", 1); if ((flags & NDN_URI_ESCAPE_MASK) == 0) flags |= NDN_URI_DEFAULT_ESCAPE; if (flags & NDN_URI_MIXEDESCAPE) { ndn_uri_append_mixedescaped(c, comp, compsize); } else if (flags & NDN_URI_PERCENTESCAPE) ndn_uri_append_percentescaped(c, comp, compsize); } ndn_buf_check_close(d); if (d->decoder.state < 0) return (d->decoder.state); if (ncomp == 0) ndn_charbuf_append(c, "/", 1); return(ncomp); }
static int ndn_name_last_component_offset(const unsigned char *ndnb, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, ndnb, size); int res = -1; if (ndn_buf_match_dtag(d, NDN_DTAG_Name)) { ndn_buf_advance(d); res = d->decoder.token_index; /* in case of 0 components */ while (ndn_buf_match_dtag(d, NDN_DTAG_Component)) { res = d->decoder.token_index; ndn_buf_advance(d); if (ndn_buf_match_blob(d, NULL, NULL)) ndn_buf_advance(d); ndn_buf_check_close(d); } ndn_buf_check_close(d); } return ((d->decoder.state >= 0) ? res : -1); }
int ndn_parse_tagged_required_uintmax(struct ndn_buf_decoder *d, enum ndn_dtag dtag, uintmax_t *result) { int res = -1; if (ndn_buf_match_dtag(d, dtag)) { ndn_buf_advance(d); res = ndn_parse_uintmax(d, result); ndn_buf_check_close(d); } else { return (d->decoder.state = -__LINE__); } return (res); }
struct ndn_forwarding_entry * ndn_forwarding_entry_parse(const unsigned char *p, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, p, size); struct ndn_charbuf *store = ndn_charbuf_create(); struct ndn_forwarding_entry *result; const unsigned char *val; size_t sz; size_t start; size_t end; int action_off = -1; int ndnd_id_off = -1; if (store == NULL) return(NULL); result = calloc(1, sizeof(*result)); if (result == NULL) { ndn_charbuf_destroy(&store); return(NULL); } if (ndn_buf_match_dtag(d, NDN_DTAG_ForwardingEntry)) { ndn_buf_advance(d); action_off = ndn_parse_tagged_string(d, NDN_DTAG_Action, store); if (ndn_buf_match_dtag(d, NDN_DTAG_Name)) { result->name_prefix = ndn_charbuf_create(); start = d->decoder.token_index; ndn_parse_Name(d, NULL); end = d->decoder.token_index; ndn_charbuf_append(result->name_prefix, p + start, end - start); } else result->name_prefix = NULL; if (ndn_buf_match_dtag(d, NDN_DTAG_PublisherPublicKeyDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &val, &sz)) { ndn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ndn_buf_check_close(d); if (d->decoder.state >= 0) { ndnd_id_off = store->length; ndn_charbuf_append(store, val, sz); result->ndnd_id_size = sz; } } result->faceid = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FaceID); result->flags = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_ForwardingFlags); result->lifetime = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FreshnessSeconds); ndn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !NDN_FINAL_DSTATE(d->decoder.state) || store->length > sizeof(result->store)) ndn_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->ndnd_id = (ndnd_id_off == -1) ? NULL : result->store + ndnd_id_off; } ndn_charbuf_destroy(&store); return(result); }
PyObject * KeyLocator_obj_from_ndn(PyObject *py_keylocator) { struct ndn_buf_decoder decoder, *d; struct ndn_charbuf *keylocator; struct ndn_charbuf *name; struct ndn_pkey *pubkey; size_t start, stop; int r; PyObject *py_o; PyObject *py_KeyLocator_obj = NULL; keylocator = NDNObject_Get(KEY_LOCATOR, py_keylocator); debug("KeyLocator_from_ndn start\n"); d = ndn_buf_decoder_start(&decoder, keylocator->buf, keylocator->length); assert(d); //should always succeed if (!ndn_buf_match_dtag(d, NDN_DTAG_KeyLocator)) { PyErr_SetString(g_PyExc_NDNKeyLocatorError, "The input isn't a valid" " KeyLocator"); return NULL; } ndn_buf_advance(d); if (ndn_buf_match_dtag(d, NDN_DTAG_KeyName)) { const unsigned char *bname; size_t bname_size; PyObject *py_name_obj; ndn_buf_advance(d); start = d->decoder.token_index; r = ndn_parse_Name(d, NULL); stop = d->decoder.token_index; if (r < 0) return PyErr_Format(g_PyExc_NDNKeyLocatorError, "Error finding" " NDN_DTAG_Name for KeyName (decoder state: %d)", d->decoder.state); assert(stop > start); bname_size = stop - start; bname = d->buf + start; /* r = ndn_ref_tagged_BLOB(NDN_DTAG_Name, d->buf, start, stop, &bname, &bname_size); if (r < 0) return PyErr_Format(g_PyExc_NDNKeyLocatorError, "Error getting" " NDN_DTAG_Name BLOB for KeyName (decoder state: %d)", d->decoder.state); */ debug("Parse NDN_DTAG_Name inside KeyName, len=%zd\n", bname_size); py_o = NDNObject_New_charbuf(NAME, &name); if (!py_o) return NULL; r = ndn_charbuf_append(name, bname, bname_size); if (r < 0) { Py_DECREF(py_o); return PyErr_NoMemory(); } py_name_obj = Name_obj_from_ndn(py_o); Py_DECREF(py_o); if (!py_name_obj) return NULL; py_KeyLocator_obj = PyObject_CallObject(g_type_KeyLocator, NULL); if (!py_KeyLocator_obj) { Py_DECREF(py_name_obj); goto error; } r = PyObject_SetAttrString(py_KeyLocator_obj, "keyName", py_name_obj); Py_DECREF(py_name_obj); JUMP_IF_NEG(r, error); #pragma message "Parse and add digest to the keylocator" } else if (ndn_buf_match_dtag(d, NDN_DTAG_Key)) { const unsigned char *dkey; size_t dkey_size; PyObject *py_key_obj, *py_ndn_key; start = d->decoder.token_index; r = ndn_parse_required_tagged_BLOB(d, NDN_DTAG_Key, 1, -1); stop = d->decoder.token_index; if (r < 0) return PyErr_Format(g_PyExc_NDNKeyLocatorError, "Error finding" " NDN_DTAG_Key for Key (decoder state: %d)", d->decoder.state); r = ndn_ref_tagged_BLOB(NDN_DTAG_Key, d->buf, start, stop, &dkey, &dkey_size); if (r < 0) return PyErr_Format(g_PyExc_NDNKeyLocatorError, "Error getting" " NDN_DTAG_Key BLOB for Key (decoder state: %d)", d->decoder.state); debug("Parse NDN_DTAG_Key, len=%zd\n", dkey_size); pubkey = ndn_d2i_pubkey(dkey, dkey_size); // free with ndn_pubkey_free() if (!pubkey) { PyErr_SetString(g_PyExc_NDNKeyLocatorError, "Unable to parse key to" " internal representation"); return NULL; } py_ndn_key = NDNObject_New(PKEY_PUB, pubkey); if (!py_ndn_key) { ndn_pubkey_free(pubkey); return NULL; } py_key_obj = Key_obj_from_ndn(py_ndn_key); Py_DECREF(py_ndn_key); if (!py_key_obj) return NULL; py_KeyLocator_obj = PyObject_CallObject(g_type_KeyLocator, NULL); if (!py_KeyLocator_obj) { Py_DECREF(py_key_obj); goto error; } r = PyObject_SetAttrString(py_KeyLocator_obj, "key", py_key_obj); Py_DECREF(py_key_obj); JUMP_IF_NEG(r, error); } else if (ndn_buf_match_dtag(d, NDN_DTAG_Certificate)) { PyErr_SetString(PyExc_NotImplementedError, "Found certificate DTAG," " which currently is unsupported"); return NULL; } else { PyErr_SetString(g_PyExc_NDNKeyLocatorError, "Unknown KeyLocator Type"); return NULL; } ndn_buf_check_close(d); // we don't really check the parser, though- return py_KeyLocator_obj; error: Py_XDECREF(py_KeyLocator_obj); return NULL; }
/** * Parse a ndnb-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 ndn_face_instance * ndn_face_instance_parse(const unsigned char *p, size_t size) { struct ndn_buf_decoder decoder; struct ndn_buf_decoder *d = ndn_buf_decoder_start(&decoder, p, size); struct ndn_charbuf *store = ndn_charbuf_create(); struct ndn_face_instance *result; const unsigned char *val; size_t sz; int action_off = -1; int ndnd_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) { ndn_charbuf_destroy(&store); return(NULL); } result->store = store; if (ndn_buf_match_dtag(d, NDN_DTAG_FaceInstance)) { ndn_buf_advance(d); action_off = ndn_parse_tagged_string(d, NDN_DTAG_Action, store); if (ndn_buf_match_dtag(d, NDN_DTAG_PublisherPublicKeyDigest)) { ndn_buf_advance(d); if (ndn_buf_match_blob(d, &val, &sz)) { ndn_buf_advance(d); if (sz != 32) d->decoder.state = -__LINE__; } ndn_buf_check_close(d); if (d->decoder.state >= 0) { ndnd_id_off = store->length; ndn_charbuf_append(store, val, sz); result->ndnd_id_size = sz; } } result->faceid = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FaceID); result->descr.ipproto = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_IPProto); host_off = ndn_parse_tagged_string(d, NDN_DTAG_Host, store); port_off = ndn_parse_tagged_string(d, NDN_DTAG_Port, store); mcast_off = ndn_parse_tagged_string(d, NDN_DTAG_MulticastInterface, store); result->descr.mcast_ttl = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_MulticastTTL); result->lifetime = ndn_parse_optional_tagged_nonNegativeInteger(d, NDN_DTAG_FreshnessSeconds); ndn_buf_check_close(d); } else d->decoder.state = -__LINE__; if (d->decoder.index != size || !NDN_FINAL_DSTATE(d->decoder.state)) ndn_face_instance_destroy(&result); else { char *b = (char *)store->buf; result->action = (action_off == -1) ? NULL : b + action_off; result->ndnd_id = (ndnd_id_off == -1) ? NULL : store->buf + ndnd_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); }