u_int
juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p)
{
        struct juniper_l2info_t l2info;
        struct juniper_services_header {
            u_int8_t svc_id;
            u_int8_t flags_len;
            u_int8_t svc_set_id[2];
            u_int8_t dir_iif[4];
        };
        const struct juniper_services_header *sh;

        l2info.pictype = DLT_JUNIPER_SERVICES;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        sh = (struct juniper_services_header *)p;

        if (eflag)
            printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
                   sh->svc_id,
                   sh->flags_len,
                   EXTRACT_16BITS(&sh->svc_set_id),
                   EXTRACT_24BITS(&sh->dir_iif[1]));

        
        ip_heuristic_guess(p, l2info.length);

        return l2info.header_len;
}
Exemple #2
0
u_int
juniper_services_print(const struct pcap_pkthdr *h, packetbody_t p)
{
        struct juniper_l2info_t l2info;
        struct juniper_services_header {
            u_int8_t svc_id;
            u_int8_t flags_len;
            u_int8_t svc_set_id[2];
            u_int8_t dir_iif[4];
        };
        __capability const struct juniper_services_header *sh;

        l2info.pictype = DLT_JUNIPER_SERVICES;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        sh = (__capability const struct juniper_services_header *)p;

        if (eflag)
            printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
                   sh->svc_id,
                   sh->flags_len,
                   EXTRACT_16BITS(&sh->svc_set_id),
                   EXTRACT_24BITS(&sh->dir_iif[1]));

        /* no proto field - lets guess by first byte of IP header*/
        ip_heuristic_guess(p, l2info.length);

        return l2info.header_len;
}
u_int
juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p)
{
        struct juniper_l2info_t l2info;
        struct juniper_monitor_header {
            u_int8_t pkt_type;
            u_int8_t padding;
            u_int8_t iif[2];
            u_int8_t service_id[4];
        };
        const struct juniper_monitor_header *mh;

        l2info.pictype = DLT_JUNIPER_MONITOR;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        mh = (struct juniper_monitor_header *)p;

        if (eflag)
            printf("service-id %u, iif %u, pkt-type %u: ",
                   EXTRACT_32BITS(&mh->service_id),
                   EXTRACT_16BITS(&mh->iif),
                   mh->pkt_type);

        
        ip_heuristic_guess(p, l2info.length);

        return l2info.header_len;
}
Exemple #4
0
u_int
juniper_monitor_print(const struct pcap_pkthdr *h, packetbody_t p)
{
        struct juniper_l2info_t l2info;
        struct juniper_monitor_header {
            u_int8_t pkt_type;
            u_int8_t padding;
            u_int8_t iif[2];
            u_int8_t service_id[4];
        };
        __capability const struct juniper_monitor_header *mh;

        l2info.pictype = DLT_JUNIPER_MONITOR;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        mh = (__capability const struct juniper_monitor_header *)p;

        if (eflag)
            printf("service-id %u, iif %u, pkt-type %u: ",
                   EXTRACT_32BITS(&mh->service_id),
                   EXTRACT_16BITS(&mh->iif),
                   mh->pkt_type);

        /* no proto field - lets guess by first byte of IP header*/
        ip_heuristic_guess(p, l2info.length);

        return l2info.header_len;
}
Exemple #5
0
u_int
juniper_services_print(netdissect_options *ndo,
                       const struct pcap_pkthdr *h, register const u_char *p)
{
        struct juniper_l2info_t l2info;
        struct juniper_services_header {
            uint8_t svc_id;
            uint8_t flags_len;
            uint8_t svc_set_id[2];
            uint8_t dir_iif[4];
        };
        const struct juniper_services_header *sh;

        l2info.pictype = DLT_JUNIPER_SERVICES;
        if (juniper_parse_header(ndo, p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        sh = (struct juniper_services_header *)p;

        if (ndo->ndo_eflag)
            ND_PRINT((ndo, "service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
                   sh->svc_id,
                   sh->flags_len,
                   EXTRACT_16BITS(&sh->svc_set_id),
                   EXTRACT_24BITS(&sh->dir_iif[1])));

        /* no proto field - lets guess by first byte of IP header*/
        ip_heuristic_guess (ndo, p, l2info.length);

        return l2info.header_len;
}
Exemple #6
0
u_int
juniper_monitor_print(netdissect_options *ndo,
                      const struct pcap_pkthdr *h, register const u_char *p)
{
        struct juniper_l2info_t l2info;
        struct juniper_monitor_header {
            uint8_t pkt_type;
            uint8_t padding;
            uint8_t iif[2];
            uint8_t service_id[4];
        };
        const struct juniper_monitor_header *mh;

        l2info.pictype = DLT_JUNIPER_MONITOR;
        if (juniper_parse_header(ndo, p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;
        mh = (struct juniper_monitor_header *)p;

        if (ndo->ndo_eflag)
            ND_PRINT((ndo, "service-id %u, iif %u, pkt-type %u: ",
                   EXTRACT_32BITS(&mh->service_id),
                   EXTRACT_16BITS(&mh->iif),
                   mh->pkt_type));

        /* no proto field - lets guess by first byte of IP header*/
        ip_heuristic_guess (ndo, p, l2info.length);

        return l2info.header_len;
}
Exemple #7
0
u_int
juniper_atm2_print(netdissect_options *ndo,
                   const struct pcap_pkthdr *h, register const u_char *p)
{
        uint16_t extracted_ethertype;

        struct juniper_l2info_t l2info;

        l2info.pictype = DLT_JUNIPER_ATM2;
        if (juniper_parse_header(ndo, p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;

        if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */
            oam_print(ndo, p, l2info.length, ATM_OAM_NOHEC);
            return l2info.header_len;
        }

        if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
            EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */

            if (llc_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL,
                          &extracted_ethertype) != 0)
                return l2info.header_len;
        }

        if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */
            (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) {
            ether_print(ndo, p, l2info.length, l2info.caplen, NULL, NULL);
            return l2info.header_len;
        }

        if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
            isoclns_print(ndo, p + 1, l2info.length - 1, l2info.caplen - 1);
            /* FIXME check if frame was recognized */
            return l2info.header_len;
        }

        if(juniper_ppp_heuristic_guess(ndo, p, l2info.length) != 0) /* PPPoA vcmux encaps ? */
            return l2info.header_len;

        if (ip_heuristic_guess(ndo, p, l2info.length) != 0) /* last try - vcmux encaps ? */
            return l2info.header_len;

	return l2info.header_len;
}
u_int
juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p)
{
        u_int16_t extracted_ethertype;

        struct juniper_l2info_t l2info;

        l2info.pictype = DLT_JUNIPER_ATM2;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;

        if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { 
            oam_print(p,l2info.length,ATM_OAM_NOHEC);
            return l2info.header_len;
        }

        if (EXTRACT_24BITS(p) == 0xfefe03 || 
            EXTRACT_24BITS(p) == 0xaaaa03) { 

            if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
                          &extracted_ethertype) != 0)
                return l2info.header_len;
        }

        if (l2info.direction != JUNIPER_BPF_PKT_IN && 
            (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) {
            ether_print(p, l2info.length, l2info.caplen);
            return l2info.header_len;
        }

        if (p[0] == 0x03) { 
            isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
            
            return l2info.header_len;
        }

        if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) 
            return l2info.header_len;

        if(ip_heuristic_guess(p, l2info.length) != 0) 
            return l2info.header_len;

	return l2info.header_len;
}
u_int
juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p)
{
        u_int16_t extracted_ethertype;

        struct juniper_l2info_t l2info;

        l2info.pictype = DLT_JUNIPER_ATM1;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;

        if (l2info.cookie[0] == 0x80) { 
            oam_print(p,l2info.length,ATM_OAM_NOHEC);
            return l2info.header_len;
        }

        if (EXTRACT_24BITS(p) == 0xfefe03 || 
            EXTRACT_24BITS(p) == 0xaaaa03) { 

            if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
                          &extracted_ethertype) != 0)
                return l2info.header_len;
        }

        if (p[0] == 0x03) { 
            isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
            
            return l2info.header_len;
        }

        if(ip_heuristic_guess(p, l2info.length) != 0) 
            return l2info.header_len;

	return l2info.header_len;
}
u_int
juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p)
{
        u_int16_t extracted_ethertype;

        struct juniper_l2info_t l2info;

        l2info.pictype = DLT_JUNIPER_ATM1;
        if(juniper_parse_header(p, h, &l2info) == 0)
            return l2info.header_len;

        p+=l2info.header_len;

        if (l2info.cookie[0] == 0x80) { /* OAM cell ? */
            oam_print(p,l2info.length,ATM_OAM_NOHEC);
            return l2info.header_len;
        }

        if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
            EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */

            if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
                          &extracted_ethertype) != 0)
                return l2info.header_len;
        }

        if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
            isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
            /* FIXME check if frame was recognized */
            return l2info.header_len;
        }

        if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */
            return l2info.header_len;

	return l2info.header_len;
}
static int
juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {

    struct juniper_cookie_table_t *lp = juniper_cookie_table;
    u_int idx, offset;
#ifdef DLT_JUNIPER_ATM2
    u_int32_t control_word;
#endif

    l2info->header_len = 0;
    l2info->cookie_len = 0;
    l2info->proto = 0;


    l2info->length = h->len;
    l2info->caplen = h->caplen;
    l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
    
    TCHECK2(p[0],4);
    if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { 
        printf("no magic-number found!");
        return 0;
    } 

    if (eflag) 
        printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));

    
    if ((p[3] & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
        offset = 6 + EXTRACT_16BITS(p+4);
        if (eflag>1)
            printf("ext-len %u, ",EXTRACT_16BITS(p+4));
    } else
        offset = 4;

    if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {            
        if (eflag)
            printf("no-L2-hdr, ");

        TCHECK2(p[offset+4],1);
        if(ip_heuristic_guess(p+offset+4,l2info->length-(offset+4)) == 0)
            printf("no IP-hdr found!");

        l2info->header_len=offset+4;
        return 0; 
        
    }
    l2info->header_len = offset;
    p+=l2info->header_len;
    l2info->length -= l2info->header_len;
    l2info->caplen -= l2info->header_len;

    
    while (lp->s != NULL) {
        if (lp->pictype == l2info->pictype) {

            l2info->cookie_len += lp->cookie_len;

            switch (p[0]) {
            case LS_COOKIE_ID:
                l2info->cookie_type = LS_COOKIE_ID;
                l2info->cookie_len += 2;
                break;
            case AS_COOKIE_ID:
                l2info->cookie_type = AS_COOKIE_ID;
                l2info->cookie_len = 8;
                break;
            
            default:
                l2info->bundle = l2info->cookie[0];
                break;
            }


#ifdef DLT_JUNIPER_MFR
            
            if (l2info->pictype == DLT_JUNIPER_MFR &&
                (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
                l2info->cookie_len = 0;
            }
#endif

            l2info->header_len += l2info->cookie_len;
            l2info->length -= l2info->cookie_len;
            l2info->caplen -= l2info->cookie_len;

            if (eflag)
                printf("%s-PIC, cookie-len %u",
                       lp->s,
                       l2info->cookie_len);

            if (l2info->cookie_len > 0) {
                TCHECK2(p[0],l2info->cookie_len);
                if (eflag)
                    printf(", cookie 0x");
                for (idx = 0; idx < l2info->cookie_len; idx++) {
                    l2info->cookie[idx] = p[idx]; 
                    if (eflag) printf("%02x",p[idx]);
                }
            }

            if (eflag) printf(": "); 
            

            l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 
            break;
        }
        ++lp;
    }
    p+=l2info->cookie_len;

    
    switch(l2info->pictype) {
#ifdef DLT_JUNIPER_MLPPP
    case DLT_JUNIPER_MLPPP:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;            
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MLFR
    case DLT_JUNIPER_MLFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MFR
    case DLT_JUNIPER_MFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM2
    case DLT_JUNIPER_ATM2:
        TCHECK2(p[0],4);
        
        if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
            control_word = EXTRACT_32BITS(p);
            
            switch(control_word) {
            case 0: 
            case 0x08000000: 
            case 0x08380000: 
                l2info->header_len += 4;
                break;
            default:
                break;
            }
            
            if (eflag)
                printf("control-word 0x%08x ", control_word);
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM1
    case DLT_JUNIPER_ATM1:
        break;
#endif
#ifdef DLT_JUNIPER_PPP
    case DLT_JUNIPER_PPP:
        break;
#endif
#ifdef DLT_JUNIPER_CHDLC
    case DLT_JUNIPER_CHDLC:
        break;
#endif
#ifdef DLT_JUNIPER_ETHER
    case DLT_JUNIPER_ETHER:
        break;
#endif
#ifdef DLT_JUNIPER_FRELAY
    case DLT_JUNIPER_FRELAY:
        break;
#endif

    default:
        printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
        break;
    }
    
    if (eflag > 1)
        printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);

    return 1; 
 trunc:
    printf("[|juniper_hdr], length %u",h->len);
    return 0;
}
static int
juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {

    struct juniper_cookie_table_t *lp = juniper_cookie_table;
    u_int idx, offset;
#ifdef DLT_JUNIPER_ATM2
    u_int32_t control_word;
#endif

    l2info->header_len = 0;
    l2info->cookie_len = 0;
    l2info->proto = 0;


    l2info->length = h->len;
    l2info->caplen = h->caplen;
    l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
    
    TCHECK2(p[0],4);
    if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
        printf("no magic-number found!");
        return 0;
    } 

    if (eflag) /* print direction */
        printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));

    /* extensions present ?  - calculate how much bytes to skip */
    if ((p[3] & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
        offset = 6 + EXTRACT_16BITS(p+4);
        if (eflag>1)
            printf("ext-len %u, ",EXTRACT_16BITS(p+4));
    } else
        offset = 4;

    if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {            
        if (eflag)
            printf("no-L2-hdr, ");

        /* there is no link-layer present -
         * perform the v4/v6 heuristics
         * to figure out what it is
         */
        TCHECK2(p[offset+4],1);
        if(ip_heuristic_guess(p+offset+4,l2info->length-(offset+4)) == 0)
            printf("no IP-hdr found!");

        l2info->header_len=offset+4;
        return 0; /* stop parsing the output further */
        
    }
    l2info->header_len = offset;
    p+=l2info->header_len;
    l2info->length -= l2info->header_len;
    l2info->caplen -= l2info->header_len;

    /* search through the cookie table and copy values matching for our PIC type */
    while (lp->s != NULL) {
        if (lp->pictype == l2info->pictype) {

            l2info->cookie_len += lp->cookie_len;

            switch (p[0]) {
            case LS_COOKIE_ID:
                l2info->cookie_type = LS_COOKIE_ID;
                l2info->cookie_len += 2;
                break;
            case AS_COOKIE_ID:
                l2info->cookie_type = AS_COOKIE_ID;
                l2info->cookie_len = 8;
                break;
            
            default:
                l2info->bundle = l2info->cookie[0];
                break;
            }


#ifdef DLT_JUNIPER_MFR
            /* MFR child links don't carry cookies */
            if (l2info->pictype == DLT_JUNIPER_MFR &&
                (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
                l2info->cookie_len = 0;
            }
#endif

            l2info->header_len += l2info->cookie_len;
            l2info->length -= l2info->cookie_len;
            l2info->caplen -= l2info->cookie_len;

            if (eflag)
                printf("%s-PIC, cookie-len %u",
                       lp->s,
                       l2info->cookie_len);

            if (l2info->cookie_len > 0) {
                TCHECK2(p[0],l2info->cookie_len);
                if (eflag)
                    printf(", cookie 0x");
                for (idx = 0; idx < l2info->cookie_len; idx++) {
                    l2info->cookie[idx] = p[idx]; /* copy cookie data */
                    if (eflag) printf("%02x",p[idx]);
                }
            }

            if (eflag) printf(": "); /* print demarc b/w L2/L3*/
            

            l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 
            break;
        }
        ++lp;
    }
    p+=l2info->cookie_len;

    /* DLT_ specific parsing */
    switch(l2info->pictype) {
#ifdef DLT_JUNIPER_MLPPP
    case DLT_JUNIPER_MLPPP:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;            
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MLFR
    case DLT_JUNIPER_MLFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MFR
    case DLT_JUNIPER_MFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM2
    case DLT_JUNIPER_ATM2:
        TCHECK2(p[0],4);
        /* ATM cell relay control word present ? */
        if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
            control_word = EXTRACT_32BITS(p);
            /* some control word heuristics */
            switch(control_word) {
            case 0: /* zero control word */
            case 0x08000000: /* < JUNOS 7.4 control-word */
            case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
                l2info->header_len += 4;
                break;
            default:
                break;
            }
            
            if (eflag)
                printf("control-word 0x%08x ", control_word);
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM1
    case DLT_JUNIPER_ATM1:
        break;
#endif
#ifdef DLT_JUNIPER_PPP
    case DLT_JUNIPER_PPP:
        break;
#endif
#ifdef DLT_JUNIPER_CHDLC
    case DLT_JUNIPER_CHDLC:
        break;
#endif
#ifdef DLT_JUNIPER_ETHER
    case DLT_JUNIPER_ETHER:
        break;
#endif
#ifdef DLT_JUNIPER_FRELAY
    case DLT_JUNIPER_FRELAY:
        break;
#endif

    default:
        printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
        break;
    }
    
    if (eflag > 1)
        printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);

    return 1; /* everything went ok so far. continue parsing */
 trunc:
    printf("[|juniper_hdr], length %u",h->len);
    return 0;
}
Exemple #13
0
static int
juniper_parse_header (packetbody_t p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {

    struct juniper_cookie_table_t *lp = juniper_cookie_table;
    u_int idx, jnx_ext_len, jnx_header_len = 0;
    u_int8_t tlv_type,tlv_len;
    u_int32_t control_word;
    int tlv_value;
    packetbody_t tptr;


    l2info->header_len = 0;
    l2info->cookie_len = 0;
    l2info->proto = 0;


    l2info->length = h->len;
    l2info->caplen = h->caplen;
    PACKET_HAS_SPACE_OR_TRUNC(p,4);
    l2info->flags = p[3];
    l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
    
    if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
        printf("no magic-number found!");
        return 0;
    } 

    if (eflag) /* print direction */
        printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));

    /* magic number + flags */
    jnx_header_len = 4;

    if (vflag>1)
        printf("\n\tJuniper PCAP Flags [%s]",
               bittok2str(jnx_flag_values, "none", l2info->flags));

    /* extensions present ?  - calculate how much bytes to skip */
    if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {

        tptr = p+jnx_header_len;

        /* ok to read extension length ? */
        PACKET_HAS_SPACE_OR_TRUNC(tptr, 2);
        jnx_ext_len = EXTRACT_16BITS(tptr);
        jnx_header_len += 2;
        tptr +=2;
        
        /* nail up the total length -
         * just in case something goes wrong
         * with TLV parsing */
        jnx_header_len += jnx_ext_len;
        
        if (vflag>1)
            printf(", PCAP Extension(s) total length %u",
                   jnx_ext_len);
        
        PACKET_HAS_SPACE_OR_TRUNC(tptr, jnx_ext_len);
        while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) {
            tlv_type = *(tptr++);
            tlv_len = *(tptr++);
            tlv_value = 0;
            
            /* sanity check */
            if (tlv_type == 0 || tlv_len == 0)
                break;
            
            if (vflag>1)
                printf("\n\t  %s Extension TLV #%u, length %u, value ",
                       tok2str(jnx_ext_tlv_values,"Unknown",tlv_type),
                       tlv_type,
                       tlv_len);
            
            tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len);
            switch (tlv_type) {
            case JUNIPER_EXT_TLV_IFD_NAME:
                /* FIXME */
                break;
            case JUNIPER_EXT_TLV_IFD_MEDIATYPE:
            case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE:
                if (tlv_value != -1) {
                    if (vflag>1)
                        printf("%s (%u)",
                               tok2str(juniper_ifmt_values, "Unknown", tlv_value),
                               tlv_value);
                }
                break;
            case JUNIPER_EXT_TLV_IFL_ENCAPS:
            case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS:
                if (tlv_value != -1) {
                    if (vflag>1)
                        printf("%s (%u)",
                               tok2str(juniper_ifle_values, "Unknown", tlv_value),
                               tlv_value);
                }
                break;
            case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */
            case JUNIPER_EXT_TLV_IFL_UNIT:
            case JUNIPER_EXT_TLV_IFD_IDX:
            default:
                if (tlv_value != -1) {
                    if (vflag>1)
                        printf("%u",tlv_value);
                }
                break;
            }
            
            tptr+=tlv_len;
            jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD;
        }
        
        if (vflag>1)
            printf("\n\t-----original packet-----\n\t");
    } 
    
    if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {            
        if (eflag)
            printf("no-L2-hdr, ");

        /* there is no link-layer present -
         * perform the v4/v6 heuristics
         * to figure out what it is
         */
        PACKET_HAS_SPACE_OR_TRUNC(p, (jnx_header_len+4) + 1);
        if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0)
            printf("no IP-hdr found!");

        l2info->header_len=jnx_header_len+4;
        return 0; /* stop parsing the output further */
        
    }
    l2info->header_len = jnx_header_len;
    p+=l2info->header_len;
    l2info->length -= l2info->header_len;
    l2info->caplen -= l2info->header_len;

    /* search through the cookie table and copy values matching for our PIC type */
    while (lp->s != NULL) {
        if (lp->pictype == l2info->pictype) {

            l2info->cookie_len += lp->cookie_len;

            switch (p[0]) {
            case LS_COOKIE_ID:
                l2info->cookie_type = LS_COOKIE_ID;
                l2info->cookie_len += 2;
                break;
            case AS_COOKIE_ID:
                l2info->cookie_type = AS_COOKIE_ID;
                l2info->cookie_len = 8;
                break;
            
            default:
                l2info->bundle = l2info->cookie[0];
                break;
            }


#ifdef DLT_JUNIPER_MFR
            /* MFR child links don't carry cookies */
            if (l2info->pictype == DLT_JUNIPER_MFR &&
                (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
                l2info->cookie_len = 0;
            }
#endif

            l2info->header_len += l2info->cookie_len;
            l2info->length -= l2info->cookie_len;
            l2info->caplen -= l2info->cookie_len;

            if (eflag)
                printf("%s-PIC, cookie-len %u",
                       lp->s,
                       l2info->cookie_len);

            if (l2info->cookie_len > 0) {
                PACKET_HAS_SPACE_OR_TRUNC(p,l2info->cookie_len);
                if (eflag)
                    printf(", cookie 0x");
                for (idx = 0; idx < l2info->cookie_len; idx++) {
                    l2info->cookie[idx] = p[idx]; /* copy cookie data */
                    if (eflag) printf("%02x",p[idx]);
                }
            }

            if (eflag) printf(": "); /* print demarc b/w L2/L3*/
            

            l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 
            break;
        }
        ++lp;
    }
    p+=l2info->cookie_len;

    /* DLT_ specific parsing */
    switch(l2info->pictype) {
#ifdef DLT_JUNIPER_MLPPP
    case DLT_JUNIPER_MLPPP:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;            
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MLFR
    case DLT_JUNIPER_MLFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_MFR
    case DLT_JUNIPER_MFR:
        switch (l2info->cookie_type) {
        case LS_COOKIE_ID:
            l2info->bundle = l2info->cookie[1];
            l2info->proto = EXTRACT_16BITS(p);        
            l2info->header_len += 2;
            l2info->length -= 2;
            l2info->caplen -= 2;
            break;
        case AS_COOKIE_ID:
            l2info->bundle = (EXTRACT_16BITS(cheri_ptr(&l2info->cookie[6], 2))>>3)&0xfff;
            l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
            break;
        default:
            l2info->bundle = l2info->cookie[0];
            break;
        }
        break;
#endif
#ifdef DLT_JUNIPER_ATM2
    case DLT_JUNIPER_ATM2:
        PACKET_HAS_SPACE_OR_TRUNC(p,4);
        /* ATM cell relay control word present ? */
        if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
            control_word = EXTRACT_32BITS(p);
            /* some control word heuristics */
            switch(control_word) {
            case 0: /* zero control word */
            case 0x08000000: /* < JUNOS 7.4 control-word */
            case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
                l2info->header_len += 4;
                break;
            default:
                break;
            }
            
            if (eflag)
                printf("control-word 0x%08x ", control_word);
        }
        break;
#endif
#ifdef DLT_JUNIPER_GGSN
    case DLT_JUNIPER_GGSN:
        break;
#endif
#ifdef DLT_JUNIPER_ATM1
    case DLT_JUNIPER_ATM1:
        break;
#endif
#ifdef DLT_JUNIPER_PPP
    case DLT_JUNIPER_PPP:
        break;
#endif
#ifdef DLT_JUNIPER_CHDLC
    case DLT_JUNIPER_CHDLC:
        break;
#endif
#ifdef DLT_JUNIPER_ETHER
    case DLT_JUNIPER_ETHER:
        break;
#endif
#ifdef DLT_JUNIPER_FRELAY
    case DLT_JUNIPER_FRELAY:
        break;
#endif

    default:
        printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
        break;
    }
    
    if (eflag > 1)
        printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);

    return 1; /* everything went ok so far. continue parsing */
 trunc:
    printf("[|juniper_hdr], length %u",h->len);
    return 0;
}