diff options
Diffstat (limited to 'packet-tr.c')
-rw-r--r-- | packet-tr.c | 250 |
1 files changed, 143 insertions, 107 deletions
diff --git a/packet-tr.c b/packet-tr.c index fce7be4279..a7eca11f17 100644 --- a/packet-tr.c +++ b/packet-tr.c @@ -2,7 +2,7 @@ * Routines for Token-Ring packet disassembly * Gilbert Ramirez <gram@verdict.uthscsa.edu> * - * $Id: packet-tr.c,v 1.14 1999/06/16 20:14:51 gram Exp $ + * $Id: packet-tr.c,v 1.15 1999/07/07 22:51:56 gram Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@unicom.net> @@ -36,36 +36,85 @@ #include <glib.h> #include "packet.h" #include "etypes.h" + +int proto_tr = -1; +int hf_tr_dst = -1; +int hf_tr_src = -1; +int hf_tr_dst_vendor = -1; +int hf_tr_src_vendor = -1; +int hf_tr_sr = -1; +int hf_tr_ac = -1; +int hf_tr_priority = -1; +int hf_tr_frame = -1; +int hf_tr_monitor_cnt = -1; +int hf_tr_priority_reservation = -1; +int hf_tr_fc = -1; +int hf_tr_fc_type = -1; +int hf_tr_fc_pcf = -1; +int hf_tr_rif_bytes = -1; +int hf_tr_broadcast = -1; +int hf_tr_max_frame_size = -1; +int hf_tr_direction = -1; +int hf_tr_rif = -1; +int hf_tr_rif_ring = -1; +int hf_tr_rif_bridge = -1; + +static const value_string ac_vals[] = { + { 0, "Token" }, + { 0x10, "Frame" }, + { 0, NULL } +}; + +static const value_string pcf_vals[] = { + { 0, "Normal buffer" }, + { 1, "Express buffer" }, + { 2, "Purge" }, + { 3, "Claim Token" }, + { 4, "Beacon" }, + { 5, "Active Monitor Present" }, + { 6, "Standby Monitor Present" }, + { 0, NULL }, +}; + +static const value_string frame_vals[] = { + { 0, "MAC" }, + { 64, "LLC" }, + { 128, "Reserved" }, + { 0, NULL }, +}; + +static const value_string broadcast_vals[] = { + { 0 << 5, "Non-broadcast" }, + { 1 << 5, "Non-broadcast" }, + { 2 << 5, "Non-broadcast" }, + { 3 << 5, "Non-broadcast" }, + { 4 << 5, "All-routes broadcast" }, + { 5 << 5, "All-routes broadcast" }, + { 6 << 5, "Single-route broadcast" }, + { 7 << 5, "Single-route broadcast" }, + { 0, NULL } +}; + +static const value_string max_frame_size_vals[] = { + { 0, "516" }, + { 1, "1500" }, + { 2, "2052" }, + { 3, "4472" }, + { 4, "8144" }, + { 5, "11407" }, + { 6, "17800" }, + { 0, NULL } +}; + +static const value_string direction_vals[] = { + { 0, "From originating station (-->)" }, + { 128, "To originating station (<--)" }, + { 0, NULL } +}; static void add_ring_bridge_pairs(int rcf_len, const u_char *pd, proto_tree *tree); -static char* -sr_broadcast(u_char val) { - - if (val < 4) { - return "Non-broadcast"; - } - else if (val < 6) { - return "All-routes broadcast"; - } - else { - return "Single-route broadcast"; - } -} - -static int -sr_frame(u_char val) { - - int rc_frame[7] = { 516, 1500, 2052, 4472, 8144, 11407, 17800 }; - - if (val > 6) { - return -1; - } - else return rc_frame[val]; -} - - void capture_tr(const u_char *pd, guint32 cap_len, packet_counts *ld) { @@ -115,10 +164,6 @@ capture_tr(const u_char *pd, guint32 cap_len, packet_counts *ld) { source_routed = 1; } -/* else { - printf("0e+%d = %02X 0f+%d = %02X\n", trn_rif_bytes, pd[0x0e + trn_rif_bytes], - trn_rif_bytes, pd[0x0f + trn_rif_bytes]); - } */ } @@ -163,7 +208,7 @@ capture_tr(const u_char *pd, guint32 cap_len, packet_counts *ld) { void dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { - proto_tree *fh_tree, *bf_tree; + proto_tree *tr_tree, *bf_tree; proto_item *ti; int offset = 14; @@ -184,35 +229,9 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { guint8 trn_shost_nonsr[6]; - static const value_string ac_vals[] = { - { 0, "Token" }, - { 0x10, "Frame" }, - { 0, NULL } - }; - - static const value_string pcf_vals[] = { - { 0, "Normal buffer" }, - { 1, "Express buffer" }, - { 2, "Purge" }, - { 3, "Claim Token" }, - { 4, "Beacon" }, - { 5, "Active Monitor Present" }, - { 6, "Standby Monitor Present" }, - { 0, NULL }, - }; - - static const value_string frame_vals[] = { - { 0, "MAC" }, - { 64, "LLC" }, - { 128, "Reserved" }, - { 0, NULL }, - }; /* Token-Ring Strings */ char *fc[] = { "MAC", "LLC", "Reserved", "Unknown" }; - char *rc_arrow[] = { "-->", "<--" }; - char *rc_direction[] = { "From originating station", - "To originating station" }; /* get the data */ memcpy(&trn_ac, &pd[0], sizeof(guint8)); @@ -296,60 +315,61 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { /* protocol analysis tree */ if (tree) { - ti = proto_tree_add_item(tree, 0, 14 + actual_rif_bytes, "Token-Ring"); - fh_tree = proto_tree_new(); - proto_item_add_subtree(ti, fh_tree, ETT_TOKEN_RING); + /* Create Token-Ring Tree */ + ti = proto_tree_add_item(tree, proto_tr, 0, 14 + actual_rif_bytes, NULL); + tr_tree = proto_item_add_subtree(ti, ETT_TOKEN_RING); - ti = proto_tree_add_item(fh_tree, 0, 1, "Access Control (0x%02x)", trn_ac); - bf_tree = proto_tree_new(); - proto_item_add_subtree(ti, bf_tree, ETT_TOKEN_RING_AC); + /* Create the Access Control bitfield tree */ + ti = proto_tree_add_item_format(tr_tree, hf_tr_ac, 0, 1, trn_ac, + "Access Control (0x%02x)", trn_ac); + bf_tree = proto_item_add_subtree(ti, ETT_TOKEN_RING_AC); - proto_tree_add_item(bf_tree, 0, 1, "%s", + proto_tree_add_item_format(bf_tree, hf_tr_priority, 0, 1, trn_ac & 0xe0, decode_numeric_bitfield(trn_ac, 0xe0, 8, "Priority = %d")); - proto_tree_add_item(bf_tree, 0, 1, "%s", + proto_tree_add_item_format(bf_tree, hf_tr_frame, 0, 1, trn_ac & 0x10, decode_enumerated_bitfield(trn_ac, 0x10, 8, ac_vals, "%s")); - proto_tree_add_item(bf_tree, 0, 1, "%s", + proto_tree_add_item_format(bf_tree, hf_tr_monitor_cnt, 0, 1, trn_ac & 0x08, decode_numeric_bitfield(trn_ac, 0x08, 8, "Monitor Count")); - proto_tree_add_item(bf_tree, 0, 1, "%s", + proto_tree_add_item_format(bf_tree, hf_tr_priority_reservation, 0, 1, trn_ac & 0x07, decode_numeric_bitfield(trn_ac, 0x07, 8, "Priority Reservation = %d")); + /* Create the Frame Control bitfield tree */ + ti = proto_tree_add_item_format(tr_tree, hf_tr_fc, 1, 1, trn_fc, + "Frame Control (0x%02x)", trn_fc); + bf_tree = proto_item_add_subtree(ti, ETT_TOKEN_RING_FC); - ti = proto_tree_add_item(fh_tree, 1, 1, "Frame Control (0x%02x)", trn_fc); - bf_tree = proto_tree_new(); - proto_item_add_subtree(ti, bf_tree, ETT_TOKEN_RING_FC); - - proto_tree_add_item(bf_tree, 1, 1, "%s", + proto_tree_add_item_format(bf_tree, hf_tr_fc_type, 1, 1, trn_fc & 0xc0, decode_enumerated_bitfield(trn_fc, 0xc0, 8, frame_vals, "%s")); - proto_tree_add_item(bf_tree, 1, 1, "%s", + proto_tree_add_item_format(bf_tree, hf_tr_fc_pcf, 1, 1, trn_fc & 0x0f, decode_enumerated_bitfield(trn_fc, 0x0f, 8, pcf_vals, "%s")); - proto_tree_add_item(fh_tree, 2, 6, "Destination: %s", - ether_to_str((guint8 *) trn_dhost)); - proto_tree_add_item(fh_tree, 8, 6, "Source: %s", - ether_to_str((guint8 *) trn_shost)); + proto_tree_add_item(tr_tree, hf_tr_dst, 2, 6, trn_dhost); + proto_tree_add_item_hidden(tr_tree, hf_tr_dst_vendor, 2, 3, trn_dhost); + proto_tree_add_item(tr_tree, hf_tr_src, 8, 6, trn_shost); + proto_tree_add_item_hidden(tr_tree, hf_tr_src_vendor, 8, 3, trn_shost); + proto_tree_add_item_hidden(tr_tree, hf_tr_sr, 8, 1, source_routed); - if (source_routed) { - proto_tree_add_item(fh_tree, 14, 1, "RIF length: %d bytes", trn_rif_bytes); + /* non-source-routed version of src addr */ + proto_tree_add_item_hidden(tr_tree, hf_tr_src, 8, 6, trn_shost_nonsr); + proto_tree_add_item_hidden(tr_tree, hf_tr_src_vendor, 8, 3, trn_shost_nonsr); - proto_tree_add_item(fh_tree, 15, 1, - "%s, up to %d bytes in frame (LF=%d)", - sr_broadcast((pd[14] & 224) >> 5), - sr_frame((pd[15] & 112) >> 4), - (pd[15] & 112) >> 4); + if (source_routed) { + /* RCF Byte 1 */ + proto_tree_add_item(tr_tree, hf_tr_rif_bytes, 14, 1, trn_rif_bytes); + proto_tree_add_item(tr_tree, hf_tr_broadcast, 14, 1, pd[14] & 224); - proto_tree_add_item(fh_tree, 15, 1, - "Direction: %s (%s)", - rc_direction[(pd[15] & 128) >> 7], - rc_arrow[(pd[15] & 128) >> 7]); + /* RCF Byte 2 */ + proto_tree_add_item(tr_tree, hf_tr_max_frame_size, 15, 1, pd[15] & 112); + proto_tree_add_item(tr_tree, hf_tr_direction, 15, 1, pd[15] & 128); /* if we have more than 2 bytes of RIF, then we have ring/bridge pairs */ if (trn_rif_bytes > 2) { - add_ring_bridge_pairs(trn_rif_bytes, pd, fh_tree); + add_ring_bridge_pairs(trn_rif_bytes, pd, tr_tree); } } @@ -363,24 +383,11 @@ dissect_tr(const u_char *pd, frame_data *fd, proto_tree *tree) { tcpdump. W/o that, however, I'm guessing that DSAP == SSAP if the frame type is LLC. It's very much a hack. -- Gilbert Ramirez */ if (actual_rif_bytes > trn_rif_bytes) { - /*printf("trn_rif %d actual_rif %d\n", trn_rif_bytes, actual_rif_bytes);*/ - proto_tree_add_item(fh_tree, 14 + trn_rif_bytes, actual_rif_bytes - trn_rif_bytes, + proto_tree_add_text(tr_tree, 14 + trn_rif_bytes, actual_rif_bytes - trn_rif_bytes, "Empty RIF from Linux 2.0.x driver. The sniffing NIC " "is also running a protocol stack."); } - /* - if (source_routed && (trn_rif_bytes == 2) && silly_linux) { - proto_tree_add_item(fh_tree, 14 + trn_rif_bytes, 18 - actual_rif_bytes, - "Empty RIF from Linux 2.0.x driver. The sniffing NIC " - "is also running a protocol stack."); - } - else if ((!source_routed) && silly_linux ) { - proto_tree_add_item(fh_tree, 14, 18, - "Empty RIF from Linux 2.0.x driver. The sniffing NIC " - "is also running a protocol stack."); - }*/ } - /* The package is either MAC or LLC */ switch (frame_type) { /* MAC */ @@ -416,17 +423,46 @@ add_ring_bridge_pairs(int rcf_len, const u_char *pd, proto_tree *tree) if (j==1) { segment=pntohs(&pd[16]) >> 4; size = sprintf(buffer, "%03X",segment); + proto_tree_add_item_hidden(tree, hf_tr_rif_ring, 16, 2, segment); buff_offset += size; } segment=pntohs(&pd[17+j]) >> 4; brdgnmb=pd[16+j] & 0x0f; size = sprintf(buffer+buff_offset, "-%01X-%03X",brdgnmb,segment); + proto_tree_add_item_hidden(tree, hf_tr_rif_ring, 17+j, 2, segment); + proto_tree_add_item_hidden(tree, hf_tr_rif_bridge, 16+j, 1, brdgnmb); buff_offset += size; } + proto_tree_add_item(tree, hf_tr_rif, 16, rcf_len << 1, buffer); +} - proto_tree_add_item(tree, 16, rcf_len << 1, - "Ring-Bridge Pairs: %s", - buffer); +void +proto_register_tr(void) +{ + const hf_register_info hf[] = { + { "Access Control", "tr.ac", &hf_tr_ac, FT_UINT8, NULL }, + { "Priority", "tr.priority", &hf_tr_priority, FT_UINT8, NULL }, + { "Frame", "tr.frame", &hf_tr_frame, FT_VALS_UINT8, VALS(ac_vals) }, + { "Monitor Count", "tr.monitor_cnt", &hf_tr_monitor_cnt, FT_UINT8, NULL }, + { "Priority Reservation","tr.priority_reservation", &hf_tr_priority_reservation, FT_UINT8, NULL }, + { "Frame Control", "tr.fc", &hf_tr_fc, FT_UINT8, NULL }, + { "Frame Type", "tr.frame_type", &hf_tr_fc_type, FT_VALS_UINT8, VALS(frame_vals) }, + { "Frame PCF", "tr.frame_pcf", &hf_tr_fc_pcf, FT_VALS_UINT8, VALS(pcf_vals) }, + { "Destination", "tr.dst", &hf_tr_dst, FT_ETHER, NULL }, + { "Source", "tr.src", &hf_tr_src, FT_ETHER, NULL }, + { "Destination Hardware Vendor", "tr.dst_vendor", &hf_tr_dst_vendor, FT_ETHER_VENDOR, NULL }, + { "Source Hardware Vendor", "tr.src_vendor", &hf_tr_src_vendor, FT_ETHER_VENDOR, NULL }, + { "Source Routed", "tr.sr", &hf_tr_sr, FT_BOOLEAN, NULL }, + { "RIF Bytes", "tr.rif_bytes", &hf_tr_rif_bytes, FT_UINT8, NULL }, + { "Broadcast Type", "tr.broadcast", &hf_tr_broadcast, FT_VALS_UINT8, VALS(broadcast_vals) }, + { "Maximum Frame Size", "tr.max_frame_size", &hf_tr_max_frame_size, FT_VALS_UINT8, VALS(max_frame_size_vals) }, + { "Direction", "tr.direction", &hf_tr_direction, FT_VALS_UINT8, VALS(direction_vals) }, + { "Ring-Bridge Pairs", "tr.rif", &hf_tr_rif, FT_STRING, NULL }, + { "RIF Ring", "tr.rif_ring", &hf_tr_rif_ring, FT_UINT16, NULL }, + { "RIF Bridge", "tr.rif_bridge", &hf_tr_rif_bridge, FT_UINT8, NULL }, + }; + proto_tr = proto_register_protocol("Token-Ring", "tr"); + proto_register_field_array(proto_tr, hf, array_length(hf)); } |