Procedure:
To perform Layer 2 packet
decoding, code modifications are made to Ethereal’s LLC protocol
handler (packet-llc.c). These modifications will force Ethereal to call
a custom Layer 2 dissector when an LLC/SNAP segment is captured that
contains the OUI (Organizational Unit Identifier) we are looking for.
Other source files might need modification as well to support the additional
Layer 2 detection and dissection. Additional source code files will
need to be added to the Ethereal project to handle dissection of the
Layer 2 packets. Once the LLC protocol handler has been modified newly
the detected Layer 2 packets can be handed off to standard Ethereal
plugins.

Figure 2, Screen Capture of Ethereal's User
Interface with added Layer 2 dissection.
Files that may need modification:
Ethereal file
"epan\oui.h"
This header
file contains definitions for Organizational Unit Identifiers. If the
OUI associated with the new Layer 2 protocol is not already in this
file, it will need to be added. For the following example a new constant
representing the new OUI is named OUI_MYOUI.
Ethereal file
"epan\dissectors\packet-llc.c"
This source
code file contains functions to handle capture and dissection of LLC
and SNAP segments. Three major modifications are required in this file.
The text description for Layer 2 OUI must be added to the existing list
of OUI text descriptions in the oui_vals[ ] array.
const value_string oui_vals[ ] = {
{ OUI_ENCAP_ETHER, "Encapsulated Ethernet" },
{ OUI_CISCO, "Cisco" },
{ OUI_CISCO_90, "Cisco IOS 9.0 Compatible" },
{ OUI_BRIDGED, "Frame Relay or ATM bridged frames" },
{ OUI_ATM_FORUM, "ATM Forum" },
{ OUI_CABLE_BPDU, "DOCSIS Spanning Tree" }, /* DOCSIS spanning tree BPDU */
{ OUI_APPLE_ATALK, "Apple (AppleTalk)" },
/* Begin new code */
{ OUI_MYOUI, "My Organization" },
/* End new code */
{ 0, NULL }
};
The capture_llc()
function can also be modified to count the new Layer 2 packets as they
arrive during a capture. ( Wireshark 0.99.5 note: this code has
been moved out to capture_snap() )
void capture_llc(const u_char *pd, int offset, packet_counts *ld) {
...
if (is_snap) {
oui = pd[offset+3] << 16 | pd[offset+4] << 8 | pd[offset+5];
if (XDLC_IS_INFORMATION(control)) {
etype = pntohs(&pd[offset+6]);
switch (oui) {
case OUI_ENCAP_ETHER:
case OUI_CISCO_90:
case OUI_APPLE_ATALK:
/* No, I have no idea why Apple used
one of their own OUIs, rather than
OUI_ENCAP_ETHER, and an Ethernet
packet type as protocol ID, for
AppleTalk data packets - but used
OUI_ENCAP_ETHER and an Ethernet
packet type for AARP packets. */
capture_ethertype(etype, offset+8, pd,
ld);
break;
case OUI_CISCO:
capture_ethertype(etype,
offset + 8, pd, ld);
break;
/* Begin new code */
case OUI_MYOUI:
/* Example: double check header info, modify accordingly */
/* Make sure PID is correct */
if(etype = 0x8001)
{
/* Increment my L2 message counter */
ld->myl2p++;
}
else
{
/* We don't know what this is, increment 'other' */
ld->other++;
}
break;
/* End new code */
default:
ld->other++;
break;
}
}
...
}
Finally, the
dissect_snap() function needs to be modified to call
the Layer 2 dissector in added packet-my-layer2.c source code file when
a SNAP segment arrives with the proper Layer 2 OUI. The code comments
and structure of the code in these areas show how the developers did
not expect anyone to add any new Layer 2 protocol detection to the software.
void
dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
proto_tree *snap_tree, int control, int hf_oui, int hf_type, int hf_pid,
int bridge_pad)
{
guint32 oui;
guint16 etype;
tvbuff_t *next_tvb;
oui = tvb_get_ntoh24(tvb, offset);
etype = tvb_get_ntohs(tvb, offset+3);
if (check_col(pinfo->fd, COL_INFO)) {
col_append_fstr(pinfo->fd, COL_INFO,
"; SNAP, OUI 0x%06X (%s), PID 0x%04X",
oui, val_to_str(oui, oui_vals, "Unknown"), etype);
}
if (tree) {
proto_tree_add_uint(snap_tree, hf_oui, tvb, offset, 3, oui);
}
switch (oui) {
...
/* Begin new code */
case OUI_MYOUI:
/* Show PID */
proto_tree_add_uint(snap_tree, hf_pid, tvb, offset + 3, 2, etype);
/* Call my L2 protocol dissector */
next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
call_dissector(my_l2_handle, next_tvb, pinfo, tree);
break;
/* End new code */
...
default:
if (tree) {
proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2,
etype);
}
next_tvb = tvb_new_subset(tvb, offset+5, -1, -1);
dissect_data(next_tvb, 0, pinfo, tree);
break;
}
}
Continue.... |
|