static void dissect_xml(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbparse_t* tt; tvbparse_elem_t* tok = NULL; static GPtrArray* stack = NULL; xml_frame_t* current_frame; char* colinfo_str; if (stack != NULL) g_ptr_array_free(stack,TRUE); stack = g_ptr_array_new(); current_frame = ep_alloc(sizeof(xml_frame_t)); current_frame->type = XML_FRAME_ROOT; current_frame->name = NULL; current_frame->name_orig_case = NULL; current_frame->value = NULL; insert_xml_frame(NULL, current_frame); g_ptr_array_add(stack,current_frame); tt = tvbparse_init(tvb,0,-1,stack,want_ignore); current_frame->start_offset = 0; root_ns = NULL; if (pinfo->match_string) root_ns = g_hash_table_lookup(media_types,pinfo->match_string); if (! root_ns ) { root_ns = &xml_ns; colinfo_str = "/XML"; } else { colinfo_str = ep_strdup_printf("/%s",root_ns->name); ascii_strup_inplace(colinfo_str); } if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_append_str(pinfo->cinfo, COL_PROTOCOL, colinfo_str); current_frame->ns = root_ns; current_frame->item = proto_tree_add_item(tree,current_frame->ns->hf_tag,tvb,0,-1,FALSE); current_frame->tree = proto_item_add_subtree(current_frame->item,current_frame->ns->ett); current_frame->last_item = current_frame->item; while(( tok = tvbparse_get(tt, want) )) ; pinfo->private_data = current_frame; /* pass XML structure to the dissector calling XML */ }
static void dissect_gdb_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *gdb_tree; tvbparse_t *tt; col_set_str(pinfo->cinfo, COL_PROTOCOL, "GDB"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_protocol_format(tree, proto_gdb, tvb, 0, tvb_reported_length(tvb), "GDB Remote Serial Protocol"); gdb_tree = proto_item_add_subtree(ti, ett_gdb); /* XXX support multiple sub-trees */ tt = tvbparse_init(tvb, 0, -1, (void *)gdb_tree, NULL); while(tvbparse_get(tt, want)) { ; } }
static void dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *json_tree = NULL; proto_item *ti = NULL; json_parser_data_t parser_data; tvbparse_t *tt; const char *data_name; int offset; data_name = pinfo->match_string; if (!(data_name && data_name[0])) { /* * No information from "match_string" */ data_name = (char *)(pinfo->private_data); if (!(data_name && data_name[0])) { /* * No information from "private_data" */ data_name = NULL; } } if (tree) { ti = proto_tree_add_item(tree, proto_json, tvb, 0, -1, ENC_NA); json_tree = proto_item_add_subtree(ti, ett_json); if (data_name) proto_item_append_text(ti, ": %s", data_name); } offset = 0; parser_data.stack = ep_stack_new(); ep_stack_push(parser_data.stack, json_tree); tt = tvbparse_init(tvb, offset, -1, &parser_data, want_ignore); /* XXX, only one json in packet? */ while ((tvbparse_get(tt, want))) ; offset = tvbparse_curr_offset(tt); proto_item_set_len(ti, offset); /* if we have some unparsed data, pass to data-text-lines dissector (?) */ if (tvb_length_remaining(tvb, offset) > 0) { int datalen, reported_datalen; tvbuff_t *next_tvb; datalen = tvb_length_remaining(tvb, offset); reported_datalen = tvb_reported_length_remaining(tvb, offset); next_tvb = tvb_new_subset(tvb, offset, datalen, reported_datalen); call_dissector(text_lines_handle, next_tvb, pinfo, tree); } else if (data_name) { col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)", data_name); } }
static int dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { proto_tree *json_tree = NULL; proto_item *ti = NULL; json_parser_data_t parser_data; tvbparse_t *tt; const char *data_name; int offset; /* JSON dissector can be called in a JSON native file or when transported * by another protocol. We set the column values only if they've not been * already set by someone else. */ wmem_list_frame_t *proto = wmem_list_frame_prev(wmem_list_tail(pinfo->layers)); if (proto) { const char *name = proto_get_protocol_filter_name(GPOINTER_TO_INT(wmem_list_frame_data(proto))); if (!strcmp(name, "frame")) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "JSON"); col_set_str(pinfo->cinfo, COL_INFO, "JavaScript Object Notation"); } } data_name = pinfo->match_string; if (! (data_name && data_name[0])) { /* * No information from "match_string" */ data_name = (char *)data; if (! (data_name && data_name[0])) { /* * No information from dissector data */ data_name = NULL; } } if (tree) { ti = proto_tree_add_item(tree, hfi_json, tvb, 0, -1, ENC_NA); json_tree = proto_item_add_subtree(ti, ett_json); if (data_name) proto_item_append_text(ti, ": %s", data_name); } offset = 0; parser_data.stack = wmem_stack_new(wmem_packet_scope()); wmem_stack_push(parser_data.stack, json_tree); tt = tvbparse_init(tvb, offset, -1, &parser_data, want_ignore); /* XXX, only one json in packet? */ while ((tvbparse_get(tt, want))) ; offset = tvbparse_curr_offset(tt); proto_item_set_len(ti, offset); /* if we have some unparsed data, pass to data-text-lines dissector (?) */ if (tvb_reported_length_remaining(tvb, offset) > 0) { tvbuff_t *next_tvb; next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_with_data(text_lines_handle, next_tvb, pinfo, tree, data); } else if (data_name) { col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "(%s)", data_name); } return tvb_captured_length(tvb); }
static void dissect_ntp_ctrl(tvbuff_t *tvb, proto_tree *ntp_tree, guint8 flags) { proto_tree *flags_tree; proto_item *tf; guint8 flags2; proto_tree *status_tree, *data_tree, *item_tree; proto_item *ts, *td, *ti; guint16 status; guint16 associd; guint16 datalen; guint16 data_offset; tvbparse_t *tt; tvbparse_elem_t *element; tf = proto_tree_add_uint(ntp_tree, hf_ntp_flags, tvb, 0, 1, flags); /* Adding flag subtree and items */ flags_tree = proto_item_add_subtree(tf, ett_ntp_flags); proto_tree_add_uint(flags_tree, hf_ntp_flags_li, tvb, 0, 1, flags); proto_tree_add_uint(flags_tree, hf_ntp_flags_vn, tvb, 0, 1, flags); proto_tree_add_uint(flags_tree, hf_ntp_flags_mode, tvb, 0, 1, flags); flags2 = tvb_get_guint8(tvb, 1); tf = proto_tree_add_uint(ntp_tree, hf_ntpctrl_flags2, tvb, 1, 1, flags2); flags_tree = proto_item_add_subtree(tf, ett_ntpctrl_flags2); proto_tree_add_uint(flags_tree, hf_ntpctrl_flags2_r, tvb, 1, 1, flags2); proto_tree_add_uint(flags_tree, hf_ntpctrl_flags2_error, tvb, 1, 1, flags2); proto_tree_add_uint(flags_tree, hf_ntpctrl_flags2_more, tvb, 1, 1, flags2); proto_tree_add_uint(flags_tree, hf_ntpctrl_flags2_opcode, tvb, 1, 1, flags2); proto_tree_add_uint(ntp_tree, hf_ntpctrl_sequence, tvb, 2, 2, tvb_get_ntohs(tvb, 2)); status = tvb_get_ntohs(tvb, 4); associd = tvb_get_ntohs(tvb, 6); ts = proto_tree_add_uint(ntp_tree, hf_ntpctrl_status, tvb, 4, 2, status); status_tree = proto_item_add_subtree(ts, ett_ntpctrl_status); /* * further processing of status is only necessary in server responses */ if (flags2 & NTPCTRL_R_MASK) { if (flags2 & NTPCTRL_ERROR_MASK) { /* Check if this is an error response... */ dissect_ntp_ctrl_errorstatus(tvb, status_tree, 4, status); } else { /* ...otherwise status word depends on OpCode */ switch (flags2 & NTPCTRL_OP_MASK) { case NTPCTRL_OP_READSTAT: case NTPCTRL_OP_READVAR: case NTPCTRL_OP_WRITEVAR: case NTPCTRL_OP_ASYNCMSG: if (associd) dissect_ntp_ctrl_peerstatus(tvb, status_tree, 4, status); else dissect_ntp_ctrl_systemstatus(tvb, status_tree, 4, status); break; case NTPCTRL_OP_READCLOCK: case NTPCTRL_OP_WRITECLOCK: dissect_ntp_ctrl_clockstatus(tvb, status_tree, 4, status); break; case NTPCTRL_OP_SETTRAP: case NTPCTRL_OP_UNSETTRAP: break; } } } proto_tree_add_uint(ntp_tree, hf_ntpctrl_associd, tvb, 6, 2, associd); proto_tree_add_uint(ntp_tree, hf_ntpctrl_offset, tvb, 8, 2, tvb_get_ntohs(tvb, 8)); datalen = tvb_get_ntohs(tvb, 10); proto_tree_add_uint(ntp_tree, hf_ntpctrl_count, tvb, 10, 2, datalen); /* * dissect Data part of the NTP control message */ if (datalen) { data_offset = 12; td = proto_tree_add_item(ntp_tree, hf_ntpctrl_data, tvb, data_offset, datalen, TRUE); data_tree = proto_item_add_subtree(td, ett_ntpctrl_data); switch(flags2 & NTPCTRL_OP_MASK) { case NTPCTRL_OP_READSTAT: if (!associd) { /* * if associd == 0 then data part contains a list of the form * <association identifier><status word>, */ while(datalen) { ti = proto_tree_add_item(data_tree, hf_ntpctrl_item, tvb, data_offset, 4, TRUE); item_tree = proto_item_add_subtree(ti, ett_ntpctrl_item); proto_tree_add_uint(item_tree, hf_ntpctrl_associd, tvb, data_offset, 2, tvb_get_ntohs(tvb, data_offset)); data_offset += 2; status = tvb_get_ntohs(tvb, data_offset); ts = proto_tree_add_uint(item_tree, hf_ntpctrl_status, tvb, data_offset, 2, status); status_tree = proto_item_add_subtree(ts, ett_ntpctrl_status); dissect_ntp_ctrl_peerstatus( tvb, status_tree, 4, status ); data_offset += 2; datalen -= 4; } break; } /* * but if associd != 0, * then data part could be the same as if opcode is NTPCTRL_OP_READVAR * --> so, no "break" here! */ case NTPCTRL_OP_READVAR: case NTPCTRL_OP_WRITEVAR: case NTPCTRL_OP_READCLOCK: case NTPCTRL_OP_WRITECLOCK: tt = tvbparse_init(tvb, data_offset, datalen, NULL, want_ignore); while( (element = tvbparse_get(tt, want)) != NULL ) { tvbparse_tree_add_elem(data_tree, element); } break; case NTPCTRL_OP_ASYNCMSG: proto_tree_add_item(data_tree, hf_ntpctrl_trapmsg, tvb, data_offset, datalen, TRUE); break; /* these opcodes doesn't carry any data: NTPCTRL_OP_SETTRAP, NTPCTRL_OP_UNSETTRAP, NTPCTRL_OP_UNSPEC */ } } }