ccn_buf_decoder.c

Go to the documentation of this file.
00001 /**
00002  * @file ccn_buf_decoder.c
00003  * @brief Support for Interest and ContentObject decoding.
00004  * 
00005  * Part of the CCNx C Library.
00006  *
00007  * Copyright (C) 2008, 2009, 2010 Palo Alto Research Center, Inc.
00008  *
00009  * This library is free software; you can redistribute it and/or modify it
00010  * under the terms of the GNU Lesser General Public License version 2.1
00011  * as published by the Free Software Foundation.
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * Lesser General Public License for more details. You should have received
00016  * a copy of the GNU Lesser General Public License along with this library;
00017  * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
00018  * Fifth Floor, Boston, MA 02110-1301 USA.
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         /* The nest decrements before the closer is consumed */
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  * Parses a ccnb-encoded element expected to contain a UDATA string.
00243  * @param d is the decoder
00244  * @param dtag is the expected dtag value
00245  * @param store - on success, the string value is appended to store,
00246  *        with null termination.
00247  * @returns the offset into the store buffer of the copied value, or -1 for error.
00248  *        If a parse error occurs, d->decoder.state is set to a negative value.
00249  *        If the element is not present, -1 is returned but no parse error
00250  *        is indicated.
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             // XXX - should check for valid utf-8 data.
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  * Parses a ccnb-encoded name
00283  * @param d is the decoder
00284  * @param components may be NULL, otherwise is filled in with the 
00285  *        Component boundary offsets
00286  * @returns the number of Components in the Name, or -1 if there is an error.
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  * Parse a potentially large non-negative integer.
00425  *
00426  * @returns 0 for success, and the value is place in *result; for an error
00427  * a negative value is returned and *result is unchanged.
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         /* New-style binary timestamp, 12-bit fraction */
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         /* This is for some temporary back-compatibility */
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             /* We need to have the component offsets. */
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         /* optional MinSuffixComponents, MaxSuffixComponents */
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         /* optional PublisherID */
00610         res = ccn_parse_PublisherID(d, interest);
00611         /* optional Exclude element */
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         /* optional ChildSelector */
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         /* optional AnswerOriginKind */
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         /* optional Scope */
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         /* optional InterestLifetime */
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         /* optional Nonce */
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         /* Allow for no experimental stuff */
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 
Generated on Fri May 13 16:27:02 2011 for Content-Centric Networking in C by  doxygen 1.6.3