* Routines for Token-Ring packet disassembly
* Gilbert Ramirez <gram@verdict.uthscsa.edu>
*
- * $Id: packet-tr.c,v 1.4 1998/09/17 22:28:07 gram Exp $
+ * $Id: packet-tr.c,v 1.10 1999/02/09 00:35:38 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@unicom.net>
# include <netinet/in.h>
#endif
-#include <pcap.h>
-#include "packet.h"
#include "ethereal.h"
+#include "packet.h"
#include "etypes.h"
static void
}
+void
+capture_tr(const u_char *pd, guint32 cap_len, packet_counts *ld) {
+
+ int offset = 14;
+
+ int source_routed = 0;
+ int frame_type;
+ guint8 trn_rif_bytes;
+ guint8 actual_rif_bytes;
+
+ /* The trn_hdr struct, as separate variables */
+ guint8 trn_fc; /* field control field */
+ guint8 trn_shost[6]; /* source host */
+
+ /* get the data */
+ memcpy(&trn_fc, &pd[1], sizeof(guint8));
+ memcpy(trn_shost, &pd[8], 6 * sizeof(guint8));
+
+ frame_type = (trn_fc & 192) >> 6;
+
+ /* if the high bit on the first byte of src hwaddr is 1, then
+ this packet is source-routed */
+ source_routed = trn_shost[0] & 128;
+
+ trn_rif_bytes = pd[14] & 31;
+
+ /* sometimes we have a RCF but no RIF... half source-routed? */
+ /* I'll check for 2 bytes of RIF and the 0x70 byte */
+ if (!source_routed) {
+ if (trn_rif_bytes == 2) {
+ source_routed = 1;
+ }
+ /* the Linux 2.0 TR code strips source-route bits in
+ * order to test for SR. This can be removed from most
+ * packets with oltr, but not all. So, I try to figure out
+ * which packets should have been SR here. I'll check to
+ * see if there's a SNAP or IPX field right after
+ * my RIF fields.
+ */
+ else if ( (
+ pd[0x0e + trn_rif_bytes] == 0xaa &&
+ pd[0x0f + trn_rif_bytes] == 0xaa &&
+ pd[0x10 + trn_rif_bytes] == 0x03) ||
+ (
+ pd[0x0e + trn_rif_bytes] == 0xe0 &&
+ pd[0x0f + trn_rif_bytes] == 0xe0) ) {
+
+ 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]);
+ } */
+
+ }
+
+ if (source_routed) {
+ actual_rif_bytes = trn_rif_bytes;
+ }
+ else {
+ trn_rif_bytes = 0;
+ actual_rif_bytes = 0;
+ }
+
+ /* this is a silly hack for Linux 2.0.x. Read the comment below,
+ in front of the other #ifdef linux. If we're sniffing our own NIC,
+ we get a full RIF, sometimes with garbage */
+ if ((source_routed && trn_rif_bytes == 2 && frame_type == 1) ||
+ (!source_routed && frame_type == 1)) {
+ /* look for SNAP or IPX only */
+ if ( (pd[0x20] == 0xaa && pd[0x21] == 0xaa && pd[0x22] == 03) ||
+ (pd[0x20] == 0xe0 && pd[0x21] == 0xe0) ) {
+ actual_rif_bytes = 18;
+ }
+ }
+ offset += actual_rif_bytes;
+
+ /* The package is either MAC or LLC */
+ switch (frame_type) {
+ /* MAC */
+ case 0:
+ ld->other++;
+ break;
+ case 1:
+ capture_llc(pd, offset, cap_len, ld);
+ break;
+ default:
+ /* non-MAC, non-LLC, i.e., "Reserved" */
+ ld->other++;
+ break;
+ }
+}
+
+
void
dissect_tr(const u_char *pd, frame_data *fd, GtkTree *tree) {
/* non-source-routed version of source addr */
guint8 trn_shost_nonsr[6];
+ static const value_string fc_pcf[] = {
+ { 0, "Normal buffer" },
+ { 1, "Express buffer" },
+ { 2, "Purge" },
+ { 3, "Claim Token" },
+ { 4, "Beacon" },
+ { 5, "Active Monitor Present" },
+ { 6, "Standby Monitor Present" },
+ { 0, NULL },
+ };
/* Token-Ring Strings */
- char *fc[] = { "MAC", "LLC", "Reserved" };
- char *fc_pcf[] = {
+ char *fc[] = { "MAC", "LLC", "Reserved", "Unknown" };
+/* char *fc_pcf[] = {
"Normal buffer", "Express buffer", "Purge",
"Claim Token", "Beacon", "Active Monitor Present",
- "Standby Monitor Present" };
+ "Standby Monitor Present" };*/
char *rc_arrow[] = { "-->", "<--" };
char *rc_direction[] = { "From originating station",
"To originating station" };
/* information window */
- if (fd->win_info[0]) {
- strcpy(fd->win_info[2], ether_to_str((guint8 *)&pd[2]));
- strcpy(fd->win_info[1], ether_to_str(trn_shost_nonsr));
- strcpy(fd->win_info[3], "TR");
- sprintf(fd->win_info[4], "Token-Ring %s", fc[frame_type]);
- }
+ if (check_col(fd, COL_RES_DL_DST))
+ col_add_str(fd, COL_RES_DL_DST, ether_to_str((guint8 *)&pd[2]));
+ if (check_col(fd, COL_RES_DL_SRC))
+ col_add_str(fd, COL_RES_DL_SRC, ether_to_str(trn_shost_nonsr));
+ if (check_col(fd, COL_PROTOCOL))
+ col_add_str(fd, COL_PROTOCOL, "TR");
+ if (check_col(fd, COL_INFO))
+ col_add_fstr(fd, COL_INFO, "Token-Ring %s", fc[frame_type]);
/* protocol analysis tree */
if (tree) {
ti = add_item_to_tree(GTK_WIDGET(tree), 0, 14 + actual_rif_bytes,
- "Token-Ring (%d on wire, %d captured)", fd->pkt_len, fd->cap_len);
+ "Token-Ring");
fh_tree = gtk_tree_new();
add_subtree(ti, fh_tree, ETT_TOKEN_RING);
add_item_to_tree(fh_tree, 0, 1,
add_item_to_tree(fh_tree, 1, 1,
"Frame Control: %s, Physical Control=%d (%s)",
fc[frame_type], (trn_fc & 15),
- fc_pcf[(trn_fc & 15)]);
+ val_to_str((trn_fc & 15), fc_pcf, "Unknown"));
add_item_to_tree(fh_tree, 2, 6, "Destination: %s",
ether_to_str((guint8 *) trn_dhost));
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);
+ /*printf("trn_rif %d actual_rif %d\n", trn_rif_bytes, actual_rif_bytes);*/
add_item_to_tree(fh_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.");