static int dissect_openvpn_msg_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *openvpn_tree, proto_tree *parent_tree, gint offset) { gboolean tls_auth; guint openvpn_keyid; guint openvpn_opcode; guint32 msg_mpid = -1; guint32 msg_sessionid = -1; guint8 openvpn_predict_tlsauth_arraylength; proto_item *ti2, *ti3; proto_tree *packetarray_tree, *type_tree; guint32 msg_length_remaining; gboolean msg_lastframe; fragment_head *frag_msg; tvbuff_t *new_tvb; gboolean save_fragmented; /* Clear out stuff in the info column */ col_set_str(pinfo->cinfo, COL_PROTOCOL, PSNAME); col_clear(pinfo->cinfo,COL_INFO); /* read opcode and write to info column */ openvpn_opcode = tvb_get_bits8(tvb, offset*8, 5); col_append_fstr(pinfo->cinfo, COL_INFO, "MessageType: %s", val_to_str_const(openvpn_opcode, openvpn_message_types, "Unknown Messagetype")); openvpn_keyid = tvb_get_bits8(tvb, offset*8 + 5, 3); proto_item_append_text(parent_tree, ", Opcode: %s, Key ID: %d", val_to_str(openvpn_opcode, openvpn_message_types, "Unknown (0x%02x)"), openvpn_keyid); ti2 = proto_tree_add_item(openvpn_tree, hf_openvpn_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN); proto_item_append_text(ti2, " [opcode/key_id]"); type_tree = proto_item_add_subtree(ti2, ett_openvpn_type); proto_tree_add_item(type_tree, hf_openvpn_opcode, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(type_tree, hf_openvpn_keyid, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* if we have a P_CONTROL or P_ACK packet */ if (openvpn_opcode != P_DATA_V1) { /* read sessionid */ msg_sessionid = tvb_get_bits32(tvb, offset*8+32, 32, ENC_BIG_ENDIAN); proto_tree_add_item(openvpn_tree, hf_openvpn_sessionid, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; /* tls-auth detection (this can be overridden by preferences */ openvpn_predict_tlsauth_arraylength = tvb_get_guint8(tvb, offset); /* if the first 4 bytes that would, if tls-auth is used, contain part of the hmac, lack entropy, we asume no tls-auth is used */ if (pref_tls_auth_override == FALSE) { if ((openvpn_opcode != P_DATA_V1) && (openvpn_predict_tlsauth_arraylength > 0) && check_for_valid_hmac(tvb_get_ntohl(tvb, offset))) { tls_auth = TRUE; } else { tls_auth = FALSE; } } else { tls_auth = pref_tls_auth; } if (tls_auth == TRUE) { proto_tree_add_item(openvpn_tree, hf_openvpn_hmac, tvb, offset, tls_auth_hmac_size, ENC_NA); offset += tls_auth_hmac_size; if (tvb_length_remaining(tvb, offset) >= 8) { proto_tree_add_item(openvpn_tree, hf_openvpn_pid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (pref_long_format) { proto_tree_add_item(openvpn_tree, hf_openvpn_net_time, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } } if (tvb_length_remaining(tvb, offset) >= 1) { /* read P_ACK packet-id array length */ gint pid_arraylength = tvb_get_guint8(tvb, offset); gint i; proto_tree_add_item(openvpn_tree, hf_openvpn_mpid_arraylength, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (pid_arraylength > 0) { ti3 = proto_tree_add_text(openvpn_tree, tvb, offset, 0, "Packet-ID Array"); packetarray_tree = proto_item_add_subtree(ti3, ett_openvpn_packetarray); for (i = 0; i < pid_arraylength; i++) { proto_tree_add_item(packetarray_tree, hf_openvpn_mpid_arrayelement, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } if (tvb_length_remaining(tvb, offset) >= 8) { proto_tree_add_item(openvpn_tree, hf_openvpn_rsessionid, tvb, offset, 8, ENC_BIG_ENDIAN); offset += 8; } } } /* if we have a P_CONTROL packet */ if (openvpn_opcode != P_ACK_V1) { /* read Message Packet-ID */ if (tvb_length_remaining(tvb, offset) >= 4) { msg_mpid = tvb_get_bits32(tvb, offset*8, 32, ENC_BIG_ENDIAN); proto_tree_add_item(openvpn_tree, hf_openvpn_mpid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } } } /* if we have more data left, determine what to do */ msg_length_remaining = tvb_length_remaining(tvb, offset); if (msg_length_remaining == 0) { return tvb_length(tvb); } if (openvpn_opcode != P_CONTROL_V1) { proto_tree *data_tree; ti2 = proto_tree_add_text(openvpn_tree, tvb, offset, -1, "Data (%d bytes)", tvb_length_remaining(tvb, offset)); data_tree = proto_item_add_subtree(ti2, ett_openvpn_data); proto_tree_add_item(data_tree, hf_openvpn_data, tvb, offset, -1, ENC_NA); return tvb_length(tvb); } /* Try to reassemble */ /* an ordinary openvpn control packet contains 100 bytes only if it is part of a fragmented message and is not the last fragment of the current transmission. Note that the tvb contains exactly one openvpn PDU: UDP: by definition; TCP: because of the use of tcp_dissect_pdus(). */ if (msg_length_remaining == 100) { msg_lastframe = FALSE; } else { msg_lastframe = TRUE; } save_fragmented = pinfo->fragmented; pinfo->fragmented = TRUE; frag_msg = fragment_add_seq_next( &msg_reassembly_table, tvb, offset, pinfo, msg_sessionid, /* ID for fragments belonging together */ NULL, msg_length_remaining, /* fragment length - to the end */ !(msg_lastframe)); /* More fragments ? */ /* show "data" fragment on tree unless "reassembled" message has just one part. */ /* i.e., show if ("not reassembled") or ("reassembled" and "has multiple fragments") */ if ((frag_msg == NULL) || (frag_msg->next != NULL)) { proto_tree *data_tree; ti2 = proto_tree_add_text(openvpn_tree, tvb, offset, -1, "Message fragment (%d bytes)", tvb_length_remaining(tvb, offset)); data_tree = proto_item_add_subtree(ti2, ett_openvpn_data); proto_tree_add_item(data_tree, hf_openvpn_fragment_bytes, tvb, offset, -1, ENC_NA); } new_tvb = NULL; if (frag_msg) { if (msg_lastframe) { /* Reassembled */ new_tvb = process_reassembled_data(tvb, offset, pinfo, "Reassembled Message", frag_msg, &openvpn_frag_items, NULL, openvpn_tree); if (frag_msg->next != NULL) { /* multiple frags ? */ col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled "); /* overwritten by next dissector */ } } else { /* Not last packet of reassembled Short Message */ col_append_fstr(pinfo->cinfo, COL_INFO, " (Message fragment %d) ", msg_mpid); if (pinfo->fd->num != frag_msg->reassembled_in) { /* Add a "Reassembled in" link if not reassembled in this frame */ proto_tree_add_uint(openvpn_tree, hf_openvpn_reassembled_in, tvb, 0, 0, frag_msg->reassembled_in); } } } /* if (frag_msg) */ pinfo->fragmented = save_fragmented; /* Now see if we need to call subdissector. new_tvb is non-null if we "reassembled* a message (even just one fragment) */ if (new_tvb) { /* call SSL/TLS dissector if we just processed the last fragment */ call_dissector(ssl_handle, new_tvb, pinfo, parent_tree); } return tvb_length(tvb); }
static int dissect_xtp_tspec(tvbuff_t *tvb, proto_tree *tree, guint32 offset) { guint32 len = tvb_length_remaining(tvb, offset); guint32 start = offset; proto_item *ti, *ti2; proto_tree *xtp_subtree; struct xtp_traffic_spec1 tspec[1]; int error = 0; ti = proto_tree_add_text(tree, tvb, offset, len, "Traffic Specifier"); xtp_subtree = proto_item_add_subtree(ti, ett_xtp_tspec); if (len < XTP_TRAFFIC_SPEC0_LEN) { proto_item_append_text(ti, ", bogus length(%u, must be at least %u)", len, XTP_TRAFFIC_SPEC0_LEN); return 0; } /** parse common fields **/ /* tlen(2) */ tspec->tlen = tvb_get_ntohs(tvb, offset); offset += 2; /* service(1) */ tspec->service = tvb_get_guint8(tvb, offset); offset++; /* tformat(1) */ tspec->tformat = tvb_get_guint8(tvb, offset); /** display common fields */ offset = start; /* tlen(2) */ ti = proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_tlen, tvb, offset, 2, tspec->tlen); offset += 2; if (tspec->tlen > len) { proto_item_append_text(ti, ", bogus length(%u, must be at most %u)", tspec->tlen, len); error = 1; } /* service(1) */ proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_service, tvb, offset, 1, tspec->service); offset++; /* tformat(1) */ ti2 = proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_tformat, tvb, offset, 1, tspec->tformat); offset++; switch (tspec->tformat) { case 0: if (tspec->tlen != XTP_TRAFFIC_SPEC0_LEN) { proto_item_append_text(ti, ", bogus length(%u, must be %u)", tspec->tlen, XTP_TRAFFIC_SPEC0_LEN); error = 1; } break; case 1: if (tspec->tlen != XTP_TRAFFIC_SPEC1_LEN) { proto_item_append_text(ti, ", bogus length(%u, must be %u)", tspec->tlen, XTP_TRAFFIC_SPEC1_LEN); error = 1; } break; default: proto_item_append_text(ti2, ", Unsupported tformat(%u)", tspec->tformat); error = 1; break; } if (error) return (offset - start); /** parse and display each traffic fields **/ switch (tspec->tformat) { case 0: /* traffic(4) */ tspec->maxdata = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_traffic, tvb, offset, 4, tspec->maxdata); offset += 4; break; case 1: /* maxdata(4) */ tspec->maxdata = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_maxdata, tvb, offset, 4, tspec->maxdata); offset += 4; /* inrate(4) */ tspec->inrate = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_inrate, tvb, offset, 4, tspec->inrate); offset += 4; /* inburst(4) */ tspec->inburst = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_inburst, tvb, offset, 4, tspec->inburst); offset += 4; /* outrate(4) */ tspec->outrate = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_outrate, tvb, offset, 4, tspec->outrate); offset += 4; /* outburst(4) */ tspec->outburst = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_tspec_outburst, tvb, offset, 4, tspec->outburst); offset += 4; break; default: break; } return (offset - start); }
/* main dissector */ static int dissect_xtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint32 offset, len; proto_item *ti; proto_tree *xtp_tree, *xtp_cmd_tree, *xtp_subtree; struct xtphdr xtph[1]; int error = 0; gchar *options = "<None>"; const char *fstr[] = { "<None>", "NOCHECK", "EDGE", "NOERR", "MULTI", "RES", "SORT", "NOFLOW", "FASTNAK", "SREQ", "DREQ", "RCLOSE", "WCLOSE", "EOM", "END", "BTAG" }; gint fpos = 0, returned_length; guint i, bpos; guint cmd_options; vec_t cksum_vec[1]; guint16 computed_cksum; gboolean have_btag; if ((len = tvb_length(tvb)) < XTP_HEADER_LEN) return 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "XTP"); col_clear(pinfo->cinfo, COL_INFO); /** parse header **/ offset = 0; /* key(8) */ xtph->key = tvb_get_ntohl(tvb, offset); xtph->key <<= 32; xtph->key += tvb_get_ntohl(tvb, offset+4); offset += 8; /* cmd(4) */ xtph->cmd = tvb_get_ntohl(tvb, offset); xtph->cmd_options = xtph->cmd >> 8; xtph->cmd_ptype = xtph->cmd & 0xff; xtph->cmd_ptype_ver = (xtph->cmd_ptype & 0xe0) >> 5; xtph->cmd_ptype_pformat = xtph->cmd_ptype & 0x1f; offset += 4; /* dlen(4) */ xtph->dlen = tvb_get_ntohl(tvb, offset); offset += 4; /* check(2) */ xtph->check = tvb_get_ntohs(tvb, offset); offset += 2; /* sort(2) */ xtph->sort = tvb_get_ntohs(tvb, offset); offset += 2; /* sync(4) */ xtph->sync = tvb_get_ntohl(tvb, offset); offset += 4; /* seq(8) */ xtph->seq = tvb_get_ntohl(tvb, offset); xtph->seq <<= 32; xtph->seq += tvb_get_ntohl(tvb, offset+4); #define MAX_OPTIONS_LEN 128 options=ep_alloc(MAX_OPTIONS_LEN); options[0]=0; cmd_options = xtph->cmd_options >> 8; for (i = 0; i < 16; i++) { bpos = 1 << (15 - i); if (cmd_options & bpos) { returned_length = g_snprintf(&options[fpos], MAX_OPTIONS_LEN-fpos, "%s%s", fpos?", ":"", fstr[i]); fpos += MIN(returned_length, MAX_OPTIONS_LEN-fpos); } } if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(xtph->cmd_ptype_pformat, pformat_vals, "Unknown pformat (%u)")); col_append_fstr(pinfo->cinfo, COL_INFO, " [%s]", options); col_append_fstr(pinfo->cinfo, COL_INFO, " Seq=%" G_GINT64_MODIFIER "u", xtph->seq); col_append_fstr(pinfo->cinfo, COL_INFO, " Len=%u", xtph->dlen); } if (tree) { ti = proto_tree_add_item(tree, proto_xtp, tvb, 0, -1, ENC_NA); /** add summary **/ proto_item_append_text(ti, ", Key: 0x%016" G_GINT64_MODIFIER "X", xtph->key); proto_item_append_text(ti, ", Seq: %" G_GINT64_MODIFIER "u", xtph->seq); proto_item_append_text(ti, ", Len: %u", xtph->dlen); xtp_tree = proto_item_add_subtree(ti, ett_xtp); /* key(8) */ offset = 0; proto_tree_add_uint64(xtp_tree, hf_xtp_key, tvb, offset, 8, xtph->key); offset += 8; /* cmd(4) */ ti = proto_tree_add_uint(xtp_tree, hf_xtp_cmd, tvb, offset, 4, xtph->cmd); xtp_cmd_tree = proto_item_add_subtree(ti, ett_xtp_cmd); ti = proto_tree_add_uint(xtp_cmd_tree, hf_xtp_cmd_options, tvb, offset, 3, xtph->cmd_options); /** add summary **/ proto_item_append_text(ti, " [%s]", options); xtp_subtree = proto_item_add_subtree(ti, ett_xtp_cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_nocheck, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_edge, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_noerr, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_multi, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_res, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_sort, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_noflow, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_fastnak, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_sreq, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_dreq, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_rclose, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_wclose, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_eom, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_end, tvb, offset, 3, xtph->cmd_options); proto_tree_add_boolean(xtp_subtree, hf_xtp_cmd_options_btag, tvb, offset, 3, xtph->cmd_options); offset += 3; ti = proto_tree_add_uint(xtp_cmd_tree, hf_xtp_cmd_ptype, tvb, offset, 1, xtph->cmd_ptype); xtp_subtree = proto_item_add_subtree(ti, ett_xtp_cmd_ptype); proto_tree_add_uint(xtp_subtree, hf_xtp_cmd_ptype_ver, tvb, offset, 1, xtph->cmd_ptype_ver); if (xtph->cmd_ptype_ver != XTP_VERSION_4) { proto_item_append_text(ti, ", Unknown XTP version (%03X)", xtph->cmd_ptype_ver); error = 1; } proto_tree_add_uint(xtp_subtree, hf_xtp_cmd_ptype_pformat, tvb, offset, 1, xtph->cmd_ptype_pformat); offset++; /* dlen(4) */ ti = proto_tree_add_uint(xtp_tree, hf_xtp_dlen, tvb, offset, 4, xtph->dlen); if (xtph->dlen != len - XTP_HEADER_LEN) { proto_item_append_text(ti, ", bogus length (%u, must be %u)", xtph->dlen, len - XTP_HEADER_LEN); error = 1; } offset += 4; /* check(2) */ if (!pinfo->fragmented) { guint32 check_len = XTP_HEADER_LEN; if (!(xtph->cmd_options & XTP_CMD_OPTIONS_NOCHECK)) check_len += xtph->dlen; cksum_vec[0].ptr = tvb_get_ptr(tvb, 0, check_len); cksum_vec[0].len = check_len; computed_cksum = in_cksum(cksum_vec, 1); if (computed_cksum == 0) { proto_tree_add_text(xtp_tree, tvb, offset, 2, "Checksum: 0x%04x [correct]", xtph->check); } else { proto_tree_add_text(xtp_tree, tvb, offset, 2, "Checksum: 0x%04x [incorrect, should be 0x%04x]", xtph->check, in_cksum_shouldbe(xtph->check, computed_cksum)); } } else { proto_tree_add_text(xtp_tree, tvb, offset, 2, "Checksum: 0x%04x", xtph->check); } offset += 2; /* sort(2) */ proto_tree_add_uint(xtp_tree, hf_xtp_sort, tvb, offset, 2, xtph->sort); offset += 2; /* sync(4) */ proto_tree_add_uint(xtp_tree, hf_xtp_sync, tvb, offset, 4, xtph->sync); offset += 4; /* seq(8) */ proto_tree_add_uint64(xtp_tree, hf_xtp_seq, tvb, offset, 8, xtph->seq); offset += 8; if (!error) { switch (xtph->cmd_ptype_pformat) { case XTP_DATA_PKT: have_btag = !!(xtph->cmd_options & XTP_CMD_OPTIONS_BTAG); dissect_xtp_data(tvb, xtp_tree, offset, have_btag); break; case XTP_CNTL_PKT: dissect_xtp_cntl(tvb, pinfo, xtp_tree, offset); break; case XTP_FIRST_PKT: dissect_xtp_first(tvb, xtp_tree, offset); break; case XTP_ECNTL_PKT: dissect_xtp_ecntl(tvb, pinfo, xtp_tree, offset); break; case XTP_TCNTL_PKT: dissect_xtp_tcntl(tvb, pinfo, xtp_tree, offset); break; case XTP_JOIN_PKT: /* obsolete */ break; case XTP_JCNTL_PKT: dissect_xtp_jcntl(tvb, pinfo, xtp_tree, offset); break; case XTP_DIAG_PKT: dissect_xtp_diag(tvb, xtp_tree, offset); break; default: /* error */ break; } } } return tvb_length(tvb); }
static int dissect_ccn_interest(const unsigned char *ccnb, size_t ccnb_size, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *name_tree; proto_tree *exclude_tree; proto_item *titem; struct ccn_parsed_interest interest; struct ccn_parsed_interest *pi = &interest; struct ccn_buf_decoder decoder; struct ccn_buf_decoder *d; const unsigned char *bloom; size_t bloom_size = 0; struct ccn_charbuf *c; struct ccn_indexbuf *comps; const unsigned char *comp; size_t comp_size; const unsigned char *blob; size_t blob_size; ssize_t l; unsigned int i; double lifetime; int res; comps = ccn_indexbuf_create(); res = ccn_parse_interest(ccnb, ccnb_size, pi, comps); if (res < 0) return (res); /* Name */ l = pi->offset[CCN_PI_E_Name] - pi->offset[CCN_PI_B_Name]; c = ccn_charbuf_create(); ccn_uri_append(c, ccnb, ccnb_size, 1); titem = proto_tree_add_string(tree, hf_ccn_name, tvb, pi->offset[CCN_PI_B_Name], l, ccn_charbuf_as_string(c)); name_tree = proto_item_add_subtree(titem, ett_name); ccn_charbuf_destroy(&c); for (i = 0; i < comps->n - 1; i++) { res = ccn_name_comp_get(ccnb, comps, i, &comp, &comp_size); titem = proto_tree_add_item(name_tree, hf_ccn_name_components, tvb, comp - ccnb, comp_size, FALSE); } /* MinSuffixComponents */ l = pi->offset[CCN_PI_E_MinSuffixComponents] - pi->offset[CCN_PI_B_MinSuffixComponents]; if (l > 0) { i = pi->min_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_minsuffixcomponents, tvb, pi->offset[CCN_PI_B_MinSuffixComponents], l, i); } /* MaxSuffixComponents */ l = pi->offset[CCN_PI_E_MaxSuffixComponents] - pi->offset[CCN_PI_B_MaxSuffixComponents]; if (l > 0) { i = pi->max_suffix_comps; titem = proto_tree_add_uint(tree, hf_ccn_maxsuffixcomponents, tvb, pi->offset[CCN_PI_B_MaxSuffixComponents], l, i); } /* PublisherPublicKeyDigest */ /* Exclude */ l = pi->offset[CCN_PI_E_Exclude] - pi->offset[CCN_PI_B_Exclude]; if (l > 0) { c = ccn_charbuf_create(); d = ccn_buf_decoder_start(&decoder, ccnb + pi->offset[CCN_PI_B_Exclude], l); if (!ccn_buf_match_dtag(d, CCN_DTAG_Exclude)) { ccn_charbuf_destroy(&c); return(-1); } ccn_charbuf_append_string(c, "Exclude: "); ccn_buf_advance(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } while (ccn_buf_match_dtag(d, CCN_DTAG_Component)) { ccn_buf_advance(d); comp_size = 0; if (ccn_buf_match_blob(d, &comp, &comp_size)) ccn_buf_advance(d); ccn_uri_append_percentescaped(c, comp, comp_size); ccn_charbuf_append_string(c, " "); ccn_buf_check_close(d); if (ccn_buf_match_dtag(d, CCN_DTAG_Any)) { ccn_buf_advance(d); ccn_charbuf_append_string(c, "* "); ccn_buf_check_close(d); } else if (ccn_buf_match_dtag(d, CCN_DTAG_Bloom)) { ccn_buf_advance(d); if (ccn_buf_match_blob(d, &bloom, &bloom_size)) ccn_buf_advance(d); ccn_charbuf_append_string(c, "? "); ccn_buf_check_close(d); } } titem = proto_tree_add_text(tree, tvb, pi->offset[CCN_PI_B_Exclude], l, "%s", ccn_charbuf_as_string(c)); exclude_tree = proto_item_add_subtree(titem, ett_exclude); ccn_charbuf_destroy(&c); } /* ChildSelector */ l = pi->offset[CCN_PI_E_ChildSelector] - pi->offset[CCN_PI_B_ChildSelector]; if (l > 0) { i = pi->orderpref; titem = proto_tree_add_uint(tree, hf_ccn_childselector, tvb, pi->offset[CCN_PI_B_ChildSelector], l, i); proto_item_append_text(titem, ", %s", val_to_str(i & 1, VALS(childselectordirection_vals), "")); } /* AnswerOriginKind */ l = pi->offset[CCN_PI_E_AnswerOriginKind] - pi->offset[CCN_PI_B_AnswerOriginKind]; if (l > 0) { i = pi->answerfrom; titem = proto_tree_add_uint(tree, hf_ccn_answeroriginkind, tvb, pi->offset[CCN_PI_B_AnswerOriginKind], l, i); } /* Scope */ l = pi->offset[CCN_PI_E_Scope] - pi->offset[CCN_PI_B_Scope]; if (l > 0) { i = pi->scope; titem = proto_tree_add_uint(tree, hf_ccn_scope, tvb, pi->offset[CCN_PI_B_Scope], l, i); } /* InterestLifetime */ l = pi->offset[CCN_PI_E_InterestLifetime] - pi->offset[CCN_PI_B_InterestLifetime]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_InterestLifetime, ccnb, pi->offset[CCN_PI_B_InterestLifetime], pi->offset[CCN_PI_E_InterestLifetime], &blob, &blob_size); lifetime = 0.0; for (i = 0; i < blob_size; i++) lifetime = lifetime * 256.0 + (double)blob[i]; lifetime /= 4096.0; titem = proto_tree_add_double(tree, hf_ccn_interestlifetime, tvb, blob - ccnb, blob_size, lifetime); } /* Nonce */ l = pi->offset[CCN_PI_E_Nonce] - pi->offset[CCN_PI_B_Nonce]; if (l > 0) { i = ccn_ref_tagged_BLOB(CCN_DTAG_Nonce, ccnb, pi->offset[CCN_PI_B_Nonce], pi->offset[CCN_PI_E_Nonce], &blob, &blob_size); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, ", <"); for (i = 0; i < blob_size; i++) col_append_fstr(pinfo->cinfo, COL_INFO, "%02x", blob[i]); col_append_str(pinfo->cinfo, COL_INFO, ">"); } titem = proto_tree_add_item(tree, hf_ccn_nonce, tvb, blob - ccnb, blob_size, FALSE); } return (1); }
/* dissector of each payload */ static int dissect_xtp_aseg(tvbuff_t *tvb, proto_tree *tree, guint32 offset) { guint32 len = tvb_length_remaining(tvb, offset); guint32 start = offset; proto_item *ti, *ti2, *top_ti; proto_tree *xtp_subtree; struct xtp_ip_addr_seg aseg[1]; int error = 0; top_ti = proto_tree_add_text(tree, tvb, offset, len, "Address Segment"); xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_aseg); if (len < XTP_NULL_ADDR_SEG_LEN) { proto_item_append_text(top_ti, ", bogus length(%u, must be at least %u)", len, XTP_NULL_ADDR_SEG_LEN); return 0; } /** parse common fields **/ /* alen(2) */ aseg->alen = tvb_get_ntohs(tvb, offset); offset += 2; /* adomain(1) */ aseg->adomain = tvb_get_guint8(tvb, offset); offset++; /* aformat(1) */ aseg->aformat = tvb_get_guint8(tvb, offset); /** display common fields **/ offset = start; /* alen(2) */ ti = proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_alen, tvb, offset, 2, aseg->alen); offset += 2; if (aseg->alen > len) { proto_item_append_text(ti, ", bogus length(%u, must be at most %u)", aseg->alen, len); error = 1; } /* adomain(1) */ proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_adomain, tvb, offset, 1, aseg->adomain); offset++; /* aformat(1) */ ti2 = proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_aformat, tvb, offset, 1, aseg->aformat); offset++; switch (aseg->aformat) { case 0: if (aseg->alen != XTP_NULL_ADDR_SEG_LEN) { proto_item_append_text(ti, ", bogus length(%u, must be %u)", aseg->alen, XTP_NULL_ADDR_SEG_LEN); error = 1; } break; case 1: if (aseg->alen != XTP_IP_ADDR_SEG_LEN) { proto_item_append_text(ti, ", bogus length(%u, must be %u)", aseg->alen, XTP_IP_ADDR_SEG_LEN); error = 1; } break; default: if (aseg->aformat < 128) { proto_item_append_text(ti2, ", Unsupported aformat(%u)", aseg->aformat); error = 1; } break; } if (error) return (offset - start); /** parse and display each address fileds */ switch (aseg->aformat) { case 0: /* address(4) */ aseg->dsthost = tvb_get_ntohl(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_address, tvb, offset, 4, aseg->dsthost); offset += 4; break; case 1: /* dsthost(4) */ aseg->dsthost = tvb_get_ipv4(tvb, offset); proto_tree_add_ipv4(xtp_subtree, hf_xtp_aseg_dsthost, tvb, offset, 4, aseg->dsthost); offset += 4; /* srchost(4) */ aseg->srchost = tvb_get_ipv4(tvb, offset); proto_tree_add_ipv4(xtp_subtree, hf_xtp_aseg_srchost, tvb, offset, 4, aseg->srchost); offset += 4; /* dstport(2) */ aseg->dstport = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_dstport, tvb, offset, 2, aseg->dstport); offset += 2; /* srcport(2) */ aseg->srcport = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(xtp_subtree, hf_xtp_aseg_srcport, tvb, offset, 2, aseg->srcport); offset += 2; /** add summary **/ proto_item_append_text(top_ti, ", Dst Port: %u", aseg->dstport); proto_item_append_text(top_ti, ", Src Port: %u", aseg->srcport); break; default: break; } return (offset - start); }
/* Decode REG-RSP messages. */ void dissect_mac_mgmt_msg_reg_rsp_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tlv_offset; guint tvb_len, payload_type; proto_item *reg_rsp_item = NULL; proto_tree *reg_rsp_tree = NULL; proto_item *tlv_item = NULL; proto_tree *tlv_tree = NULL; proto_tree *sub_tree = NULL; gboolean hmac_found = FALSE; tlv_info_t tlv_info; gint tlv_type; guint tlv_len; guint this_offset = 0; tlv_info_t sub_tlv_info; gint sub_tlv_type; gint sub_tlv_len; guint sub_tlv_offset; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, offset); if (payload_type != MAC_MGMT_MSG_REG_RSP) { return; } if (tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type REG-RSP */ reg_rsp_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, offset, tvb_len, "MAC Management Message, REG-RSP (7)"); /* add MAC REG-RSP subtree */ reg_rsp_tree = proto_item_add_subtree(reg_rsp_item, ett_mac_mgmt_msg_reg_rsp_decoder); /* display the Message Type */ proto_tree_add_item(reg_rsp_tree, hf_reg_rsp_message_type, tvb, offset, 1, FALSE); proto_tree_add_item(reg_rsp_tree, hf_reg_rsp_status, tvb, offset + 1, 1, FALSE); offset += 2; while (offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if (tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "REG-RSP TLV error"); } proto_tree_add_item(reg_rsp_tree, hf_reg_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case REG_ARQ_PARAMETERS: case REG_SS_MGMT_SUPPORT: case REG_IP_MGMT_MODE: case REG_IP_VERSION: case REG_UL_TRANSPORT_CIDS_SUPPORTED: case REG_IP_PHS_SDU_ENCAP: case REG_MAX_CLASSIFIERS_SUPPORTED: case REG_PHS_SUPPORT: case REG_ARQ_SUPPORT: case REG_DSX_FLOW_CONTROL: case REG_MCA_FLOW_CONTROL: case REG_MCAST_POLLING_CIDS: case REG_NUM_DL_TRANS_CID: case REG_MAC_ADDRESS: #ifdef WIMAX_16E_2005 case REG_TLV_T_20_MAX_MAC_DATA_PER_FRAME_SUPPORT: case REG_TLV_T_21_PACKING_SUPPORT: case REG_TLV_T_22_MAC_EXTENDED_RTPS_SUPPORT: case REG_TLV_T_23_MAX_NUM_BURSTS_TRANSMITTED_CONCURRENTLY_TO_THE_MS: case REG_TLV_T_26_METHOD_FOR_ALLOCATING_IP_ADDR_SECONDARY_MGMNT_CONNECTION: case REG_TLV_T_27_HANDOVER_SUPPORTED: case REG_TLV_T_29_HO_PROCESS_OPTIMIZATION_MS_TIMER: case REG_TLV_T_31_MOBILITY_FEATURES_SUPPORTED: case REG_TLV_T_40_ARQ_ACK_TYPE: case REG_TLV_T_41_MS_HO_CONNECTIONS_PARAM_PROCESSING_TIME: case REG_TLV_T_42_MS_HO_TEK_PROCESSING_TIME: case REG_TLV_T_43_MAC_HEADER_AND_EXTENDED_SUBHEADER_SUPPORT: case REG_POWER_SAVING_CLASS_CAPABILITY: #endif dissect_extended_tlv(reg_rsp_tree, tlv_type, tvb, tlv_offset, tlv_len, pinfo, offset, proto_mac_mgmt_msg_reg_rsp_decoder); break; case REG_RSP_SECONDARY_MGMT_CID: tlv_tree = add_tlv_subtree(&tlv_info, ett_reg_rsp_message_tree, reg_rsp_tree, hf_reg_rsp_secondary_mgmt_cid, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_reg_rsp_secondary_mgmt_cid, tvb, tlv_offset, tlv_len, FALSE); break; case REG_RSP_TLV_T_36_TOTAL_PROVISIONED_SERVICE_FLOW_DSAs: tlv_tree = add_tlv_subtree(&tlv_info, ett_reg_rsp_message_tree, reg_rsp_tree, hf_reg_total_provisioned_sf, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_reg_total_provisioned_sf, tvb, tlv_offset, tlv_len, FALSE); break; case REG_RSP_TLV_T_24_CID_UPDATE_ENCODINGS: /* Display CID update encodings */ /* add subtree */ sub_tree = add_protocol_subtree(&tlv_info, ett_reg_rsp_message_tree, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "CID update encodings (%u byte(s))", tlv_len); /* Use a local copy of tlv_offset */ this_offset = tlv_offset; while(this_offset < tlv_len) { /* Get the sub TLV data. */ init_tlv_info(&sub_tlv_info, tvb, this_offset); /* get the sub TLV type */ sub_tlv_type = get_tlv_type(&sub_tlv_info); /* get the TLV length */ sub_tlv_len = get_tlv_length(&sub_tlv_info); if (tlv_type == -1 || sub_tlv_len > MAX_TLV_LEN || sub_tlv_len < 1) { /* invalid tlv info */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "REG-RSP TLV error"); } proto_tree_add_item(reg_rsp_tree, hf_reg_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the offset to the sub TLV data */ sub_tlv_offset = this_offset + get_tlv_value_offset(&sub_tlv_info); switch (sub_tlv_type) { case REG_RSP_TLV_T_24_1_CID_UPDATE_ENCODINGS_NEW_CID: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_reg_rsp_message_tree, sub_tree, hf_reg_rsp_new_cid_after_ho, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_reg_rsp_new_cid_after_ho, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; case REG_RSP_TLV_T_24_2_CID_UPDATE_ENCODINGS_SFID: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_reg_rsp_message_tree, sub_tree, hf_reg_rsp_service_flow_id, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_reg_rsp_service_flow_id, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; case REG_RSP_TLV_T_24_3_CID_UPDATE_ENCODINGS_CONNECTION_INFO: tlv_tree = add_protocol_subtree(&sub_tlv_info, ett_reg_rsp_message_tree, sub_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, sub_tlv_offset, sub_tlv_len, "CID Update Encodings Connection Info (%u byte(s))", tlv_len); /* Decode the DSC_RSP subTLV's */ dissect_mac_mgmt_msg_dsc_rsp_decoder(tvb_new_subset(tvb, sub_tlv_offset, sub_tlv_len, sub_tlv_len), pinfo, tlv_tree); break; default: tlv_tree = add_tlv_subtree(&sub_tlv_info, ett_reg_rsp_message_tree, sub_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, sub_tlv_offset, sub_tlv_len, FALSE); break; } this_offset = sub_tlv_len + sub_tlv_offset; } break; case REG_RSP_TLV_T_28_HO_SYSTEM_RESOURCE_RETAIN_TIME: tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "System Resource Retain Time (%u byte(s))", tlv_len); tlv_item = proto_tree_add_item(tlv_tree, hf_reg_rsp_system_resource_retain_time, tvb, tlv_offset, tlv_len, FALSE); if (include_cor2_changes) { proto_item_append_text(tlv_item, " (in units of 100 milliseconds)"); } else { proto_item_append_text(tlv_item, " (multiple of 100 milliseconds)"); } break; case DSx_UPLINK_FLOW: /* display Uplink Service Flow Encodings info */ /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "Uplink Service Flow Encodings (%u byte(s))", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, tlv_tree); break; case DSx_DOWNLINK_FLOW: /* display Downlink Service Flow Encodings info */ /* add subtree */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "Downlink Service Flow Encodings (%u byte(s))", tlv_len); /* decode and display the DL Service Flow Encodings */ wimax_service_flow_encodings_decoder(tvb_new_subset(tvb, tlv_offset, tlv_len, tlv_len), pinfo, tlv_tree); break; case HMAC_TUPLE: /* Table 348d */ /* decode and display the HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "HMAC Tuple (%u byte(s))", tlv_len); wimax_hmac_tuple_decoder(tlv_tree, tvb, offset+2, tlv_len); hmac_found = TRUE; break; case CMAC_TUPLE: /* Table 348b */ /* decode and display the CMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "CMAC Tuple (%u byte(s))", tlv_len); wimax_cmac_tuple_decoder(tlv_tree, tvb, offset+2, tlv_len); break; case SHORT_HMAC_TUPLE: case SHORT_HMAC_TUPLE_COR2: if ((!include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE)) || (include_cor2_changes && (tlv_type == SHORT_HMAC_TUPLE_COR2))) { /* decode and display the Short HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_reg_rsp_decoder, reg_rsp_tree, proto_mac_mgmt_msg_reg_rsp_decoder, tvb, tlv_offset, tlv_len, "Short HMAC Tuple (%u byte(s))", tlv_len); wimax_short_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len); } else { /* Unknown TLV Type */ tlv_tree = add_tlv_subtree(&tlv_info, ett_reg_rsp_message_tree, reg_rsp_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); } break; case VENDOR_SPECIFIC_INFO: case VENDOR_ID_ENCODING: case MAC_VERSION_ENCODING: wimax_common_tlv_encoding_decoder(tvb_new_subset(tvb, offset, (tvb_len - offset), (tvb_len - offset)), pinfo, reg_rsp_tree); break; default: tlv_tree = add_tlv_subtree(&tlv_info, ett_reg_rsp_message_tree, reg_rsp_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); proto_tree_add_item(tlv_tree, hf_tlv_type, tvb, tlv_offset, tlv_len, FALSE); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (!hmac_found) proto_item_append_text(reg_rsp_tree, " (HMAC Tuple is missing !)"); } }
/* * Dissect RTSE PDUs inside a PPDU. */ static int dissect_rtse(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void* data) { int offset = 0; int old_offset; proto_item *item; proto_tree *tree; proto_tree *next_tree=NULL; tvbuff_t *next_tvb = NULL; tvbuff_t *data_tvb = NULL; fragment_head *frag_msg = NULL; guint32 fragment_length; guint32 rtse_id = 0; gboolean data_handled = FALSE; struct SESSION_DATA_STRUCTURE* session; conversation_t *conversation = NULL; asn1_ctx_t asn1_ctx; asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo); /* do we have application context from the acse dissector? */ if (data == NULL) return 0; session = (struct SESSION_DATA_STRUCTURE*)data; /* save parent_tree so subdissectors can create new top nodes */ top_tree=parent_tree; asn1_ctx.private_data = session; col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTSE"); col_clear(pinfo->cinfo, COL_INFO); if (rtse_reassemble && ((session->spdu_type == SES_DATA_TRANSFER) || (session->spdu_type == SES_MAJOR_SYNC_POINT))) { /* Use conversation index as fragment id */ conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (conversation != NULL) { rtse_id = conversation->index; } session->rtse_reassemble = TRUE; } if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) { frag_msg = fragment_end_seq_next (&rtse_reassembly_table, pinfo, rtse_id, NULL); next_tvb = process_reassembled_data (tvb, offset, pinfo, "Reassembled RTSE", frag_msg, &rtse_frag_items, NULL, parent_tree); } item = proto_tree_add_item(parent_tree, proto_rtse, next_tvb ? next_tvb : tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_rtse); if (rtse_reassemble && session->spdu_type == SES_DATA_TRANSFER) { /* strip off the OCTET STRING encoding - including any CONSTRUCTED OCTET STRING */ dissect_ber_octet_string(FALSE, &asn1_ctx, tree, tvb, offset, hf_rtse_segment_data, &data_tvb); if (data_tvb) { fragment_length = tvb_captured_length_remaining (data_tvb, 0); proto_item_append_text(asn1_ctx.created_item, " (%u byte%s)", fragment_length, plurality(fragment_length, "", "s")); frag_msg = fragment_add_seq_next (&rtse_reassembly_table, data_tvb, 0, pinfo, rtse_id, NULL, fragment_length, TRUE); if (frag_msg && pinfo->fd->num != frag_msg->reassembled_in) { /* Add a "Reassembled in" link if not reassembled in this frame */ proto_tree_add_uint (tree, *(rtse_frag_items.hf_reassembled_in), data_tvb, 0, 0, frag_msg->reassembled_in); } pinfo->fragmented = TRUE; data_handled = TRUE; } else { fragment_length = tvb_captured_length_remaining (tvb, offset); } col_append_fstr(pinfo->cinfo, COL_INFO, "[RTSE fragment, %u byte%s]", fragment_length, plurality(fragment_length, "", "s")); } else if (rtse_reassemble && session->spdu_type == SES_MAJOR_SYNC_POINT) { if (next_tvb) { /* ROS won't do this for us */ session->ros_op = (ROS_OP_INVOKE | ROS_OP_ARGUMENT); /*offset=*/dissect_ber_external_type(FALSE, tree, next_tvb, 0, &asn1_ctx, -1, call_rtse_external_type_callback); top_tree = NULL; /* Return other than 0 to indicate that we handled this packet */ return 1; } else { offset = tvb_captured_length (tvb); } pinfo->fragmented = FALSE; data_handled = TRUE; } if (!data_handled) { while (tvb_reported_length_remaining(tvb, offset) > 0){ old_offset=offset; offset=dissect_rtse_RTSE_apdus(TRUE, tvb, offset, &asn1_ctx, tree, -1); if(offset == old_offset){ next_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_rtse_unknown, &item, "Unknown RTSE PDU"); expert_add_info (pinfo, item, &ei_rtse_unknown_rtse_pdu); dissect_unknown_ber(pinfo, tvb, offset, next_tree); break; } } } top_tree = NULL; return tvb_captured_length(tvb); }
int dissect_IDispatch_Invoke_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep) { guint32 u32Pointer; guint32 u32Pointer2; guint32 u32Pointer3; guint32 u32VariableOffset; guint32 u32ArraySize; guint32 u32SubStart; guint16 u16Code; guint16 u16Reserved; guint32 u32HelpContext; guint32 u32Reserved; guint32 u32DeferredFillIn; guint32 u32ArgErr; guint32 u32HResult; guint32 u32SCode; guint32 u32VarRef; gchar szName[1000] = { 0 }; proto_item *excepinfo_item; proto_tree *excepinfo_tree; offset = dissect_dcom_that(tvb, offset, pinfo, tree, drep); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer); if (u32Pointer) { offset = dissect_dcom_VARIANT(tvb, offset, pinfo, tree, drep, hf_dispatch_varresult); } /* ExcepInfo */ excepinfo_item = proto_tree_add_item(tree, hf_dispatch_excepinfo, tvb, offset, 0, ENC_NA); excepinfo_tree = proto_item_add_subtree (excepinfo_item, ett_dispatch_excepinfo); u32SubStart = offset; offset = dissect_dcom_WORD(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_code, &u16Code); offset = dissect_dcom_WORD(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_reserved16, &u16Reserved); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, excepinfo_tree, drep, &u32Pointer); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, excepinfo_tree, drep, &u32Pointer2); offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, excepinfo_tree, drep, &u32Pointer3); offset = dissect_dcom_DWORD(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_help_context, &u32HelpContext); offset = dissect_dcom_DWORD(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_reserved32, &u32Reserved); offset = dissect_dcom_DWORD(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_deferred_fill_in, &u32DeferredFillIn); offset = dissect_dcom_DWORD(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_scode, &u32SCode); if (u32Pointer) { offset = dissect_dcom_BSTR(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_source, szName, sizeof(szName)); } if (u32Pointer2) { offset = dissect_dcom_BSTR(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_description, szName, sizeof(szName)); } if (u32Pointer3) { offset = dissect_dcom_BSTR(tvb, offset, pinfo, excepinfo_tree, drep, hf_dispatch_help_file, szName, sizeof(szName)); } proto_item_append_text(excepinfo_item, ", SCode: %s", val_to_str(u32SCode, dcom_hresult_vals, "Unknown (0x%08x)")); proto_item_set_len(excepinfo_item, offset - u32SubStart); /* end of ExcepInfo */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep, hf_dispatch_arg_err, &u32ArgErr); /* rgVarRef: VARIANT[u32VarRef] */ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, &u32ArraySize); u32VarRef = u32ArraySize; u32VariableOffset = offset + u32ArraySize * 4; while(u32ArraySize--) { offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, tree, drep, hf_dispatch_varrefarg); } } offset = u32VariableOffset; /* HRESULT of call */ offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, drep, &u32HResult); col_append_fstr(pinfo->cinfo, COL_INFO, " SCode=%s VarRef=%u -> %s", val_to_str(u32SCode, dcom_hresult_vals, "Unknown (0x%08x)"), u32VarRef, val_to_str(u32HResult, dcom_hresult_vals, "Unknown (0x%08x)") ); return offset; }
static int dissect_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset) { proto_item *pitem = NULL; guint control_type; guint8 unknown_control_type; guint8 uuid_size; guint16 uuid_dst; guint16 uuid_src; guint16 response_message; guint16 list_length; guint i_item; proto_tree_add_item(tree, hf_btbnep_control_type, tvb, offset, 1, ENC_BIG_ENDIAN); control_type = tvb_get_guint8(tvb, offset); offset += 1; col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(control_type, control_type_vals, "Unknown type")); switch(control_type) { case 0x00: /* Command Not Understood */ proto_tree_add_item(tree, hf_btbnep_unknown_control_type, tvb, offset, 1, ENC_BIG_ENDIAN); unknown_control_type = tvb_get_guint8(tvb, offset); offset += 1; col_append_fstr(pinfo->cinfo, COL_INFO, " - Unknown(%s)", val_to_str_const(unknown_control_type, control_type_vals, "Unknown type")); break; case 0x01: /* Setup Connection Request */ proto_tree_add_item(tree, hf_btbnep_uuid_size, tvb, offset, 1, ENC_BIG_ENDIAN); uuid_size = tvb_get_guint8(tvb, offset); offset += 1; pitem = proto_tree_add_item(tree, hf_btbnep_destination_service_uuid, tvb, offset, uuid_size, ENC_NA); uuid_dst = tvb_get_ntohs(tvb, offset); proto_item_append_text(pitem, " (%s)", val_to_str_ext(uuid_dst, &bluetooth_uuid_vals_ext, "Unknown uuid")); offset += uuid_size; pitem = proto_tree_add_item(tree, hf_btbnep_source_service_uuid, tvb, offset, uuid_size, ENC_NA); uuid_src = tvb_get_ntohs(tvb, offset); proto_item_append_text(pitem, " (%s)", val_to_str_ext(uuid_src, &bluetooth_uuid_vals_ext, "Unknown uuid")); offset += uuid_size; col_append_fstr(pinfo->cinfo, COL_INFO, " - dst: <%s>, src: <%s>", val_to_str_ext(uuid_dst, &bluetooth_uuid_vals_ext, "Unknown uuid"), val_to_str_ext(uuid_src, &bluetooth_uuid_vals_ext, "Unknown uuid")); break; case 0x02: /* Setup Connection Response */ proto_tree_add_item(tree, hf_btbnep_setup_connection_response_message, tvb, offset, 2, ENC_BIG_ENDIAN); response_message = tvb_get_ntohs(tvb, offset); offset += 2; col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(response_message, setup_connection_response_message_vals, "Unknown response message")); break; case 0x03: /* Filter Net Type Set */ proto_tree_add_item(tree, hf_btbnep_list_length, tvb, offset, 2, ENC_BIG_ENDIAN); list_length = tvb_get_ntohs(tvb, offset); offset += 2; for (i_item = 0; i_item + 4 > i_item && i_item < list_length; i_item += 4) { proto_tree_add_item(tree, hf_btbnep_network_type_start, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_btbnep_network_type_end, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } break; case 0x04: /* Filter Net Type Response */ proto_tree_add_item(tree, hf_btbnep_filter_net_type_response_message, tvb, offset, 2, ENC_BIG_ENDIAN); response_message = tvb_get_ntohs(tvb, offset); offset += 2; col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(response_message, filter_net_type_response_message_vals, "Unknown response message")); break; case 0x05: /*Filter Multi Addr Set*/ proto_tree_add_item(tree, hf_btbnep_list_length, tvb, offset, 2, ENC_BIG_ENDIAN); list_length = tvb_get_ntohs(tvb, offset); offset += 2; for (i_item = 0; i_item + 12 > i_item && i_item < list_length; i_item += 12) { proto_tree_add_item(tree, hf_btbnep_multicast_address_start, tvb, offset, 6, ENC_NA); offset += 6; proto_tree_add_item(tree, hf_btbnep_multicast_address_end, tvb, offset, 6, ENC_NA); offset += 6; } break; case 0x06: /* Filter Multi Addr Response */ proto_tree_add_item(tree, hf_btbnep_filter_multi_addr_response_message, tvb, offset, 2, ENC_BIG_ENDIAN); response_message = tvb_get_ntohs(tvb, offset); offset += 2; col_append_fstr(pinfo->cinfo, COL_INFO, " - %s", val_to_str_const(response_message, filter_multi_addr_response_message_vals, "Unknown response message")); break; }; return offset; }
static int add_option_info(tvbuff_t *tvb, int pos, proto_tree *tree, proto_item *ti) { guint8 tag, length, fcs_err = 0, encr = 0, seen_fcs_err = 0; proto_tree *tag_tree; /* * Read all option tags in an endless loop. If the packet is malformed this * loop might be a problem. */ while (TRUE) { tag = tvb_get_guint8(tvb, pos); if ((tag != TZSP_HDR_PAD) && (tag != TZSP_HDR_END)) { length = tvb_get_guint8(tvb, pos+1); tag_tree = proto_tree_add_subtree(tree, tvb, pos, 2+length, ett_tag, NULL, val_to_str_const(tag, option_tag_vals, "Unknown")); } else { tag_tree = proto_tree_add_subtree(tree, tvb, pos, 1, ett_tag, NULL, val_to_str_const(tag, option_tag_vals, "Unknown")); length = 0; } proto_tree_add_item(tag_tree, hf_option_tag, tvb, pos, 1, ENC_BIG_ENDIAN); pos++; if ((tag != TZSP_HDR_PAD) && (tag != TZSP_HDR_END)) { proto_tree_add_item(tag_tree, hf_option_length, tvb, pos, 1, ENC_BIG_ENDIAN); pos++; } switch (tag) { case TZSP_HDR_PAD: break; case TZSP_HDR_END: /* Fill in header with information from other tags. */ if (seen_fcs_err) { proto_item_append_text(ti,"%s", fcs_err?"FCS Error":(encr?"Encrypted":"Good")); } return pos; case TZSP_HDR_ORIGINAL_LENGTH: proto_tree_add_item(tag_tree, hf_original_length, tvb, pos, 2, ENC_BIG_ENDIAN); break; case WLAN_RADIO_HDR_SIGNAL: proto_tree_add_item(tag_tree, hf_signal, tvb, pos, 1, ENC_BIG_ENDIAN); break; case WLAN_RADIO_HDR_NOISE: proto_tree_add_item(tag_tree, hf_silence, tvb, pos, 1, ENC_BIG_ENDIAN); break; case WLAN_RADIO_HDR_RATE: proto_tree_add_item(tag_tree, hf_rate, tvb, pos, 1, ENC_BIG_ENDIAN); break; case WLAN_RADIO_HDR_TIMESTAMP: proto_tree_add_item(tag_tree, hf_time, tvb, pos, 4, ENC_BIG_ENDIAN); break; case WLAN_RADIO_HDR_MSG_TYPE: proto_tree_add_item(tag_tree, hf_status_msg_type, tvb, pos, 1, ENC_BIG_ENDIAN); break; case WLAN_RADIO_HDR_CF: proto_tree_add_item(tag_tree, hf_status_pcf, tvb, pos, 1, ENC_NA); break; case WLAN_RADIO_HDR_UN_DECR: proto_tree_add_item(tag_tree, hf_status_undecrypted, tvb, pos, 1, ENC_NA); encr = tvb_get_guint8(tvb, pos); break; case WLAN_RADIO_HDR_FCS_ERR: seen_fcs_err = 1; proto_tree_add_item(tag_tree, hf_status_fcs_error, tvb, pos, 1, ENC_NA); fcs_err = tvb_get_guint8(tvb, pos); break; case WLAN_RADIO_HDR_CHANNEL: proto_tree_add_item(tag_tree, hf_channel, tvb, pos, 1, ENC_BIG_ENDIAN); break; case TZSP_HDR_SENSOR: proto_tree_add_item(tag_tree, hf_sensormac, tvb, pos, 6, ENC_NA); break; default: proto_tree_add_item(tag_tree, hf_unknown, tvb, pos, length, ENC_NA); break; } pos += length; } }
int dissect_IDispatch_Invoke_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep) { guint32 u32DispIdMember; e_uuid_t riid; guint32 u32Lcid; guint32 u32Flags; guint32 u32Args; guint32 u32NamedArgs; guint32 u32Pointer; guint32 u32Pointer2; guint32 u32ArraySize; guint32 u32VariableOffset; guint32 u32VarRef; guint32 u32VarRefIdx; guint32 u32TmpOffset; guint32 u32SubStart; proto_item *feature_item; proto_tree *feature_tree; proto_item *dispparams_item; proto_tree *dispparams_tree; offset = dissect_dcom_this(tvb, offset, pinfo, tree, drep); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep, hf_dispatch_id, &u32DispIdMember); col_append_fstr(pinfo->cinfo, COL_INFO, " ID=0x%x", u32DispIdMember); offset = dissect_dcom_UUID(tvb, offset, pinfo, tree, drep, hf_dispatch_riid, &riid); offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep, hf_dispatch_lcid, &u32Lcid); /* dispatch flags */ u32TmpOffset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL, drep, hf_dispatch_flags, &u32Flags); feature_item = proto_tree_add_uint (tree, hf_dispatch_flags, tvb, offset, 4, u32Flags); feature_tree = proto_item_add_subtree (feature_item, ett_dispatch_flags); if (feature_tree) { proto_tree_add_boolean (feature_tree, hf_dispatch_flags_propputref, tvb, offset, 4, u32Flags); proto_tree_add_boolean (feature_tree, hf_dispatch_flags_propput, tvb, offset, 4, u32Flags); proto_tree_add_boolean (feature_tree, hf_dispatch_flags_propget, tvb, offset, 4, u32Flags); proto_tree_add_boolean (feature_tree, hf_dispatch_flags_method, tvb, offset, 4, u32Flags); } if (u32Flags & DISPATCH_FLAGS_METHOD) { proto_item_append_text(feature_item, ", Method"); col_append_str(pinfo->cinfo, COL_INFO, " Method"); } if (u32Flags & DISPATCH_FLAGS_PROPGET) { proto_item_append_text(feature_item, ", PropertyGet"); col_append_str(pinfo->cinfo, COL_INFO, " PropertyGet"); } if (u32Flags & DISPATCH_FLAGS_PROPPUT) { proto_item_append_text(feature_item, ", PropertyPut"); col_append_str(pinfo->cinfo, COL_INFO, " PropertyPut"); } if (u32Flags & DISPATCH_FLAGS_PROPPUTREF) { proto_item_append_text(feature_item, ", PropertyPutRef"); col_append_str(pinfo->cinfo, COL_INFO, " PropertyPutRef"); } offset = u32TmpOffset; dispparams_item = proto_tree_add_item(tree, hf_dispatch_dispparams, tvb, offset, 0, ENC_NA); dispparams_tree = proto_item_add_subtree (dispparams_item, ett_dispatch_params); u32SubStart = offset; /* DISPPARAMS */ /* VARIANT rgvarg[u32Args] */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, dispparams_tree, drep, &u32Pointer); /* DISPID rgdispidNamedArgs[u32NamedArgs] */ offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, dispparams_tree, drep, &u32Pointer2); offset = dissect_dcom_DWORD(tvb, offset, pinfo, dispparams_tree, drep, hf_dispatch_args, &u32Args); offset = dissect_dcom_DWORD(tvb, offset, pinfo, dispparams_tree, drep, hf_dispatch_named_args, &u32NamedArgs); if (u32Pointer) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, dispparams_tree, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize * 4; while(u32ArraySize--) { offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, dispparams_tree, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, dispparams_tree, drep, hf_dispatch_arg); } } offset = u32VariableOffset; } /* DISPID rgdispidNamedArgs[u32NamedArgs] */ if (u32Pointer2) { offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, dispparams_tree, drep, &u32ArraySize); while(u32ArraySize--) { offset = dissect_dcom_DWORD(tvb, offset, pinfo, dispparams_tree, drep, hf_dispatch_id, &u32DispIdMember); } } proto_item_append_text(dispparams_item, ", Args: %u NamedArgs: %u", u32Args, u32NamedArgs); proto_item_set_len(dispparams_item, offset - u32SubStart); /* end of DISPPARAMS */ /* u32VarRef */ offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep, hf_dispatch_varref, &u32VarRef); /* rgVarRefIdx: UINT[u32VarRef] */ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, &u32ArraySize); while(u32ArraySize--) { offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, drep, hf_dispatch_varrefidx, &u32VarRefIdx); } /* rgVarRef: VARIANT[u32VarRef] */ offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, tree, drep, &u32ArraySize); u32VariableOffset = offset + u32ArraySize * 4; while(u32ArraySize--) { offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, tree, drep, &u32Pointer); if (u32Pointer) { u32VariableOffset = dissect_dcom_VARIANT(tvb, u32VariableOffset, pinfo, tree, drep, hf_dispatch_varrefarg); } } col_append_fstr(pinfo->cinfo, COL_INFO, " Args=%u NamedArgs=%u VarRef=%u", u32Args, u32NamedArgs, u32VarRef); return u32VariableOffset; }
static void dissect_rsp_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset) { proto_item *item; proto_tree *tree; gboolean bidi_resid_present = FALSE; guint8 flags; item = proto_tree_add_item(parent_tree, hf_fcp_rspflags, tvb, offset, 1, ENC_LITTLE_ENDIAN); tree = proto_item_add_subtree(item, ett_fcp_rsp_flags); flags = tvb_get_guint8(tvb, offset); if (!flags) proto_item_append_text(item, " (No values set)"); /* BIDI RSP */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_bidi, tvb, offset, 1, flags); if (flags & 0x80) { bidi_resid_present = TRUE; proto_item_append_text(item, " BIDI_RSP"); if (flags & (~( 0x80 ))) proto_item_append_text(item, ","); } flags &= (~( 0x80 )); /* these two bits are only defined if the bidi bit is set */ if (bidi_resid_present) { /* BIDI READ RESID UNDER */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_bidi_rru, tvb, offset, 1, flags); if (flags & 0x40) { proto_item_append_text(item, " BIDI_RRU"); if (flags & (~( 0x40 ))) proto_item_append_text(item, ","); } flags &= (~( 0x40 )); /* BIDI READ RESID OVER */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_bidi_rro, tvb, offset, 1, flags); if (flags & 0x20) { proto_item_append_text(item, " BIDI_RRO"); if (flags & (~( 0x20 ))) proto_item_append_text(item, ","); } flags &= (~( 0x20 )); } /* Conf Req */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_conf_req, tvb, offset, 1, flags); if (flags & 0x10) { proto_item_append_text(item, " CONF REQ"); if (flags & (~( 0x10 ))) proto_item_append_text(item, ","); } flags &= (~( 0x10 )); /* Resid Under */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_resid_under, tvb, offset, 1, flags); if (flags & 0x08) { proto_item_append_text(item, " RESID UNDER"); if (flags & (~( 0x08 ))) proto_item_append_text(item, ","); } flags &= (~( 0x08 )); /* Resid Over */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_resid_over, tvb, offset, 1, flags); if (flags & 0x04) { proto_item_append_text(item, " RESID OVER"); if (flags & (~( 0x04 ))) proto_item_append_text(item, ","); } flags &= (~( 0x04 )); /* SNS len valid */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_sns_vld, tvb, offset, 1, flags); if (flags & 0x02) { proto_item_append_text(item, " SNS VLD"); if (flags & (~( 0x02 ))) proto_item_append_text(item, ","); } flags &= (~( 0x02 )); /* rsp len valid */ proto_tree_add_boolean(tree, hf_fcp_rsp_flags_res_vld, tvb, offset, 1, flags); if (flags & 0x01) { proto_item_append_text(item, " RES VLD"); if (flags & (~( 0x01 ))) proto_item_append_text(item, ","); } flags &= (~( 0x01 )); if (flags) { proto_item_append_text(item, " Unknown bitmap value 0x%x", flags); } }
static void dissect_task_mgmt_flags(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset) { proto_item *item; proto_tree *tree; guint8 flags; item = proto_tree_add_item(parent_tree, hf_fcp_taskmgmt, tvb, offset, 1, ENC_LITTLE_ENDIAN); tree = proto_item_add_subtree(item, ett_fcp_taskmgmt); flags = tvb_get_guint8(tvb, offset); if (!flags) proto_item_append_text(item, " (No values set)"); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_obsolete, tvb, offset, 1, flags); if (flags & 0x80) { proto_item_append_text(item, " OBSOLETE"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP OBSOLETE] "); } flags &= (~( 0x80 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_clear_aca, tvb, offset, 1, flags); if (flags & 0x40) { proto_item_append_text(item, " CLEAR ACA"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP CLEAR_ACA] "); } flags &= (~( 0x40 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_target_reset, tvb, offset, 1, flags); if (flags & 0x20) { proto_item_append_text(item, " TARGET RESET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP TARGET_RESET] "); } flags &= (~( 0x20 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_lu_reset, tvb, offset, 1, flags); if (flags & 0x10) { proto_item_append_text(item, " LU RESET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP LU_RESET] "); } flags &= (~( 0x10 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_rsvd, tvb, offset, 1, flags); if (flags & 0x08) { proto_item_append_text(item, " RSVD"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP RSVD] "); } flags &= (~( 0x08 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_clear_task_set, tvb, offset, 1, flags); if (flags & 0x04) { proto_item_append_text(item, " CLEAR TASK SET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP CLEAR_TASK_SET] "); } flags &= (~( 0x04 )); proto_tree_add_boolean(tree, hf_fcp_mgmt_flags_abort_task_set, tvb, offset, 1, flags); if (flags & 0x02) { proto_item_append_text(item, " ABORT TASK SET"); col_prepend_fence_fstr(pinfo->cinfo, COL_INFO, "[FCP ABORT_TASK_SET] "); } flags &= (~( 0x02 )); if (flags) { proto_item_append_text(item, " Unknown bitmap value 0x%x", flags); } }
static int add_option_info(tvbuff_t *tvb, int pos, proto_tree *tree, proto_item *ti) { guint8 tag, length, fcs_err = 0, encr = 0, seen_fcs_err = 0; /* * Read all option tags in an endless loop. If the packet is malformed this * loop might be a problem. */ while (TRUE) { tag = tvb_get_guint8(tvb, pos++); switch (tag) { case TZSP_HDR_PAD: length = 0; break; case TZSP_HDR_END: /* Fill in header with information from other tags. */ if (seen_fcs_err) { if (tree) proto_item_append_text(ti,"%s", fcs_err?"FCS Error":(encr?"Encrypted":"Good")); } return pos; case TZSP_HDR_ORIGINAL_LENGTH: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_int (tree, hf_original_length, tvb, pos-2, 4, tvb_get_ntohs(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_SIGNAL: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_int (tree, hf_signal, tvb, pos-2, 3, (char)tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_NOISE: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_int (tree, hf_silence, tvb, pos-2, 3, (char)tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_RATE: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_rate, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_TIMESTAMP: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_time, tvb, pos-2, 6, tvb_get_ntohl(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_MSG_TYPE: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_status_msg_type, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_CF: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_boolean (tree, hf_status_pcf, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case WLAN_RADIO_HDR_UN_DECR: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_boolean (tree, hf_status_undecrypted, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); encr = tvb_get_guint8(tvb, pos); pos += length; break; case WLAN_RADIO_HDR_FCS_ERR: seen_fcs_err = 1; length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_boolean (tree, hf_status_fcs_error, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); fcs_err = tvb_get_guint8(tvb, pos); pos += length; break; case WLAN_RADIO_HDR_CHANNEL: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_uint (tree, hf_channel, tvb, pos-2, 3, tvb_get_guint8(tvb, pos)); pos += length; break; case TZSP_HDR_SENSOR: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_ether(tree, hf_sensormac, tvb, pos-2, 6, tvb_get_ptr (tvb, pos, 6)); pos += length; break; default: length = tvb_get_guint8(tvb, pos++); if (tree) proto_tree_add_bytes(tree, hf_unknown, tvb, pos-2, length+2, tvb_get_ptr(tvb, pos, length)); pos += length; break; } } }
static void dissect_ancp_port_up_dn_mgmt(tvbuff_t *tvb, proto_tree *ancp_tree, gint offset) { proto_item *sti = NULL; proto_tree *tlv_tree = NULL, *dsl_tree = NULL; guint8 tech_type; guint16 blk_len, tlen, ttype, stlvtype, stlvlen; gint16 num_tlvs, num_stlvs; gint val; proto_tree_add_item(ancp_tree, hf_ancp_port, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ancp_tree, hf_ancp_port_sess_num, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ancp_tree, hf_ancp_evt_seq_num, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ancp_tree, hf_ancp_label, tvb, offset, 8, FALSE); offset += 8; /* Start of the Extension Block */ proto_tree_add_item(ancp_tree, hf_ancp_reserved, tvb, offset, 1, FALSE); offset += 1; /* * We have already displayed the message type in the common header dissect * need not display this again here - skip it */ offset += 1; /* Message type in Ext Blk */ proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, FALSE); tech_type = tvb_get_guint8(tvb, offset); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_blk_len, tvb, offset, 1, FALSE); offset += 1; if (tech_type == TECH_TYPE_DSL) { proto_tree_add_item(ancp_tree, hf_ancp_num_ext_tlvs, tvb, offset, 2, FALSE); num_tlvs = tvb_get_ntohs(tvb, offset); offset += 2; sti = proto_tree_add_item(ancp_tree, hf_ancp_len, tvb, offset, 2, FALSE); blk_len = tvb_get_ntohs(tvb, offset); proto_item_append_text(sti, " (Extension Block)"); offset += 2; /* Create a TLV sub tree */ tlv_tree = proto_item_add_subtree(sti, ett_ancp_len); for( ;num_tlvs; num_tlvs--) { proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_type, tvb, offset, 2, FALSE); ttype = tvb_get_ntohs(tvb, offset); offset += 2; sti = proto_tree_add_item(tlv_tree, hf_ancp_len, tvb, offset, 2, FALSE); tlen = tvb_get_ntohs(tvb, offset); offset += 2; /* * Extension Block is common for event message and port * management message, but the TLVs that can appear * are different */ switch (ttype) { case TLV_DSL_LINE_ATTRIBUTES: /* Create a DSL Attribute SubTree */ dsl_tree = proto_item_add_subtree(sti, ett_ancp_ext_tlv_type); num_stlvs = tlen / 8; /* TODO - better way? */ for ( ;num_stlvs; num_stlvs--) { proto_tree_add_item(dsl_tree, hf_ancp_dsl_line_stlv_type, tvb, offset, 2, FALSE); stlvtype = tvb_get_ntohs(tvb, offset); offset += 2; /* Skip sub-tlv-len display for now */ stlvlen = tvb_get_ntohs(tvb, offset); offset += 2; /* Sub TLV Length */ sti = proto_tree_add_item(dsl_tree, hf_ancp_dsl_line_stlv_value, tvb, offset, stlvlen, FALSE); val = tvb_get_ntohl(tvb, offset); offset += stlvlen; /* Except loop-encap, rest are 4B */ switch (stlvtype) { case TLV_DSL_LINE_STATE: proto_item_append_text(sti, " (%s)", val_to_str(val, dsl_line_state_names, "Unknown (0x%02x)")); break; case TLV_DSL_TYPE: proto_item_append_text(sti, " (%s)", val_to_str(val, dsl_line_type_names, "Unknown (0x%02x)")); break; default: /* Add Unit */ proto_item_append_text(sti, " %s", val_to_str(stlvtype, dsl_line_attr_units, "Unknown (0x%02x)")); break; } SKIPPADDING(offset, stlvlen); } break; case TLV_PING_OPAQUE_DATA: /* 2 32b values*/ proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(tlv_tree, hf_ancp_oam_opaque, tvb, offset, 4, FALSE); offset += 4; break; case TLV_PING_PARAMS: /* Count (1B) Timeout (1B), 2B empty */ proto_tree_add_item(tlv_tree, hf_ancp_oam_loopb_cnt, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(tlv_tree, hf_ancp_oam_timeout, tvb, offset, 1, FALSE); offset += 1; /* Lets not bother about 2B until IETF WG figures out */ offset += 2; break; default: /* Assume TLV value is string - covers ALCID, OAM resp */ proto_tree_add_item(tlv_tree, hf_ancp_ext_tlv_value_str, tvb, offset, tlen, FALSE); offset += tlen; SKIPPADDING(offset, tlen); break; } /* end switch {ttype} */ } /* end for {numtlvs} */ } /* end if {DSL} */ }
/* Decode DREG-CMD messages. */ void dissect_mac_mgmt_msg_dreg_cmd_decoder(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; guint tlv_offset; guint tvb_len, payload_type; proto_item *dreg_cmd_item = NULL; proto_tree *dreg_cmd_tree = NULL; proto_tree *tlv_tree = NULL; tlv_info_t tlv_info; gint tlv_type; gint tlv_len; gboolean hmac_found = FALSE; /* Ensure the right payload type */ payload_type = tvb_get_guint8(tvb, 0); if(payload_type != MAC_MGMT_MSG_DREG_CMD) { return; } if (tree) { /* we are being asked for details */ /* Get the tvb reported length */ tvb_len = tvb_reported_length(tvb); /* display MAC payload type DREG-CMD */ dreg_cmd_item = proto_tree_add_protocol_format(tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, 0, tvb_len, "MAC Management Message, DREG-CMD (29)"); /* add MAC DREG CMD subtree */ dreg_cmd_tree = proto_item_add_subtree(dreg_cmd_item, ett_mac_mgmt_msg_dreg_decoder); /* display the Message Type */ proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_message_type, tvb, offset, 1, FALSE); offset ++; /* display the Action Code */ if (include_cor2_changes) proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_action_cor2, tvb, offset, 1, FALSE); else proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_action, tvb, offset, 1, FALSE); /* show the Reserved bits */ proto_tree_add_item(dreg_cmd_tree, hf_dreg_cmd_reserved, tvb, offset, 1, FALSE); offset ++; while(offset < tvb_len) { /* Get the TLV data. */ init_tlv_info(&tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&tlv_info); if(tlv_type == -1 || tlv_len > MAX_TLV_LEN || tlv_len < 1) { /* invalid tlv info */ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "DREG-CMD TLV error"); } proto_tree_add_item(dreg_cmd_tree, hf_dreg_invalid_tlv, tvb, offset, (tvb_len - offset), FALSE); break; } /* get the offset to the TLV data */ tlv_offset = offset + get_tlv_value_offset(&tlv_info); switch (tlv_type) { case HMAC_TUPLE: /* Table 348d */ /* decode and display the HMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, tlv_offset, tlv_len, "HMAC Tuple (%u byte(s))", tlv_len); wimax_hmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len); hmac_found = TRUE; break; case CMAC_TUPLE: /* Table 348b */ /* decode and display the CMAC Tuple */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, tlv_offset, tlv_len, "CMAC Tuple (%u byte(s))", tlv_len); wimax_cmac_tuple_decoder(tlv_tree, tvb, tlv_offset, tlv_len); break; default: /* Decode DREG-CMD sub-TLV's */ tlv_tree = add_protocol_subtree(&tlv_info, ett_mac_mgmt_msg_dreg_decoder, dreg_cmd_tree, proto_mac_mgmt_msg_dreg_cmd_decoder, tvb, tlv_offset, tlv_len, "DREG-CMD sub-TLV's (%u byte(s))", tlv_len); dissect_dreg_tlv(tlv_tree, tlv_type, tvb, tlv_offset, tlv_len); break; } offset = tlv_len + tlv_offset; } /* end of TLV process while loop */ if (!hmac_found) proto_item_append_text(dreg_cmd_tree, " (HMAC Tuple is missing !)"); } }
static void dissect_ancp_adj_msg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ancp_tree, gint offset, struct ancp_tap_t *ancp_info ) { proto_item *sti = NULL; proto_tree *ancp_cap_tree = NULL; guint8 byte, numcaps, adjcode; guint16 tlv_len; sti = proto_tree_add_item(ancp_tree, hf_ancp_timer, tvb, offset, 1, FALSE); offset += 1; proto_item_append_text(sti, " msec"); sti = proto_tree_add_item(ancp_tree, hf_ancp_adj_code, tvb, offset, 1, FALSE); byte = tvb_get_guint8(tvb, offset); offset += 1; adjcode = byte & ADJ_CODE_MASK; ancp_info->ancp_adjcode = adjcode; /* stats */ proto_item_append_text(sti, " (%s, M Flag %s)", val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)"), byte >> 7 ? "Set" : "Unset"); col_append_fstr(pinfo->cinfo, COL_INFO, " (%s)", val_to_str(adjcode, adj_code_names, "Unknown (0x%02x)")); proto_tree_add_item(ancp_tree, hf_ancp_sender_name, tvb, offset, 6, FALSE); offset += 6; proto_tree_add_item(ancp_tree, hf_ancp_receiver_name, tvb,offset, 6, FALSE); offset += 6; proto_tree_add_item(ancp_tree, hf_ancp_sender_port, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ancp_tree, hf_ancp_receiver_port, tvb,offset, 4, FALSE); offset += 4; sti = proto_tree_add_item(ancp_tree, hf_ancp_p_info, tvb, offset, 1, FALSE); byte = tvb_get_guint8(tvb, offset); offset += 1; proto_item_append_text(sti, " (Type = %d, Flag = %d)", byte >> 4, byte & 0x0F); proto_tree_add_item(ancp_tree, hf_ancp_sender_instance, tvb, offset, 3, FALSE); offset += 3; proto_tree_add_item(ancp_tree, hf_ancp_p_id, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(ancp_tree, hf_ancp_receiver_instance, tvb, offset, 3, FALSE); offset += 3; proto_tree_add_item(ancp_tree, hf_ancp_tech_type, tvb, offset, 1, FALSE); offset += 1; sti = proto_tree_add_item(ancp_tree, hf_ancp_num_tlvs, tvb, offset, 1, FALSE); numcaps = tvb_get_guint8(tvb, offset); offset += 1; /* Start the capability subtree */ ancp_cap_tree = proto_item_add_subtree(sti, ett_ancp_tot_len); proto_tree_add_item(ancp_cap_tree, hf_ancp_tot_len, tvb, offset, 2, FALSE); tlv_len = tvb_get_ntohs(tvb, offset); offset += 2; for ( ;numcaps; numcaps--) { sti = proto_tree_add_item(ancp_cap_tree, hf_ancp_cap, tvb, offset, 2, FALSE); offset += 2; tlv_len = tvb_get_ntohs(tvb, offset); offset += 2; proto_item_append_text(sti, " (%d bytes)", tlv_len); /* TODO - if there are non boolean caps, validate before use */ } }
static int usbip_dissect_urb(packet_info *pinfo, tvbuff_t *tvb, proto_tree *tree, proto_tree *orig, int offset, usbip_conv_info_t *usbip_info) { proto_item *ti = NULL; usbip_transaction_t *usbip_trans; guint32 command; guint32 devid; guint32 seqnum; guint32 dir; guint32 ep; struct usbip_header header; proto_tree_add_item_ret_uint(tree, hf_usbip_command, tvb, offset, 4, ENC_BIG_ENDIAN, &command); offset += 4; proto_tree_add_item_ret_uint(tree, hf_usbip_seqnum, tvb, offset, 4, ENC_BIG_ENDIAN, &seqnum); offset += 4; dir = tvb_get_ntohl(tvb, offset + 4); ep = tvb_get_ntohl(tvb, offset + 8); devid = tvb_get_ntohl(tvb, offset); if (!PINFO_FD_VISITED(pinfo)) { if (command == OP_CMD_SUBMIT || command == OP_CMD_UNLINK) { usbip_trans = wmem_new(wmem_file_scope(), usbip_transaction_t); usbip_trans->devid = devid; usbip_trans->dir = dir; usbip_trans->ep = ep; usbip_trans->seqnum = seqnum; usbip_trans->cmd_frame = pinfo->num; usbip_trans->ret_frame = 0; usbip_trans->unlink_seqnum = 0; wmem_tree_insert32(usbip_info->pdus, seqnum, (void *) usbip_trans); } else { usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum); if (usbip_trans) usbip_trans->ret_frame = pinfo->num; } } else { usbip_trans = (usbip_transaction_t *) wmem_tree_lookup32(usbip_info->pdus, seqnum); } if (!usbip_trans) { usbip_trans = wmem_new(wmem_packet_scope(), usbip_transaction_t); usbip_trans->cmd_frame = 0; usbip_trans->ret_frame = 0; usbip_trans->devid = 0; usbip_trans->unlink_seqnum = 0; usbip_trans->seqnum = seqnum; } /* only the OP_CMD_SUBMIT has a valid devid - in all other case we have to restore it from the transaction */ if (command == OP_RET_SUBMIT || command == OP_RET_UNLINK) { devid = usbip_trans->devid; ep = usbip_trans->ep; dir = usbip_trans->dir; } ti = proto_tree_add_uint(tree, hf_usbip_cmd_frame, NULL, 0, 0, usbip_trans->cmd_frame); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_ret_frame, NULL, 0, 0, usbip_trans->ret_frame); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_devid, NULL, 0, 0, devid); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_direction, NULL, 0, 0, dir); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_uint(tree, hf_usbip_ep, NULL, 0, 0, ep); PROTO_ITEM_SET_GENERATED(ti); proto_tree_add_item(tree, hf_usbip_devid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_usbip_direction, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_usbip_ep, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; header.ep = ep; header.dir = dir; header.devid = devid & 0x00ff; header.busid = devid >> 16; switch (command) { case OP_CMD_SUBMIT: offset = dissect_cmd_submit(pinfo, tree, tvb, offset); dissect_usb_common(tvb, pinfo, orig, USB_HEADER_USBIP, &header); break; case OP_CMD_UNLINK: offset = dissect_cmd_unlink(pinfo, tree, tvb, offset, usbip_info, usbip_trans); break; case OP_RET_SUBMIT: { guint32 status; status = tvb_get_ntohl(tvb, offset); offset = dissect_ret_submit(pinfo, tree, tvb, offset); if (status == 0) dissect_usb_common(tvb, pinfo, orig, USB_HEADER_USBIP, &header); break; } case OP_RET_UNLINK: offset = dissect_ret_unlink(pinfo, tree, tvb, offset, usbip_info, usbip_trans->unlink_seqnum); break; default: proto_tree_add_item(tree, hf_usbip_urb_data, tvb, offset, -1, ENC_NA); offset = tvb_reported_length_remaining(tvb, offset); expert_add_info_format( pinfo, ti, &ei_usbip, "Dissector for USBIP Command" " (%x) code not implemented, Contact" " Wireshark developers if you want this supported", command); proto_item_append_text(ti, ": Undecoded"); break; } return offset; }
/*FUNCTION:------------------------------------------------------ * NAME * dissect_zep * DESCRIPTION * IEEE 802.15.4 packet dissection routine for Wireshark. * PARAMETERS * tvbuff_t *tvb - pointer to buffer containing raw packet. * packet_info *pinfo - pointer to packet information fields * proto_tree *tree - pointer to data tree Wireshark uses to display packet. * RETURNS * void *--------------------------------------------------------------- */ static void dissect_zep(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *proto_root, *pi; proto_tree *zep_tree; guint8 ieee_packet_len; guint8 zep_header_len; zep_info zep_data; dissector_handle_t next_dissector; /* Determine whether this is a Q51/IEEE 802.15.4 sniffer packet or not */ if(strcmp(tvb_get_string(wmem_packet_scope(), tvb, 0, 2), ZEP_PREAMBLE)){ /* This is not a Q51/ZigBee sniffer packet */ call_dissector(data_handle, tvb, pinfo, tree); return; } memset(&zep_data, 0, sizeof(zep_data)); /* Zero all zep_data fields. */ /* Extract the protocol version from the ZEP header. */ zep_data.version = tvb_get_guint8(tvb, 2); if (zep_data.version == 1) { /* Type indicates a ZEP_v1 packet. */ zep_header_len = ZEP_V1_HEADER_LEN; zep_data.type = 0; zep_data.channel_id = tvb_get_guint8(tvb, 3); zep_data.device_id = tvb_get_ntohs(tvb, 4); zep_data.lqi_mode = tvb_get_guint8(tvb, 6)?1:0; zep_data.lqi = tvb_get_guint8(tvb, 7); ieee_packet_len = (tvb_get_guint8(tvb, ZEP_V1_HEADER_LEN - 1) & ZEP_LENGTH_MASK); } else { /* At the time of writing, v2 is the latest version of ZEP, assuming * anything higher than v2 has identical format. */ zep_data.type = tvb_get_guint8(tvb, 3); if (zep_data.type == ZEP_V2_TYPE_ACK) { /* ZEP Ack has only the seqno. */ zep_header_len = ZEP_V2_ACK_LEN; zep_data.seqno = tvb_get_ntohl(tvb, 4); ieee_packet_len = 0; } else { /* Although, only type 1 corresponds to data, if another value is present, assume it is dissected the same. */ zep_header_len = ZEP_V2_HEADER_LEN; zep_data.channel_id = tvb_get_guint8(tvb, 4); zep_data.device_id = tvb_get_ntohs(tvb, 5); zep_data.lqi_mode = tvb_get_guint8(tvb, 7)?1:0; zep_data.lqi = tvb_get_guint8(tvb, 8); ntp_to_nstime(tvb, 9, &(zep_data.ntp_time)); zep_data.seqno = tvb_get_ntohl(tvb, 17); ieee_packet_len = (tvb_get_guint8(tvb, ZEP_V2_HEADER_LEN - 1) & ZEP_LENGTH_MASK); } } #if 0 /*??dat*/ if (zep_data.ntp_time.secs && zep_data.ntp_time.nsecs) { pinfo->fd->abs_ts = zep_data.ntp_time; } #endif if(ieee_packet_len < tvb_length(tvb)-zep_header_len){ /* Packet's length is mis-reported, abort dissection */ call_dissector(data_handle, tvb, pinfo, tree); return; } /* Enter name info protocol field */ col_set_str(pinfo->cinfo, COL_PROTOCOL, (zep_data.version==1)?"ZEP":"ZEPv2"); /* Enter name info protocol field */ if (!((zep_data.version>=2) && (zep_data.type==ZEP_V2_TYPE_ACK))) col_add_fstr(pinfo->cinfo, COL_INFO, "Encapsulated ZigBee Packet [Channel]=%i [Length]=%i", zep_data.channel_id, ieee_packet_len); else col_add_fstr(pinfo->cinfo, COL_INFO, "Ack, Sequence Number: %i", zep_data.seqno); if(tree){ /* Create subtree for the ZEP Header */ if (!((zep_data.version>=2) && (zep_data.type==ZEP_V2_TYPE_ACK))) { proto_root = proto_tree_add_protocol_format(tree, proto_zep, tvb, 0, zep_header_len, "ZigBee Encapsulation Protocol, Channel: %i, Length: %i", zep_data.channel_id, ieee_packet_len); } else { proto_root = proto_tree_add_protocol_format(tree, proto_zep, tvb, 0, zep_header_len, "ZigBee Encapsulation Protocol, Ack"); } zep_tree = proto_item_add_subtree(proto_root, ett_zep); /* Display the information in the subtree */ proto_tree_add_text(zep_tree, tvb, 0, 2, "Protocol ID String: EX"); if (zep_data.version==1) { proto_tree_add_uint(zep_tree, hf_zep_version, tvb, 2, 1, zep_data.version); proto_tree_add_uint(zep_tree, hf_zep_channel_id, tvb, 3, 1, zep_data.channel_id); proto_tree_add_uint(zep_tree, hf_zep_device_id, tvb, 4, 2, zep_data.device_id); proto_tree_add_boolean_format(zep_tree, hf_zep_lqi_mode, tvb, 6, 1, zep_data.lqi_mode, "LQI/CRC Mode: %s", zep_data.lqi_mode?"CRC":"LQI"); if(!(zep_data.lqi_mode)){ proto_tree_add_uint(zep_tree, hf_zep_lqi, tvb, 7, 1, zep_data.lqi); } proto_tree_add_text(zep_tree, tvb, 7+((zep_data.lqi_mode)?0:1), 7+((zep_data.lqi_mode)?1:0), "Reserved Fields"); } else { proto_tree_add_uint(zep_tree, hf_zep_version, tvb, 2, 1, zep_data.version); if (zep_data.type == ZEP_V2_TYPE_ACK) { proto_tree_add_uint_format_value(zep_tree, hf_zep_type, tvb, 3, 1, zep_data.type, "%i (Ack)", ZEP_V2_TYPE_ACK); proto_tree_add_uint(zep_tree, hf_zep_seqno, tvb, 4, 4, zep_data.seqno); } else { proto_tree_add_uint_format_value(zep_tree, hf_zep_type, tvb, 3, 1, zep_data.type, "%i (%s)", zep_data.type, (zep_data.type==ZEP_V2_TYPE_DATA)?"Data":"Reserved"); proto_tree_add_uint(zep_tree, hf_zep_channel_id, tvb, 4, 1, zep_data.channel_id); proto_tree_add_uint(zep_tree, hf_zep_device_id, tvb, 5, 2, zep_data.device_id); proto_tree_add_boolean_format(zep_tree, hf_zep_lqi_mode, tvb, 7, 1, zep_data.lqi_mode, "LQI/CRC Mode: %s", zep_data.lqi_mode?"CRC":"LQI"); if(!(zep_data.lqi_mode)){ proto_tree_add_uint(zep_tree, hf_zep_lqi, tvb, 8, 1, zep_data.lqi); } pi = proto_tree_add_time(zep_tree, hf_zep_timestamp, tvb, 9, 8, &(zep_data.ntp_time)); proto_item_append_text(pi, " (%ld.%09ds)", (long)zep_data.ntp_time.secs, zep_data.ntp_time.nsecs); proto_tree_add_uint(zep_tree, hf_zep_seqno, tvb, 17, 4, zep_data.seqno); } } if (!((zep_data.version==2) && (zep_data.type==ZEP_V2_TYPE_ACK))) proto_tree_add_uint_format_value(zep_tree, hf_zep_ieee_length, tvb, zep_header_len - 1, 1, ieee_packet_len, "%i %s", ieee_packet_len, (ieee_packet_len==1)?"Byte":"Bytes"); } /* Determine which dissector to call next. */ if (zep_data.lqi_mode) { /* CRC present, use standard IEEE dissector. */ next_dissector = ieee802154_handle; } else { /* ChipCon compliant FCS present. */ next_dissector = ieee802154_ccfcs_handle; } if (!next_dissector) { /* IEEE 802.15.4 dissectors couldn't be found. */ next_dissector = data_handle; } /* Call the IEEE 802.15.4 dissector */ if (!((zep_data.version>=2) && (zep_data.type==ZEP_V2_TYPE_ACK))) { next_tvb = tvb_new_subset(tvb, zep_header_len, ieee_packet_len, ieee_packet_len); call_dissector(next_dissector, next_tvb, pinfo, tree); } } /* dissect_ieee802_15_4 */
/** Dissector for SoupBinTCP messages */ static void dissect_soupbintcp_common( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { struct conv_data *conv_data; struct pdu_data *pdu_data; tvbuff_t *sub_tvb = NULL; const char *pkt_name; const char *tmp_buf; proto_item *ti; proto_tree *soupbintcp_tree = NULL; conversation_t *conv = NULL; guint16 expected_len; guint8 pkt_type; gint offset = 0; guint this_seq = 0, next_seq; /* Get the 16-bit big-endian SOUP packet length */ expected_len = tvb_get_ntohs(tvb, 0); /* Get the 1-byte SOUP message type */ pkt_type = tvb_get_guint8(tvb, 2); /* Since we use the packet name a few times, get and save that value */ pkt_name = val_to_str(pkt_type, pkt_type_val, "Unknown (%u)"); /* Set the protocol name in the summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "SoupBinTCP"); /* Set the packet name in the info column */ col_clear(pinfo->cinfo, COL_INFO); col_add_str(pinfo->cinfo, COL_INFO, pkt_name); /* Sequence number tracking * * SOUP does not number packets from client to server (the server * acknowledges all important messages, so the client should use * the acks to figure out if the server received the message, and * otherwise resend it). * * Packets from server to client are numbered, but it's implicit. * The Login Accept packet contains the next sequence number that * the server will send, and the client needs to count the * Sequenced Data packets that it receives to know what their * sequence numbers are. * * So, we grab the next sequence number from the Login Acceptance * packet, and save it in a conversation_t we associate with the * TCP session. Then, for each Sequenced Data packet we receive, * the first time it's processed (when PINFO_FD_VISITED() is * false), we write it into the PDU's frame's private data pointer * and increment the saved sequence number (in the conversation_t). * * If the visited flag is true, then we've dissected this packet * already, and so we can fetch the sequence number from the * frame's private data area. * * In either case, if there's any problem, we report zero as the * sequence number, and try to continue dissecting. */ /* If first dissection of Login Accept, save sequence number */ if (pkt_type == 'A' && !PINFO_FD_VISITED(pinfo)) { tmp_buf = tvb_get_ephemeral_string(tvb, 13, 20); next_seq = atoi(tmp_buf); /* Create new conversation for this session */ conv = conversation_new(PINFO_FD_NUM(pinfo), &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); /* Store starting sequence number for session's packets */ conv_data = (struct conv_data *)wmem_alloc(wmem_file_scope(), sizeof(struct conv_data)); conv_data->next_seq = next_seq; conversation_add_proto_data(conv, proto_soupbintcp, conv_data); } /* Handle sequence numbering for a Sequenced Data packet */ if (pkt_type == 'S') { if (!PINFO_FD_VISITED(pinfo)) { /* Get next expected sequence number from conversation */ conv = find_conversation(PINFO_FD_NUM(pinfo), &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (!conv) { this_seq = 0; } else { conv_data = (struct conv_data *)conversation_get_proto_data(conv, proto_soupbintcp); if (conv_data) { this_seq = conv_data->next_seq++; } else { this_seq = 0; } pdu_data = (struct pdu_data *)wmem_alloc( wmem_file_scope(), sizeof(struct pdu_data)); pdu_data->seq_num = this_seq; p_add_proto_data(pinfo->fd, proto_soupbintcp, 0, pdu_data); } } else { pdu_data = (struct pdu_data *)p_get_proto_data( pinfo->fd, proto_soupbintcp, 0); if (pdu_data) { this_seq = pdu_data->seq_num; } else { this_seq = 0; } } col_append_fstr(pinfo->cinfo, COL_INFO, ", SeqNum = %u", this_seq); } if (tree) { /* Create sub-tree for SoupBinTCP details */ ti = proto_tree_add_item(tree, proto_soupbintcp, tvb, 0, -1, FALSE); soupbintcp_tree = proto_item_add_subtree(ti, ett_soupbintcp); /* Append the packet name to the sub-tree item */ proto_item_append_text(ti, ", %s", pkt_name); /* Length */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_packet_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* Type */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_packet_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; switch (pkt_type) { case '+': /* Debug Message */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_text, tvb, offset, expected_len - 1, ENC_ASCII|ENC_NA); break; case 'A': /* Login Accept */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_session, tvb, offset, 10, ENC_ASCII|ENC_NA); offset += 10; tmp_buf = tvb_get_ephemeral_string(tvb, offset, 20); proto_tree_add_string_format_value(soupbintcp_tree, hf_soupbintcp_next_seq_num, tvb, offset, 20, "X", "%d", atoi(tmp_buf)); break; case 'J': /* Login Reject */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_reject_code, tvb, offset, 1, ENC_BIG_ENDIAN); break; case 'U': /* Unsequenced Data */ /* Display handled by sub-dissector */ break; case 'S': /* Sequenced Data */ proto_item_append_text(ti, ", SeqNum=%u", this_seq); proto_tree_add_string_format_value(soupbintcp_tree, hf_soupbintcp_seq_num, tvb, offset, 0, "X", "%u (Calculated)", this_seq); /* Display handled by sub-dissector */ break; case 'L': /* Login Request */ proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_username, tvb, offset, 6, ENC_ASCII|ENC_NA); offset += 6; proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_password, tvb, offset, 10, ENC_ASCII|ENC_NA); offset += 10; proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_session, tvb, offset, 10, ENC_ASCII|ENC_NA); offset += 10; tmp_buf = tvb_get_ephemeral_string(tvb, offset, 20); proto_tree_add_string_format_value(soupbintcp_tree, hf_soupbintcp_req_seq_num, tvb, offset, 20, "X", "%d", atoi(tmp_buf)); break; case 'H': /* Server Heartbeat */ break; case 'O': /* Logout Request */ break; case 'R': /* Client Heartbeat */ break; case 'Z': /* End of Session */ break; default: /* Unknown */ proto_tree_add_item(tree, hf_soupbintcp_message, tvb, offset, -1, ENC_ASCII|ENC_NA); break; } } /* Call sub-dissector for encapsulated data */ if (pkt_type == 'S' || pkt_type == 'U') { /* Sub-dissector tvb starts at 3 (length (2) + pkt_type (1)) */ sub_tvb = tvb_new_subset_remaining(tvb, 3); /* If this packet is part of a conversation, call dissector * for the conversation if available */ if (try_conversation_dissector(&pinfo->dst, &pinfo->src, pinfo->ptype, pinfo->srcport, pinfo->destport, sub_tvb, pinfo, tree)) { return; } /* Otherwise, try heuristic dissectors */ if (dissector_try_heuristic(heur_subdissector_list, sub_tvb, pinfo, tree, NULL)) { return; } /* Otherwise, give up, and just print the bytes in hex */ if (tree) { proto_tree_add_item(soupbintcp_tree, hf_soupbintcp_message, sub_tvb, 0, -1, ENC_ASCII|ENC_NA); } } }
static void dissect_status (packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *tvb, int offset, guint8 flags) { proto_item *item=NULL; proto_tree *tree=NULL; if(parent_tree){ item=proto_tree_add_uint(parent_tree, hf_sbccs_dib_status, tvb, offset, 1, flags); tree=proto_item_add_subtree(item, ett_sbccs_dib_status); } proto_tree_add_boolean(tree, hf_sbccs_dib_status_attention, tvb, offset, 1, flags); if (flags&0x80){ proto_item_append_text(item, " Attention"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Attention"); } } flags&=(~( 0x80 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_modifier, tvb, offset, 1, flags); if (flags&0x40){ proto_item_append_text(item, " Status Modifier"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Status Modifier"); } } flags&=(~( 0x40 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_cue, tvb, offset, 1, flags); if (flags&0x20){ proto_item_append_text(item, " Control-Unit End"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Control-Unit End"); } } flags&=(~( 0x20 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_busy, tvb, offset, 1, flags); if (flags&0x10){ proto_item_append_text(item, " Busy"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Busy"); } } flags&=(~( 0x10 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_channelend, tvb, offset, 1, flags); if (flags&0x08){ proto_item_append_text(item, " Channel End"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Channel End"); } } flags&=(~( 0x08 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_deviceend, tvb, offset, 1, flags); if (flags&0x04){ proto_item_append_text(item, " Device End"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Device End"); } } flags&=(~( 0x04 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_check, tvb, offset, 1, flags); if (flags&0x02){ proto_item_append_text(item, " Unit Check"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Unit Check"); } } flags&=(~( 0x02 )); proto_tree_add_boolean(tree, hf_sbccs_dib_status_unit_exception, tvb, offset, 1, flags); if (flags&0x01){ proto_item_append_text(item, " Unit Exception"); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_str(pinfo->cinfo, COL_INFO, " Unit Exception"); } } flags&=(~( 0x01 )); }
static gint dissect_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset, gboolean is_client_message) { /* flow: reqests: only client -> server; responses: only server -> */ proto_item *pitem; guint16 control_pdu_id; guint credits; guint timeout; guint context_id; guint notification_register; guint number; gint parameter_length; pitem = proto_tree_add_item(tree, hf_bthcrp_control_pdu_id, tvb, offset, 2, ENC_BIG_ENDIAN); control_pdu_id = tvb_get_ntohs(tvb, offset); offset += 2; col_append_fstr(pinfo->cinfo, COL_INFO, "Control: %s %s", ((is_client_message) ? "Request" : "Response"), val_to_str(control_pdu_id, control_pdu_id_vals, "Unknown PDU ID")); if (control_pdu_id >= 0x8000) { proto_item_append_text(pitem, " (Vendor Specific)"); col_append_str(pinfo->cinfo, COL_INFO, " (Vendor Specific)"); } else if (control_pdu_id == 0x0000 || control_pdu_id >= 0x000B ) { proto_item_append_text(pitem, " (Reserved)"); col_append_str(pinfo->cinfo, COL_INFO, " (Reserved)"); } proto_tree_add_item(tree, hf_bthcrp_control_transaction_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; pitem = proto_tree_add_item(tree, hf_bthcrp_control_parameter_length, tvb, offset, 2, ENC_BIG_ENDIAN); parameter_length = tvb_get_ntohs(tvb, offset); offset += 2; if (!is_client_message && parameter_length < 2) { expert_add_info_format(pinfo, pitem, &ei_bthcrp_control_parameter_length, "Parameter length is shorter than 2 in response"); } if (parameter_length < tvb_reported_length_remaining(tvb, offset)) { expert_add_info_format(pinfo, pitem, &ei_bthcrp_control_parameter_length, "Parameter length is shorter than payload length"); } else if (parameter_length > tvb_reported_length_remaining(tvb, offset)) { expert_add_info_format(pinfo, pitem, &ei_bthcrp_control_parameter_length, "Parameter length is larger than payload length"); } if (!is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_status, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } if (control_pdu_id >= 0x8000) { if (tvb_reported_length_remaining(tvb, offset)) { proto_tree_add_item(tree, hf_bthcrp_data, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_NA); offset += tvb_reported_length_remaining(tvb, offset); } } else switch(control_pdu_id) { case 0x0001: /* CR_DataChannelCreditGrant */ if (is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_client_credit_granted, tvb, offset, 4, ENC_BIG_ENDIAN); credits = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - CreditGranted: %u", credits); offset += 4; } break; case 0x0002: /* CR_DataChannelCreditRequest */ if (!is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_server_credit_granted, tvb, offset, 4, ENC_BIG_ENDIAN); credits = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - CreditGranted: %u", credits); offset += 4; } break; case 0x0003: /* CR_DataChannelCreditReturn */ if (is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_client_credit_return, tvb, offset, 4, ENC_BIG_ENDIAN); credits = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Client Credit Return: %u", credits); offset += 4; } else { proto_tree_add_item(tree, hf_bthcrp_control_server_credit_return, tvb, offset, 4, ENC_BIG_ENDIAN); credits = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Server Credit Return: %u", credits); offset += 4; } break; case 0x0004: /* CR_DataChannelCreditQuery */ if (is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_client_credit_query, tvb, offset, 4, ENC_BIG_ENDIAN); credits = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Client Credit: %u", credits); offset += 4; } else { proto_tree_add_item(tree, hf_bthcrp_control_server_credit_query, tvb, offset, 4, ENC_BIG_ENDIAN); credits = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Server Credit: %u", credits); offset += 4; } break; case 0x0005: /* CR_GetLPTStatus */ if (!is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_status_reserved_76, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_bthcrp_control_status_paper_empty, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_bthcrp_control_status_select, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_bthcrp_control_status_not_error, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_bthcrp_control_status_reserved_20, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } break; case 0x0006: /* CR_Get1284ID */ if (is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_start_byte, tvb, offset, 2, ENC_BIG_ENDIAN); number = tvb_get_ntohs(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Start Byte: %u", number); offset += 2; proto_tree_add_item(tree, hf_bthcrp_control_number_of_bytes, tvb, offset, 2, ENC_BIG_ENDIAN); number = tvb_get_ntohs(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Number Of Bytes: %u", number); offset += 2; } else { guint8 *id; proto_tree_add_item(tree, hf_bthcrp_control_1284_id, tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_ASCII | ENC_NA); id = tvb_get_string_enc(wmem_packet_scope(), tvb, offset, tvb_reported_length_remaining(tvb, offset), ENC_ASCII); col_append_fstr(pinfo->cinfo, COL_INFO, " - 1284 ID: %s", id); offset += tvb_reported_length_remaining(tvb, offset); } break; case 0x0007: /* CR_SoftReset */ case 0x0008: /* CR_HardReset */ break; case 0x0009: /* CR_RegisterNotification */ if (is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_register, tvb, offset, 1, ENC_BIG_ENDIAN); notification_register = tvb_get_guint8(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Register: %s", val_to_str(notification_register, register_vals, "unknown register")); offset += 1; proto_tree_add_item(tree, hf_bthcrp_callback_context_id, tvb, offset, 4, ENC_BIG_ENDIAN); context_id = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Callback ContextID: %u", context_id); offset += 4; proto_tree_add_item(tree, hf_bthcrp_control_callback_timeout, tvb, offset, 4, ENC_BIG_ENDIAN); timeout = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Callback Timeout: %u", timeout); offset += 4; } else { proto_tree_add_item(tree, hf_bthcrp_control_timeout, tvb, offset, 4, ENC_BIG_ENDIAN); timeout = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Timeout: %u", timeout); offset += 4; proto_tree_add_item(tree, hf_bthcrp_control_callback_timeout, tvb, offset, 4, ENC_BIG_ENDIAN); timeout = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, ", Callback Timeout: %u", timeout); offset += 4; } break; case 0x000A: /* CR_NotificationConnectionAlive */ if (!is_client_message) { proto_tree_add_item(tree, hf_bthcrp_control_timeout, tvb, offset, 4, ENC_BIG_ENDIAN); timeout = tvb_get_ntohl(tvb, offset); col_append_fstr(pinfo->cinfo, COL_INFO, " - Timeout: %u", timeout); offset += 4; } break; } return offset; }
static void dissect_wfd_subelem_session_info(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset, guint16 len) { int end = offset + len, next; proto_item *item; proto_tree *descr; while (offset < end) { guint8 dlen = tvb_get_guint8(tvb, offset); next = offset + 1 + dlen; item = proto_tree_add_text(tree, tvb, offset, 1 + dlen, "WFD Device Info Descriptor"); descr = proto_item_add_subtree(item, ett_wfd_dev_info_descr); if (offset + 1 + dlen > end || dlen < 23) { expert_add_info(pinfo, item, &ei_wfd_subelem_session_descr_invalid); break; } proto_tree_add_item(descr, hf_wfd_subelem_session_descr_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(descr, hf_wfd_subelem_session_dev_addr, tvb, offset, 6, ENC_NA); proto_item_append_text(descr, ": %s", tvb_ether_to_str(tvb, offset)); offset += 6; proto_tree_add_item(descr, hf_wfd_subelem_session_assoc_bssid, tvb, offset, 6, ENC_NA); offset += 6; proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_type, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_coupled_sink_source, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_coupled_sink_sink, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_available, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_wsd, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_pc, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_content_protection, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_time_sync, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_wfd_subelem_session_dev_info_audio_unsupp_pri_sink, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_wfd_subelem_session_dev_info_audio_only_supp_source, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_wfd_subelem_session_dev_info_tdls_persistent_group, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_wfd_subelem_session_dev_info_tdls_persistent_group_reinvoke, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_wfd_subelem_session_dev_info_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(descr, hf_wfd_subelem_session_dev_info_max_throughput, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(descr, hf_wfd_subelem_session_coupled_sink_status_bitmap, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(descr, hf_wfd_subelem_session_coupled_sink_reserved, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_item(descr, hf_wfd_subelem_session_coupled_sink_addr, tvb, offset, 6, ENC_NA); offset += 6; if (offset < next) { proto_tree_add_text(descr, tvb, offset, next - offset, "Extra info in the end of descriptor"); } offset = next; } }
static void dissect_vmlab(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree* volatile vmlab_tree; proto_item* ti; guint32 offset=0; const guint8* src_addr; const guint8* dst_addr; const guint8* eth_addr; guint8 attributes; guint8 portgroup; volatile guint16 encap_proto; col_set_str(pinfo->cinfo, COL_PROTOCOL, "VMLAB"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_vmlab, tvb, 0, 24, FALSE); vmlab_tree = proto_item_add_subtree(ti, ett_vmlab); /* Flags*/ attributes = tvb_get_guint8(tvb, offset); proto_tree_add_item(vmlab_tree, hf_vmlab_flags_part1, tvb, offset, 1, FALSE); proto_tree_add_item(vmlab_tree, hf_vmlab_flags_fragment, tvb, offset, 1, FALSE); proto_tree_add_item(vmlab_tree, hf_vmlab_flags_part2, tvb, offset, 1, FALSE); if (attributes & 0x04) { proto_item_append_text(ti, ", Fragment"); } offset += 1; /* Portgroup*/ portgroup = tvb_get_guint8(tvb, offset); proto_tree_add_uint(vmlab_tree, hf_vmlab_portgroup, tvb, offset, 1, portgroup); proto_item_append_text(ti, ", Portgroup: %d", portgroup); offset += 1; /* The next two bytes were always 0x0000 as far as I could tell*/ offset += 2; /* Not really clear, what the difference between this and the next MAC address is Both are usually equal*/ eth_addr=tvb_get_ptr(tvb, offset, 6); proto_tree_add_item(vmlab_tree, hf_vmlab_eth_addr, tvb, offset, 6, ENC_NA); offset += 6; dst_addr=tvb_get_ptr(tvb, offset, 6); proto_tree_add_item(vmlab_tree, hf_vmlab_eth_dst, tvb, offset, 6, ENC_NA); offset += 6; /* Source MAC*/ src_addr=tvb_get_ptr(tvb, offset, 6); proto_tree_add_item(vmlab_tree, hf_vmlab_eth_src, tvb, offset, 6, ENC_NA); offset += 6; proto_item_append_text(ti, ", Src: %s (%s), Dst: %s (%s)", get_ether_name(src_addr), ether_to_str(src_addr), get_ether_name(dst_addr), ether_to_str(dst_addr)); /* Encapsulated Ethertype is also part of the block*/ encap_proto = tvb_get_ntohs(tvb, offset); offset += 2; /* Now call whatever was encapsulated*/ ethertype(encap_proto, tvb, offset, pinfo, tree, vmlab_tree, hf_vmlab_etype, hf_vmlab_trailer, 0); }
static int dissect_xtp_traffic_cntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset) { guint32 len = tvb_length_remaining(tvb, offset); guint32 start = offset; proto_item *top_ti; proto_tree *xtp_subtree; struct xtp_traffic_cntl tcntl[1]; top_ti = proto_tree_add_text(tree, tvb, offset, len, "Traffic Control Segment"); xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_tcntl); if (len < XTP_TRAFFIC_CNTL_LEN) { proto_item_append_text(top_ti, ", bogus length(%u, must be at least %u)", len, XTP_TRAFFIC_CNTL_LEN); return 0; } /** parse **/ /* rseq(8) */ tcntl->rseq = tvb_get_ntohl(tvb, offset); tcntl->rseq <<= 32; tcntl->rseq += tvb_get_ntohl(tvb, offset+4); offset += 8; /* alloc(8) */ tcntl->alloc = tvb_get_ntohl(tvb, offset); tcntl->alloc <<= 32; tcntl->alloc += tvb_get_ntohl(tvb, offset+4); offset += 8; /* echo(4) */ tcntl->echo = tvb_get_ntohl(tvb, offset); offset += 4; /* rsvd(4) */ tcntl->rsvd = tvb_get_ntohl(tvb, offset); offset += 4; /* xkey(8) */ tcntl->xkey = tvb_get_ntohl(tvb, offset); tcntl->xkey <<= 32; tcntl->xkey += tvb_get_ntohl(tvb, offset+4); /** add summary **/ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " Recv-Seq=%" G_GINT64_MODIFIER "u", tcntl->rseq); col_append_fstr(pinfo->cinfo, COL_INFO, " Alloc=%" G_GINT64_MODIFIER "u", tcntl->alloc); } proto_item_append_text(top_ti, ", Recv-Seq: %" G_GINT64_MODIFIER "u", tcntl->rseq); /** display **/ offset = start; /* rseq(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_rseq, tvb, offset, 8, tcntl->rseq); offset += 8; /* alloc(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_alloc, tvb, offset, 8, tcntl->alloc); offset += 4; /* echo(4) */ proto_tree_add_uint(xtp_subtree, hf_xtp_tcntl_echo, tvb, offset, 4, tcntl->echo); offset += 4; /* rsvd(4) */ proto_tree_add_uint(xtp_subtree, hf_xtp_tcntl_rsvd, tvb, offset, 4, tcntl->rsvd); offset += 4; /* xkey(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_tcntl_xkey, tvb, offset, 8, tcntl->xkey); offset += 8; return (offset - start); }
static void dissect_starteam(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gint offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "StarTeam"); if(check_col(pinfo->cinfo, COL_INFO)){ /* This is a trick to know whether this is the first PDU in this packet or not */ if(iPreviousFrameNumber != (gint) pinfo->fd->num){ col_clear(pinfo->cinfo, COL_INFO); } else { col_append_str(pinfo->cinfo, COL_INFO, " | "); } } iPreviousFrameNumber = pinfo->fd->num; if(tvb_length(tvb) >= 16){ guint32 iCommand = 0; gboolean bRequest = FALSE; if(tvb_get_ntohl(tvb, offset + 0) == STARTEAM_MAGIC){ /* This packet is a response */ bRequest = FALSE; if(check_col(pinfo->cinfo, COL_INFO)){ col_append_fstr(pinfo->cinfo, COL_INFO, "Reply: %d bytes", tvb_length(tvb)); } } else if(tvb_length_remaining(tvb, offset) >= 28 && tvb_get_ntohl(tvb, offset + 20) == STARTEAM_MAGIC){ /* This packet is a request */ bRequest = TRUE; if(tvb_length_remaining(tvb, offset) >= 66){ iCommand = tvb_get_letohl(tvb, offset + 62); } if(check_col(pinfo->cinfo, COL_INFO)){ col_append_str(pinfo->cinfo, COL_INFO, val_to_str_ext(iCommand, &starteam_opcode_vals_ext, "Unknown (0x%02x)")); } } if(tree){ proto_tree *starteam_tree; proto_tree *starteamroot_tree; proto_item *ti; ti = proto_tree_add_item(tree, proto_starteam, tvb, offset, -1, ENC_NA); if (bRequest) proto_item_append_text(ti, " (%s)", val_to_str_ext(iCommand, &starteam_opcode_vals_ext, "Unknown (0x%02x)")); starteamroot_tree = proto_item_add_subtree(ti, ett_starteam); if(bRequest){ if(tvb_length_remaining(tvb, offset) >= 20){ ti = proto_tree_add_text(starteamroot_tree, tvb, offset, 20, STARTEAM_TEXT_MDH); starteam_tree = proto_item_add_subtree(ti, ett_starteam_mdh); proto_tree_add_item(starteam_tree, hf_starteam_mdh_session_tag, tvb, offset + 0, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_mdh_ctimestamp, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_mdh_flags, tvb, offset + 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_mdh_keyid, tvb, offset + 12, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_mdh_reserved, tvb, offset + 16, 4, ENC_LITTLE_ENDIAN); offset += 20; } } if(tvb_length_remaining(tvb, offset) >= 16){ ti = proto_tree_add_text(starteamroot_tree, tvb, offset, 16, STARTEAM_TEXT_PH); starteam_tree = proto_item_add_subtree(ti, ett_starteam_ph); proto_tree_add_item(starteam_tree, hf_starteam_ph_signature, tvb, offset + 0, 4, ENC_ASCII|ENC_NA); proto_tree_add_item(starteam_tree, hf_starteam_ph_packet_size, tvb, offset + 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_ph_data_size, tvb, offset + 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_ph_data_flags, tvb, offset + 12, 4, ENC_LITTLE_ENDIAN); offset += 16; if(bRequest){ if(tvb_length_remaining(tvb, offset) >= 38){ ti = proto_tree_add_text(starteamroot_tree, tvb, offset, 38, STARTEAM_TEXT_ID); starteam_tree = proto_item_add_subtree(ti, ett_starteam_id); proto_tree_add_item(starteam_tree, hf_starteam_id_revision_level, tvb, offset + 0, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_id_client, tvb, offset + 2, 16, ENC_ASCII|ENC_NA); proto_tree_add_item(starteam_tree, hf_starteam_id_connect, tvb, offset + 18, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_id_component, tvb, offset + 22, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_id_command, tvb, offset + 26, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_id_command_time, tvb, offset + 30, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(starteam_tree, hf_starteam_id_command_userid, tvb, offset + 34, 4, ENC_LITTLE_ENDIAN); offset += 38; } } if(tvb_length_remaining(tvb, offset) > 0){ ti = proto_tree_add_text(starteamroot_tree, tvb, offset, -1, STARTEAM_TEXT_DATA); starteam_tree = proto_item_add_subtree(ti, ett_starteam_data); proto_tree_add_item(starteam_tree, hf_starteam_data_data, tvb, offset, tvb_length_remaining(tvb, offset), ENC_ASCII|ENC_NA); } } } } }
static void dissect_xtp_ecntl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 offset) { guint32 len = tvb_length_remaining(tvb, offset); guint32 start = offset; proto_item *top_ti; proto_tree *xtp_subtree; struct xtp_ecntl ecntl[1]; guint64 *spans, *p; guint32 spans_len; guint i; top_ti = proto_tree_add_text(tree, tvb, offset, len, "Error Control Segment"); xtp_subtree = proto_item_add_subtree(top_ti, ett_xtp_ecntl); if (len < MIN_XTP_ECNTL_PKT_LEN) { proto_item_append_text(top_ti, ", bogus length (%u, must be at least %u)", len, MIN_XTP_ECNTL_PKT_LEN); return; } /** parse **/ /* rseq(8) */ ecntl->rseq = tvb_get_ntohl(tvb, offset); ecntl->rseq <<= 32; ecntl->rseq += tvb_get_ntohl(tvb, offset+4); offset += 8; /* alloc(8) */ ecntl->alloc = tvb_get_ntohl(tvb, offset); ecntl->alloc <<= 32; ecntl->alloc += tvb_get_ntohl(tvb, offset+4); offset += 8; /* echo(4) */ ecntl->echo = tvb_get_ntohl(tvb, offset); offset += 4; /* nspan(4) */ ecntl->nspan = tvb_get_ntohl(tvb, offset); offset += 4; len = len + XTP_HEADER_LEN - offset; spans_len = 16 * ecntl->nspan; if (len != spans_len) { proto_item_append_text(top_ti, ", bogus spans field length (%u, must be %u)", len, spans_len); return; } /* spans(16n) */ spans = ep_alloc0(spans_len); p = spans; for (i = 0; i < ecntl->nspan*2; i++) { guint64 span = tvb_get_ntohl(tvb, offset); span <<= 32; span += tvb_get_ntohl(tvb, offset+4); *p++ = span; offset += 8; } /** add summary **/ if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, " Recv-Seq=%" G_GINT64_MODIFIER "u", ecntl->rseq); col_append_fstr(pinfo->cinfo, COL_INFO, " Alloc=%" G_GINT64_MODIFIER "u", ecntl->alloc); } proto_item_append_text(top_ti, ", Recv-Seq: %" G_GINT64_MODIFIER "u", ecntl->rseq); /** display **/ offset = start; /* rseq(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_rseq, tvb, offset, 8, ecntl->rseq); offset += 8; /* alloc(8) */ proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_alloc, tvb, offset, 8, ecntl->alloc); offset += 8; /* echo(4) */ proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_echo, tvb, offset, 4, ecntl->echo); offset += 4; /* nspan(4) */ proto_tree_add_uint(xtp_subtree, hf_xtp_ecntl_nspan, tvb, offset, 4, ecntl->nspan); offset += 4; /* spans(16n) */ p = spans; for (i = 0; i < ecntl->nspan; i++) { proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_span_left, tvb, offset, 8, *p); p++; offset += 8; proto_tree_add_uint64(xtp_subtree, hf_xtp_ecntl_span_right, tvb, offset, 8, *p); p++; offset += 8; } return; }
void gcp_analyze_msg(proto_tree* gcp_tree, tvbuff_t* gcp_tvb, gcp_msg_t* m, gcp_hf_ett_t* ids) { gcp_trx_msg_t* t; gcp_ctxs_t contexts = {NULL,NULL}; gcp_ctxs_t* ctx_node; gcp_cmd_msg_t* c; for (t = m->trxs; t; t = t->next) { for (c = t->trx->cmds; c; c = c->next) { gcp_ctx_t* ctx = c->cmd->ctx; for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) { if (ctx_node->ctx->id == ctx->id) { break; } } if (! ctx_node) { ctx_node = ep_new(gcp_ctxs_t); ctx_node->ctx = ctx; ctx_node->next = contexts.next; contexts.next = ctx_node; } } } for (ctx_node = contexts.next; ctx_node; ctx_node = ctx_node->next) { gcp_ctx_t* ctx = ctx_node->ctx; proto_item* ctx_item = proto_tree_add_uint(gcp_tree,ids->hf.ctx,gcp_tvb,0,0,ctx->id); proto_tree* ctx_tree = proto_item_add_subtree(ctx_item,ids->ett.ctx); gcp_terms_t *ctx_term; PROTO_ITEM_SET_GENERATED(ctx_item); if (ctx->cmds) { proto_item* history_item = proto_tree_add_text(ctx_tree,gcp_tvb,0,0,"[ Command History ]"); proto_tree* history_tree = proto_item_add_subtree(history_item,ids->ett.ctx_cmds); for (c = ctx->cmds; c; c = c->next) { proto_item* cmd_item = proto_tree_add_uint(history_tree,ids->hf.ctx_cmd,gcp_tvb,0,0,c->cmd->msg->framenum); if (c->cmd->str) proto_item_append_text(cmd_item," %s ",c->cmd->str); PROTO_ITEM_SET_GENERATED(cmd_item); if (c->cmd->error) { proto_item_set_expert_flags(cmd_item, PI_RESPONSE_CODE, PI_WARN); } } } if (( ctx_term = ctx->terms.next )) { proto_item* terms_item = proto_tree_add_text(ctx_tree,gcp_tvb,0,0,"[ Terminations Used ]"); proto_tree* terms_tree = proto_item_add_subtree(terms_item,ids->ett.ctx_terms); for (; ctx_term; ctx_term = ctx_term->next ) { if ( ctx_term->term && ctx_term->term->str) { proto_item* pi = proto_tree_add_string(terms_tree,ids->hf.ctx_term,gcp_tvb,0,0,ctx_term->term->str); proto_tree* term_tree = proto_item_add_subtree(pi,ids->ett.ctx_term); PROTO_ITEM_SET_GENERATED(pi); if (ctx_term->term->type) { pi = proto_tree_add_uint(term_tree,ids->hf.ctx_term_type,gcp_tvb,0,0,ctx_term->term->type); PROTO_ITEM_SET_GENERATED(pi); } if (ctx_term->term->bir) { pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_bir,gcp_tvb,0,0,ctx_term->term->bir); PROTO_ITEM_SET_GENERATED(pi); } if (ctx_term->term->nsap) { pi = proto_tree_add_string(term_tree,ids->hf.ctx_term_nsap,gcp_tvb,0,0,ctx_term->term->nsap); PROTO_ITEM_SET_GENERATED(pi); } if (ctx_term->term->bir && ctx_term->term->nsap) { gchar* tmp_key = ep_strdup_printf("%s:%s",ctx_term->term->nsap,ctx_term->term->bir); gchar* key = g_ascii_strdown(tmp_key, -1); alcap_tree_from_bearer_key(term_tree, gcp_tvb, key); g_free(key); } } } } } }
/* Code to actually dissect the packets */ static int rsip_parameter(tvbuff_t *tvb, proto_tree *rsip_tree, int off, int eoff) { int consumed, i, paramleft; guint8 addrtype, flowpolicy, method, number, paramtype, tuntype; guint16 error, ind, paramlen, portnum; guint32 bid, cid, leasetm, msgc; proto_tree *p_tree, *v_tree; proto_item *pti, *vti; struct e_in6_addr in6; /* XXX */ if (off >= eoff) return 0; paramtype = tvb_get_guint8(tvb, off); paramlen = tvb_get_ntohs(tvb, off + 1); pti = proto_tree_add_text(rsip_tree, tvb, off, 3 + paramlen, "%s", val_to_str(paramtype, param_type_vals, "Unknown (%d)")); p_tree = proto_item_add_subtree(pti, ett_rsip_param); proto_tree_add_item(p_tree, hf_rsip_parameter_type, tvb, off, 1, ENC_BIG_ENDIAN); proto_tree_add_item(p_tree, hf_rsip_parameter_length, tvb, off + 1, 2, ENC_BIG_ENDIAN); consumed = 3; if (paramlen == 0) return consumed; vti = proto_tree_add_item(p_tree, hf_rsip_parameter_value, tvb, off + 3, paramlen, ENC_NA); v_tree = proto_item_add_subtree(vti, ett_rsip_param_val); switch (paramtype) { case 1: /* Address */ proto_tree_add_item(v_tree, hf_rsip_parameter_address_type, tvb, off + 3, 1, ENC_BIG_ENDIAN); addrtype = tvb_get_guint8(tvb, off + 3); switch (addrtype) { case 0: /* Reserved */ break; case 1: /* IPv4 */ if (paramlen - 1 > 0) { proto_tree_add_item(v_tree, hf_rsip_parameter_address_ipv4, tvb, off + 4, paramlen - 1, ENC_BIG_ENDIAN); proto_item_append_text(pti, ": %s", tvb_ip_to_str(tvb, off + 4)); } else proto_item_append_text(pti, ": Any IPv4 Address"); break; case 2: /* IPv4 netmask */ if (paramlen - 1 > 0) { proto_tree_add_item(v_tree, hf_rsip_parameter_address_ipv4_netmask, tvb, off + 4, paramlen - 1, ENC_BIG_ENDIAN); proto_item_append_text(pti, "(netmask): %s", tvb_ip_to_str(tvb, off + 4)); } else proto_item_append_text(pti, ": Any IPv4 Netmask"); break; case 3: /* IPv6 */ if (paramlen - 1 > 0) { tvb_get_ipv6(tvb, off + 4, &in6); proto_tree_add_item(v_tree, hf_rsip_parameter_address_ipv6, tvb, off + 4, paramlen - 1, ENC_NA); proto_item_append_text(pti, ": %s", ip6_to_str(&in6)); } else proto_item_append_text(pti, ": Any IPv6 Address"); break; case 4: /* FQDN */ if (paramlen - 1 > 0) { proto_tree_add_item(v_tree, hf_rsip_parameter_address_fqdn, tvb, off + 4, paramlen - 1, ENC_ASCII|ENC_NA); proto_item_append_text(pti, ": %s", tvb_format_text(tvb, off + 4, paramlen - 1)); } else proto_item_append_text(pti, ": Any Fully Qualified Domain Name"); break; default: proto_tree_add_text(p_tree, tvb, off + 4, paramlen - 1, ": Unknown Address Type"); break; } break; case 2: /* Ports */ proto_tree_add_item(v_tree, hf_rsip_parameter_ports_number, tvb, off + 3, 1, ENC_BIG_ENDIAN); number = tvb_get_guint8(tvb, off + 3); if (paramlen == 1) { switch (number) { case 0: proto_item_append_text(pti, ": Unspecified"); break; case 1: proto_item_append_text(pti, ": Any port"); break; default: proto_item_append_text(pti, ": Any %d ports", number); break; } } else { portnum = tvb_get_ntohs(tvb, off + 4); if (number == 1) { proto_tree_add_item(v_tree, hf_rsip_parameter_ports_port_number, tvb, off + 4, 2, ENC_BIG_ENDIAN); } else { paramleft = paramlen - 1; if (paramleft == 2) { proto_tree_add_uint_format_value(v_tree, hf_rsip_parameter_ports_port_number, tvb, off + 4, 2, portnum, "%d - %d", portnum, portnum + number); proto_item_append_text(pti, ": %d - %d", portnum, portnum + number); } else { for (i = off + 4; paramleft > 0; i += 2, paramleft -= 2) proto_tree_add_item(v_tree, hf_rsip_parameter_ports_port_number, tvb, i, 2, ENC_BIG_ENDIAN); proto_item_append_text(pti, ": List of %d Ports", number); } } } break; case 3: /* Lease Time */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_lease_time, tvb, off + 3, paramlen, ENC_BIG_ENDIAN); leasetm = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d seconds", leasetm); break; case 4: /* Client ID */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_client_id, tvb, off + 3, paramlen, ENC_BIG_ENDIAN); cid = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d", cid); break; case 5: /* Bind ID */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_bind_id, tvb, off + 3, paramlen, ENC_BIG_ENDIAN); bid = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d", bid); break; case 6: /* Tunnel Type */ /* XXX if paramlen != 1 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_tunnel_type, tvb, off + 3, paramlen, ENC_BIG_ENDIAN); tuntype = tvb_get_guint8(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(tuntype, tunnel_type_vals, "Unknown Tunnel Type (%d)")); break; case 7: /* RSIP Method */ /* XXX if paramlen != 1 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_method, tvb, off + 3, paramlen, ENC_BIG_ENDIAN); method = tvb_get_guint8(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(method, method_vals, "Unknown RSIP Method (%d)")); break; case 8: /* Error */ /* XXX if paramlen != 2 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_error, tvb, off + 3, paramlen, ENC_BIG_ENDIAN); error = tvb_get_ntohs(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(error, error_number_vals, "Undefined Error (%d)")); break; case 9: /* Flow Policy */ /* XXX if paramlen != 2 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_flow_policy_local, tvb, off + 3, 1, ENC_BIG_ENDIAN); flowpolicy = tvb_get_guint8(tvb, off + 3); proto_item_append_text(pti, ": %s", val_to_str(flowpolicy, lcl_flow_policy_vals, "Undefined Local Flow Policy (%d)")); proto_tree_add_item(v_tree, hf_rsip_parameter_flow_policy_remote, tvb, off + 4, 1, ENC_BIG_ENDIAN); flowpolicy = tvb_get_guint8(tvb, off + 4); proto_item_append_text(pti, "/%s", val_to_str(flowpolicy, rmt_flow_policy_vals, "Undefined Remote Flow Policy (%d)")); break; case 10: /* Indicator */ /* XXX if paramlen != 2 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_indicator, tvb, off + 3, 2, ENC_BIG_ENDIAN); ind = tvb_get_ntohs(tvb, off + 3); proto_item_append_text(pti, ": %d", ind); break; case 11: /* Message Counter */ /* XXX if paramlen != 4 we've got a protocol violation */ proto_tree_add_item(v_tree, hf_rsip_parameter_message_counter, tvb, off + 3, 4, ENC_BIG_ENDIAN); msgc = tvb_get_ntohl(tvb, off + 3); proto_item_append_text(pti, ": %d", msgc); break; case 12: /* Vendor Specific */ proto_tree_add_item(v_tree, hf_rsip_parameter_vendor_specific_vendor_id, tvb, off + 3, 2, ENC_BIG_ENDIAN); proto_tree_add_item(v_tree, hf_rsip_parameter_vendor_specific_subtype, tvb, off + 5, 2, ENC_BIG_ENDIAN); proto_tree_add_item(v_tree, hf_rsip_parameter_vendor_specific_value, tvb, off + 9, paramlen - 4, ENC_NA); break; case 22: /* SPI */ proto_tree_add_item(v_tree, hf_rsip_parameter_spi_number, tvb, off + 3, 2, ENC_BIG_ENDIAN); /* XXX need loop? */ proto_tree_add_item(v_tree, hf_rsip_parameter_spi, tvb, off + 5, 4, ENC_BIG_ENDIAN); break; default: break; } consumed += paramlen; return consumed; }
/* Code to actually dissect the PAGP packets */ static void dissect_pagp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint32 raw_word; guint16 raw_half_word; guint16 num_tlvs; guint16 tlv; guint16 len; guint16 ii; guint16 offset = PAGP_FIRST_TLV; guint8 raw_octet; guint8 flags; guchar *ch; proto_tree *pagp_tree = NULL; proto_item *pagp_item; proto_tree *flags_tree; proto_item *flags_item; proto_tree *tlv_tree; proto_item *tlv_item; const char *sep; col_set_str(pinfo->cinfo, COL_PROTOCOL, "PAGP"); /* PAGP Protocol */ col_clear(pinfo->cinfo, COL_INFO); pinfo->current_proto = "PAGP"; raw_octet = tvb_get_guint8(tvb, PAGP_VERSION_NUMBER); if (tree) { pagp_item = proto_tree_add_protocol_format(tree, proto_pagp, tvb, 0, -1, "Port Aggregation Protocol"); pagp_tree = proto_item_add_subtree(pagp_item, ett_pagp); proto_tree_add_uint(pagp_tree, hf_pagp_version_number, tvb, PAGP_VERSION_NUMBER, 1, raw_octet); } col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(raw_octet, pdu_vers, "Unknown PDU version")); if (raw_octet == PAGP_FLUSH_PDU) { col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s", tvb_ether_to_str(tvb, PAGP_FLUSH_LOCAL_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_flush_local_device_id, tvb, PAGP_FLUSH_LOCAL_DEVICE_ID, 6, ENC_NA); col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s", tvb_ether_to_str(tvb, PAGP_FLUSH_PARTNER_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_flush_partner_device_id, tvb, PAGP_FLUSH_PARTNER_DEVICE_ID, 6, ENC_NA); raw_word = tvb_get_ntohl(tvb, PAGP_FLUSH_TRANSACTION_ID); col_append_fstr(pinfo->cinfo, COL_INFO, "; Transaction ID: 0x%x ", raw_word); proto_tree_add_uint(pagp_tree, hf_pagp_flush_transaction_id, tvb, PAGP_FLUSH_TRANSACTION_ID, 4, raw_word); return; } /* Info PDU */ flags = tvb_get_guint8(tvb, PAGP_FLAGS); col_append_fstr(pinfo->cinfo, COL_INFO, "; Flags 0x%x", flags); if (tree) { flags_item = proto_tree_add_uint(pagp_tree, hf_pagp_flags, tvb, PAGP_FLAGS, 1, flags); flags_tree = proto_item_add_subtree(flags_item, ett_pagp_flags); sep = initial_sep; APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_SLOW_HELLO, flags_item, "%sSlow Hello"); proto_tree_add_boolean(flags_tree, hf_pagp_flags_slow_hello, tvb, PAGP_FLAGS, 1, flags); APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_AUTO_MODE, flags_item, "%sAuto Mode"); proto_tree_add_boolean(flags_tree, hf_pagp_flags_auto_mode, tvb, PAGP_FLAGS, 1, flags); APPEND_BOOLEAN_FLAG(flags & PAGP_FLAGS_CONSISTENT_STATE, flags_item, "%sConsistent State"); proto_tree_add_boolean(flags_tree, hf_pagp_flags_consistent_state, tvb, PAGP_FLAGS, 1, flags); sep = cont_sep; if (sep != initial_sep) { /* We put something in; put in the terminating ")" */ proto_item_append_text(flags_item, ")"); } } col_append_fstr(pinfo->cinfo, COL_INFO, "; Local DevID: %s", tvb_ether_to_str(tvb, PAGP_LOCAL_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_local_device_id, tvb, PAGP_LOCAL_DEVICE_ID, 6, ENC_NA); if (tree) { raw_octet = tvb_get_guint8(tvb, PAGP_LOCAL_LEARN_CAP); proto_tree_add_uint(pagp_tree, hf_pagp_local_learn_cap, tvb, PAGP_LOCAL_LEARN_CAP, 1, raw_octet); raw_octet = tvb_get_guint8(tvb, PAGP_LOCAL_PORT_PRIORITY); proto_tree_add_uint(pagp_tree, hf_pagp_local_port_priority, tvb, PAGP_LOCAL_PORT_PRIORITY, 1, raw_octet); raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_SENT_PORT_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_local_sent_port_ifindex, tvb, PAGP_LOCAL_SENT_PORT_IFINDEX, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_GROUP_CAPABILITY); proto_tree_add_uint(pagp_tree, hf_pagp_local_group_capability, tvb, PAGP_LOCAL_GROUP_CAPABILITY, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_LOCAL_GROUP_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_local_group_ifindex, tvb, PAGP_LOCAL_GROUP_IFINDEX, 4, raw_word); } col_append_fstr(pinfo->cinfo, COL_INFO, ", Partner DevID: %s", tvb_ether_to_str(tvb, PAGP_PARTNER_DEVICE_ID)); proto_tree_add_item(pagp_tree, hf_pagp_partner_device_id, tvb, PAGP_PARTNER_DEVICE_ID, 6, ENC_NA); if (tree) { raw_octet = tvb_get_guint8(tvb, PAGP_PARTNER_LEARN_CAP); proto_tree_add_uint(pagp_tree, hf_pagp_partner_learn_cap, tvb, PAGP_PARTNER_LEARN_CAP, 1, raw_octet); raw_octet = tvb_get_guint8(tvb, PAGP_PARTNER_PORT_PRIORITY); proto_tree_add_uint(pagp_tree, hf_pagp_partner_port_priority, tvb, PAGP_PARTNER_PORT_PRIORITY, 1, raw_octet); raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_SENT_PORT_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_partner_sent_port_ifindex, tvb, PAGP_PARTNER_SENT_PORT_IFINDEX, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_GROUP_CAPABILITY); proto_tree_add_uint(pagp_tree, hf_pagp_partner_group_capability, tvb, PAGP_PARTNER_GROUP_CAPABILITY, 4, raw_word); raw_word = tvb_get_ntohl(tvb, PAGP_PARTNER_GROUP_IFINDEX); proto_tree_add_uint(pagp_tree, hf_pagp_partner_group_ifindex, tvb, PAGP_PARTNER_GROUP_IFINDEX, 4, raw_word); raw_half_word = tvb_get_ntohs(tvb, PAGP_PARTNER_COUNT); proto_tree_add_uint(pagp_tree, hf_pagp_partner_count, tvb, PAGP_PARTNER_COUNT, 2, raw_half_word); num_tlvs = tvb_get_ntohs(tvb, PAGP_NUM_TLVS); proto_tree_add_uint(pagp_tree, hf_pagp_num_tlvs, tvb, PAGP_NUM_TLVS, 2, num_tlvs); /* dump TLV entries */ for ( ii = 0; ii < num_tlvs; ii++ ) { tlv = tvb_get_ntohs(tvb, offset); len = tvb_get_ntohs(tvb, offset + 2); if ( len == 0 ) { proto_tree_add_text(pagp_tree, tvb, offset, -1, "Unknown data - TLV len=0"); return; } tlv_item = proto_tree_add_text (pagp_tree, tvb, offset, len, "TLV Entry #%d", ii+1); tlv_tree = proto_item_add_subtree (tlv_item, ett_pagp_tlvs); proto_tree_add_uint_format (tlv_tree, hf_pagp_tlv, tvb, offset,2,tlv,"Type = %d (%s)", tlv, val_to_str_const(tlv,tlv_types, "Unknown")) ; proto_tree_add_text (tlv_tree, tvb, offset+2, 2, "Length = %u bytes (includes Type and Length)", len) ; if ( tvb_reported_length_remaining(tvb, offset) < len ) { proto_tree_add_text(tlv_tree, tvb, offset, -1, "TLV length too large"); return; } switch (tlv) { case PAGP_TLV_DEVICE_NAME: ch = tvb_get_string(wmem_packet_scope(), tvb, offset+4, len-4); proto_tree_add_string(tlv_tree, hf_pagp_tlv_device_name, tvb, offset+4, len-4, ch); break; case PAGP_TLV_PORT_NAME: ch = tvb_get_string(wmem_packet_scope(), tvb, offset+4, len-4); proto_tree_add_string(tlv_tree, hf_pagp_tlv_port_name, tvb, offset+4, len-4, ch); break; case PAGP_TLV_AGPORT_MAC: proto_tree_add_item(tlv_tree, hf_pagp_tlv_agport_mac, tvb, offset+4, 6, ENC_NA); break; case PAGP_TLV_RESERVED: break; } offset += len; } } }