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
Bi-directional Fault Detection (BFD) support
Support for Juniper's DLT_JUNIPER_ATM{1,2} values
Support for Juniper's PPPOE encapsulation
}
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_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 gboolean ppp_heuristic_guess(guint16 proto);
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 */
static void
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_tree *subtree = NULL;
guint8 direction,l2hdr_presence,flags,ipvers,atm1_header_len,atm2_header_len;
guint32 magic_number, cookie1, proto;
guint8 ipvers,atm1_header_len,atm2_header_len,flags;
guint32 cookie1, proto;
guint64 cookie2;
guint offset;
guint offset = 0;
int bytes_processed;
tvbuff_t *next_tvb;
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))
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) {
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;
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;
default: /* should not happen */
ti = proto_tree_add_text (tree, tvb, 0, 0 , "Juniper unknown ATM PIC");
return;
}
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;
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;
}
}
subtree = proto_item_add_subtree(ti, ett_juniper);
/* parse header, match mgc, extract flags and build first tree */
bytes_processed = dissect_juniper_header(tvb, pinfo, tree, ti, &flags);
if(bytes_processed == -1)
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);
@ -214,9 +260,11 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
switch (atm_pictype) {
case JUNIPER_ATM1:
tisub = proto_tree_add_uint(subtree, hf_juniper_atm1_cookie, tvb, 4, 4, cookie1);
offset += atm1_header_len;
break;
case JUNIPER_ATM2:
tisub = proto_tree_add_uint64(subtree, hf_juniper_atm2_cookie, tvb, 4, 8, cookie2);
offset += atm2_header_len;
break;
default: /* should not happen */
return;
@ -248,7 +296,7 @@ dissect_juniper_atm(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16
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) &&
atm_pictype != JUNIPER_ATM1) {
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_atm2_handle;
dissector_handle_t juniper_pppoe_handle;
osinl_subdissector_table = find_dissector_table("osinl");
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_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_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
* byte. I don't know whether any captures look like that,
* 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.
*/

View File

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

View File

@ -165,8 +165,9 @@
#define WTAP_ENCAP_NETTL_FDDI 74
#define WTAP_ENCAP_NETTL_UNKNOWN 75
#define WTAP_ENCAP_MTP2_WITH_PHDR 76
#define WTAP_ENCAP_JUNIPER_PPPOE 77
/* 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.
We support writing some many of these file types, too, so we