From Hannes Gredler

support for Juniper PPPOE encapsulation


svn path=/trunk/; revision=14346
This commit is contained in:
Ronnie Sahlberg 2005-05-11 11:24:17 +00:00
parent fcab322ada
commit 4e3c7cc716
5 changed files with 132 additions and 71 deletions

View File

@ -740,6 +740,7 @@ Hannes Gredler <hannes[AT]juniper.net> {
Support MPLS over CHDLC Support MPLS over CHDLC
Bi-directional Fault Detection (BFD) support Bi-directional Fault Detection (BFD) support
Support for Juniper's DLT_JUNIPER_ATM{1,2} values Support for Juniper's DLT_JUNIPER_ATM{1,2} values
Support for Juniper's PPPOE encapsulation
} }
Inoue <inoue[AT]ainet.or.jp> { Inoue <inoue[AT]ainet.or.jp> {

View File

@ -82,10 +82,103 @@ static dissector_handle_t data_handle;
static dissector_table_t osinl_subdissector_table; static dissector_table_t osinl_subdissector_table;
static dissector_table_t osinl_excl_subdissector_table; static dissector_table_t osinl_excl_subdissector_table;
int dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags);
static void dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype); static void dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 atm_pictype);
static gboolean ppp_heuristic_guess(guint16 proto); static gboolean ppp_heuristic_guess(guint16 proto);
static guint ip_heuristic_guess(guint8 ip_header_byte); static guint ip_heuristic_guess(guint8 ip_header_byte);
/* generic juniper header dissector */
int
dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags)
{
proto_item *tisub;
proto_tree *subtree = NULL;
guint8 direction,l2hdr_presence,ipvers;
guint32 magic_number;
tvbuff_t *next_tvb;
magic_number = tvb_get_ntoh24(tvb, 0);
*flags = tvb_get_guint8(tvb, 3);
direction = *flags & JUNIPER_FLAG_PKT_IN;
l2hdr_presence = *flags & JUNIPER_FLAG_NO_L2;
subtree = proto_item_add_subtree(ti, ett_juniper);
tisub = proto_tree_add_text (subtree, tvb, 0, 3,
"Magic-Number: 0x%06x (%scorrect)",
magic_number,
(magic_number == JUNIPER_PCAP_MAGIC) ? "" : "in" );
if (magic_number != JUNIPER_PCAP_MAGIC)
return -1;
tisub = proto_tree_add_uint_format (subtree, hf_juniper_direction, tvb, 3, 1,
direction, "Direction: %s",
val_to_str(direction,juniper_direction_vals,"Unknown"));
tisub = proto_tree_add_uint_format (subtree, hf_juniper_l2hdr_presence, tvb, 3, 1,
l2hdr_presence, "L2-header: %s",
val_to_str(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown"));
if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
next_tvb = tvb_new_subset(tvb, 8, -1, -1);
ipvers = ip_heuristic_guess(tvb_get_guint8(tvb, 8)); /* try IP */
if (ipvers != 0) {
ti = proto_tree_add_text (subtree, tvb, 8, 0,
"Payload Type: Null encapsulation IPv%u",
ipvers);
switch (ipvers) {
case 6:
call_dissector(ipv6_handle, next_tvb, pinfo, tree);
break;
case 4:
call_dissector(ipv4_handle, next_tvb, pinfo, tree);
break;
}
}
return -1;
}
return 4; /* 4 bytes parsed */
}
/* PPPoE dissector */
static void
dissect_juniper_pppoe(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_tree *subtree = NULL;
guint offset;
int bytes_processed;
guint8 flags;
tvbuff_t *next_tvb;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Juniper PPPoE");
if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO);
offset = 0;
ti = proto_tree_add_text (tree, tvb, offset, 4, "Juniper PPPoE PIC");
bytes_processed = dissect_juniper_header(tvb, pinfo, tree, ti, &flags);
/* parse header, match mgc, extract flags and build first tree */
if(bytes_processed == -1)
return;
else
offset+=bytes_processed;
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
ti = proto_tree_add_text (subtree, tvb, offset, 0, "Payload Type: Ethernet");
call_dissector(eth_handle, next_tvb, pinfo, tree);
}
/* wrapper for passing the PIC type to the generic ATM dissector */ /* wrapper for passing the PIC type to the generic ATM dissector */
static void static void
dissect_juniper_atm1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) dissect_juniper_atm1(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
@ -106,11 +199,11 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
{ {
proto_item *ti,*tisub; proto_item *ti,*tisub;
proto_tree *subtree = NULL; proto_tree *subtree = NULL;
guint8 direction,l2hdr_presence,flags,ipvers,atm1_header_len,atm2_header_len; guint8 ipvers,atm1_header_len,atm2_header_len,flags;
guint32 magic_number, cookie1, proto; guint32 cookie1, proto;
guint64 cookie2; guint64 cookie2;
guint offset; guint offset = 0;
int bytes_processed;
tvbuff_t *next_tvb; tvbuff_t *next_tvb;
switch (atm_pictype) { switch (atm_pictype) {
@ -132,80 +225,33 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
if (check_col(pinfo->cinfo, COL_INFO)) if (check_col(pinfo->cinfo, COL_INFO))
col_clear(pinfo->cinfo, COL_INFO); col_clear(pinfo->cinfo, COL_INFO);
offset = 0;
magic_number = tvb_get_ntoh24(tvb, 0);
flags = tvb_get_guint8(tvb, 3);
direction = flags & JUNIPER_FLAG_PKT_IN;
l2hdr_presence = flags & JUNIPER_FLAG_NO_L2;
if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
atm1_header_len = 8;
atm2_header_len = 8;
}
else {
atm1_header_len = 8;
atm2_header_len = 12;
}
switch (atm_pictype) { switch (atm_pictype) {
case JUNIPER_ATM1: case JUNIPER_ATM1:
ti = proto_tree_add_text (tree, tvb, 0, atm1_header_len, "Juniper ATM1 PIC"); ti = proto_tree_add_text (tree, tvb, 0, 4 , "Juniper ATM1 PIC");
break; break;
case JUNIPER_ATM2: case JUNIPER_ATM2:
ti = proto_tree_add_text (tree, tvb, 0, atm2_header_len, "Juniper ATM2 PIC"); ti = proto_tree_add_text (tree, tvb, 0, 4 , "Juniper ATM2 PIC");
break; break;
default: /* should not happen */ default: /* should not happen */
ti = proto_tree_add_text (tree, tvb, 0, 0 , "Juniper unknown ATM PIC"); ti = proto_tree_add_text (tree, tvb, 0, 0 , "Juniper unknown ATM PIC");
return; return;
} }
subtree = proto_item_add_subtree(ti, ett_juniper); subtree = proto_item_add_subtree(ti, ett_juniper);
/* parse header, match mgc, extract flags and build first tree */
tisub = proto_tree_add_text (subtree, tvb, 0, 3, bytes_processed = dissect_juniper_header(tvb, pinfo, tree, ti, &flags);
"Magic-Number: 0x%06x (%scorrect)", if(bytes_processed == -1)
magic_number,
(magic_number == JUNIPER_PCAP_MAGIC) ? "" : "in" );
if (magic_number != JUNIPER_PCAP_MAGIC)
return;
tisub = proto_tree_add_uint_format (subtree, hf_juniper_direction, tvb, 3, 1,
direction, "Direction: %s",
val_to_str(direction,juniper_direction_vals,"Unknown"));
tisub = proto_tree_add_uint_format (subtree, hf_juniper_l2hdr_presence, tvb, 3, 1,
l2hdr_presence, "L2-header: %s",
val_to_str(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown"));
switch (atm_pictype) {
case JUNIPER_ATM1:
offset += atm1_header_len;
break;
case JUNIPER_ATM2:
offset += atm2_header_len;
break;
default: /* should not happen */
return;
}
if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
ipvers = ip_heuristic_guess(tvb_get_guint8(tvb, offset)); /* try IP */
if (ipvers != 0) {
ti = proto_tree_add_text (subtree, tvb, offset, 0,
"Payload Type: Null encapsulation IPv%u",
ipvers);
switch (ipvers) {
case 6:
call_dissector(ipv6_handle, next_tvb, pinfo, tree);
break;
case 4:
call_dissector(ipv4_handle, next_tvb, pinfo, tree);
break;
}
}
return; return;
else
offset+=bytes_processed;
if ((flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
atm1_header_len = 4;
atm2_header_len = 4;
}
else {
atm1_header_len = 4;
atm2_header_len = 8;
} }
cookie1 = tvb_get_ntohl(tvb,4); cookie1 = tvb_get_ntohl(tvb,4);
@ -214,9 +260,11 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
switch (atm_pictype) { switch (atm_pictype) {
case JUNIPER_ATM1: case JUNIPER_ATM1:
tisub = proto_tree_add_uint(subtree, hf_juniper_atm1_cookie, tvb, 4, 4, cookie1); tisub = proto_tree_add_uint(subtree, hf_juniper_atm1_cookie, tvb, 4, 4, cookie1);
offset += atm1_header_len;
break; break;
case JUNIPER_ATM2: case JUNIPER_ATM2:
tisub = proto_tree_add_uint64(subtree, hf_juniper_atm2_cookie, tvb, 4, 8, cookie2); tisub = proto_tree_add_uint64(subtree, hf_juniper_atm2_cookie, tvb, 4, 8, cookie2);
offset += atm2_header_len;
break; break;
default: /* should not happen */ default: /* should not happen */
return; return;
@ -248,7 +296,7 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
return; return;
} }
if (direction != JUNIPER_FLAG_PKT_IN && /* ether-over-1483 encaps ? */ if ((flags & JUNIPER_FLAG_PKT_IN) != JUNIPER_FLAG_PKT_IN && /* ether-over-1483 encaps ? */
(cookie1 & JUNIPER_ATM2_GAP_COUNT_MASK) && (cookie1 & JUNIPER_ATM2_GAP_COUNT_MASK) &&
atm_pictype != JUNIPER_ATM1) { atm_pictype != JUNIPER_ATM1) {
ti = proto_tree_add_text (subtree, tvb, offset, 0, "Payload Type: Ethernet"); ti = proto_tree_add_text (subtree, tvb, offset, 0, "Payload Type: Ethernet");
@ -418,6 +466,7 @@ proto_reg_handoff_juniper(void)
{ {
dissector_handle_t juniper_atm1_handle; dissector_handle_t juniper_atm1_handle;
dissector_handle_t juniper_atm2_handle; dissector_handle_t juniper_atm2_handle;
dissector_handle_t juniper_pppoe_handle;
osinl_subdissector_table = find_dissector_table("osinl"); osinl_subdissector_table = find_dissector_table("osinl");
osinl_excl_subdissector_table = find_dissector_table("osinl.excl"); osinl_excl_subdissector_table = find_dissector_table("osinl.excl");
@ -430,7 +479,9 @@ proto_reg_handoff_juniper(void)
juniper_atm2_handle = create_dissector_handle(dissect_juniper_atm2, proto_juniper); juniper_atm2_handle = create_dissector_handle(dissect_juniper_atm2, proto_juniper);
juniper_atm1_handle = create_dissector_handle(dissect_juniper_atm1, proto_juniper); juniper_atm1_handle = create_dissector_handle(dissect_juniper_atm1, proto_juniper);
juniper_pppoe_handle = create_dissector_handle(dissect_juniper_pppoe, proto_juniper);
dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_ATM2, juniper_atm2_handle); dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_ATM2, juniper_atm2_handle);
dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_ATM1, juniper_atm1_handle); dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_ATM1, juniper_atm1_handle);
dissector_add("wtap_encap", WTAP_ENCAP_JUNIPER_PPPOE, juniper_pppoe_handle);
} }

View File

@ -356,8 +356,13 @@ static const struct {
* of the 0xff03 header, the 0xff, is replaced by a direction * of the 0xff03 header, the 0xff, is replaced by a direction
* byte. I don't know whether any captures look like that, * byte. I don't know whether any captures look like that,
* but it is used for some Linux IP filtering (ipfilter?). * but it is used for some Linux IP filtering (ipfilter?).
* */
* 167 and 168 are reserved for more Juniper private-chassis-
/* Ethernet PPPoE frames captured on a service PIC */
{ 167, WTAP_ENCAP_JUNIPER_PPPOE },
/*
* 168 is reserved for more Juniper private-chassis-
* internal meta-information. * internal meta-information.
*/ */

View File

@ -287,6 +287,9 @@ static const struct encap_type_info {
/* WTAP_ENCAP_MTP2_WITH_PHDR */ /* WTAP_ENCAP_MTP2_WITH_PHDR */
{ "MTP2 with pseudoheader", "mtp2-with-phdr" }, { "MTP2 with pseudoheader", "mtp2-with-phdr" },
/* WTAP_ENCAP_JUNIPER_PPPOE */
{ "Juniper PPPoE", "juniper-pppoe" },
}; };
/* Name that should be somewhat descriptive. */ /* Name that should be somewhat descriptive. */

View File

@ -165,8 +165,9 @@
#define WTAP_ENCAP_NETTL_FDDI 74 #define WTAP_ENCAP_NETTL_FDDI 74
#define WTAP_ENCAP_NETTL_UNKNOWN 75 #define WTAP_ENCAP_NETTL_UNKNOWN 75
#define WTAP_ENCAP_MTP2_WITH_PHDR 76 #define WTAP_ENCAP_MTP2_WITH_PHDR 76
#define WTAP_ENCAP_JUNIPER_PPPOE 77
/* last WTAP_ENCAP_ value + 1 */ /* last WTAP_ENCAP_ value + 1 */
#define WTAP_NUM_ENCAP_TYPES 77 #define WTAP_NUM_ENCAP_TYPES 78
/* File types that can be read by wiretap. /* File types that can be read by wiretap.
We support writing some many of these file types, too, so we We support writing some many of these file types, too, so we