diff options
author | Guy Harris <guy@alum.mit.edu> | 2003-04-18 00:32:47 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2003-04-18 00:32:47 +0000 |
commit | 2020b91759f20cccb7aeaade0596cb5ac0da16b3 (patch) | |
tree | 6eb74955c7490867aa793fe40ee64194d4ded46f /packet-vines.c | |
parent | 197b9b228b3ce7c85ae44190fcfe3f7da5b48bf8 (diff) | |
download | wireshark-2020b91759f20cccb7aeaade0596cb5ac0da16b3.tar.gz wireshark-2020b91759f20cccb7aeaade0596cb5ac0da16b3.tar.bz2 wireshark-2020b91759f20cccb7aeaade0596cb5ac0da16b3.zip |
Add support for Vines IPC.
Dissect the transport control field differently for broadcast packets.
svn path=/trunk/; revision=7481
Diffstat (limited to 'packet-vines.c')
-rw-r--r-- | packet-vines.c | 357 |
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); +} + |