aboutsummaryrefslogtreecommitdiffstats
path: root/packet-vines.c
diff options
context:
space:
mode:
authorguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2003-04-18 00:32:47 +0000
committerguy <guy@f5534014-38df-0310-8fa8-9805f1628bb7>2003-04-18 00:32:47 +0000
commit7c78f24250ef5f5075c25d09c59366e3c8ce2a5e (patch)
tree6eb74955c7490867aa793fe40ee64194d4ded46f /packet-vines.c
parentc3b2e630a78f73efba6809b3f106589843b7f6a0 (diff)
Add support for Vines IPC.
Dissect the transport control field differently for broadcast packets. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@7481 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'packet-vines.c')
-rw-r--r--packet-vines.c357
1 files changed, 270 insertions, 87 deletions
diff --git a/packet-vines.c b/packet-vines.c
index 1c474ffe0b..cc71325fc1 100644
--- a/packet-vines.c
+++ b/packet-vines.c
@@ -1,7 +1,7 @@
/* packet-vines.c
* Routines for Banyan VINES protocol packet disassembly
*
- * $Id: packet-vines.c,v 1.47 2003/04/17 20:30:42 guy Exp $
+ * $Id: packet-vines.c,v 1.48 2003/04/18 00:32:47 guy Exp $
*
* Don Lafontaine <lafont02@cn.ca>
*
@@ -60,11 +60,18 @@ static int proto_vines_spp = -1;
static gint ett_vines_spp = -1;
static gint ett_vines_spp_control = -1;
+static int proto_vines_ipc = -1;
+
+static gint ett_vines_ipc = -1;
+static gint ett_vines_ipc_control = -1;
+
static void dissect_vines_frp(tvbuff_t *, packet_info *, proto_tree *);
#if 0
static void dissect_vines_arp(tvbuff_t *, packet_info *, proto_tree *);
static void dissect_vines_icp(tvbuff_t *, packet_info *, proto_tree *);
+#endif
static void dissect_vines_ipc(tvbuff_t *, packet_info *, proto_tree *);
+#if 0
static void dissect_vines_rtp(tvbuff_t *, packet_info *, proto_tree *);
#endif
static void dissect_vines_spp(tvbuff_t *, packet_info *, proto_tree *);
@@ -247,6 +254,12 @@ proto_reg_handoff_vines_llc(void)
static dissector_table_t vines_dissector_table;
+static const value_string class_vals[] = {
+ { 0x00, "Reachable regardless of cost" },
+ { 0x30, "Reachable via LAN" },
+ { 0, NULL }
+};
+
static const value_string proto_vals[] = {
{ VIP_PROTO_IPC, "IPC" },
{ VIP_PROTO_SPP, "SPP" },
@@ -263,9 +276,8 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
e_vip viph;
proto_tree *vip_tree, *tctl_tree;
proto_item *ti;
-/* gchar tos_str[32]; */
const guint8 *dst_addr, *src_addr;
- int is_broadcast = 0;
+ gboolean is_broadcast = FALSE;
int hops = 0;
tvbuff_t *next_tvb;
@@ -291,11 +303,6 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
*/
switch (viph.vip_proto) {
- case VIP_PROTO_IPC:
- if (check_col(pinfo->cinfo, COL_PROTOCOL))
- col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IPC");
- break;
-
case VIP_PROTO_ARP:
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines ARP");
@@ -326,36 +333,10 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
SET_ADDRESS(&pinfo->dst, AT_VINES, VINES_ADDR_LEN, dst_addr);
/* helpers to decode flags */
- /* FIXME: Not used yet */
- if ((viph.vip_dnet == 0xffffffff) && (viph.vip_dsub == 0xffff)) {
- is_broadcast = 1;
- }
+ if ((viph.vip_dnet == 0xffffffff) && (viph.vip_dsub == 0xffff))
+ is_broadcast = TRUE;
hops = viph.vip_tctl & 0xf;
- /*
- viph.ip_tos = IPTOS_TOS(viph.ip_tos);
- switch (viph.ip_tos) {
- case IPTOS_NONE:
- strcpy(tos_str, "None");
- break;
- case IPTOS_LOWDELAY:
- strcpy(tos_str, "Minimize delay");
- break;
- case IPTOS_THROUGHPUT:
- strcpy(tos_str, "Maximize throughput");
- break;
- case IPTOS_RELIABILITY:
- strcpy(tos_str, "Maximize reliability");
- break;
- case IPTOS_LOWCOST:
- strcpy(tos_str, "Minimize cost");
- break;
- default:
- strcpy(tos_str, "Unknon. Malformed?");
- break;
- }
- */
-
if (tree) {
ti = proto_tree_add_item(tree, proto_vines, tvb,
offset, viph.vip_pktlen,
@@ -373,24 +354,29 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
tctl_tree = proto_item_add_subtree(ti, ett_vines_tctl);
/*
* XXX - bit 0x80 is "Normal" if 0; what is it if 1?
- *
- * XXX - the Cisco document mentioned in packet-vines.h
- * says that there are 3 bits of class for broadcast
- * packets; can we determine whether this is a broadcast
- * packet by looking at the VINES destination address?
*/
- proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
- decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
- "Forwarding router can handle redirect packets",
- "Forwarding router cannot handle redirect packets"));
- proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
- decode_boolean_bitfield(viph.vip_tctl, 0x20, 1*8,
- "Return metric notification packet",
- "Do not return metric notification packet"));
- proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
- decode_boolean_bitfield(viph.vip_tctl, 0x10, 1*8,
- "Return exception notification packet",
- "Do not return exception notification packet"));
+ if (is_broadcast) {
+ proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
+ decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
+ "Router nodes",
+ "All nodes"));
+ proto_tree_add_text(tctl_tree, tvb, offset + 4, 1, "%s",
+ decode_enumerated_bitfield(viph.vip_tctl, 0x30, 1*8,
+ class_vals, "%s"));
+ } else {
+ proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
+ decode_boolean_bitfield(viph.vip_tctl, 0x40, 1*8,
+ "Forwarding router can handle redirect packets",
+ "Forwarding router cannot handle redirect packets"));
+ proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
+ decode_boolean_bitfield(viph.vip_tctl, 0x20, 1*8,
+ "Return metric notification packet",
+ "Do not return metric notification packet"));
+ proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
+ decode_boolean_bitfield(viph.vip_tctl, 0x10, 1*8,
+ "Return exception notification packet",
+ "Do not return exception notification packet"));
+ }
proto_tree_add_text(tctl_tree, tvb, offset + 4, 1,
decode_numeric_bitfield(viph.vip_tctl, 0x0F, 1*8,
"Hop count remaining = %u"));
@@ -405,7 +391,6 @@ dissect_vines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
VINES_ADDR_LEN,
"Source: %s",
vines_addr_to_str(src_addr));
-
}
offset += 18;
@@ -453,11 +438,13 @@ proto_reg_handoff_vines(void)
}
static const value_string pkttype_vals[] = {
- { VSPP_PKTTYPE_DATA, "Data" },
- { VSPP_PKTTYPE_DISC, "Disconnect" },
- { VSPP_PKTTYPE_PROBE, "Probe" },
- { VSPP_PKTTYPE_ACK, "Ack" },
- { 0, NULL }
+ { PKTTYPE_DGRAM, "Datagram" },
+ { PKTTYPE_DATA, "Data" },
+ { PKTTYPE_ERR, "Error" },
+ { PKTTYPE_DISC, "Disconnect" },
+ { PKTTYPE_PROBE, "Probe" },
+ { PKTTYPE_ACK, "Ack" },
+ { 0, NULL }
};
static heur_dissector_list_t vines_spp_heur_subdissector_list;
@@ -467,9 +454,9 @@ dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
int offset = 0;
e_vspp viph;
- proto_tree *vspp_tree, *control_tree;
- proto_item *ti;
- tvbuff_t *next_tvb;
+ proto_tree *vspp_tree, *control_tree;
+ proto_item *ti;
+ tvbuff_t *next_tvb;
if (check_col(pinfo->cinfo, COL_PROTOCOL))
col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSPP");
@@ -497,30 +484,6 @@ dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
viph.vspp_rmtid, viph.vspp_lclid, viph.vspp_dport,
viph.vspp_sport);
- /*
- iph.ip_tos = IPTOS_TOS(iph.ip_tos);
- switch (iph.ip_tos) {
- case IPTOS_NONE:
- strcpy(tos_str, "None");
- break;
- case IPTOS_LOWDELAY:
- strcpy(tos_str, "Minimize delay");
- break;
- case IPTOS_THROUGHPUT:
- strcpy(tos_str, "Maximize throughput");
- break;
- case IPTOS_RELIABILITY:
- strcpy(tos_str, "Maximize reliability");
- break;
- case IPTOS_LOWCOST:
- strcpy(tos_str, "Minimize cost");
- break;
- default:
- strcpy(tos_str, "Unknon. Malformed?");
- break;
- }
- */
-
if (tree) {
ti = proto_tree_add_item(tree, proto_vines_spp, tvb, offset,
sizeof(viph), FALSE);
@@ -579,7 +542,7 @@ dissect_vines_spp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
* dissect it as data.
*/
next_tvb = tvb_new_subset(tvb, offset, -1, -1);
- if (viph.vspp_pkttype != VSPP_PKTTYPE_DATA ||
+ if (viph.vspp_pkttype != PKTTYPE_DATA ||
!dissector_try_heuristic(vines_spp_heur_subdissector_list,
next_tvb, pinfo, tree))
call_dissector(data_handle, next_tvb, pinfo, tree);
@@ -610,3 +573,223 @@ proto_reg_handoff_vines_spp(void)
proto_vines_spp);
dissector_add("vines_ip.protocol", VIP_PROTO_SPP, vines_spp_handle);
}
+
+static heur_dissector_list_t vines_ipc_heur_subdissector_list;
+
+static const value_string vipc_err_vals[] = {
+ { 151, "Bad socket descriptor" },
+ { 152, "Address already in use" },
+ { 153, "Invalid operation" },
+ { 154, "User address parameter fault" },
+ { 155, "Net/host unreachable" },
+ { 156, "Message overflow error" },
+ { 157, "Destination socket does not exist" },
+ { 158, "Address family does not exist" },
+ { 159, "Socket type does not exist" },
+ { 160, "Protocol does not exist" },
+ { 161, "No more sockets available" },
+ { 162, "No buffer space available" },
+ { 163, "Timeout event" },
+ { 164, "Operation not supported" },
+ { 165, "Resource not available" },
+ { 166, "Internal communication service failure" },
+ { 167, "Controller reset failure" },
+ { 0, NULL }
+};
+
+static void
+dissect_vines_ipc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ int offset = 0;
+ e_vipc viph;
+ proto_tree *vipc_tree = NULL, *control_tree;
+ proto_item *ti;
+ tvbuff_t *next_tvb;
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "VIPC");
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* To do: check for runts, errs, etc. */
+
+ /* Avoids alignment problems on many architectures. */
+ tvb_memcpy(tvb, (guint8 *)&viph, offset, sizeof(e_vipc));
+
+ viph.vipc_sport = g_ntohs(viph.vipc_sport);
+ viph.vipc_dport = g_ntohs(viph.vipc_dport);
+ viph.vipc_lclid = g_ntohs(viph.vipc_lclid);
+ viph.vipc_rmtid = g_ntohs(viph.vipc_rmtid);
+
+ if (check_col(pinfo->cinfo, COL_PROTOCOL))
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Vines IPC");
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ switch (viph.vipc_pkttype) {
+
+ case PKTTYPE_DGRAM:
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "%s D=%04x S=%04x",
+ val_to_str(viph.vipc_pkttype, pkttype_vals,
+ "Unknown packet type (0x%02x)"),
+ viph.vipc_dport, viph.vipc_sport);
+ break;
+
+ case PKTTYPE_ERR:
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "%s NS=%u NR=%u Err=%s RID=%04x LID=%04x D=%04x S=%04x",
+ val_to_str(viph.vipc_pkttype, pkttype_vals,
+ "Unknown packet type (0x%02x)"),
+ viph.vipc_seqno, viph.vipc_ack,
+ val_to_str(viph.vipc_err_len,
+ vipc_err_vals, "Unknown (%u)"),
+ viph.vipc_rmtid, viph.vipc_lclid,
+ viph.vipc_dport, viph.vipc_sport);
+ break;
+
+ default:
+ col_add_fstr(pinfo->cinfo, COL_INFO,
+ "%s NS=%u NR=%u Len=%u RID=%04x LID=%04x D=%04x S=%04x",
+ val_to_str(viph.vipc_pkttype, pkttype_vals,
+ "Unknown packet type (0x%02x)"),
+ viph.vipc_seqno, viph.vipc_ack,
+ viph.vipc_err_len, viph.vipc_rmtid,
+ viph.vipc_lclid, viph.vipc_dport,
+ viph.vipc_sport);
+ break;
+ }
+ }
+
+ if (tree) {
+ ti = proto_tree_add_item(tree, proto_vines_ipc, tvb, offset,
+ sizeof(viph), FALSE);
+ vipc_tree = proto_item_add_subtree(ti, ett_vines_ipc);
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Source port: 0x%04x", viph.vipc_sport);
+ }
+ offset += 2;
+ if (tree) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Destination port: 0x%04x",
+ viph.vipc_dport);
+ }
+ offset += 2;
+ if (tree) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 1,
+ "Packet type: 0x%02x (%s)",
+ viph.vipc_pkttype,
+ val_to_str(viph.vipc_pkttype, pkttype_vals,
+ "Unknown"));
+ }
+ offset += 1;
+ if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
+ if (tree) {
+ ti = proto_tree_add_text(vipc_tree, tvb, offset, 1,
+ "Control: 0x%02x",
+ viph.vipc_control);
+ control_tree = proto_item_add_subtree(ti,
+ ett_vines_ipc_control);
+ /*
+ * XXX - do reassembly based on BOM/EOM bits.
+ */
+ proto_tree_add_text(control_tree, tvb, offset, 1,
+ decode_boolean_bitfield(viph.vipc_control, 0x80,
+ 1*8,
+ "Send immediate acknowledgment",
+ "Do not send immediate acknowledgement"));
+ proto_tree_add_text(control_tree, tvb, offset, 1,
+ decode_boolean_bitfield(viph.vipc_control, 0x40,
+ 1*8,
+ "End of message",
+ "Not end of message"));
+ proto_tree_add_text(control_tree, tvb, offset, 1,
+ decode_boolean_bitfield(viph.vipc_control, 0x20,
+ 1*8,
+ "Beginning of message",
+ "Not beginning of message"));
+ proto_tree_add_text(control_tree, tvb, offset, 1,
+ decode_boolean_bitfield(viph.vipc_control, 0x10,
+ 1*8,
+ "Abort current message",
+ "Do not abort current message"));
+ }
+ }
+ offset += 1;
+ if (viph.vipc_pkttype != PKTTYPE_DGRAM) {
+ if (tree) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Local Connection ID: 0x%04x",
+ viph.vipc_lclid);
+ }
+ offset += 2;
+ if (tree) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Remote Connection ID: 0x%04x",
+ viph.vipc_rmtid);
+ }
+ offset += 2;
+ if (tree) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Sequence number: %u",
+ viph.vipc_seqno);
+ }
+ offset += 2;
+ if (tree) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Ack number: %u", viph.vipc_ack);
+ }
+ offset += 2;
+ if (tree) {
+ if (viph.vipc_pkttype == PKTTYPE_ERR) {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Error: %s (%u)",
+ val_to_str(viph.vipc_err_len,
+ vipc_err_vals,
+ "Unknown"),
+ viph.vipc_err_len);
+ } else {
+ proto_tree_add_text(vipc_tree, tvb, offset, 2,
+ "Length: %u",
+ viph.vipc_err_len);
+ }
+ }
+ offset += 2;
+ }
+
+ /*
+ * For data packets, try the heuristic dissectors for Vines SPP;
+ * if none of them accept the packet, or if it's not a data packet,
+ * dissect it as data.
+ */
+ next_tvb = tvb_new_subset(tvb, offset, -1, -1);
+ if (viph.vipc_pkttype != PKTTYPE_DATA ||
+ !dissector_try_heuristic(vines_ipc_heur_subdissector_list,
+ next_tvb, pinfo, tree))
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+}
+
+void
+proto_register_vines_ipc(void)
+{
+ static gint *ett[] = {
+ &ett_vines_ipc,
+ &ett_vines_ipc_control,
+ };
+
+ proto_vines_ipc = proto_register_protocol("Banyan Vines IPC",
+ "Vines IPC", "vines_ipc");
+ proto_register_subtree_array(ett, array_length(ett));
+
+ register_heur_dissector_list("vines_ipc",
+ &vines_ipc_heur_subdissector_list);
+}
+
+void
+proto_reg_handoff_vines_ipc(void)
+{
+ dissector_handle_t vines_ipc_handle;
+
+ vines_ipc_handle = create_dissector_handle(dissect_vines_ipc,
+ proto_vines_ipc);
+ dissector_add("vines_ip.protocol", VIP_PROTO_IPC, vines_ipc_handle);
+}
+