1 #include "packet-smb-common.h"
3 struct notify_response {
9 static const int* witness_move_ipaddr_list_flags_fields[] = {
10 &hf_witness_move_ipaddr_list_flags_ipv4,
11 &hf_witness_move_ipaddr_list_flags_ipv6,
14 static const true_false_string valid_tfs = {
18 static const value_string witness_change_type_vals[] = {
21 {0xFF, "Unavailable"},
25 static int witness_dissect_move_ipaddr(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
27 proto_item *ti = proto_tree_add_text(tree, tvb, offset, -1, "IP");
28 proto_tree *tr = proto_item_add_subtree(ti, ett_witness_move_ipaddr);
30 guint32 flags = tvb_get_letohl(tvb, offset);
31 proto_tree_add_bitmask(tr, tvb, offset,
32 hf_witness_move_ipaddr_list_flags,
33 ett_witness_move_ipaddr_list_flags,
34 witness_move_ipaddr_list_flags_fields,
38 proto_tree_add_item(tr, hf_witness_move_ipaddr_list_ipv4, tvb, offset, 4, ENC_BIG_ENDIAN);
41 const char *ip = tvb_ip_to_str(tvb, offset);
42 proto_item_append_text(tr, " %s", ip);
43 proto_item_append_text(tree, " %s", ip);
44 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", ip);
48 proto_tree_add_item(tr, hf_witness_move_ipaddr_list_ipv6, tvb, offset, 16, ENC_BIG_ENDIAN);
51 const char *ip = tvb_ip6_to_str(tvb, offset);
52 proto_item_append_text(tr, " %s", ip);
53 proto_item_append_text(tree, " %s", ip);
54 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", ip);
58 proto_item_set_end(ti, tvb, offset);
62 static int witness_dissect_move_request(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
64 guint32 length, num, n;
66 proto_item *ti = proto_tree_add_text(tree, tvb, offset, -1, "Move");
67 proto_tree *tr = proto_item_add_subtree(ti, ett_message_buffer);
69 length = tvb_get_letohl(tvb, offset);
70 proto_tree_add_text(tr, tvb, offset, 4, "Length: %u", length);
73 proto_tree_add_text(tr, tvb, offset, 4, "Reserved");
76 num = tvb_get_letohl(tvb, offset);
77 proto_tree_add_text(tr, tvb, offset, 4, "Num: %u", num);
80 for (n=0; n<num; n++) {
81 offset = witness_dissect_move_ipaddr(tvb, offset, pinfo, tr);
84 proto_item_set_end(ti, tvb, offset);
90 static int witness_dissect_resource_change(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree)
94 const int old_offset = offset;
96 proto_item *ti = proto_tree_add_text(tree, tvb, offset, -1, "Change");
97 proto_tree *tr = proto_item_add_subtree(ti, ett_message_buffer);
99 length = tvb_get_letohl(tvb, offset);
100 proto_tree_add_text(tr, tvb, offset, 4, "Length: %u", length);
103 type = tvb_get_letohl(tvb, offset);
104 proto_tree_add_item(tr, hf_witness_change_type, tvb, offset, 4, ENC_LITTLE_ENDIAN);
107 name = tvb_get_ephemeral_unicode_string(tvb, offset, length-8, ENC_LITTLE_ENDIAN);
108 proto_tree_add_string(tr, hf_witness_change_name, tvb, offset, length-8, name);
110 proto_item_append_text(ti, ": %s -> %s", name,
111 val_to_str(type, witness_change_type_vals,
112 "Invalid (0x04%x)"));
114 proto_item_set_len(ti, length);
116 return old_offset + length;
120 witness_dissect_notifyResponse_message(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree,
121 void * notify_response)
123 const int old_offset = offset;
124 int (*dissect)(tvbuff_t *, int, packet_info*, proto_tree *);
128 // struct notify_response *resp = pinfo->private_data;
129 struct notify_response *resp = notify_response;
131 switch (resp->type) {
134 dissect = &witness_dissect_move_request;
136 case RESOURCE_CHANGE:
137 msg = "Resource Change";
138 dissect = &witness_dissect_resource_change;
142 dissect = &witness_dissect_move_request;
146 dissect = &witness_dissect_move_request;
149 DISSECTOR_ASSERT(FALSE);
153 col_append_fstr(pinfo->cinfo, COL_INFO, ": %s", msg);
155 for (n=0; n < resp->num; n++) {
156 offset = dissect(tvb, offset, pinfo, tree);
159 DISSECTOR_ASSERT((unsigned)offset == (unsigned)old_offset + resp->length);
164 dissect_ndr_ucbuffer(tvbuff_t *tvb, gint offset, packet_info *pinfo,
165 proto_tree *tree, guint8 *drep,
166 int (*dissect)(tvbuff_t *, int, packet_info*, proto_tree*, void*),
169 dcerpc_info *di = pinfo->private_data;
170 const int old_offset = offset;
171 int conformance_size = di->call_data->flags & DCERPC_IS_NDR64 ? 8 : 4;
173 if (di->conformant_run) {
176 /* conformant run, just dissect the max_count header */
177 di->conformant_run = 0;
178 offset = dissect_ndr_uint3264(tvb, offset, pinfo, tree, di, drep,
179 hf_dcerpc_array_max_count, &val);
180 di->array_max_count = (gint32)val;
181 di->array_max_count_offset = offset-conformance_size;
182 di->conformant_run = 1;
183 di->conformant_eaten = offset-old_offset;
187 /* we don't remember where in the bytestream this field was */
188 proto_tree_add_uint(tree, hf_dcerpc_array_max_count, tvb,
189 di->array_max_count_offset, conformance_size,
190 di->array_max_count);
192 /* real run, dissect the elements */
193 tvb_ensure_bytes_exist(tvb, offset, di->array_max_count);
194 subtvb = tvb_new_subset(tvb, offset, di->array_max_count, di->array_max_count);
196 // pinfo->private_data = private_data;
197 offset += dissect(subtvb, 0, pinfo, tree, private_data);
198 // pinfo->private_data = di;
200 DISSECTOR_ASSERT((unsigned)offset == (unsigned)old_offset + di->array_max_count);
207 witness_dissect_element_notifyResponse_message_buffer_(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info* di, guint8 *drep)
209 offset = dissect_ndr_ucbuffer(tvb, offset, pinfo, tree, drep, witness_dissect_notifyResponse_message, di->private_data);
215 witness_dissect_struct_notifyResponse(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, dcerpc_info* di, guint8 *drep, int hf_index, guint32 param _U_)
217 proto_item *item = NULL;
218 proto_tree *tree = NULL;
219 const int old_offset = offset;
221 struct notify_response response;
226 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
227 tree = proto_item_add_subtree(item, ett_witness_witness_notifyResponse);
230 offset = witness_dissect_enum_notifyResponse_type(tvb, offset, pinfo, tree, di, drep,
231 hf_witness_witness_notifyResponse_message_type, &response.type);
233 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_witness_witness_notifyResponse_length, &response.length);
235 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep, hf_witness_witness_notifyResponse_num_messages, &response.num);
237 if (!di->conformant_run) {
238 if (di->private_data) {
239 DISSECTOR_ASSERT(memcmp(di->private_data, &response, sizeof(response)) == 0);
241 di->private_data = ep_memdup(&response, sizeof(response));
245 offset = witness_dissect_element_notifyResponse_message_buffer(tvb, offset, pinfo, tree, di, drep);
247 proto_item_set_len(item, offset-old_offset);
249 if (di->call_data->flags & DCERPC_IS_NDR64) {
257 witness_dissect_element_interfaceInfo_group_name(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *parent_tree, dcerpc_info *di _U_, guint8 *drep _U_)
261 guint16 bc = tvb_length_remaining(tvb, offset);
263 str = get_unicode_or_ascii_string(tvb, &offset, TRUE, &len, TRUE, TRUE, &bc);
267 pi = proto_tree_add_string(parent_tree, hf_witness_witness_interfaceInfo_group_name, tvb, offset, 2*260, str);
268 proto_item_append_text(pi, " [%d]", len);
269 proto_item_append_text(parent_tree, ": %s", str);
272 //proto_tree_add_bytes
275 return offset + 2*260;
279 PIDL_dissect_ipv4address(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep _U_, int hfindex, guint32 param)
281 // guint32 ip = tvb_get_ipv4(tvb,offset); //tvb_get_ntohl(tvb, offset);
282 if (di->conformant_run) {
283 /* just a run to handle conformant arrays, no scalars to dissect */
288 if (!di->no_align && (offset % 4)) {
289 offset += 4 - (offset % 4);
292 proto_tree_add_item(tree, hfindex, tvb, offset, 4, ENC_BIG_ENDIAN);
295 if (param & PIDL_SET_COL_INFO) {
296 const char *ip = tvb_ip_to_str(tvb, offset);
297 header_field_info *hf_info = proto_registrar_get_nth(hfindex);
299 proto_item_append_text(proto_tree_get_parent(tree), " %s:%s", hf_info->name, ip);
301 col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, ip);
307 PIDL_dissect_ipv6address(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep _U_, int hfindex, guint32 param)
309 // tvb_get_ipv6(tvb, offset, &addr);
310 if (di->conformant_run) {
311 /* just a run to handle conformant arrays, no scalars to dissect */
316 if (!di->no_align && (offset % 2)) {
317 offset += 2 - (offset % 2);
320 proto_tree_add_item(tree, hfindex, tvb, offset, 16, ENC_BIG_ENDIAN);
322 if (param & PIDL_SET_COL_INFO) {
323 const char *ip = tvb_ip6_to_str(tvb, offset);
324 header_field_info *hf_info = proto_registrar_get_nth(hfindex);
326 proto_item_append_text(proto_tree_get_parent(tree), " %s:%s", hf_info->name, ip);
328 col_append_fstr(pinfo->cinfo, COL_INFO," %s:%s", hf_info->name, ip);
336 witness_dissect_enum_interfaceInfo_state(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hf_index, guint32* param _U_)
338 return PIDL_dissect_uint16(tvb, offset, pinfo, tree, di, drep, hf_index, PIDL_SET_COL_INFO);