#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.11 2005-04-25 18:53:27 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.16 2005-05-17 09:37:30 hannes Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "ppp.h"
#include "llc.h"
#include "nlpid.h"
+#include "ethertype.h"
#define JUNIPER_BPF_OUT 0 /* Outgoing packet */
#define JUNIPER_BPF_IN 1 /* Incoming packet */
#define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */
#define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
+#define JUNIPER_LSQ_L3_PROTO_SHIFT 4
+#define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT) /* must be 0! */
+#define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+
static struct tok juniper_direction_values[] = {
{ JUNIPER_BPF_IN, "In"},
{ JUNIPER_BPF_OUT, "Out"},
{ 0, NULL}
};
-/* FIXME change enums to real DLT_s */
-enum {
- JUNIPER_ATM1,
- JUNIPER_ATM2,
- JUNIPER_MLPPP,
- JUNIPER_MLFR,
- JUNIPER_MFR
-};
-
-enum {
- DEFAULT,
- LS_COOKIE
-};
-
struct juniper_cookie_table_t {
u_int32_t pictype; /* pic type */
u_int8_t cookie_len; /* cookie len */
};
static struct juniper_cookie_table_t juniper_cookie_table[] = {
- { JUNIPER_ATM1, 4, "ATM1"},
- { JUNIPER_ATM2, 8, "ATM2"},
- { JUNIPER_MLPPP, 2, "MLPPP"},
- { JUNIPER_MLFR, 2, "MLFR"},
- { JUNIPER_MFR, 4, "MFR"},
+ { DLT_JUNIPER_ATM1, 4, "ATM1"},
+ { DLT_JUNIPER_ATM2, 8, "ATM2"},
+ { DLT_JUNIPER_MLPPP, 2, "MLPPP"},
+ { DLT_JUNIPER_MLFR, 2, "MLFR"},
+ { DLT_JUNIPER_MFR, 4, "MFR"},
+ { DLT_JUNIPER_PPPOE, 0, "PPPoE"},
+ { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"},
};
struct juniper_l2info_t {
};
#define LS_COOKIE_ID 0x54
+#define AS_COOKIE_ID 0x47
#define LS_MLFR_COOKIE_LEN 4
#define ML_MLFR_COOKIE_LEN 2
#define LS_MFR_COOKIE_LEN 6
int juniper_ppp_heuristic_guess(register const u_char *, u_int);
static int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *);
+u_int
+juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_PPPOE;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ /* this DLT contains nothing but raw ethernet frames */
+ ether_print(p, l2info.length, l2info.caplen);
+ return l2info.header_len;
+}
+
+u_int
+juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+ u_int16_t extracted_ethertype;
+
+ l2info.pictype = DLT_JUNIPER_PPPOE_ATM;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+
+ extracted_ethertype = EXTRACT_16BITS(p);
+ /* this DLT contains nothing but raw PPPoE frames,
+ * prepended with a type field*/
+ if (ether_encap_print(extracted_ethertype,
+ p+ETHERTYPE_LEN,
+ l2info.length-ETHERTYPE_LEN,
+ l2info.caplen-ETHERTYPE_LEN,
+ &extracted_ethertype) == 0)
+ /* ether_type not known, probably it wasn't one */
+ printf("unknown ethertype 0x%04x", extracted_ethertype);
+
+ return l2info.header_len;
+}
+
u_int
juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p)
{
struct juniper_l2info_t l2info;
- l2info.pictype = JUNIPER_MLPPP;
+ l2info.pictype = DLT_JUNIPER_MLPPP;
if(juniper_parse_header(p, h, &l2info) == 0)
return l2info.header_len;
if (eflag &&
EXTRACT_16BITS(&l2info.cookie) != PPP_OSI &&
EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL))
- printf(", Bundle-ID %u: ",l2info.bundle);
+ printf("Bundle-ID %u: ",l2info.bundle);
p+=l2info.header_len;
+ /* first try the LSQ protos */
+ switch(l2info.proto) {
+ case JUNIPER_LSQ_L3_PROTO_IPV4:
+ ip_print(gndo, p, l2info.length);
+ return l2info.header_len;
+ case JUNIPER_LSQ_L3_PROTO_IPV6:
+ ip6_print(p,l2info.length);
+ return l2info.header_len;
+ case JUNIPER_LSQ_L3_PROTO_MPLS:
+ mpls_print(p,l2info.length);
+ return l2info.header_len;
+ case JUNIPER_LSQ_L3_PROTO_ISO:
+ isoclns_print(p,l2info.length,l2info.caplen);
+ return l2info.header_len;
+ default:
+ break;
+ }
+
+ /* zero length cookie ? */
switch (EXTRACT_16BITS(&l2info.cookie)) {
case PPP_OSI:
ppp_print(p-2,l2info.length+2);
{
struct juniper_l2info_t l2info;
- l2info.pictype = JUNIPER_MFR;
+ l2info.pictype = DLT_JUNIPER_MFR;
if(juniper_parse_header(p, h, &l2info) == 0)
return l2info.header_len;
{
struct juniper_l2info_t l2info;
- l2info.pictype = JUNIPER_MLFR;
+ l2info.pictype = DLT_JUNIPER_MLFR;
if(juniper_parse_header(p, h, &l2info) == 0)
return l2info.header_len;
struct juniper_l2info_t l2info;
- l2info.pictype = JUNIPER_ATM1;
+ l2info.pictype = DLT_JUNIPER_ATM1;
if(juniper_parse_header(p, h, &l2info) == 0)
return l2info.header_len;
struct juniper_l2info_t l2info;
- l2info.pictype = JUNIPER_ATM2;
+ l2info.pictype = DLT_JUNIPER_ATM2;
if(juniper_parse_header(p, h, &l2info) == 0)
return l2info.header_len;
l2info->cookie_len = lp->cookie_len;
l2info->header_len += lp->cookie_len;
- if(p[0] == LS_COOKIE_ID) {
- l2info->cookie_type = LS_COOKIE;
+ switch (p[0]) {
+ case LS_COOKIE_ID:
+ l2info->cookie_type = LS_COOKIE_ID;
l2info->cookie_len += 2;
l2info->header_len += 2;
- l2info->bundle = l2info->cookie[1];
- } else l2info->bundle = l2info->cookie[0];
+ break;
+ case AS_COOKIE_ID:
+ l2info->cookie_type = AS_COOKIE_ID;
+ l2info->cookie_len += 6;
+ l2info->header_len += 6;
+ break;
+
+ default:
+ l2info->bundle = l2info->cookie[0];
+ break;
+ }
if (eflag)
- printf("%s-PIC, cookie-len %u, cookie 0x",
+ printf("%s-PIC, cookie-len %u",
lp->s,
l2info->cookie_len);
-
- for (idx = 0; idx < l2info->cookie_len; idx++) {
- l2info->cookie[idx] = p[idx]; /* copy cookie data */
- if (eflag) printf("%02x",p[idx]);
+
+ if (l2info->cookie_len > 0) {
+ 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*/
/* DLT_ specific parsing */
switch(l2info->pictype) {
- case JUNIPER_MLPPP:
- if (l2info->cookie_type == LS_COOKIE) {
+ case DLT_JUNIPER_MLPPP:
+ switch (l2info->cookie_type) {
+ case LS_COOKIE_ID:
l2info->bundle = l2info->cookie[1];
- } else {
+ 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;
- case JUNIPER_MLFR: /* fall through */
- case JUNIPER_MFR:
- if (l2info->cookie_type == LS_COOKIE) {
+ case DLT_JUNIPER_MLFR: /* fall through */
+ case DLT_JUNIPER_MFR:
+ switch (l2info->cookie_type) {
+ case LS_COOKIE_ID:
l2info->bundle = l2info->cookie[1];
- } else {
+ break;
+ case AS_COOKIE_ID:
+ l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
+ break;
+ default:
l2info->bundle = l2info->cookie[0];
+ break;
}
l2info->proto = EXTRACT_16BITS(p);
l2info->header_len += 2;
l2info->length -= 2;
l2info->caplen -= 2;
break;
- case JUNIPER_ATM2:
- case JUNIPER_ATM1:
+ case DLT_JUNIPER_ATM2:
+ /* ATM cell relay control word present ? */
+ if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK && *p & 0x08) {
+ l2info->header_len += 4;
+ if (eflag)
+ printf("control-word 0x%08x ",EXTRACT_32BITS(p));
+ }
+ break;
+ case DLT_JUNIPER_ATM1:
default:
-
break;
}