Пример #1
0
int 
handle_ccn_content_obj(unsigned char **buf, int *len, int offset, FILE *stream){
    int num, typ;
    if(dehead(buf, len, &num, &typ)) return -1;
    print_offset(offset); printf("<CONTENTOBJ>\n");
    while(typ != 2){
        dehead(buf, len, &num, &typ);
    }
    while(1)
    {
        switch(num)
        {
            case CCN_DTAG_NAME:
                handle_ccn_name(buf, len, offset+4, stream);
                break;
            case CCN_DTAG_SIGNATURE:
                handle_ccn_signature(buf, len, offset+4, stream);
                break;
            case CCN_DTAG_CONTENT:
                handle_ccn_content(buf, len, offset+4, stream);
                break;
            default:
                goto Bail;
                break;
        }
        if(dehead(buf, len, &num, &typ)) break;
    }
    Bail:
    print_offset(offset); printf("</CONTENTOBJ>\n");
    return 0;
}
Пример #2
0
int 
handle_ccn_name(unsigned char **buf, int *len, int offset, FILE *stream){
    int num, typ, i;
    if(dehead(buf, len, &num, &typ)) return -1;
    print_offset(offset); printf("<NAME>\n");
    
    for(i = 0; i < 3; ++i)
    {
        if(num != CCN_DTAG_COMPONENT) return -1;
                handle_ccn_component_content(buf, len, offset+4, stream);
        if(dehead(buf, len, &num, &typ)) return -1;
        
    }
    print_offset(offset); printf("</NAME>\n");
    return 0;
}
Пример #3
0
int
handle_ccn_debugrequest(unsigned char **buf, int *len, int offset, FILE *stream)
{
    int num, typ;
    
    print_offset(offset); printf("<DEBUGREQUEST>\n");
    while(1)
    {
        if(dehead(buf, len, &num, &typ)) goto Bail;
        switch(num)
        {
            case CCN_DTAG_ACTION:
                handle_ccn_action(buf, len, offset+4, stream);
                break;
            case CCNL_DTAG_DEBUGACTION:
                handle_ccn_debugaction(buf, len, offset+4, stream);
                break;
            default:
                goto Bail;
        }
    }
    Bail:
    print_offset(offset); printf("</DEBUGREQUEST>\n");
    return 0;
}
Пример #4
0
int 
handle_ccn_debugreply(unsigned char **buf, int *len, int offset, FILE *stream)
{
    int num, typ;
   
    print_offset(offset); printf("<DEBUGREPLY>\n");
    
    while(1)
    {
        if(dehead(buf, len, &num, &typ)) return -1;
        switch(num)
        {
            case CCNL_DTAG_INTERFACE:
                handle_ccn_debugreply_content(buf, len, offset+4, "INTERFACE", stream);
                break;
            case CCN_DTAG_FACEINSTANCE:
                handle_ccn_debugreply_content(buf, len, offset+4, "FACEINSTANCE", stream);
                break;
            case CCN_DTAG_FWDINGENTRY:
                handle_ccn_debugreply_content(buf, len, offset+4, "FWDINGENTRY", stream);
                break;
            case CCN_DTAG_INTEREST:
                handle_ccn_debugreply_content(buf, len, offset+4, "INTEREST", stream);
                break;
            case CCN_DTAG_CONTENT:
                handle_ccn_debugreply_content(buf, len, offset+4, "CONTENT", stream);
                break;
            default:
                goto Bail;
        }
    }
    Bail:
    print_offset(offset); printf("</DEBUGREPLY>\n"); 
    return 0;
}
Пример #5
0
int 
handle_ccn_content(unsigned char **buf, int *len, int offset, FILE *stream){
    int num, typ;
    if(dehead(buf, len, &num, &typ)) return -1;
    print_offset(offset); printf("<CONTENT>\n");
    while(typ != 2){
        dehead(buf, len, &num, &typ);
    }
    while(1)
    {
        switch(num)
        {
            case CCN_DTAG_NAME:
                handle_ccn_name(buf, len, offset+4, stream);
                break;
            case CCN_DTAG_INTEREST:
                break;
            case CCNL_DTAG_DEBUGREQUEST:
                handle_ccn_debugrequest(buf, len, offset+4, stream);
                break;
            case CCNL_DTAG_DEBUGREPLY:
                handle_ccn_debugreply(buf, len, offset+4, stream);
                break;
            case CCN_DTAG_FACEINSTANCE:
                handle_ccn_debugreply_content(buf, len, offset+4, "FACEINSTANCE", stream);
                break;
            case CCNL_DTAG_DEVINSTANCE:
                handle_ccn_debugreply_content(buf, len, offset+4, "DEVINSTANCE", stream);
                break;
            case CCNL_DTAG_PREFIX:
                handle_ccn_debugreply_content(buf, len, offset+4, "PREFIX", stream);
                break;
            case CCN_DTAG_ACTION:
                print_offset(offset + 4); print_tag_content_with_tag(buf, len, "ACTION", stream);
                break;
            default:
                //printf("%i,%i\n", num, typ);
                goto Bail;
                break;
        }
        if(dehead(buf, len, &num, &typ)) break;
    }
    Bail:
    print_offset(offset); printf("</CONTENT>\n");
    return 0;
}
Пример #6
0
int print_tag_content_with_tag(unsigned char **buf, int *len, char *tag, FILE *stream)
{
    int num, typ; 
    printf("<%s>", tag);
    dehead(buf, len, &num, &typ);
    print_tag_content(buf, len, stream);
    printf("</%s>\n", tag);
    return 0;
}
Пример #7
0
int 
handle_ccn_action(unsigned char **buf, int *len, int offset, FILE *stream)
{
    int num, typ;
    if(dehead(buf, len, &num, &typ)) return -1;
    print_offset(offset); printf("<ACTION>");
    print_tag_content(buf,len,stream);
    printf("</ACTION>\n");
    return 0;
}
Пример #8
0
int 
handle_ccn_component_content(unsigned char **buf, int *len, int offset, FILE *stream)
{
    int num, typ;
    print_offset(offset);
    printf("<COMPONENT>");
    if(dehead(buf, len, &num, &typ)) return -1;
    print_tag_content(buf,len,stream);
    printf("</COMPONENT>\n");
    return 0;
}
Пример #9
0
int  
handle_ccn_packet(unsigned char *buf, int len, int offset, FILE *stream){
    
    int num, typ;
    if(dehead(&buf, &len, &num, &typ)) return -1;
    switch(num)
    {
        case CCN_DTAG_CONTENTOBJ:
            return handle_ccn_content_obj(&buf, &len, offset, stream);
            break;
        case CCN_DTAG_INTEREST:
            break;
    }
    return 0;
}
Пример #10
0
static int hunt_for_end(unsigned char **buf, int *len, unsigned char **valptr,
                        int *vallen)
{
    int typ, num;

    while (dehead(buf, len, &num, &typ) == 0) {
        if (num == 0 && typ == 0) {
            return 0;
        }

        if (consume(typ, num, buf, len, valptr, vallen) < 0) {
            return -1;
        }
    }

    return -1;
}
Пример #11
0
int 
handle_ccn_signature(unsigned char **buf, int *buflen, int offset, FILE *stream)
{
   int num, typ, i;
   if(dehead(buf, buflen, &num, &typ)) return -1; 
   if (typ != CCN_TT_BLOB) return 0;
   
   print_offset(offset);
   printf("<SIGNATURE>");
   for(i = 0; i < num; ++i){
       printf("%c",(*buf)[i]);
   }
       
   printf("</SIGNATURE>\n");
   
   *buflen -= (num+1);
   *buf += (num+1);
   
    
    return 0;
}
Пример #12
0
int ccnl_core_RX_datagram(struct ccnl_relay_s *relay, struct ccnl_face_s *from,
                          unsigned char **data, int *datalen)
{
    int rc = 0, num = 0, typ = 0;
    DEBUGMSG(1, "ccnl_core_RX_datagram: %d bytes from face=%p (id=%d.%d)\n",
             *datalen, (void *) from, relay->id, from ? from->faceid : -1);

    while (rc >= 0 && *datalen > 0) {
        if (dehead(data, datalen, &num, &typ) || typ != CCN_TT_DTAG) {
            return -1;
        }

        switch (num) {
            case CCN_DTAG_INTEREST:
                /* no break */

            case CCN_DTAG_CONTENTOBJ:
                rc = ccnl_core_RX_i_or_c(relay, from, data, datalen);
                continue;
#ifdef USE_FRAG

            case CCNL_DTAG_FRAGMENT2012:
                rc = ccnl_frag_RX_frag2012(ccnl_core_RX_datagram, relay, from, data, datalen);
                continue;

            case CCNL_DTAG_FRAGMENT:
                rc = ccnl_frag_RX_CCNx2013(ccnl_core_RX_datagram, relay, from, data, datalen);
                continue;
#endif

            default:
                DEBUGMSG(15, "  unknown datagram type %d\n", num);
                return -1;
        }
    }

    return rc;
}
Пример #13
0
int main()
{
        struct body_s *bod, *out;
        struct buf_s *buf;
        int n = 0,i=0;
        ssize_t len = 0;
        uint16_t cmdid = 0;
        int32_t num=-16;
        struct darray_s *da;
        struct head_s *head;
        
        bod = (struct body_s*)calloc(PACKET_SIZE, sizeof(struct body_s));
        out = (struct body_s*)calloc(1, sizeof(struct body_s));

        printf("boy size:%d\n", sizeof(struct body_s));
        
        printf("num:%lld, zigzag:%lld\n", (int64_t)num, zigzag((int64_t)num));

        head = (struct head_s*)calloc(1, sizeof(struct head_s)); 
        if (head == NULL) return 0;
        
        head->cmdid = 0xF001;
        head->seq = 0x10001;
        head->uid = 0x1000;
        head->aid = 0x0001;

        buf = buf_calloc(1024);
        len = enpacket(head, (u_char*)NULL, 0, 0, NULL, 0, buf);
        printf("packet buf:%p, len:%d\n", buf->buf_pos, (int)buf->buf_len); 
        hexdump((u_char *)buf->buf_pos, buf->buf_len);        
        
        memset(head, 0, sizeof(struct head_s));
        len = dehead(buf, head);
        if (len==-1) {
                printf("errno:%d, errstr:%s\n", errno, strerror(errno));
                exit(1);
        }
        printf("cmdid:%x\n", head->cmdid); 
        switch (head->cmdid){
        case 0xF001:
                //out->a17 = (u_char*)calloc(1,10);
                da = darray_calloc(1, sizeof(*bod));
                
                if (depacket_da(buf, NULL, 0, da) == -1)
                        perror("ERR DEBODY\n");

                printf("da used %d\n",da->da_used);
                body_handler(head, (struct body_s*)da->da_values);

                darray_free(da);
                break;
        default:
                break;
        }
        
        free(bod);
        free(out);

        free(head);
        buf_free(buf);
        
        


}
Пример #14
0
struct ccnl_buf_s *
ccnl_extract_prefix_nonce_ppkd(unsigned char **data, int *datalen, int *scope,
                               int *aok, int *min, int *max, struct ccnl_prefix_s **prefix,
                               struct ccnl_buf_s **nonce, struct ccnl_buf_s **ppkd,
                               unsigned char **content, int *contlen)
{
    unsigned char *start = *data - 2, *cp;
    int num, typ, len;
    struct ccnl_prefix_s *p;
    struct ccnl_buf_s *buf, *n = 0, *pub = 0;
    DEBUGMSG(99, "ccnl_extract_prefix\n");

    p = (struct ccnl_prefix_s *) ccnl_calloc(1, sizeof(struct ccnl_prefix_s));

    if (!p) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        return NULL;
    }

    p->comp = (unsigned char **) ccnl_malloc(
                  CCNL_MAX_NAME_COMP * sizeof(unsigned char **));
    p->complen = (int *) ccnl_malloc(CCNL_MAX_NAME_COMP * sizeof(int));

    if (!p->comp || !p->complen) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        goto Bail;
    }

    while (dehead(data, datalen, &num, &typ) == 0) {
        if (num == 0 && typ == 0) {
            break;    // end
        }

        if (typ == CCN_TT_DTAG) {
            if (num == CCN_DTAG_NAME) {
                while (1) {
                    if (dehead(data, datalen, &num, &typ) != 0) {
                        goto Bail;
                    }

                    if (num == 0 && typ == 0) {
                        break;
                    }

                    if (typ == CCN_TT_DTAG && num == CCN_DTAG_COMPONENT
                        && p->compcnt < CCNL_MAX_NAME_COMP) {
                        if (hunt_for_end(data, datalen, p->comp + p->compcnt,
                                         p->complen + p->compcnt) < 0) {
                            goto Bail;
                        }

                        p->compcnt++;
                    }
                    else {
                        if (consume(typ, num, data, datalen, 0, 0) < 0) {
                            goto Bail;
                        }
                    }
                }

                continue;
            }

            if (num == CCN_DTAG_SCOPE || num == CCN_DTAG_NONCE
                || num == CCN_DTAG_MINSUFFCOMP
                || num == CCN_DTAG_MAXSUFFCOMP
                || num == CCN_DTAG_PUBPUBKDIGEST) {
                if (hunt_for_end(data, datalen, &cp, &len) < 0) {
                    goto Bail;
                }

                if (num == CCN_DTAG_SCOPE && len == 1 && scope) {
                    *scope = isdigit(*cp) && (*cp < '3') ? *cp - '0' : -1;
                }

                if (num == CCN_DTAG_ANSWERORIGKIND && aok) {
                    *aok = data2uint(cp, len);
                }

                if (num == CCN_DTAG_MINSUFFCOMP && min) {
                    *min = data2uint(cp, len);
                }

                if (num == CCN_DTAG_MAXSUFFCOMP && max) {
                    *max = data2uint(cp, len);
                }

                if (num == CCN_DTAG_NONCE && !n) {
                    n = ccnl_buf_new(cp, len);
                }

                if (num == CCN_DTAG_PUBPUBKDIGEST && !pub) {
                    pub = ccnl_buf_new(cp, len);
                }

                if (num == CCN_DTAG_EXCLUDE) {
                    DEBUGMSG(49, "warning: 'exclude' field ignored\n");
                }
                else {
                    continue;
                }
            }

            if (num == CCN_DTAG_CONTENT || num == CCN_DTAG_CONTENTOBJ) {
                if (consume(typ, num, data, datalen, content, contlen) < 0) {
                    goto Bail;
                }

                continue;
            }
        }

        if (consume(typ, num, data, datalen, 0, 0) < 0) {
            goto Bail;
        }
    }

    if (prefix) {
        p->comp[p->compcnt] = NULL;
        *prefix = p;
    }
    else {
        free_prefix(p);
    }

    if (nonce) {
        *nonce = n;
    }
    else {
        ccnl_free(n);
    }

    if (ppkd) {
        *ppkd = pub;
    }
    else {
        ccnl_free(pub);
    }

    buf = ccnl_buf_new(start, *data - start);

    if (!buf) {
        puts("can't get more memory from malloc, dropping ccn msg...");
        goto Bail;
    }

    // carefully rebase ptrs to new buf because of 64bit pointers:
    if (content) {
        *content = buf->data + (*content - start);
    }

    for (num = 0; num < p->compcnt; num++) {
        p->comp[num] = buf->data + (p->comp[num] - start);
    }

    return buf;
Bail:
    free_prefix(p);
    free_2ptr_list(n, pub);
    return NULL;
}
Пример #15
0
int ccnl_frag_RX_CCNx2013(RX_datagram callback, struct ccnl_relay_s *relay,
                          struct ccnl_face_s *from, unsigned char **data, int *datalen)
{
    int rc, num, typ, pdutypelen;
    unsigned char *pdutype = 0;
    struct serialFragPDU_s s;

    DEBUGMSG(99, "ccnl_frag_RX_CCNx2013 (%d bytes)\n", *datalen);
    serialFragPDU_init(&s);

    while (dehead(data, datalen, &num, &typ) == 0) {
        if (num == 0 && typ == 0) {
            break;    /* end */
        }

        if (typ == CCN_TT_DTAG) {
            switch (num) {
                case CCNL_DTAG_FRAG_TYPE:
                    if (hunt_for_end(data, datalen, &pdutype, &pdutypelen)
                        || pdutypelen != 3) {
                        goto Bail;
                    }

                    continue;

                case CCNL_DTAG_FRAG_SEQNR:
                    getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq")
                    ;
                    continue;

                case CCNL_DTAG_FRAG_FLAGS:
                    getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags")
                    ;
                    continue;

                case CCN_DTAG_CONTENT:

                    //		if (frag) /* error: more than one content entry */
                    if (consume(typ, num, data, datalen, &s.content, &s.contlen)
                        < 0) {
                        goto Bail;
                    }

                    continue;

                    /* CCNL extensions: */
                case CCN_DTAG_INTEREST:
                case CCN_DTAG_CONTENTOBJ:
                    rc = ccnl_core_RX_i_or_c(relay, from, data, datalen);

                    if (rc < 0) {
                        return rc;
                    }

                    continue;

                case CCNL_DTAG_FRAG_OLOSS:
                    getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss")
                    ;
                    continue;

                case CCNL_DTAG_FRAG_YSEQN:
                    getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq")
                    ;
                    continue;

                default:
                    break;
            }
        }

        if (consume(typ, num, data, datalen, 0, 0) < 0) {
            goto Bail;
        }
    }

    if (!pdutype || !s.content) {
        /* ||
         (s.HAS&(HAS_FLAGS|HAS_OSEQ)) != (HAS_FLAGS|HAS_OSEQ) ) {
         */
        DEBUGMSG(1, "* incomplete frag\n");
        return 0;
    }

    DEBUGMSG(1, "hop-by-hop\n");

    if (memcmp(pdutype, CCNL_FRAG_TYPE_CCNx2013_VAL, 3) == 0) { /* hop-by-hop */
        if (from) {
            if (!from->frag)
                from->frag = ccnl_frag_new(CCNL_FRAG_CCNx2013,
                                           relay->ifs[from->ifndx].mtu);

            if (from->frag && from->frag->protocol == CCNL_FRAG_CCNx2013) {
                ccnl_frag_RX_serialfragment(callback, relay, from, &s);
            }
            else {
                DEBUGMSG(1, "WRONG FRAG PROTOCOL\n");
            }
        }
        else {
            ccnl_frag_RX_serialfragment(callback, relay, from, &s);
        }
    }

    /*
     * echo "FMTE" | base64 -d | hexdump -v -e '/1 "@x%02x"'| tr @ '\\'; echo
     */
    if (memcmp(pdutype, "\x14\xc4\xc4", 3) == 0) { /* mid-to-end fragment */
        /* not implemented yet */
    }

    DEBUGMSG(1, "mid-to-end fragment\n");

    return 0;
Bail:
    DEBUGMSG(1, "* frag bailing\n");
    return -1;
}
Пример #16
0
int ccnl_frag_RX_frag2012(RX_datagram callback, struct ccnl_relay_s *relay,
                          struct ccnl_face_s *from, unsigned char **data, int *datalen)
{
    int num, typ;
    struct serialFragPDU_s s;
    DEBUGMSG(99, "ccnl_frag_RX_frag2012 (%d bytes)\n", *datalen);

    serialFragPDU_init(&s);

    while (dehead(data, datalen, &num, &typ) == 0) {
        if (num == 0 && typ == 0) {
            break;    /* end */
        }

        if (typ == CCN_TT_DTAG) {
            switch (num) {
                case CCN_DTAG_CONTENT:
                    DEBUGMSG(18, "  frag content\n");

                    //		if (s.content) /* error: more than one content entry */
                    if (consume(typ, num, data, datalen, &s.content, &s.contlen)
                        < 0) {
                        goto Bail;
                    }

                    continue;

                case CCNL_DTAG_FRAG_FLAGS:
                    getNumField(s.flags, s.flagwidth, HAS_FLAGS, "flags")
                    ;
                    continue;

                case CCNL_DTAG_FRAG_SEQNR:
                    getNumField(s.ourseq, s.ourseqwidth, HAS_OSEQ, "ourseq")
                    ;
                    continue;

                case CCNL_DTAG_FRAG_OLOSS:
                    getNumField(s.ourloss, s.ourlosswidth, HAS_OLOS, "ourloss")
                    ;
                    continue;

                case CCNL_DTAG_FRAG_YSEQN:
                    getNumField(s.yourseq, s.yourseqwidth, HAS_YSEQ, "yourseq")
                    ;
                    continue;

                default:
                    break;
            }
        }

        if (consume(typ, num, data, datalen, 0, 0) < 0) {
            goto Bail;
        }
    }

    if (!s.content || s.HAS != 15) {
        DEBUGMSG(1, "* incomplete frag\n");
        return 0;
    }

    if (from) {
        if (!from->frag)
            from->frag = ccnl_frag_new(CCNL_FRAG_SEQUENCED2012,
                                       relay->ifs[from->ifndx].mtu);

        if (from->frag && from->frag->protocol == CCNL_FRAG_SEQUENCED2012) {
            ccnl_frag_RX_serialfragment(callback, relay, from, &s);
        }
        else {
            DEBUGMSG(1, "WRONG FRAG PROTOCOL\n");
        }
    }
    else {
        ccnl_frag_RX_serialfragment(callback, relay, from, &s);
    }

    return 0;
Bail:
    DEBUGMSG(1, "* frag bailing\n");
    return -1;
}
Пример #17
0
int
handle_ccn_debugreply_content(unsigned char **buf, int *len, int offset, char* tag, FILE *stream)
{
    int num, typ;
    print_offset(offset); printf("<%s>\n", tag);
    while(1)
    {
        if(dehead(buf, len, &num, &typ)) return -1;
        switch(num)
        {
            case CCNL_DTAG_IFNDX:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "IFNDX", stream);
               break;
            case CCNL_DTAG_ADDRESS:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "ADDRESS", stream);
               break;
            case CCNL_DTAG_ETH:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "ETH", stream);
               break;
            case CCNL_DTAG_SOCK:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "SOCK", stream);
               break;
            case CCNL_DTAG_REFLECT:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "REFLECT", stream);
               break;
            case CCN_DTAG_FACEID:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "FACEID", stream);
               break;   
            case CCNL_DTAG_NEXT:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "NEXT", stream);
               break;
            case CCNL_DTAG_PREV:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "PREV", stream);
               break;
            case CCNL_DTAG_FWD:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "FWD", stream);
               break;
            case CCNL_DTAG_FACEFLAGS:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "FACEFLAGS", stream);
               break;
            case CCNL_DTAG_IP:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "IP", stream);
               break;
            case CCNL_DTAG_UNIX:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "UNIX", stream);
               break;
            case CCNL_DTAG_PEER:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "PEER", stream);
               break;
            case CCNL_DTAG_FACE:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "FACE", stream);
               break;
            case CCNL_DTAG_INTERESTPTR:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "INTERESTPTR", stream);
               break;
            case CCNL_DTAG_LAST:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "LAST", stream);
               break;
            case CCNL_DTAG_MIN:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "MIN", stream);
               break;
            case CCNL_DTAG_MAX:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "MAX", stream);
               break;
            case CCNL_DTAG_RETRIES:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "RETRIES", stream);
               break;
            case CCNL_DTAG_PUBLISHER:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "PUBLISHER", stream);
               break;
            case CCNL_DTAG_CONTENTPTR:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "CONTENTPTR", stream);
               break;
            case CCNL_DTAG_LASTUSE:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "LASTUSE", stream);
               break;
            case CCNL_DTAG_SERVEDCTN:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "SERVEDCTN", stream);
               break;
            case CCN_DTAG_ACTION:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "ACTION", stream);
               break;
            case CCNL_DTAG_MACSRC:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "MACSRC", stream);
               break;
            case CCNL_DTAG_IP4SRC:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "IP4SRC", stream);
               break;
            case CCN_DTAG_IPPROTO:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "IPPROTO", stream);
               break;
            case CCN_DTAG_HOST:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "HOST", stream);
               break;
            case CCN_DTAG_PORT:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "PORT", stream);
               break;
            case CCNL_DTAG_FRAG:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "FRAG", stream);
               break;
            case CCNL_DTAG_MTU:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "MTU", stream);
               break;
            case CCNL_DTAG_DEVFLAGS:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "DEVFLAGS", stream);
               break;
            case CCNL_DTAG_DEVNAME:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "DEVNAME", stream);
               break;
            case CCN_DTAG_NAME:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "NAME", stream);
               break;
            case CCNL_DTAG_PREFIX:
               print_offset(offset+4); 
               print_tag_content_with_tag(buf, len, "PREFIX", stream);
               break;
            default: 
              goto Bail;
        }
    }
    Bail:
    print_offset(offset); printf("</%s>\n", tag);
    return 0;
}