aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2011-07-05 08:20:23 +0000
committerAnders Broman <anders.broman@ericsson.com>2011-07-05 08:20:23 +0000
commit9e5a06a2effe7f8f17b51cf996f7410ae16e960a (patch)
tree10b7c30d72194e14db02b2bfe2d33806201eb6b4
parent99d0148b9939612642a89400fb753012cab2cdf2 (diff)
From Sven Eckelmann:
Add support for v14 https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6046 svn path=/trunk/; revision=37901
-rw-r--r--epan/dissectors/packet-batadv.c1176
1 files changed, 1175 insertions, 1 deletions
diff --git a/epan/dissectors/packet-batadv.c b/epan/dissectors/packet-batadv.c
index 765f73feb7..665c810259 100644
--- a/epan/dissectors/packet-batadv.c
+++ b/epan/dissectors/packet-batadv.c
@@ -42,12 +42,23 @@
#define BATADV_BCAST_V5 0x04
#define BATADV_VIS_V5 0x05
#define BATADV_UNICAST_FRAG_V12 0x06
+#define BATADV_TT_QUERY_V14 0x07
+#define BATADV_ROAM_ADV_V14 0x08
#define ECHO_REPLY 0
#define DESTINATION_UNREACHABLE 3
#define ECHO_REQUEST 8
#define TTL_EXCEEDED 11
+#define TT_TYPE_MASK 0x3
+#define TT_REQUEST 0
+#define TT_RESPONSE 1
+
+#define TT_FULL_TABLE 0x04
+
+#define TT_CHANGE_DEL 0x01
+#define TT_CLIENT_ROAM 0x02
+
#define BAT_RR_LEN 16
struct batman_packet_v5 {
@@ -121,6 +132,22 @@ struct batman_packet_v11 {
};
#define BATMAN_PACKET_V11_SIZE 22
+struct batman_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl;
+ guint8 flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */
+ guint32 seqno;
+ address orig;
+ address prev_sender;
+ guint8 gw_flags; /* flags related to gateway class */
+ guint8 tq;
+ guint8 tt_num_changes;
+ guint8 ttvn; /* translation table version number */
+ guint16 tt_crc;
+};
+#define BATMAN_PACKET_V14_SIZE 26
+
struct icmp_packet_v6 {
guint8 packet_type;
guint8 version; /* batman version field */
@@ -145,6 +172,19 @@ struct icmp_packet_v7 {
};
#define ICMP_PACKET_V7_SIZE 19
+struct icmp_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl;
+ guint8 msg_type; /* see ICMP message types above */
+ address dst;
+ address orig;
+ guint16 seqno;
+ guint8 uid;
+ guint8 reserved;
+};
+#define ICMP_PACKET_V14_SIZE 20
+
struct unicast_packet_v6 {
guint8 packet_type;
guint8 version;
@@ -153,6 +193,15 @@ struct unicast_packet_v6 {
};
#define UNICAST_PACKET_V6_SIZE 9
+struct unicast_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl;
+ guint8 ttvn; /* destination translation table version number */
+ address dest;
+};
+#define UNICAST_PACKET_V14_SIZE 12
+
struct unicast_frag_packet_v12 {
guint8 packet_type;
guint8 version;
@@ -164,6 +213,19 @@ struct unicast_frag_packet_v12 {
};
#define UNICAST_FRAG_PACKET_V12_SIZE 18
+struct unicast_frag_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl;
+ guint8 ttvn; /* destination translation table version number */
+ address dest;
+ guint8 flags;
+ guint8 align;
+ address orig;
+ guint16 seqno;
+};
+#define UNICAST_FRAG_PACKET_V14_SIZE 20
+
struct bcast_packet_v6 {
guint8 packet_type;
guint8 version; /* batman version field */
@@ -181,6 +243,16 @@ struct bcast_packet_v10 {
};
#define BCAST_PACKET_V10_SIZE 13
+struct bcast_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl;
+ guint8 reserved;
+ guint32 seqno;
+ address orig;
+};
+#define BCAST_PACKET_V14_SIZE 14
+
struct vis_packet_v6 {
guint8 packet_type;
guint8 version; /* batman version field */
@@ -207,11 +279,50 @@ struct vis_packet_v10 {
};
#define VIS_PACKET_V10_SIZE 27
+struct vis_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl; /* TTL */
+ guint8 vis_type; /* which type of vis-participant sent this? */
+ guint32 seqno; /* sequence number */
+ guint8 entries; /* number of entries behind this struct */
+ guint8 reserved;
+ address vis_orig; /* originator that announces its neighbors */
+ address target_orig; /* who should receive this packet */
+ address sender_orig; /* who sent or rebroadcasted this packet */
+};
+#define VIS_PACKET_V14_SIZE 28
+
#define VIS_ENTRY_V6_SIZE 7
#define VIS_ENTRY_V8_SIZE 13
#define VIS_TYPE_SERVER_SYNC 0
#define VIS_TYPE_CLIENT_UPDATE 1
+
+struct tt_query_packet_v14 {
+ guint8 packet_type;
+ guint8 version; /* batman version field */
+ guint8 ttl;
+ guint8 flags;
+ address dst;
+ address src;
+ guint8 ttvn;
+ guint16 tt_data;
+};
+#define TT_QUERY_PACKET_V14_SIZE 19
+
+#define TT_ENTRY_V14_SIZE 7
+
+struct roam_adv_packet_v14 {
+ guint8 packet_type;
+ guint8 version;
+ guint8 ttl;
+ guint8 reserved;
+ address dst;
+ address src;
+ address client;
+};
+#define ROAM_ADV_PACKET_V14_SIZE 22
/* End content from packet-batadv.h */
/* trees */
@@ -226,6 +337,11 @@ static gint ett_batadv_unicast = -1;
static gint ett_batadv_unicast_frag = -1;
static gint ett_batadv_vis = -1;
static gint ett_batadv_vis_entry = -1;
+static gint ett_batadv_tt_query = -1;
+static gint ett_batadv_tt_query_flags = -1;
+static gint ett_batadv_tt_entry = -1;
+static gint ett_batadv_tt_entry_flags = -1;
+static gint ett_batadv_roam_adv = -1;
static gint ett_msg_fragment = -1;
static gint ett_msg_fragments = -1;
@@ -242,6 +358,9 @@ static int hf_batadv_batman_seqno32 = -1;
static int hf_batadv_batman_orig = -1;
static int hf_batadv_batman_prev_sender = -1;
static int hf_batadv_batman_num_tt = -1;
+static int hf_batadv_batman_tt_num_changes = -1;
+static int hf_batadv_batman_ttvn = -1;
+static int hf_batadv_batman_tt_crc = -1;
static int hf_batadv_batman_tt = -1;
static int hf_batadv_bcast_version = -1;
@@ -261,10 +380,12 @@ static int hf_batadv_icmp_seqno = -1;
static int hf_batadv_unicast_version = -1;
static int hf_batadv_unicast_dst = -1;
static int hf_batadv_unicast_ttl = -1;
+static int hf_batadv_unicast_ttvn = -1;
static int hf_batadv_unicast_frag_version = -1;
static int hf_batadv_unicast_frag_dst = -1;
static int hf_batadv_unicast_frag_ttl = -1;
+static int hf_batadv_unicast_frag_ttvn = -1;
static int hf_batadv_unicast_frag_flags = -1;
static int hf_batadv_unicast_frag_orig = -1;
static int hf_batadv_unicast_frag_seqno = -1;
@@ -282,6 +403,27 @@ static int hf_batadv_vis_entry_src = -1;
static int hf_batadv_vis_entry_dst = -1;
static int hf_batadv_vis_entry_quality = -1;
+static int hf_batadv_tt_query_version = -1;
+static int hf_batadv_tt_query_ttl = -1;
+static int hf_batadv_tt_query_flags = -1;
+static int hf_batadv_tt_query_flags_type = -1;
+static int hf_batadv_tt_query_flags_full_table = -1;
+static int hf_batadv_tt_query_dst = -1;
+static int hf_batadv_tt_query_src = -1;
+static int hf_batadv_tt_query_ttvn = -1;
+static int hf_batadv_tt_query_tt_crc = -1;
+static int hf_batadv_tt_query_entries = -1;
+static int hf_batadv_tt_entry = -1;
+static int hf_batadv_tt_entry_flags = -1;
+static int hf_batadv_tt_entry_flags_change_del = -1;
+static int hf_batadv_tt_entry_flags_client_roam = -1;
+
+static int hf_batadv_roam_adv_version = -1;
+static int hf_batadv_roam_adv_ttl = -1;
+static int hf_batadv_roam_adv_dst = -1;
+static int hf_batadv_roam_adv_src = -1;
+static int hf_batadv_roam_adv_client = -1;
+
static int hf_msg_fragments = -1;
static int hf_msg_fragment = -1;
static int hf_msg_fragment_overlap = -1;
@@ -314,6 +456,12 @@ static const value_string vis_packettypenames[] = {
{ 0, NULL }
};
+static const value_string tt_query_type_v14[] = {
+ {TT_REQUEST, "Request"},
+ {TT_RESPONSE, "Response"},
+ {0, NULL}
+};
+
static const fragment_items msg_frag_items = {
/* Fragment subtrees */
&ett_msg_fragment,
@@ -347,28 +495,42 @@ static int dissect_batadv_batman_v7(tvbuff_t *tvb, int offset, packet_info *pinf
static int dissect_batadv_batman_v9(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
static int dissect_batadv_batman_v10(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
static int dissect_batadv_batman_v11(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
+static int dissect_batadv_batman_v14(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_bcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_bcast_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_bcast_v10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_bcast_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_icmp_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_icmp_v7(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_icmp_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_unicast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
-static void dissect_batadv_unicast_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_unicast_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_unicast_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+static void dissect_batadv_unicast_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_unicast_frag_v12(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_unicast_frag_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_vis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_vis_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_vis_v10(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_vis_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_batadv_tt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_vis_entry_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static void dissect_vis_entry_v8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_tt_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_tt_query_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_tt_entry_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
+static void dissect_batadv_roam_adv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+static void dissect_batadv_roam_adv_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
+
/* other dissectors */
static dissector_handle_t data_handle;
static dissector_handle_t eth_handle;
@@ -412,6 +574,12 @@ static void dissect_batman_plugin(tvbuff_t *tvb, packet_info *pinfo, proto_tree
case BATADV_VIS_V5:
dissect_batadv_vis(tvb, pinfo, tree);
break;
+ case BATADV_TT_QUERY_V14:
+ dissect_batadv_tt_query(tvb, pinfo, tree);
+ break;
+ case BATADV_ROAM_ADV_V14:
+ dissect_batadv_roam_adv(tvb, pinfo, tree);
+ break;
default:
/* dunno */
{
@@ -467,6 +635,11 @@ static void dissect_batadv_batman(tvbuff_t *tvb, packet_info *pinfo, proto_tree
offset = dissect_batadv_batman_v10(tvb, offset, pinfo, tree);
}
break;
+ case 14:
+ while (offset != -1 && tvb_length_remaining(tvb, offset) >= BATMAN_PACKET_V14_SIZE) {
+ offset = dissect_batadv_batman_v14(tvb, offset, pinfo, tree);
+ }
+ break;
default:
col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
call_dissector(data_handle, tvb, pinfo, tree);
@@ -1029,6 +1202,130 @@ static int dissect_batadv_batman_v11(tvbuff_t *tvb, int offset, packet_info *pin
return offset;
}
+static int dissect_batadv_batman_v14(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *tf, *tgw;
+ proto_tree *batadv_batman_tree = NULL, *flag_tree;
+ guint8 type;
+ struct batman_packet_v14 *batman_packeth;
+ const guint8 *prev_sender_addr, *orig_addr;
+ gint i;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+
+ batman_packeth = ep_alloc(sizeof(struct batman_packet_v14));
+
+ type = tvb_get_guint8(tvb, offset+0);
+ batman_packeth->version = tvb_get_guint8(tvb, offset+1);
+
+ /* don't interpret padding as B.A.T.M.A.N. advanced packet */
+ if (batman_packeth->version == 0 || type != BATADV_PACKET_V5) {
+ return -1;
+ }
+
+ batman_packeth->ttl = tvb_get_guint8(tvb, offset+2);
+ batman_packeth->flags = tvb_get_guint8(tvb, offset+3);
+ batman_packeth->seqno = tvb_get_ntohl(tvb, offset+4);
+ orig_addr = tvb_get_ptr(tvb, offset+8, 6);
+ SET_ADDRESS(&batman_packeth->orig, AT_ETHER, 6, orig_addr);
+ prev_sender_addr = tvb_get_ptr(tvb, offset+14, 6);
+ SET_ADDRESS(&batman_packeth->prev_sender, AT_ETHER, 6, prev_sender_addr);
+ batman_packeth->gw_flags = tvb_get_guint8(tvb, offset+20);
+ batman_packeth->tq = tvb_get_guint8(tvb, offset+21);
+ batman_packeth->tt_num_changes = tvb_get_guint8(tvb, offset+22);
+ batman_packeth->ttvn = tvb_get_guint8(tvb, offset+23);
+ batman_packeth->tt_crc = tvb_get_ntohs(tvb, offset+24);
+
+ /* Set info column */
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Seq=%u", batman_packeth->seqno);
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, offset, BATMAN_PACKET_V14_SIZE,
+ "B.A.T.M.A.N., Orig: %s (%s)",
+ get_ether_name(orig_addr), ether_to_str(orig_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, offset, BATMAN_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_batman_tree = proto_item_add_subtree(ti, ett_batadv_batman);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_batman_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_PACKET_V5,
+ "Packet Type: %s (%u)", "BATADV_PACKET", BATADV_PACKET_V5);
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ tf = proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_flags, tvb, offset, 1, FALSE);
+ /* <flags> */
+ flag_tree = proto_item_add_subtree(tf, ett_batadv_batman_flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_batman_flags_directlink, tvb, offset, 1, batman_packeth->flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_batman_flags_vis_server, tvb, offset, 1, batman_packeth->flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_batman_flags_primaries_first_hop, tvb, offset, 1, batman_packeth->flags);
+ /* </flags> */
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_seqno32, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_ether(batadv_batman_tree, hf_batadv_batman_orig, tvb, offset, 6, orig_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_batman_tree, hf_batadv_batman_prev_sender, tvb, offset, 6, prev_sender_addr);
+ offset += 6;
+
+ tgw = proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_gwflags, tvb, offset, 1, FALSE);
+ dissect_batadv_gwflags(tvb, batman_packeth->gw_flags, offset, tgw);
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_tq, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_tt_num_changes, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_ttvn, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_batman_tree, hf_batadv_batman_tt_crc, tvb, offset, 2, FALSE);
+ offset += 2;
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, orig_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, orig_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, batman_packeth);
+
+ for (i = 0; i < batman_packeth->tt_num_changes; i++) {
+ next_tvb = tvb_new_subset(tvb, offset, TT_ENTRY_V14_SIZE, TT_ENTRY_V14_SIZE);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ dissect_tt_entry_v14(next_tvb, pinfo, batadv_batman_tree);
+ offset += TT_ENTRY_V14_SIZE;
+ }
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
+
+ return offset;
+}
+
static void dissect_batadv_tt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
const guint8 *tt;
@@ -1074,6 +1371,9 @@ static void dissect_batadv_bcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
case 13:
dissect_batadv_bcast_v10(tvb, pinfo, tree);
break;
+ case 14:
+ dissect_batadv_bcast_v14(tvb, pinfo, tree);
+ break;
default:
col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
call_dissector(data_handle, tvb, pinfo, tree);
@@ -1217,6 +1517,80 @@ static void dissect_batadv_bcast_v10(tvbuff_t *tvb, packet_info *pinfo, proto_tr
}
}
+static void dissect_batadv_bcast_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct bcast_packet_v14 *bcast_packeth;
+ const guint8 *orig_addr;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+ int offset = 0;
+ proto_tree *batadv_bcast_tree = NULL;
+
+ bcast_packeth = ep_alloc(sizeof(struct bcast_packet_v14));
+
+ bcast_packeth->version = tvb_get_guint8(tvb, 1);
+ bcast_packeth->ttl = tvb_get_guint8(tvb, 2);
+ bcast_packeth->reserved = tvb_get_guint8(tvb, 3);
+ bcast_packeth->seqno = tvb_get_ntohl(tvb, 4);
+ orig_addr = tvb_get_ptr(tvb, 8, 6);
+ SET_ADDRESS(&bcast_packeth->orig, AT_ETHER, 6, orig_addr);
+
+ /* Set info column */
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Seq=%u", bcast_packeth->seqno);
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, BCAST_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. Bcast, Orig: %s (%s)",
+ get_ether_name(orig_addr), ether_to_str(orig_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, BCAST_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_bcast_tree = proto_item_add_subtree(ti, ett_batadv_bcast);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_bcast_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_BCAST_V5,
+ "Packet Type: %s (%u)", "BATADV_BCAST", BATADV_BCAST_V5);
+ offset += 1;
+
+ proto_tree_add_item(batadv_bcast_tree, hf_batadv_bcast_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_bcast_tree, hf_batadv_bcast_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ /* Skip 1 byte of padding. */
+ offset += 1;
+
+ proto_tree_add_item(batadv_bcast_tree, hf_batadv_bcast_seqno32, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_ether(batadv_bcast_tree, hf_batadv_bcast_orig, tvb, offset, 6, orig_addr);
+ offset += 6;
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, orig_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, orig_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, bcast_packeth);
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ call_dissector(eth_handle, next_tvb, pinfo, tree);
+ }
+}
+
static void dissect_batadv_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 version;
@@ -1238,6 +1612,9 @@ static void dissect_batadv_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
case 13:
dissect_batadv_icmp_v7(tvb, pinfo, tree);
break;
+ case 14:
+ dissect_batadv_icmp_v14(tvb, pinfo, tree);
+ break;
default:
col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
call_dissector(data_handle, tvb, pinfo, tree);
@@ -1448,6 +1825,102 @@ static void dissect_batadv_icmp_v7(tvbuff_t *tvb, packet_info *pinfo, proto_tree
}
}
+static void dissect_batadv_icmp_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct icmp_packet_v14 *icmp_packeth;
+ const guint8 *dst_addr, *orig_addr;
+ proto_item *ti;
+ proto_tree *batadv_icmp_tree = NULL;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+ int offset = 0;
+
+ icmp_packeth = ep_alloc(sizeof(struct icmp_packet_v14));
+
+ icmp_packeth->version = tvb_get_guint8(tvb, 1);
+ icmp_packeth->ttl = tvb_get_guint8(tvb, 2);
+ icmp_packeth->msg_type = tvb_get_guint8(tvb, 3);
+ dst_addr = tvb_get_ptr(tvb, 4, 6);
+ SET_ADDRESS(&icmp_packeth->dst, AT_ETHER, 6, dst_addr);
+ orig_addr = tvb_get_ptr(tvb, 10, 6);
+ SET_ADDRESS(&icmp_packeth->orig, AT_ETHER, 6, orig_addr);
+ icmp_packeth->seqno = tvb_get_ntohs(tvb, 16);
+ icmp_packeth->uid = tvb_get_guint8(tvb, 17);
+ icmp_packeth->reserved = tvb_get_guint8(tvb, 18);
+
+ /* Set info column */
+ if (check_col(pinfo->cinfo, COL_INFO)) {
+ col_add_fstr(pinfo->cinfo, COL_INFO, "[%s] Seq=%u",
+ val_to_str(icmp_packeth->msg_type, icmp_packettypenames, "Unknown (0x%02x)"),
+ icmp_packeth->seqno);
+ }
+
+ /* Set tree info */
+ if (tree) {
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, ICMP_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. ICMP, Orig: %s (%s), Dst: %s (%s)",
+ get_ether_name(orig_addr), ether_to_str(orig_addr), get_ether_name(dst_addr), ether_to_str(dst_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, ICMP_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_icmp_tree = proto_item_add_subtree(ti, ett_batadv_icmp);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_icmp_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_ICMP_V5,
+ "Packet Type: %s (%u)", "BATADV_ICMP", BATADV_ICMP_V5);
+ offset += 1;
+
+ proto_tree_add_item(batadv_icmp_tree, hf_batadv_icmp_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_icmp_tree, hf_batadv_icmp_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_icmp_tree, hf_batadv_icmp_msg_type, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_ether(batadv_icmp_tree, hf_batadv_icmp_dst, tvb, offset, 6, dst_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_icmp_tree, hf_batadv_icmp_orig, tvb, offset, 6, orig_addr);
+ offset += 6;
+
+ proto_tree_add_item(batadv_icmp_tree, hf_batadv_icmp_seqno, tvb, offset, 2, FALSE);
+ offset += 2;
+
+ proto_tree_add_item(batadv_icmp_tree, hf_batadv_icmp_uid, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ /* Skip 1 byte of padding. */
+ offset += 1;
+
+ /* rr data available? */
+ length_remaining = tvb_length_remaining(tvb, offset);
+ if (length_remaining >= 1 + BAT_RR_LEN * 6) {
+ dissect_batadv_icmp_rr(batadv_icmp_tree, tvb, offset);
+ offset += 1 + BAT_RR_LEN * 6;
+ }
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, orig_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, orig_addr);
+
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, orig_addr);
+ SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, orig_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, icmp_packeth);
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
+}
+
static void dissect_batadv_unicast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 version;
@@ -1467,6 +1940,9 @@ static void dissect_batadv_unicast(tvbuff_t *tvb, packet_info *pinfo, proto_tree
case 13:
dissect_batadv_unicast_v6(tvb, pinfo, tree);
break;
+ case 14:
+ dissect_batadv_unicast_v14(tvb, pinfo, tree);
+ break;
default:
col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
call_dissector(data_handle, tvb, pinfo, tree);
@@ -1540,6 +2016,76 @@ static void dissect_batadv_unicast_v6(tvbuff_t *tvb, packet_info *pinfo, proto_t
}
}
+static void dissect_batadv_unicast_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct unicast_packet_v14 *unicast_packeth;
+ const guint8 *dest_addr;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+ int offset = 0;
+ proto_tree *batadv_unicast_tree = NULL;
+
+ unicast_packeth = ep_alloc(sizeof(struct unicast_packet_v14));
+
+ unicast_packeth->version = tvb_get_guint8(tvb, 1);
+ unicast_packeth->ttl = tvb_get_guint8(tvb, 2);
+ unicast_packeth->ttvn = tvb_get_guint8(tvb, 3);
+ dest_addr = tvb_get_ptr(tvb, 4, 6);
+ SET_ADDRESS(&unicast_packeth->dest, AT_ETHER, 6, dest_addr);
+
+ /* Set info column */
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, UNICAST_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. Unicast, Dst: %s (%s)",
+ get_ether_name(dest_addr), ether_to_str(dest_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, UNICAST_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_unicast_tree = proto_item_add_subtree(ti, ett_batadv_unicast);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_unicast_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_UNICAST_V5,
+ "Packet Type: %s (%u)", "BATADV_UNICAST", BATADV_UNICAST_V5);
+ offset += 1;
+
+ proto_tree_add_item(batadv_unicast_tree, hf_batadv_unicast_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_unicast_tree, hf_batadv_unicast_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_unicast_tree, hf_batadv_unicast_ttvn, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_ether(batadv_unicast_tree, hf_batadv_unicast_dst, tvb, offset, 6, dest_addr);
+ offset += 6;
+
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dest_addr);
+ SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dest_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, unicast_packeth);
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ call_dissector(eth_handle, next_tvb, pinfo, tree);
+ }
+}
+
static void dissect_batadv_unicast_frag(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 version;
@@ -1553,6 +2099,9 @@ static void dissect_batadv_unicast_frag(tvbuff_t *tvb, packet_info *pinfo, proto
case 13:
dissect_batadv_unicast_frag_v12(tvb, pinfo, tree);
break;
+ case 14:
+ dissect_batadv_unicast_frag_v14(tvb, pinfo, tree);
+ break;
default:
col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
call_dissector(data_handle, tvb, pinfo, tree);
@@ -1663,6 +2212,117 @@ static void dissect_batadv_unicast_frag_v12(tvbuff_t *tvb, packet_info *pinfo, p
pinfo->fragmented = save_fragmented;
}
+static void dissect_batadv_unicast_frag_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_item *tf;
+ struct unicast_frag_packet_v14 *unicast_frag_packeth;
+ const guint8 *dest_addr, *orig_addr;
+ gboolean save_fragmented = FALSE;
+ fragment_data *frag_msg = NULL;
+ proto_tree *batadv_unicast_frag_tree = NULL, *flag_tree;
+
+ tvbuff_t *new_tvb;
+ int offset = 0;
+ int head = 0;
+
+ unicast_frag_packeth = ep_alloc(sizeof(struct unicast_frag_packet_v14));
+
+ unicast_frag_packeth->version = tvb_get_guint8(tvb, 1);
+ unicast_frag_packeth->ttl = tvb_get_guint8(tvb, 2);
+ unicast_frag_packeth->ttvn = tvb_get_guint8(tvb, 3);
+ dest_addr = tvb_get_ptr(tvb, 4, 6);
+ SET_ADDRESS(&unicast_frag_packeth->dest, AT_ETHER, 6, dest_addr);
+ unicast_frag_packeth->flags = tvb_get_guint8(tvb, 10);
+ unicast_frag_packeth->align = tvb_get_guint8(tvb, 11);
+ orig_addr = tvb_get_ptr(tvb, 12, 6);
+ SET_ADDRESS(&unicast_frag_packeth->orig, AT_ETHER, 6, orig_addr);
+ unicast_frag_packeth->seqno = tvb_get_ntohs(tvb, 18);
+
+ save_fragmented = pinfo->fragmented;
+ pinfo->fragmented = TRUE;
+
+ /* Set info column */
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, UNICAST_FRAG_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. Unicast Fragment, Dst: %s (%s)",
+ get_ether_name(dest_addr), ether_to_str(dest_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, UNICAST_FRAG_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_unicast_frag_tree = proto_item_add_subtree(ti, ett_batadv_unicast_frag);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_unicast_frag_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_UNICAST_FRAG_V12,
+ "Packet Type: %s (%u)", "BATADV_UNICAST", BATADV_UNICAST_FRAG_V12);
+ offset += 1;
+
+ proto_tree_add_item(batadv_unicast_frag_tree, hf_batadv_unicast_frag_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_unicast_frag_tree, hf_batadv_unicast_frag_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_unicast_frag_tree, hf_batadv_unicast_frag_ttvn, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_ether(batadv_unicast_frag_tree, hf_batadv_unicast_frag_dst, tvb, offset, 6, dest_addr);
+ offset += 6;
+
+ tf = proto_tree_add_item(batadv_unicast_frag_tree, hf_batadv_unicast_frag_flags, tvb, offset, 1, FALSE);
+ /* <flags> */
+ flag_tree = proto_item_add_subtree(tf, ett_batadv_batman_flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_unicast_frag_flags_head, tvb, offset, 1, unicast_frag_packeth->flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_unicast_frag_flags_largetail, tvb, offset, 1, unicast_frag_packeth->flags);
+ /* </flags> */
+ offset += 1;
+
+ /* Skip 1 byte of padding. */
+ offset += 1;
+
+ proto_tree_add_ether(batadv_unicast_frag_tree, hf_batadv_unicast_frag_orig, tvb, offset, 6, orig_addr);
+ offset += 6;
+
+ proto_tree_add_item(batadv_unicast_frag_tree, hf_batadv_unicast_frag_seqno, tvb, offset, 2, FALSE);
+ offset += 2;
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, orig_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, orig_addr);
+
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dest_addr);
+ SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dest_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, unicast_frag_packeth);
+
+ head = (unicast_frag_packeth->flags & 0x1);
+ frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
+ unicast_frag_packeth->seqno + head,
+ msg_fragment_table,
+ msg_reassembled_table,
+ 1 - head,
+ tvb_length_remaining(tvb, offset),
+ head);
+
+ new_tvb = process_reassembled_data(tvb, offset, pinfo,
+ "Reassembled Message", frag_msg, &msg_frag_items,
+ NULL, batadv_unicast_frag_tree);
+ if (new_tvb) {
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, new_tvb);
+ }
+
+ call_dissector(eth_handle, new_tvb, pinfo, tree);
+ }
+
+ pinfo->fragmented = save_fragmented;
+}
+
static void dissect_batadv_vis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
guint8 version;
@@ -1684,6 +2344,9 @@ static void dissect_batadv_vis(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
case 13:
dissect_batadv_vis_v10(tvb, pinfo, tree);
break;
+ case 14:
+ dissect_batadv_vis_v14(tvb, pinfo, tree);
+ break;
default:
col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
call_dissector(data_handle, tvb, pinfo, tree);
@@ -1925,6 +2588,114 @@ static void dissect_batadv_vis_v10(tvbuff_t *tvb, packet_info *pinfo, proto_tree
}
}
+static void dissect_batadv_vis_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct vis_packet_v14 *vis_packeth;
+ const guint8 *vis_orig_addr, *target_orig_addr, *sender_orig_addr;
+ proto_tree *batadv_vis_tree = NULL;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+ int offset = 0, i;
+
+ vis_packeth = ep_alloc(sizeof(struct vis_packet_v14));
+
+ vis_packeth->version = tvb_get_guint8(tvb, 1);
+ vis_packeth->ttl = tvb_get_guint8(tvb, 2);
+ vis_packeth->vis_type = tvb_get_guint8(tvb, 3);
+ vis_packeth->seqno = tvb_get_ntohl(tvb, 4);
+ vis_packeth->entries = tvb_get_guint8(tvb, 8);
+ vis_packeth->reserved = tvb_get_guint8(tvb, 9);
+
+ vis_orig_addr = tvb_get_ptr(tvb, 10, 6);
+ SET_ADDRESS(&vis_packeth->vis_orig, AT_ETHER, 6, vis_orig_addr);
+ target_orig_addr = tvb_get_ptr(tvb, 16, 6);
+ SET_ADDRESS(&vis_packeth->target_orig, AT_ETHER, 6, target_orig_addr);
+ sender_orig_addr = tvb_get_ptr(tvb, 22, 6);
+ SET_ADDRESS(&vis_packeth->sender_orig, AT_ETHER, 6, sender_orig_addr);
+
+ /* Set info column */
+ col_add_fstr(pinfo->cinfo, COL_INFO, "[%s] Seq=%u",
+ val_to_str(vis_packeth->vis_type, vis_packettypenames, "Unknown (0x%02x)"),
+ vis_packeth->seqno);
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, VIS_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. Vis, Orig: %s (%s)",
+ get_ether_name(vis_orig_addr), ether_to_str(vis_orig_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, VIS_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_vis_tree = proto_item_add_subtree(ti, ett_batadv_vis);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_vis_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_VIS_V5,
+ "Packet Type: %s (%u)", "BATADV_VIS", BATADV_VIS_V5);
+ offset += 1;
+
+ proto_tree_add_item(batadv_vis_tree, hf_batadv_vis_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_vis_tree, hf_batadv_vis_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_vis_tree, hf_batadv_vis_type, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_vis_tree, hf_batadv_vis_seqno32, tvb, offset, 4, FALSE);
+ offset += 4;
+
+ proto_tree_add_item(batadv_vis_tree, hf_batadv_vis_entries, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ /* Skip 1 byte of padding. */
+ offset += 1;
+
+ proto_tree_add_ether(batadv_vis_tree, hf_batadv_vis_vis_orig, tvb, offset, 6, vis_orig_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_vis_tree, hf_batadv_vis_target_orig, tvb, offset, 6, target_orig_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_vis_tree, hf_batadv_vis_sender_orig, tvb, offset, 6, sender_orig_addr);
+ offset += 6;
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, sender_orig_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, vis_orig_addr);
+
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, target_orig_addr);
+ SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, target_orig_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, vis_packeth);
+
+ for (i = 0; i < vis_packeth->entries; i++) {
+ next_tvb = tvb_new_subset(tvb, offset, VIS_ENTRY_V8_SIZE, VIS_ENTRY_V8_SIZE);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ dissect_vis_entry_v8(next_tvb, pinfo, batadv_vis_tree);
+ offset += VIS_ENTRY_V8_SIZE;
+ }
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
+}
+
static void dissect_vis_entry_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
{
const guint8 *dst;
@@ -1975,6 +2746,284 @@ static void dissect_vis_entry_v8(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr
proto_tree_add_item(batadv_vis_entry_tree, hf_batadv_vis_entry_quality, tvb, 12, 1, FALSE);
}
+static void dissect_batadv_tt_query(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint8 version;
+
+ /* set protocol name */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "BATADV_TT_QUERY");
+
+ version = tvb_get_guint8(tvb, 1);
+ switch (version) {
+ case 14:
+ dissect_batadv_tt_query_v14(tvb, pinfo, tree);
+ break;
+ default:
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
+ call_dissector(data_handle, tvb, pinfo, tree);
+ break;
+ }
+}
+
+static void dissect_batadv_tt_query_v14(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ struct tt_query_packet_v14 *tt_query_packeth;
+ const guint8 *dst_addr, *src_addr;
+ proto_item *tf;
+ proto_tree *batadv_tt_query_tree = NULL, *flag_tree;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+ int offset = 0, i;
+ int tt_type;
+
+ tt_query_packeth = ep_alloc(sizeof(struct tt_query_packet_v14));
+
+ tt_query_packeth->version = tvb_get_guint8(tvb, 1);
+ tt_query_packeth->ttl = tvb_get_guint8(tvb, 2);
+ tt_query_packeth->flags = tvb_get_guint8(tvb, 3);
+
+ dst_addr = tvb_get_ptr(tvb, 4, 6);
+ SET_ADDRESS(&tt_query_packeth->dst, AT_ETHER, 6, dst_addr);
+ src_addr = tvb_get_ptr(tvb, 10, 6);
+ SET_ADDRESS(&tt_query_packeth->src, AT_ETHER, 6, src_addr);
+ tt_query_packeth->ttvn = tvb_get_guint8(tvb, 16);
+ tt_query_packeth->tt_data = tvb_get_ntohs(tvb, 17);
+
+ tt_type = TT_TYPE_MASK & tt_query_packeth->flags;
+
+ /* Set info column */
+ switch (tt_type) {
+ case TT_REQUEST:
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Request=%hu", tt_query_packeth->ttvn);
+ break;
+ case TT_RESPONSE:
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Response=%hu", tt_query_packeth->ttvn);
+ break;
+ default:
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Type %u", tt_type);
+ break;
+ }
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, TT_QUERY_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. TT Query, Dst: %s (%s)",
+ get_ether_name(dst_addr), ether_to_str(dst_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, TT_QUERY_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_tt_query_tree = proto_item_add_subtree(ti, ett_batadv_tt_query);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_tt_query_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_TT_QUERY_V14,
+ "Packet Type: %s (%u)", "BATADV_TT_QUERY", BATADV_TT_QUERY_V14);
+ offset += 1;
+
+ proto_tree_add_item(batadv_tt_query_tree, hf_batadv_tt_query_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_tt_query_tree, hf_batadv_tt_query_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ tf = proto_tree_add_item(batadv_tt_query_tree, hf_batadv_tt_query_flags, tvb, offset, 1, FALSE);
+ /* <flags> */
+ flag_tree = proto_item_add_subtree(tf, ett_batadv_tt_query_flags);
+ proto_tree_add_uint(flag_tree, hf_batadv_tt_query_flags_type, tvb, offset, 1, tt_type);
+ proto_tree_add_boolean(flag_tree, hf_batadv_tt_query_flags_full_table, tvb, offset, 1, tt_query_packeth->flags);
+ /* </flags> */
+ offset += 1;
+
+ proto_tree_add_ether(batadv_tt_query_tree, hf_batadv_tt_query_dst, tvb, offset, 6, dst_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_tt_query_tree, hf_batadv_tt_query_src, tvb, offset, 6, src_addr);
+ offset += 6;
+
+ proto_tree_add_item(batadv_tt_query_tree, hf_batadv_tt_query_ttvn, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ switch (tt_type) {
+ case TT_REQUEST:
+ proto_tree_add_item(batadv_tt_query_tree, hf_batadv_tt_query_tt_crc, tvb, offset, 2, FALSE);
+ break;
+ case TT_RESPONSE:
+ proto_tree_add_item(batadv_tt_query_tree, hf_batadv_tt_query_entries, tvb, offset, 2, FALSE);
+ break;
+ default:
+ break;
+ }
+ offset += 2;
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src_addr);
+
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst_addr);
+ SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, tt_query_packeth);
+
+ if (tt_type == TT_RESPONSE) {
+ for (i = 0; i < tt_query_packeth->tt_data; i++) {
+ next_tvb = tvb_new_subset(tvb, offset, TT_ENTRY_V14_SIZE, TT_ENTRY_V14_SIZE);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ dissect_tt_entry_v14(next_tvb, pinfo, batadv_tt_query_tree);
+ offset += TT_ENTRY_V14_SIZE;
+ }
+ }
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
+}
+
+static void dissect_tt_entry_v14(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
+{
+ const guint8 *entry;
+ guint8 flags;
+ proto_item *tf;
+ proto_tree *batadv_tt_entry_tree = NULL, *flag_tree;
+
+ flags = tvb_get_guint8(tvb, 0);
+ entry = tvb_get_ptr(tvb, 1, 6);
+
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, TT_ENTRY_V14_SIZE,
+ "TT Entry: %s (%s)",
+ get_ether_name(entry), ether_to_str(entry));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, TT_ENTRY_V14_SIZE, FALSE);
+ }
+ batadv_tt_entry_tree = proto_item_add_subtree(ti, ett_batadv_tt_entry);
+ }
+
+ tf = proto_tree_add_item(batadv_tt_entry_tree, hf_batadv_tt_entry_flags, tvb, 0, 1, FALSE);
+ /* <flags> */
+ flag_tree = proto_item_add_subtree(tf, ett_batadv_tt_entry_flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_tt_entry_flags_change_del, tvb, 0, 1, flags);
+ proto_tree_add_boolean(flag_tree, hf_batadv_tt_entry_flags_client_roam, tvb, 0, 1, flags);
+ /* </flags> */
+ proto_tree_add_ether(batadv_tt_entry_tree, hf_batadv_tt_entry, tvb, 1, 6, entry);
+}
+
+static void dissect_batadv_roam_adv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint8 version;
+
+ /* set protocol name */
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "BATADV_ROAM_ADV");
+
+ version = tvb_get_guint8(tvb, 1);
+ switch (version) {
+ case 14:
+ dissect_batadv_roam_adv_v14(tvb, pinfo, tree);
+ break;
+ default:
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Unsupported Version %d", version);
+ call_dissector(data_handle, tvb, pinfo, tree);
+ break;
+ }
+}
+
+static void dissect_batadv_roam_adv_v14(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ struct roam_adv_packet_v14 *roam_adv_packeth;
+ const guint8 *dst_addr, *src_addr, *client_addr;
+ proto_tree *batadv_roam_adv_tree = NULL;
+
+ tvbuff_t *next_tvb;
+ guint length_remaining;
+ int offset = 0;
+
+ roam_adv_packeth = ep_alloc(sizeof(struct roam_adv_packet_v14));
+
+ roam_adv_packeth->version = tvb_get_guint8(tvb, 1);
+ roam_adv_packeth->ttl = tvb_get_guint8(tvb, 2);
+ dst_addr = tvb_get_ptr(tvb, 4, 6);
+ SET_ADDRESS(&roam_adv_packeth->dst, AT_ETHER, 6, dst_addr);
+ src_addr = tvb_get_ptr(tvb, 10, 6);
+ SET_ADDRESS(&roam_adv_packeth->src, AT_ETHER, 6, src_addr);
+ client_addr = tvb_get_ptr(tvb, 16, 6);
+ SET_ADDRESS(&roam_adv_packeth->client, AT_ETHER, 6, client_addr);
+
+ /* Set info column */
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Client %s (%s)", get_ether_name(client_addr), ether_to_str(client_addr));
+
+ /* Set tree info */
+ if (tree) {
+ proto_item *ti;
+
+ if (PTREE_DATA(tree)->visible) {
+ ti = proto_tree_add_protocol_format(tree, proto_batadv_plugin, tvb, 0, ROAM_ADV_PACKET_V14_SIZE,
+ "B.A.T.M.A.N. Roam: %s (%s)",
+ get_ether_name(client_addr), ether_to_str(client_addr));
+ } else {
+ ti = proto_tree_add_item(tree, proto_batadv_plugin, tvb, 0, ROAM_ADV_PACKET_V14_SIZE, FALSE);
+ }
+ batadv_roam_adv_tree = proto_item_add_subtree(ti, ett_batadv_roam_adv);
+ }
+
+ /* items */
+ proto_tree_add_uint_format(batadv_roam_adv_tree, hf_batadv_packet_type, tvb, offset, 1, BATADV_ROAM_ADV_V14,
+ "Packet Type: %s (%u)", "BATADV_ROAM_ADV", BATADV_ROAM_ADV_V14);
+ offset += 1;
+
+ proto_tree_add_item(batadv_roam_adv_tree, hf_batadv_roam_adv_version, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ proto_tree_add_item(batadv_roam_adv_tree, hf_batadv_roam_adv_ttl, tvb, offset, 1, FALSE);
+ offset += 1;
+
+ /* Skip 1 byte of padding. */
+ offset += 1;
+
+ proto_tree_add_ether(batadv_roam_adv_tree, hf_batadv_roam_adv_dst, tvb, offset, 6, dst_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_roam_adv_tree, hf_batadv_roam_adv_src, tvb, offset, 6, src_addr);
+ offset += 6;
+
+ proto_tree_add_ether(batadv_roam_adv_tree, hf_batadv_roam_adv_client, tvb, offset, 6, client_addr);
+ offset += 6;
+
+ SET_ADDRESS(&pinfo->dl_src, AT_ETHER, 6, src_addr);
+ SET_ADDRESS(&pinfo->src, AT_ETHER, 6, src_addr);
+
+ SET_ADDRESS(&pinfo->dl_dst, AT_ETHER, 6, dst_addr);
+ SET_ADDRESS(&pinfo->dst, AT_ETHER, 6, dst_addr);
+
+ tap_queue_packet(batadv_tap, pinfo, roam_adv_packeth);
+
+ length_remaining = tvb_length_remaining(tvb, offset);
+ if (length_remaining != 0) {
+ next_tvb = tvb_new_subset(tvb, offset, length_remaining, -1);
+
+ if (have_tap_listener(batadv_follow_tap)) {
+ tap_queue_packet(batadv_follow_tap, pinfo, next_tvb);
+ }
+
+ call_dissector(data_handle, next_tvb, pinfo, tree);
+ }
+}
+
static void batadv_init_routine(void)
{
fragment_table_init(&msg_fragment_table);
@@ -2041,6 +3090,21 @@ void proto_register_batadv(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_batadv_batman_tt_num_changes,
+ { "Number of TT Changes", "batadv.batman.tt_num_changes",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_batman_ttvn,
+ { "TT Version", "batadv.batman.ttvn",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_batman_tt_crc,
+ { "CRC of TT", "batadv.batman.tt_crc",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_batadv_batman_flags_directlink,
{ "DirectLink", "batadv.batman.flags.directlink",
FT_BOOLEAN, 8, TFS(&tfs_set_notset), 0x40,
@@ -2136,6 +3200,11 @@ void proto_register_batadv(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_batadv_unicast_ttvn,
+ { "TT Version", "batadv.unicast.ttvn",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_batadv_unicast_frag_version,
{ "Version", "batadv.unicast_frag.version",
FT_UINT8, BASE_DEC, NULL, 0x0,
@@ -2151,6 +3220,11 @@ void proto_register_batadv(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_batadv_unicast_frag_ttvn,
+ { "TT Version", "batadv.unicast_frag.ttvn",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_batadv_unicast_frag_flags,
{ "Flags", "batadv.unicast_frag.flags",
FT_UINT8, BASE_HEX, NULL, 0x0,
@@ -2236,11 +3310,106 @@ void proto_register_batadv(void)
FT_UINT8, BASE_DEC, NULL, 0x0,
NULL, HFILL }
},
+ { &hf_batadv_tt_query_version,
+ { "Version", "batadv.tt_query.version",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_ttl,
+ { "Time to Live", "batadv.tt_query.ttl",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_batadv_tt_query_flags,
+ { "Flags", "batadv.tt_query.flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_flags_type,
+ { "Query Type", "batadv.tt_query.flags.type",
+ FT_UINT8, BASE_HEX, VALS (&tt_query_type_v14), TT_TYPE_MASK,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_flags_full_table,
+ { "Full Table", "batadv.tt_query.flags.full_table",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), TT_FULL_TABLE,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_dst,
+ { "Destination", "batadv.tt_query.dst",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_src,
+ { "Source", "batadv.tt_query.src",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_ttvn,
+ { "TT Version", "batadv.tt_query.ttvn",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_tt_crc,
+ { "CRC of TT", "batadv.tt_query.tt_crc",
+ FT_UINT16, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_query_entries,
+ { "Entries", "batadv.tt_query.entries",
+ FT_UINT16, BASE_DEC, NULL, 0x0,
+ "Number of entries", HFILL }
+ },
+ { &hf_batadv_roam_adv_version,
+ { "Version", "batadv.roam_adv.version",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_roam_adv_ttl,
+ { "Time to Live", "batadv.roam_adv.ttl",
+ FT_UINT8, BASE_DEC, NULL, 0x0,
+ NULL, HFILL}
+ },
+ { &hf_batadv_roam_adv_src,
+ { "Source", "batadv.roam_adv.src",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_roam_adv_dst,
+ { "Destination", "batadv.roam_adv.dst",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_roam_adv_client,
+ { "Client", "batadv.roam_adv.client",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
{ &hf_msg_fragments,
{"Message fragments", "batadv.unicast_frag.fragments",
FT_NONE, BASE_NONE, NULL, 0x00,
NULL, HFILL }
},
+ { &hf_batadv_tt_entry,
+ { "Entry", "batadv.tt_entry.entry",
+ FT_ETHER, BASE_NONE, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_entry_flags,
+ { "Flags", "batadv.tt_entry.flags",
+ FT_UINT8, BASE_HEX, NULL, 0x0,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_entry_flags_change_del,
+ { "Delete", "batadv.tt_entry.flags.change_del",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), TT_CHANGE_DEL,
+ NULL, HFILL }
+ },
+ { &hf_batadv_tt_entry_flags_client_roam,
+ { "Client Roam", "batadv.tt_entry.flags.client_roam",
+ FT_BOOLEAN, 8, TFS(&tfs_set_notset), TT_CLIENT_ROAM,
+ NULL, HFILL }
+ },
{ &hf_msg_fragment,
{"Message fragment", "batadv.unicast_frag.fragment",
FT_FRAMENUM, BASE_NONE, NULL, 0x00,
@@ -2303,6 +3472,11 @@ void proto_register_batadv(void)
&ett_batadv_unicast_frag,
&ett_batadv_vis,
&ett_batadv_vis_entry,
+ &ett_batadv_tt_query,
+ &ett_batadv_tt_query_flags,
+ &ett_batadv_tt_entry,
+ &ett_batadv_tt_entry_flags,
+ &ett_batadv_roam_adv,
&ett_msg_fragment,
&ett_msg_fragments
};