00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <string.h>
00021 #include <stdlib.h>
00022 #include <ccn/ccn.h>
00023 #include <ccn/charbuf.h>
00024 #include <ccn/coding.h>
00025 #include <ccn/indexbuf.h>
00026
00027 struct ccn_buf_decoder *
00028 ccn_buf_decoder_start(struct ccn_buf_decoder *d,
00029 const unsigned char *buf, size_t size)
00030 {
00031 memset(&d->decoder, 0, sizeof(d->decoder));
00032 d->decoder.state |= CCN_DSTATE_PAUSE;
00033 d->buf = buf;
00034 d->size = size;
00035 ccn_skeleton_decode(&d->decoder, buf, size);
00036 return(d);
00037 }
00038
00039 void
00040 ccn_buf_advance(struct ccn_buf_decoder *d)
00041 {
00042 ccn_skeleton_decode(&d->decoder,
00043 d->buf + d->decoder.index,
00044 d->size - d->decoder.index);
00045 }
00046
00047 int
00048 ccn_buf_match_dtag(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
00049 {
00050 return (d->decoder.state >= 0 &&
00051 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG &&
00052 d->decoder.numval == dtag);
00053 }
00054
00055 int
00056 ccn_buf_match_some_dtag(struct ccn_buf_decoder *d)
00057 {
00058 return(d->decoder.state >= 0 &&
00059 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_DTAG);
00060 }
00061
00062 int
00063 ccn_buf_match_some_blob(struct ccn_buf_decoder *d)
00064 {
00065 return(d->decoder.state >= 0 &&
00066 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB);
00067 }
00068
00069 int
00070 ccn_buf_match_blob(struct ccn_buf_decoder *d,
00071 const unsigned char **bufp, size_t *sizep)
00072 {
00073 if (ccn_buf_match_some_blob(d)) {
00074 if (bufp != NULL)
00075 *bufp = d->buf + d->decoder.index;
00076 if (sizep != NULL)
00077 *sizep = d->decoder.numval;
00078 return (1);
00079 }
00080 if (bufp != NULL)
00081 *bufp = d->buf + d->decoder.token_index;
00082 if (sizep != NULL)
00083 *sizep = 0;
00084 return(0);
00085 }
00086
00087 int
00088 ccn_buf_match_udata(struct ccn_buf_decoder *d, const char *s)
00089 {
00090 size_t len = strlen(s);
00091 return (d->decoder.state >= 0 &&
00092 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA &&
00093 d->decoder.numval == len &&
00094 0 == memcmp(d->buf + d->decoder.index, s, len));
00095 }
00096
00097 int
00098 ccn_buf_match_attr(struct ccn_buf_decoder *d, const char *s)
00099 {
00100 size_t len = strlen(s);
00101 return (d->decoder.state >= 0 &&
00102 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_ATTR &&
00103 d->decoder.numval == len &&
00104 0 == memcmp(d->buf + d->decoder.index, s, len));
00105 }
00106
00107 void
00108 ccn_buf_check_close(struct ccn_buf_decoder *d)
00109 {
00110 if (d->decoder.state >= 0) {
00111 if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) != CCN_NO_TOKEN)
00112 d->decoder.state = CCN_DSTATE_ERR_NEST;
00113 else
00114 ccn_buf_advance(d);
00115 }
00116 }
00117
00118 int
00119 ccn_buf_advance_past_element(struct ccn_buf_decoder *d)
00120 {
00121 enum ccn_tt tt;
00122 int nest;
00123 if (d->decoder.state < 0)
00124 return(d->decoder.state);
00125 tt = CCN_GET_TT_FROM_DSTATE(d->decoder.state);
00126 if (tt == CCN_DTAG || tt == CCN_TAG) {
00127 nest = d->decoder.nest;
00128 ccn_buf_advance(d);
00129 while (d->decoder.state >= 0 && d->decoder.nest >= nest)
00130 ccn_buf_advance(d);
00131
00132 ccn_buf_check_close(d);
00133 }
00134 else
00135 return(-1);
00136 if (d->decoder.state < 0)
00137 return(d->decoder.state);
00138 return (0);
00139 }
00140
00141 int
00142 ccn_parse_required_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
00143 int minlen, int maxlen)
00144 {
00145 int res = -1;
00146 size_t len = 0;
00147 if (ccn_buf_match_dtag(d, dtag)) {
00148 res = d->decoder.element_index;
00149 ccn_buf_advance(d);
00150 if (ccn_buf_match_some_blob(d)) {
00151 len = d->decoder.numval;
00152 ccn_buf_advance(d);
00153 }
00154 ccn_buf_check_close(d);
00155 if (len < minlen || (maxlen >= 0 && len > maxlen)) {
00156 d->decoder.state = -__LINE__;
00157 }
00158 }
00159 else
00160 d->decoder.state = -__LINE__;
00161 if (d->decoder.state < 0)
00162 return (d->decoder.state);
00163 return(res);
00164 }
00165
00166 int
00167 ccn_parse_optional_tagged_BLOB(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
00168 int minlen, int maxlen)
00169 {
00170 if (ccn_buf_match_dtag(d, dtag))
00171 return(ccn_parse_required_tagged_BLOB(d, dtag, minlen, maxlen));
00172 return(-1);
00173 }
00174
00175 uintmax_t
00176 ccn_parse_required_tagged_binary_number(struct ccn_buf_decoder *d,
00177 enum ccn_dtag dtag,
00178 int minlen, int maxlen)
00179 {
00180 uintmax_t value = 0;
00181 const unsigned char *p = NULL;
00182 size_t len = 0;
00183 int i;
00184 if (0 <= minlen && minlen <= maxlen && maxlen <= sizeof(value) &&
00185 ccn_buf_match_dtag(d, dtag)) {
00186 ccn_buf_advance(d);
00187 if (ccn_buf_match_blob(d, &p, &len))
00188 ccn_buf_advance(d);
00189 ccn_buf_check_close(d);
00190 if (d->decoder.state < 0)
00191 return(value);
00192 if (minlen <= len && len <= maxlen)
00193 for (i = 0; i < len; i++)
00194 value = (value << 8) + p[i];
00195 else
00196 d->decoder.state = -__LINE__;
00197 }
00198 else
00199 d->decoder.state = -__LINE__;
00200 return(value);
00201 }
00202
00203 uintmax_t
00204 ccn_parse_optional_tagged_binary_number(struct ccn_buf_decoder *d, enum ccn_dtag dtag,
00205 int minlen, int maxlen, uintmax_t default_value)
00206 {
00207 if (ccn_buf_match_dtag(d, dtag))
00208 return(ccn_parse_required_tagged_binary_number(d, dtag, minlen, maxlen));
00209 return(default_value);
00210 }
00211
00212 int
00213 ccn_parse_required_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
00214 {
00215 int res = -1;
00216 if (ccn_buf_match_dtag(d, dtag)) {
00217 res = d->decoder.element_index;
00218 ccn_buf_advance(d);
00219 if (d->decoder.state >= 0 &&
00220 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA)
00221 ccn_buf_advance(d);
00222 else
00223 d->decoder.state = -__LINE__;
00224 ccn_buf_check_close(d);
00225 }
00226 else
00227 d->decoder.state = -__LINE__;
00228 if (d->decoder.state < 0)
00229 return (-1);
00230 return(res);
00231 }
00232
00233 int
00234 ccn_parse_optional_tagged_UDATA(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
00235 {
00236 if (ccn_buf_match_dtag(d, dtag))
00237 return(ccn_parse_required_tagged_UDATA(d, dtag));
00238 return(-1);
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 int
00253 ccn_parse_tagged_string(struct ccn_buf_decoder *d, enum ccn_dtag dtag, struct ccn_charbuf *store)
00254 {
00255 const unsigned char *p = NULL;
00256 size_t size = 0;
00257 int res;
00258
00259 if (ccn_buf_match_dtag(d, dtag)) {
00260 ccn_buf_advance(d);
00261 if (d->decoder.state >= 0 &&
00262 CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
00263 res = store->length;
00264 p = d->buf + d->decoder.index;
00265 size = d->decoder.numval;
00266 ccn_buf_advance(d);
00267 }
00268 ccn_buf_check_close(d);
00269 if (d->decoder.state >= 0) {
00270
00271 res = store->length;
00272 if (size > 0)
00273 ccn_charbuf_append(store, p, size);
00274 ccn_charbuf_append_value(store, 0, 1);
00275 return(res);
00276 }
00277 }
00278 return(-1);
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288 int
00289 ccn_parse_Name(struct ccn_buf_decoder *d, struct ccn_indexbuf *components)
00290 {
00291 int ncomp = 0;
00292 if (ccn_buf_match_dtag(d, CCN_DTAG_Name)) {
00293 if (components != NULL) components->n = 0;
00294 ccn_buf_advance(d);
00295 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00296 if (components != NULL)
00297 ccn_indexbuf_append_element(components, d->decoder.token_index);
00298 ncomp += 1;
00299 ccn_buf_advance(d);
00300 if (ccn_buf_match_blob(d, NULL, NULL))
00301 ccn_buf_advance(d);
00302 ccn_buf_check_close(d);
00303 }
00304 if (components != NULL)
00305 ccn_indexbuf_append_element(components, d->decoder.token_index);
00306 ccn_buf_check_close(d);
00307 }
00308 else
00309 d->decoder.state = -__LINE__;
00310 if (d->decoder.state < 0)
00311 return(-1);
00312 else
00313 return(ncomp);
00314 }
00315
00316 int
00317 ccn_parse_PublisherID(struct ccn_buf_decoder *d, struct ccn_parsed_interest *pi)
00318 {
00319 int res = -1;
00320 int iskey = 0;
00321 unsigned pubstart = d->decoder.token_index;
00322 unsigned keystart = pubstart;
00323 unsigned keyend = pubstart;
00324 unsigned pubend = pubstart;
00325 iskey = ccn_buf_match_dtag(d, CCN_DTAG_PublisherPublicKeyDigest);
00326 if (iskey ||
00327 ccn_buf_match_dtag(d, CCN_DTAG_PublisherCertificateDigest) ||
00328 ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerKeyDigest) ||
00329 ccn_buf_match_dtag(d, CCN_DTAG_PublisherIssuerCertificateDigest)) {
00330 res = d->decoder.element_index;
00331 ccn_buf_advance(d);
00332 keystart = d->decoder.token_index;
00333 if (!ccn_buf_match_some_blob(d))
00334 return (d->decoder.state = -__LINE__);
00335 ccn_buf_advance(d);
00336 keyend = d->decoder.token_index;
00337 ccn_buf_check_close(d);
00338 pubend = d->decoder.token_index;
00339 }
00340 if (d->decoder.state < 0)
00341 return (d->decoder.state);
00342 if (pi != NULL) {
00343 pi->offset[CCN_PI_B_PublisherID] = pubstart;
00344 pi->offset[CCN_PI_B_PublisherIDKeyDigest] = keystart;
00345 pi->offset[CCN_PI_E_PublisherIDKeyDigest] = iskey ? keyend : keystart;
00346 pi->offset[CCN_PI_E_PublisherID] = pubend;
00347 }
00348 return(res);
00349 }
00350
00351 static int
00352 ccn_parse_optional_Any_or_Bloom(struct ccn_buf_decoder *d)
00353 {
00354 int res;
00355 res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Bloom, 1, 1024+8);
00356 if (res >= 0)
00357 return(res);
00358 if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) {
00359 ccn_buf_advance(d);
00360 ccn_buf_check_close(d);
00361 res = 0;
00362 }
00363 if (d->decoder.state < 0)
00364 return (d->decoder.state);
00365 return(res);
00366 }
00367
00368 int
00369 ccn_parse_Exclude(struct ccn_buf_decoder *d)
00370 {
00371 int res = -1;
00372 if (ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) {
00373 res = d->decoder.element_index;
00374 ccn_buf_advance(d);
00375 ccn_parse_optional_Any_or_Bloom(d);
00376 while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) {
00377 ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Component, 0, -1);
00378 ccn_parse_optional_Any_or_Bloom(d);
00379 }
00380 ccn_buf_check_close(d);
00381 }
00382 if (d->decoder.state < 0)
00383 return (d->decoder.state);
00384 return(res);
00385 }
00386
00387
00388
00389 int
00390 ccn_parse_nonNegativeInteger(struct ccn_buf_decoder *d)
00391 {
00392 const unsigned char *p;
00393 int i;
00394 int n;
00395 int val;
00396 int newval;
00397 unsigned char c;
00398 if (d->decoder.state < 0)
00399 return(d->decoder.state);
00400 if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
00401 p = d->buf + d->decoder.index;
00402 n = d->decoder.numval;
00403 if (n < 1)
00404 return(d->decoder.state = -__LINE__);
00405 val = 0;
00406 for (i = 0; i < n; i++) {
00407 c = p[i];
00408 if ('0' <= c && c <= '9') {
00409 newval = val * 10 + (c - '0');
00410 if (newval < val)
00411 return(d->decoder.state = -__LINE__);
00412 val = newval;
00413 }
00414 else
00415 return(d->decoder.state = -__LINE__);
00416 }
00417 ccn_buf_advance(d);
00418 return(val);
00419 }
00420 return(d->decoder.state = -__LINE__);
00421 }
00422
00423
00424
00425
00426
00427
00428
00429 int
00430 ccn_parse_uintmax(struct ccn_buf_decoder *d, uintmax_t *result)
00431 {
00432 const unsigned char *p;
00433 int i;
00434 int n;
00435 uintmax_t val;
00436 uintmax_t newval;
00437 unsigned char c;
00438 if (d->decoder.state < 0)
00439 return(d->decoder.state);
00440 if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
00441 p = d->buf + d->decoder.index;
00442 n = d->decoder.numval;
00443 if (n < 1)
00444 return(d->decoder.state = -__LINE__);
00445 val = 0;
00446 for (i = 0; i < n; i++) {
00447 c = p[i];
00448 if ('0' <= c && c <= '9') {
00449 newval = val * 10 + (c - '0');
00450 if (newval < val)
00451 return(d->decoder.state = -__LINE__);
00452 val = newval;
00453 }
00454 else
00455 return(d->decoder.state = -__LINE__);
00456 }
00457 ccn_buf_advance(d);
00458 *result = val;
00459 return(0);
00460 }
00461 return(d->decoder.state = -__LINE__);
00462 }
00463
00464 int
00465 ccn_parse_timestamp(struct ccn_buf_decoder *d)
00466 {
00467 const unsigned char dlm[] = "--T::.Z";
00468 const unsigned char *p;
00469 int i;
00470 int k;
00471 int n;
00472 if (d->decoder.state < 0)
00473 return(d->decoder.state);
00474 if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_BLOB) {
00475
00476 n = d->decoder.numval;
00477 if (n < 3 || n > 7)
00478 return(d->decoder.state = -__LINE__);
00479 ccn_buf_advance(d);
00480 return(0);
00481 }
00482 if (CCN_GET_TT_FROM_DSTATE(d->decoder.state) == CCN_UDATA) {
00483
00484 p = d->buf + d->decoder.index;
00485 n = d->decoder.numval;
00486 if (n < 8 || n > 40)
00487 return(d->decoder.state = -__LINE__);
00488 if (p[n - 1] != 'Z')
00489 return(d->decoder.state = -__LINE__);
00490 for (i = 0, k = 0; i < n && '0' <= p[i] && p[i] <= '9';) {
00491 i++;
00492 if (i < n && p[i] == dlm[k]) {
00493 if (dlm[k++] == 0)
00494 return(d->decoder.state = -__LINE__);
00495 i++;
00496 }
00497 }
00498 if (k < 5)
00499 return(d->decoder.state = -__LINE__);
00500 if (!(i == n || i == n - 1))
00501 return(d->decoder.state = -__LINE__);
00502 ccn_buf_advance(d);
00503 return(0);
00504 }
00505 return(d->decoder.state = -__LINE__);
00506 }
00507
00508 int
00509 ccn_parse_required_tagged_timestamp(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
00510 {
00511 int res = -1;
00512 if (ccn_buf_match_dtag(d, dtag)) {
00513 res = d->decoder.element_index;
00514 ccn_buf_advance(d);
00515 ccn_parse_timestamp(d);
00516 ccn_buf_check_close(d);
00517 }
00518 else
00519 d->decoder.state = -__LINE__;
00520 if (d->decoder.state < 0)
00521 return (-1);
00522 return(res);
00523 }
00524
00525 int
00526 ccn_parse_optional_tagged_nonNegativeInteger(struct ccn_buf_decoder *d, enum ccn_dtag dtag)
00527 {
00528 int res = -1;
00529 if (ccn_buf_match_dtag(d, dtag)) {
00530 ccn_buf_advance(d);
00531 res = ccn_parse_nonNegativeInteger(d);
00532 ccn_buf_check_close(d);
00533 }
00534 if (d->decoder.state < 0)
00535 return (d->decoder.state);
00536 return(res);
00537 }
00538
00539 int
00540 ccn_fetch_tagged_nonNegativeInteger(enum ccn_dtag tt,
00541 const unsigned char *buf,
00542 size_t start, size_t stop)
00543 {
00544 struct ccn_buf_decoder decoder;
00545 struct ccn_buf_decoder *d;
00546 int result = -1;
00547 if (stop < start) return(-1);
00548 d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
00549 if (ccn_buf_match_dtag(d, tt)) {
00550 ccn_buf_advance(d);
00551 result = ccn_parse_nonNegativeInteger(d);
00552 ccn_buf_check_close(d);
00553 }
00554 if (result < 0)
00555 return(-1);
00556 return(result);
00557 }
00558
00559
00560 int
00561 ccn_parse_interest(const unsigned char *msg, size_t size,
00562 struct ccn_parsed_interest *interest,
00563 struct ccn_indexbuf *components)
00564 {
00565 struct ccn_buf_decoder decoder;
00566 struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
00567 int magic = 0;
00568 int ncomp = 0;
00569 int res;
00570 if (ccn_buf_match_dtag(d, CCN_DTAG_Interest)) {
00571 if (components == NULL) {
00572
00573 components = ccn_indexbuf_create();
00574 if (components == NULL) return(-1);
00575 res = ccn_parse_interest(msg, size, interest, components);
00576 ccn_indexbuf_destroy(&components);
00577 return(res);
00578 }
00579 ccn_buf_advance(d);
00580 interest->offset[CCN_PI_B_Name] = d->decoder.element_index;
00581 interest->offset[CCN_PI_B_Component0] = d->decoder.index;
00582 ncomp = ccn_parse_Name(d, components);
00583 if (d->decoder.state < 0) {
00584 memset(interest->offset, 0, sizeof(interest->offset));
00585 return(d->decoder.state);
00586 }
00587 interest->offset[CCN_PI_E_ComponentLast] = d->decoder.token_index - 1;
00588 interest->offset[CCN_PI_E_Name] = d->decoder.token_index;
00589 interest->prefix_comps = ncomp;
00590 interest->offset[CCN_PI_B_LastPrefixComponent] = components->buf[(ncomp > 0) ? (ncomp - 1) : 0];
00591 interest->offset[CCN_PI_E_LastPrefixComponent] = components->buf[ncomp];
00592
00593 interest->min_suffix_comps = 0;
00594 interest->max_suffix_comps = 32767;
00595 interest->offset[CCN_PI_B_MinSuffixComponents] = d->decoder.token_index;
00596 res = ccn_parse_optional_tagged_nonNegativeInteger(d,
00597 CCN_DTAG_MinSuffixComponents);
00598 interest->offset[CCN_PI_E_MinSuffixComponents] = d->decoder.token_index;
00599 if (res >= 0)
00600 interest->min_suffix_comps = res;
00601 interest->offset[CCN_PI_B_MaxSuffixComponents] = d->decoder.token_index;
00602 res = ccn_parse_optional_tagged_nonNegativeInteger(d,
00603 CCN_DTAG_MaxSuffixComponents);
00604 interest->offset[CCN_PI_E_MaxSuffixComponents] = d->decoder.token_index;
00605 if (res >= 0)
00606 interest->max_suffix_comps = res;
00607 if (interest->max_suffix_comps < interest->min_suffix_comps)
00608 return (d->decoder.state = -__LINE__);
00609
00610 res = ccn_parse_PublisherID(d, interest);
00611
00612 interest->offset[CCN_PI_B_Exclude] = d->decoder.token_index;
00613 res = ccn_parse_Exclude(d);
00614 interest->offset[CCN_PI_E_Exclude] = d->decoder.token_index;
00615
00616 interest->offset[CCN_PI_B_ChildSelector] = d->decoder.token_index;
00617 res = ccn_parse_optional_tagged_nonNegativeInteger(d,
00618 CCN_DTAG_ChildSelector);
00619 if (res < 0)
00620 res = 0;
00621 interest->orderpref = res;
00622 interest->offset[CCN_PI_E_ChildSelector] = d->decoder.token_index;
00623 if (interest->orderpref > 5)
00624 return (d->decoder.state = -__LINE__);
00625
00626 interest->offset[CCN_PI_B_AnswerOriginKind] = d->decoder.token_index;
00627 interest->answerfrom = ccn_parse_optional_tagged_nonNegativeInteger(d,
00628 CCN_DTAG_AnswerOriginKind);
00629 interest->offset[CCN_PI_E_AnswerOriginKind] = d->decoder.token_index;
00630 if (interest->answerfrom == -1)
00631 interest->answerfrom = CCN_AOK_DEFAULT;
00632 else if ((interest->answerfrom & CCN_AOK_NEW) != 0 &&
00633 (interest->answerfrom & CCN_AOK_CS) == 0)
00634 return (d->decoder.state = -__LINE__);
00635
00636 interest->offset[CCN_PI_B_Scope] = d->decoder.token_index;
00637 interest->scope = ccn_parse_optional_tagged_nonNegativeInteger(d,
00638 CCN_DTAG_Scope);
00639 interest->offset[CCN_PI_E_Scope] = d->decoder.token_index;
00640 if (interest->scope > 9)
00641 return (d->decoder.state = -__LINE__);
00642 if ((interest->answerfrom & CCN_AOK_EXPIRE) != 0 &&
00643 interest->scope != 0)
00644 return (d->decoder.state = -__LINE__);
00645
00646 interest->offset[CCN_PI_B_InterestLifetime] = d->decoder.token_index;
00647 res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_InterestLifetime, 1, 8);
00648 if (res >= 0)
00649 magic |= 20100401;
00650 interest->offset[CCN_PI_E_InterestLifetime] = d->decoder.token_index;
00651
00652 interest->offset[CCN_PI_B_Nonce] = d->decoder.token_index;
00653 res = ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Nonce, 4, 64);
00654 interest->offset[CCN_PI_E_Nonce] = d->decoder.token_index;
00655
00656 interest->offset[CCN_PI_B_OTHER] = d->decoder.token_index;
00657 interest->offset[CCN_PI_E_OTHER] = d->decoder.token_index;
00658 ccn_buf_check_close(d);
00659 interest->offset[CCN_PI_E] = d->decoder.index;
00660 }
00661 else
00662 return (d->decoder.state = -__LINE__);
00663 if (d->decoder.state < 0)
00664 return (d->decoder.state);
00665 if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state))
00666 return (CCN_DSTATE_ERR_CODING);
00667 if (magic == 0)
00668 magic = 20090701;
00669 if (!(magic == 20090701 || magic == 20100401))
00670 return (d->decoder.state = -__LINE__);
00671 interest->magic = magic;
00672 return (ncomp);
00673 }
00674
00675 struct parsed_KeyName {
00676 int Name;
00677 int endName;
00678 int PublisherID;
00679 int endPublisherID;
00680 };
00681
00682 static int
00683 ccn_parse_KeyName(struct ccn_buf_decoder *d, struct parsed_KeyName *x)
00684 {
00685 int res = -1;
00686 if (ccn_buf_match_dtag(d, CCN_DTAG_KeyName)) {
00687 res = d->decoder.element_index;
00688 ccn_buf_advance(d);
00689 x->Name = d->decoder.token_index;
00690 ccn_parse_Name(d, NULL);
00691 x->endName = d->decoder.token_index;
00692 x->PublisherID = ccn_parse_PublisherID(d, NULL);
00693 x->endPublisherID = d->decoder.token_index;
00694 ccn_buf_check_close(d);
00695 }
00696 else
00697 d->decoder.state = -__LINE__;
00698 if (d->decoder.state < 0)
00699 return (d->decoder.state);
00700 return(res);
00701 }
00702
00703 static int
00704 ccn_parse_Signature(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
00705 {
00706 int res = -1;
00707 int i;
00708 struct ccn_parsed_ContentObject dummy;
00709 if (x == NULL)
00710 x = &dummy;
00711 for (i = CCN_PCO_B_Signature; i <= CCN_PCO_E_Signature; i++) {
00712 x->offset[i] = d->decoder.token_index;
00713 }
00714 if (ccn_buf_match_dtag(d, CCN_DTAG_Signature)) {
00715 res = d->decoder.element_index;
00716 ccn_buf_advance(d);
00717 x->offset[CCN_PCO_B_DigestAlgorithm] = d->decoder.token_index;
00718 ccn_parse_optional_tagged_UDATA(d, CCN_DTAG_DigestAlgorithm);
00719 x->offset[CCN_PCO_E_DigestAlgorithm] = d->decoder.token_index;
00720 x->offset[CCN_PCO_B_Witness] = d->decoder.token_index;
00721 ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_Witness, 8, -1);
00722 x->offset[CCN_PCO_E_Witness] = d->decoder.token_index;
00723 x->offset[CCN_PCO_B_SignatureBits] = d->decoder.token_index;
00724 ccn_parse_required_tagged_BLOB(d, CCN_DTAG_SignatureBits, 16, -1);
00725 x->offset[CCN_PCO_E_SignatureBits] = d->decoder.token_index;
00726 ccn_buf_check_close(d);
00727 x->offset[CCN_PCO_E_Signature] = d->decoder.token_index;
00728 }
00729 if (d->decoder.state < 0)
00730 return (d->decoder.state);
00731 return(res);
00732 }
00733
00734 static int
00735 ccn_parse_SignedInfo(struct ccn_buf_decoder *d, struct ccn_parsed_ContentObject *x)
00736 {
00737 x->offset[CCN_PCO_B_SignedInfo] = d->decoder.token_index;
00738 if (ccn_buf_match_dtag(d, CCN_DTAG_SignedInfo)) {
00739 ccn_buf_advance(d);
00740 x->offset[CCN_PCO_B_PublisherPublicKeyDigest] = d->decoder.token_index;
00741 ccn_parse_required_tagged_BLOB(d, CCN_DTAG_PublisherPublicKeyDigest, 16, 64);
00742 x->offset[CCN_PCO_E_PublisherPublicKeyDigest] = d->decoder.token_index;
00743
00744 x->offset[CCN_PCO_B_Timestamp] = d->decoder.token_index;
00745 ccn_parse_required_tagged_timestamp(d, CCN_DTAG_Timestamp);
00746 x->offset[CCN_PCO_E_Timestamp] = d->decoder.token_index;
00747
00748 x->offset[CCN_PCO_B_Type] = d->decoder.token_index;
00749 x->type = CCN_CONTENT_DATA;
00750 x->type = ccn_parse_optional_tagged_binary_number(d, CCN_DTAG_Type, 3, 3, CCN_CONTENT_DATA);
00751 x->offset[CCN_PCO_E_Type] = d->decoder.token_index;
00752
00753 x->offset[CCN_PCO_B_FreshnessSeconds] = d->decoder.token_index;
00754 ccn_parse_optional_tagged_nonNegativeInteger(d, CCN_DTAG_FreshnessSeconds);
00755 x->offset[CCN_PCO_E_FreshnessSeconds] = d->decoder.token_index;
00756
00757 x->offset[CCN_PCO_B_FinalBlockID] = d->decoder.token_index;
00758 ccn_parse_optional_tagged_BLOB(d, CCN_DTAG_FinalBlockID, 1, -1);
00759 x->offset[CCN_PCO_E_FinalBlockID] = d->decoder.token_index;
00760
00761 x->offset[CCN_PCO_B_KeyLocator] = d->decoder.token_index;
00762 x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
00763 x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
00764 x->offset[CCN_PCO_B_KeyName_Name] = d->decoder.token_index;
00765 x->offset[CCN_PCO_E_KeyName_Name] = d->decoder.token_index;
00766 x->offset[CCN_PCO_B_KeyName_Pub] = d->decoder.token_index;
00767 x->offset[CCN_PCO_E_KeyName_Pub] = d->decoder.token_index;
00768 if (ccn_buf_match_dtag(d, CCN_DTAG_KeyLocator)) {
00769 ccn_buf_advance(d);
00770 x->offset[CCN_PCO_B_Key_Certificate_KeyName] = d->decoder.token_index;
00771 if (ccn_buf_match_dtag(d, CCN_DTAG_Key)) {
00772 (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Key, 0, -1);
00773 }
00774 else if (ccn_buf_match_dtag(d, CCN_DTAG_Certificate)) {
00775 (void)ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Certificate, 0, -1);
00776 }
00777 else {
00778 struct parsed_KeyName keyname = {-1, -1, -1, -1};
00779 if (ccn_parse_KeyName(d, &keyname) >= 0) {
00780 if (keyname.Name >= 0) {
00781 x->offset[CCN_PCO_B_KeyName_Name] = keyname.Name;
00782 x->offset[CCN_PCO_E_KeyName_Name] = keyname.endName;
00783 }
00784 if (keyname.PublisherID >= 0) {
00785 x->offset[CCN_PCO_B_KeyName_Pub] = keyname.PublisherID;
00786 x->offset[CCN_PCO_E_KeyName_Pub] = keyname.endPublisherID;
00787 }
00788 }
00789 }
00790 x->offset[CCN_PCO_E_Key_Certificate_KeyName] = d->decoder.token_index;
00791 ccn_buf_check_close(d);
00792 }
00793 x->offset[CCN_PCO_E_KeyLocator] = d->decoder.token_index;
00794 ccn_buf_check_close(d);
00795 }
00796 else
00797 d->decoder.state = -__LINE__;
00798 x->offset[CCN_PCO_E_SignedInfo] = d->decoder.token_index;
00799 if (d->decoder.state < 0)
00800 return (d->decoder.state);
00801 return(0);
00802 }
00803
00804 int
00805 ccn_parse_ContentObject(const unsigned char *msg, size_t size,
00806 struct ccn_parsed_ContentObject *x,
00807 struct ccn_indexbuf *components)
00808 {
00809 struct ccn_buf_decoder decoder;
00810 struct ccn_buf_decoder *d = ccn_buf_decoder_start(&decoder, msg, size);
00811 int res;
00812 x->magic = 20090415;
00813 x->digest_bytes = 0;
00814 if (ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)) {
00815 ccn_buf_advance(d);
00816 res = ccn_parse_Signature(d, x);
00817 x->offset[CCN_PCO_B_Name] = d->decoder.token_index;
00818 x->offset[CCN_PCO_B_Component0] = d->decoder.index;
00819 res = ccn_parse_Name(d, components);
00820 if (res < 0)
00821 d->decoder.state = -__LINE__;
00822 x->name_ncomps = res;
00823 x->offset[CCN_PCO_E_ComponentLast] = d->decoder.token_index - 1;
00824 x->offset[CCN_PCO_E_Name] = d->decoder.token_index;
00825 ccn_parse_SignedInfo(d, x);
00826 x->offset[CCN_PCO_B_Content] = d->decoder.token_index;
00827 ccn_parse_required_tagged_BLOB(d, CCN_DTAG_Content, 0, -1);
00828 x->offset[CCN_PCO_E_Content] = d->decoder.token_index;
00829 ccn_buf_check_close(d);
00830 x->offset[CCN_PCO_E] = d->decoder.index;
00831 }
00832 else
00833 d->decoder.state = -__LINE__;
00834 if (d->decoder.index != size || !CCN_FINAL_DSTATE(d->decoder.state))
00835 return (CCN_DSTATE_ERR_CODING);
00836 return(0);
00837 }
00838
00839 int
00840 ccn_ref_tagged_BLOB(enum ccn_dtag tt,
00841 const unsigned char *buf, size_t start, size_t stop,
00842 const unsigned char **presult, size_t *psize)
00843 {
00844 struct ccn_buf_decoder decoder;
00845 struct ccn_buf_decoder *d;
00846 if (stop < start) return(-1);
00847 d = ccn_buf_decoder_start(&decoder, buf + start, stop - start);
00848 if (ccn_buf_match_dtag(d, tt)) {
00849 ccn_buf_advance(d);
00850 if (ccn_buf_match_blob(d, presult, psize))
00851 ccn_buf_advance(d);
00852 ccn_buf_check_close(d);
00853 }
00854 else
00855 return(-1);
00856 if (d->decoder.index != d->size || !CCN_FINAL_DSTATE(d->decoder.state))
00857 return (CCN_DSTATE_ERR_CODING);
00858 return(0);
00859 }
00860
00861 static struct ccn_buf_decoder *
00862 ccn_buf_decoder_start_at_components(struct ccn_buf_decoder *d,
00863 const unsigned char *buf, size_t buflen)
00864 {
00865 ccn_buf_decoder_start(d, buf, buflen);
00866 while (ccn_buf_match_dtag(d, CCN_DTAG_Name) ||
00867 ccn_buf_match_dtag(d, CCN_DTAG_Interest) ||
00868 ccn_buf_match_dtag(d, CCN_DTAG_ContentObject)
00869 ) {
00870 ccn_buf_advance(d);
00871 ccn_parse_Signature(d, NULL);
00872 }
00873 return(d);
00874 }
00875
00876 int
00877 ccn_content_get_value(const unsigned char *data, size_t data_size,
00878 const struct ccn_parsed_ContentObject *content,
00879 const unsigned char **value, size_t *value_size)
00880 {
00881 int res;
00882 res = ccn_ref_tagged_BLOB(CCN_DTAG_Content, data,
00883 content->offset[CCN_PCO_B_Content],
00884 content->offset[CCN_PCO_E_Content],
00885 value, value_size);
00886 return(res);
00887 }
00888
00889 int
00890 ccn_compare_names(const unsigned char *a, size_t asize,
00891 const unsigned char *b, size_t bsize)
00892 {
00893 struct ccn_buf_decoder a_decoder;
00894 struct ccn_buf_decoder b_decoder;
00895 struct ccn_buf_decoder *aa =
00896 ccn_buf_decoder_start_at_components(&a_decoder, a, asize);
00897 struct ccn_buf_decoder *bb =
00898 ccn_buf_decoder_start_at_components(&b_decoder, b, bsize);
00899 const unsigned char *acp = NULL;
00900 const unsigned char *bcp = NULL;
00901 size_t acsize;
00902 size_t bcsize;
00903 int cmp = 0;
00904 int more_a;
00905 for (;;) {
00906 more_a = ccn_buf_match_dtag(aa, CCN_DTAG_Component);
00907 cmp = more_a - ccn_buf_match_dtag(bb, CCN_DTAG_Component);
00908 if (more_a == 0 || cmp != 0)
00909 break;
00910 ccn_buf_advance(aa);
00911 ccn_buf_advance(bb);
00912 acsize = bcsize = 0;
00913 if (ccn_buf_match_blob(aa, &acp, &acsize))
00914 ccn_buf_advance(aa);
00915 if (ccn_buf_match_blob(bb, &bcp, &bcsize))
00916 ccn_buf_advance(bb);
00917 cmp = acsize - bcsize;
00918 if (cmp != 0)
00919 break;
00920 cmp = memcmp(acp, bcp, acsize);
00921 if (cmp != 0)
00922 break;
00923 ccn_buf_check_close(aa);
00924 ccn_buf_check_close(bb);
00925 }
00926 return (cmp);
00927 }
00928