Witness: WIP
[wireshark-wip.git] / epan / dissectors / packet-dcerpc-witness-cnf.c
blob0f0d4ae9086f96b5296a83ba082ee6fe30e9b3a8
1 struct notify_response {
2 guint32 length;
3 guint32 num;
4 guint32 type;
5 };
7 static gint hf_witness_move_ipaddr_list_flags = -1;
8 static gint hf_witness_move_ipaddr_list_flags_ipv4 = -1;
9 static gint hf_witness_move_ipaddr_list_flags_ipv6 = -1;
10 static gint hf_witness_move_ipaddr_list_ipv4 = -1;
11 static gint hf_witness_move_ipaddr_list_ipv6 = -1;
12 static gint hf_witness_change_type = -1;
13 static gint hf_witness_change_name = -1;
15 static const int* witness_move_ipaddr_list_flags_fields[] = {
16 &hf_witness_move_ipaddr_list_flags_ipv4,
17 &hf_witness_move_ipaddr_list_flags_ipv6,
20 static const true_false_string valid_tfs = {
21 "Valid", "Not valid"
24 static const value_string witness_change_type_vals[] = {
25 {0x00, "Unknown"},
26 {0x01, "Available"},
27 {0xFF, "Unavailable"},
28 {0, NULL}
31 static gint ett_witness_move_ipaddr_list_flags = -1;
32 static gint ett_witness_move_ipaddr = -1;
33 static gint ett_message_buffer = -1;
34 static gint ett_message = -1;
36 /* { &hf_witness_move_ipaddr_list_flags, */
37 /* { "IPv4", "witness.move_ipaddr_list.flags", FT_UINT32, BASE_HEX, NULL, 0, NULL, HFILL }}, */
38 /* { &hf_witness_move_ipaddr_list_flags_ipv4, */
39 /* { "IPv4", "witness.move_ipaddr_list.ipv4", FT_BOOLEAN, 32, TFS(&valid_tfs), 0x01, NULL, HFILL }}, */
40 /* { &hf_witness_move_ipaddr_list_flags_ipv6, */
41 /* { "IPv6", "witness.move_ipaddr_list.ipv6", FT_BOOLEAN, 32, TFS(&valid_tfs), 0x02, NULL, HFILL }}, */
42 /* { &hf_witness_move_ipaddr_list_ipv4, */
43 /* { "IPv4", "witness.move_ipaddr_list.ipv4.addr", FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }}, */
44 /* { &hf_witness_move_ipaddr_list_ipv6, */
45 /* { "IPv6", "witness.move_ipaddr_list.ipv6.addr", FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }}, */
46 /* { &hf_witness_change_type, */
47 /* { "Type", "witness.change.type", FT_UINT32, BASE_HEX, VALS(witness_change_type_vals), 0, NULL, HFILL }}, */
48 /* { &hf_witness_change_name, */
49 /* { "IPv4addr", "witness.change.name", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }}, */
52 static int witness_dissect_move_ipaddr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
54 proto_item *ti = proto_tree_add_text(tree, tvb, offset, -1, "IPAddr");
55 proto_tree *tr = proto_item_add_subtree(ti, ett_witness_move_ipaddr);
57 guint32 flags = tvb_get_letohl(tvb, offset);
58 proto_tree_add_bitmask(tr, tvb, offset,
59 hf_witness_move_ipaddr_list_flags,
60 ett_witness_move_ipaddr_list_flags,
61 witness_move_ipaddr_list_flags_fields,
62 ENC_LITTLE_ENDIAN);
63 offset += 4;
65 proto_tree_add_item(tr, hf_witness_move_ipaddr_list_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
66 //proto_tree_add_ipv4
67 offset += 4;
69 proto_tree_add_item(tr, hf_witness_move_ipaddr_list_ipv6, tvb, offset, 16, ENC_BIG_ENDIAN);
70 //proto_tree_add_ipv6
71 offset += 16;
73 if (flags & 1) {
74 //add ipv4 to ti
76 if (flags & 2) {
77 //add ipv6 to ti
80 proto_item_set_end(ti, tvb, offset);
81 return offset;
84 static int witness_dissect_move_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
86 guint32 length, num, n;
88 proto_item *ti = proto_tree_add_text(tree, tvb, offset, -1, "Move");
89 proto_tree *tr = proto_item_add_subtree(ti, ett_message_buffer);
91 length = tvb_get_letohl(tvb, offset);
92 proto_tree_add_text(tr, tvb, offset, 4, "Length: %u", length);
93 offset += 4;
95 proto_tree_add_text(tr, tvb, offset, 4, "Reserved");
96 offset += 4;
98 num = tvb_get_letohl(tvb, offset);
99 proto_tree_add_text(tr, tvb, offset, 4, "Num: %u", num);
100 offset += 4;
102 for (n=0; n<num; n++) {
103 offset = witness_dissect_move_ipaddr(tvb, offset, pinfo, tr);
106 proto_item_set_end(ti, tvb, offset);
107 return offset;
112 static int witness_dissect_resource_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
114 guint32 length, type;
115 char *name;
117 proto_item *ti = proto_tree_add_text(tree, tvb, offset, -1, "Change");
118 proto_tree *tr = proto_item_add_subtree(ti, ett_message_buffer);
120 length = tvb_get_letohl(tvb, offset);
121 proto_tree_add_text(tr, tvb, offset, 4, "Length: %u", length);
122 offset += 4;
124 type = tvb_get_letohl(tvb, offset);
125 proto_tree_add_item(tr, hf_witness_change_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
126 offset += 4;
128 name = tvb_get_ephemeral_unicode_string(tvb, offset, length, ENC_LITTLE_ENDIAN);
129 proto_tree_add_string(tr, hf_witness_change_name, tvb, offset, length, name);
131 proto_item_append_text(ti, ": %s -> %s", name,
132 val_to_str(type, witness_change_type_vals,
133 "Invalid (0x04%x)"));
135 return offset;
138 static int
139 witness_dissect_notifyResponse_message(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
140 void * notify_response)
142 const int old_offset = offset;
143 int (*dissect)(tvbuff_t *, int, packet_info*, proto_tree *);
144 const char *msg;
145 unsigned n;
147 // struct notify_response *resp = pinfo->private_data;
148 struct notify_response *resp = notify_response;
150 switch (resp->type) {
151 case MOVE:
152 msg = "Move";
153 dissect = &witness_dissect_move_request;
154 break;
155 case CHANGE:
156 msg = "Change";
157 dissect = &witness_dissect_resource_change;
158 break;
159 default:
160 DISSECTOR_ASSERT(FALSE);
164 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", msg);
166 for (n=0; n < resp->num; n++) {
167 offset = dissect(tvb, offset, pinfo, tree);
170 DISSECTOR_ASSERT(offset == old_offset + resp->length);
171 return offset;
175 //XXX dissect_ndr_ucarray
176 static int
177 dissect_ndr_ucbuffer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
178 proto_tree *tree, guint8 *drep,
179 int (*dissect)(tvbuff_t *, int, packet_info*, proto_tree*, void*),
180 void *private_data)
182 dcerpc_info *di = pinfo->private_data;
183 const int old_offset = offset;
184 int conformance_size = di->call_data->flags & DCERPC_IS_NDR64 ? 8 : 4;
186 if (di->conformant_run) {
187 guint64 val;
189 /* conformant run, just dissect the max_count header */
190 di->conformant_run = 0;
191 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, drep,
192 hf_dcerpc_array_max_count, &val);
193 di->array_max_count = (gint32)val;
194 di->array_max_count_offset = offset-conformance_size;
195 di->conformant_run = 1;
196 di->conformant_eaten = offset-old_offset;
197 } else {
198 tvbuff_t *subtvb;
200 /* we don't remember where in the bytestream this field was */
201 proto_tree_add_uint(tree, hf_dcerpc_array_max_count, tvb,
202 di->array_max_count_offset, conformance_size,
203 di->array_max_count);
205 /* real run, dissect the elements */
206 tvb_ensure_bytes_exist(tvb, offset, di->array_max_count);
207 subtvb = tvb_new_subset(tvb, offset, di->array_max_count, di->array_max_count);
209 // pinfo->private_data = private_data;
210 offset += dissect(subtvb, 0, pinfo, tree, private_data);
211 // pinfo->private_data = di;
213 DISSECTOR_ASSERT(offset == old_offset + di->array_max_count);
216 return offset;
219 static int
220 witness_dissect_element_notifyResponse_message_buffer_(tvbuff_t *tvb _U_, int offset _U_, packet_info *pinfo _U_, proto_tree *tree _U_, guint8 *drep _U_)
222 dcerpc_info *di = pinfo->private_data;
223 offset = dissect_ndr_ucbuffer(tvb, offset, pinfo, tree, drep, witness_dissect_notifyResponse_message, di->private_data);
224 // offset = dissect_ndr_ucarray(tvb, offset, pinfo, tree, drep, witness_dissect_element_notifyResponse_message_buffer__);
226 return offset;
230 witness_dissect_struct_notifyResponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, guint8 *drep, int hf_index, guint32 param _U_)
232 proto_item *item = NULL;
233 proto_tree *tree = NULL;
234 dcerpc_info *di = pinfo->private_data;
235 const int old_offset = offset;
237 struct notify_response response;
239 ALIGN_TO_5_BYTES;
241 if (parent_tree) {
242 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
243 tree = proto_item_add_subtree(item, ett_witness_witness_notifyResponse);
246 offset = witness_dissect_enum_notifyResponse_type(tvb, offset, pinfo, tree, drep,
247 hf_witness_witness_notifyResponse_message_type, &response.type);
249 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_witness_witness_notifyResponse_length, &response.length);
251 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, drep, hf_witness_witness_notifyResponse_num_messages, &response.num);
253 if (!di->conformant_run) {
254 if (di->private_data) {
255 DISSECTOR_ASSERT(memcmp(di->private_data, &response, sizeof(response)) == 0);
256 } else {
257 di->private_data = ep_memdup(&response, sizeof(response));
260 // offset = dissect_ndr_ucbuffer(tvb, offset, pinfo, tree, drep, witness_dissect_notifyResponse_message, &response);
261 offset = witness_dissect_element_notifyResponse_message_buffer(tvb, offset, pinfo, tree, drep);
264 proto_item_set_len(item, offset-old_offset);
267 if (di->call_data->flags & DCERPC_IS_NDR64) {
268 ALIGN_TO_5_BYTES;
271 return offset;