static void dissect_wsmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *wsmp_tree, *wsmdata_tree; tvbuff_t *wsmdata_tvb; guint16 wsmlength, offset; guint32 psidLen, psid, supLen; guint8 elemenId, elemenLen, msb; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WSMP"); col_set_str(pinfo->cinfo, COL_INFO, "WAVE Short Message Protocol IEEE P1609.3"); /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_wsmp, tvb, 0, -1, ENC_NA); wsmp_tree = proto_item_add_subtree(ti, ett_wsmp); offset = 0; proto_tree_add_item(wsmp_tree, hf_wsmp_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; psid = tvb_get_guint8(tvb, offset); psidLen = (guint32)wme_getpsidlen((guint8*)&psid); if (psidLen == 2) psid = tvb_get_ntohs(tvb, offset); else if (psidLen == 3) psid = tvb_get_ntoh24(tvb, offset); else if (psidLen == 4) psid = tvb_get_ntohl(tvb, offset); proto_tree_add_item(wsmp_tree, hf_wsmp_psid, tvb, offset, psidLen, ENC_BIG_ENDIAN); offset += psidLen; /* TLV decoder that does not display the T and L elements */ elemenId = tvb_get_guint8(tvb, offset); while ((elemenId != WSMP) && (elemenId != WSMP_S) && (elemenId != WSMP_I)) { offset++; if (elemenId == CHANNUM) { elemenLen = tvb_get_guint8(tvb, offset); offset++; proto_tree_add_item(wsmp_tree, hf_wsmp_channel, tvb, offset, elemenLen, ENC_BIG_ENDIAN); offset += elemenLen; } else if (elemenId == DATARATE) { elemenLen = tvb_get_guint8(tvb, offset); offset++; proto_tree_add_item(wsmp_tree, hf_wsmp_rate, tvb, offset, elemenLen, ENC_BIG_ENDIAN); offset += elemenLen; } else if (elemenId == TRANSMITPW) { elemenLen = tvb_get_guint8(tvb, offset); offset++; proto_tree_add_item(wsmp_tree, hf_wsmp_txpower, tvb, offset, elemenLen, ENC_BIG_ENDIAN); offset += elemenLen; } elemenId = tvb_get_guint8(tvb, offset); } proto_tree_add_item(wsmp_tree, hf_wsmp_WAVEid, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; wsmlength = tvb_get_letohs( tvb, offset); proto_tree_add_item(wsmp_tree, hf_wsmp_wsmlength, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (elemenId == WSMP_S) { msb = 1; supLen = 0; while (msb) { msb = tvb_get_guint8(tvb, offset + supLen); msb = msb & 0x80; supLen++; } proto_tree_add_item(wsmp_tree, hf_wsmp_WSMP_S_data, tvb, offset, supLen, ENC_BIG_ENDIAN); wsmlength -= supLen; offset += supLen; } wsmdata_tree = proto_tree_add_subtree(wsmp_tree, tvb, offset, wsmlength, ett_wsmdata, NULL, "Wave Short Message"); wsmdata_tvb = tvb_new_subset(tvb, offset, -1, wsmlength); /* TODO: Branch on the application context and display accordingly * Default: call the data dissector */ if (psid == 0xbff0) { call_dissector(data_handle, wsmdata_tvb, pinfo, wsmdata_tree); } }
static void dissect_fip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint op; guint sub; guint rlen; proto_item *ti; proto_item *item; proto_tree *fip_tree; proto_tree *subtree; guint dtype; guint dlen; guint desc_offset; guint val; tvbuff_t *desc_tvb; const char *info; const char *text; col_set_str(pinfo->cinfo, COL_PROTOCOL, "FIP"); col_clear(pinfo->cinfo, COL_INFO); if (!tvb_bytes_exist(tvb, 0, FIP_HEADER_LEN)) { col_set_str(pinfo->cinfo, COL_INFO, "[packet too short]"); if (tree) proto_tree_add_protocol_format(tree, proto_fip, tvb, 0, -1, "FIP [packet too short]"); return; } op = tvb_get_ntohs(tvb, 2); sub = tvb_get_guint8(tvb, 5); switch (op) { case FIP_OP_DISC: info = val_to_str(sub, fip_disc_subcodes, "Discovery 0x%x"); break; case FIP_OP_LS: info = val_to_str(sub, fip_ls_subcodes, "Link Service 0x%x"); break; case FIP_OP_CTRL: info = val_to_str(sub, fip_ctrl_subcodes, "Control 0x%x"); break; case FIP_OP_VLAN: info = val_to_str(sub, fip_vlan_subcodes, "VLAN 0x%x"); break; case FIP_OP_VN2VN: info = val_to_str(sub, fip_vn2vn_subcodes, "VN2VN 0x%x"); break; default: info = val_to_str(op, fip_opcodes, "Unknown op 0x%x"); break; } col_add_str(pinfo->cinfo, COL_INFO, info); rlen = tvb_get_ntohs(tvb, 6); ti = proto_tree_add_protocol_format(tree, proto_fip, tvb, 0, FIP_HEADER_LEN + rlen * FIP_BPW, "FIP %s", info); fip_tree = proto_item_add_subtree(ti, ett_fip); proto_tree_add_item(fip_tree, hf_fip_ver, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(fip_tree, hf_fip_op, tvb, 2, 2, ENC_BIG_ENDIAN); switch (op) { case FIP_OP_DISC: proto_tree_add_item(fip_tree, hf_fip_disc_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_LS: proto_tree_add_item(fip_tree, hf_fip_ls_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_CTRL: proto_tree_add_item(fip_tree, hf_fip_ctrl_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_VLAN: proto_tree_add_item(fip_tree, hf_fip_vlan_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; case FIP_OP_VN2VN: proto_tree_add_item(fip_tree, hf_fip_vn2vn_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; default: proto_tree_add_item(fip_tree, hf_fip_hex_subcode, tvb, 5, 1, ENC_BIG_ENDIAN); break; } proto_tree_add_item(fip_tree, hf_fip_dlen, tvb, 6, 2, ENC_BIG_ENDIAN); proto_tree_add_bitmask(fip_tree, tvb, 8, hf_fip_flags, ett_fip_flags, hf_fip_flags_fields, ENC_BIG_ENDIAN); desc_offset = FIP_HEADER_LEN; rlen *= FIP_BPW; proto_tree_add_bytes_format(fip_tree, hf_fip_descriptors, tvb, desc_offset, rlen, NULL, "Descriptors"); while ((rlen > 0) && tvb_bytes_exist(tvb, desc_offset, 2)) { dlen = tvb_get_guint8(tvb, desc_offset + 1) * FIP_BPW; if (!dlen) { proto_tree_add_expert(fip_tree, pinfo, &ei_fip_descriptors, tvb, desc_offset, -1); break; } if (!tvb_bytes_exist(tvb, desc_offset, dlen) || dlen > rlen) { break; } desc_tvb = tvb_new_subset(tvb, desc_offset, dlen, -1); dtype = tvb_get_guint8(desc_tvb, 0); desc_offset += dlen; rlen -= dlen; switch (dtype) { case FIP_DT_PRI: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_pri, &item); proto_tree_add_item(subtree, hf_fip_desc_pri, desc_tvb, 3, 1, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_guint8(desc_tvb, 3)); break; case FIP_DT_MAC: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mac, &item); proto_tree_add_item(subtree, hf_fip_desc_mac, desc_tvb, 2, 6, ENC_NA); proto_item_append_text(item, "%s", tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':')); break; case FIP_DT_MAP_OUI: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_map, &item); text = tvb_fc_to_str(desc_tvb, 5); proto_tree_add_string(subtree, hf_fip_desc_map, desc_tvb, 5, 3, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_NAME: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_name, &item); text = tvb_fcwwn_to_str(desc_tvb, 4); proto_tree_add_string(subtree, hf_fip_desc_name, desc_tvb, 4, 8, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_FAB: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fab, &item); proto_tree_add_item(subtree, hf_fip_desc_fab_vfid, desc_tvb, 2, 2, ENC_BIG_ENDIAN); text = tvb_fc_to_str(desc_tvb, 5); proto_tree_add_string(subtree, hf_fip_desc_fab_map, desc_tvb, 5, 3, text); text = tvb_fcwwn_to_str(desc_tvb, 8); proto_tree_add_string(subtree, hf_fip_desc_fab_name, desc_tvb, 8, 8, text); proto_item_append_text(item, "%s", text); break; case FIP_DT_FCOE_SIZE: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_mdl, &item); proto_tree_add_item(subtree, hf_fip_desc_fcoe_size, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; case FIP_DT_FLOGI: case FIP_DT_FDISC: case FIP_DT_LOGO: case FIP_DT_ELP: { tvbuff_t *ls_tvb; fc_data_t fc_data = {ETHERTYPE_FIP, 0}; subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_caps, &item); ls_tvb = tvb_new_subset(desc_tvb, 4, dlen - 4, -1); call_dissector_with_data(fc_handle, ls_tvb, pinfo, subtree, &fc_data); proto_item_append_text(item, "%u bytes", dlen - 4); } break; case FIP_DT_VN: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vn, &item); proto_tree_add_item(subtree, hf_fip_desc_vn_mac, desc_tvb, 2, 6, ENC_NA); proto_tree_add_item(subtree, hf_fip_desc_vn_fid, desc_tvb, 9, 3, ENC_BIG_ENDIAN); text = tvb_fcwwn_to_str(desc_tvb, 12); proto_tree_add_string(subtree, hf_fip_desc_vn_wwpn, desc_tvb, 12, 8, text); proto_item_append_text(item, "MAC %s FC_ID %6.6x", tvb_bytes_to_ep_str_punct(desc_tvb, 2, 6, ':'), tvb_get_ntoh24(desc_tvb, 9)); break; case FIP_DT_FKA: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fka, &item); val = tvb_get_ntohl(desc_tvb, 4); proto_tree_add_uint_format_value(subtree, hf_fip_desc_fka, desc_tvb, 4, 4, val, "%u ms", val); proto_item_append_text(item, "%u ms", val); break; case FIP_DT_VEND: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vend, &item); proto_tree_add_item(subtree, hf_fip_desc_vend, desc_tvb, 4, 8, ENC_NA); if (tvb_bytes_exist(desc_tvb, 9, -1)) { proto_tree_add_item(subtree, hf_fip_desc_vend_data, desc_tvb, 9, -1, ENC_NA); } break; case FIP_DT_VLAN: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_vlan, &item); proto_tree_add_item(subtree, hf_fip_desc_vlan, desc_tvb, 2, 2, ENC_BIG_ENDIAN); proto_item_append_text(item, "%u", tvb_get_ntohs(desc_tvb, 2)); break; case FIP_DT_FC4F: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_fc4f, &item); fip_desc_fc4f(desc_tvb, subtree, item); break; default: subtree = fip_desc_type_len(fip_tree, desc_tvb, dtype, ett_fip_dt_unk, &item); proto_tree_add_item(subtree, hf_fip_desc_unk, desc_tvb, 2, -1, ENC_NA); break; } } }
static void dissect_jpeg( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) { proto_item *ti = NULL; proto_tree *jpeg_tree = NULL; proto_tree *main_hdr_tree = NULL; proto_tree *restart_hdr_tree = NULL; proto_tree *qtable_hdr_tree = NULL; guint32 fragment_offset = 0; guint16 len = 0; guint8 type = 0; guint8 q = 0; gint h = 0; gint w = 0; unsigned int offset = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "JPEG"); col_set_str(pinfo->cinfo, COL_INFO, "JPEG message"); if ( tree ) { ti = proto_tree_add_item( tree, hfi_jpeg, tvb, offset, -1, ENC_NA ); jpeg_tree = proto_item_add_subtree( ti, ett_jpeg ); ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_main_hdr, tvb, offset, 8, ENC_NA); main_hdr_tree = proto_item_add_subtree(ti, ett_jpeg); proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_ts, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_offs, tvb, offset, 3, ENC_BIG_ENDIAN); fragment_offset = tvb_get_ntoh24(tvb, offset); offset += 3; proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_type, tvb, offset, 1, ENC_BIG_ENDIAN); type = tvb_get_guint8(tvb, offset); offset += 1; proto_tree_add_item(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_q, tvb, offset, 1, ENC_BIG_ENDIAN); q = tvb_get_guint8(tvb, offset); offset += 1; w = tvb_get_guint8(tvb, offset) * 8; proto_tree_add_uint(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_width, tvb, offset, 1, w); offset += 1; h = tvb_get_guint8(tvb, offset) * 8; proto_tree_add_uint(main_hdr_tree, &hfi_rtp_jpeg_main_hdr_height, tvb, offset, 1, h); offset += 1; if (type >= 64 && type <= 127) { ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_restart_hdr, tvb, offset, 4, ENC_NA); restart_hdr_tree = proto_item_add_subtree(ti, ett_jpeg); proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_interval, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_f, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_l, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(restart_hdr_tree, &hfi_rtp_jpeg_restart_hdr_count, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } if (q >= 128 && fragment_offset == 0) { ti = proto_tree_add_item(jpeg_tree, &hfi_rtp_jpeg_qtable_hdr, tvb, offset, -1, ENC_NA); qtable_hdr_tree = proto_item_add_subtree(ti, ett_jpeg); proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_mbz, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_prec, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_length, tvb, offset, 2, ENC_BIG_ENDIAN); len = tvb_get_ntohs(tvb, offset); offset += 2; if (len > 0) { proto_tree_add_item(qtable_hdr_tree, &hfi_rtp_jpeg_qtable_hdr_data, tvb, offset, len, ENC_NA); offset += len; } proto_item_set_len(ti, len + 4); } /* The rest of the packet is the JPEG data */ proto_tree_add_item( jpeg_tree, &hfi_rtp_jpeg_payload, tvb, offset, -1, ENC_NA ); } }
/* Sub-vectors */ static int sv_text(tvbuff_t *tvb, int svoff, packet_info *pinfo, proto_tree *tree) { guint sv_length, sv_id; guint16 beacon_type, ring; guint32 error_report_timer_value; proto_tree *sv_tree, *sv_subtree; proto_item *sv_item, *len_item, *ti; guchar errors[6]; /* isolating or non-isolating */ sv_item = proto_tree_add_text(tree, tvb, svoff+0, 1, "Subvector"); sv_tree = proto_item_add_subtree(sv_item, ett_tr_sv); sv_length = tvb_get_guint8(tvb, svoff+0); len_item = proto_tree_add_item(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, ENC_NA); /* Check the SV length; it must be at least 2, to include the subvector length and indicator. */ if (sv_length < 2) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Invalid subvector: length < 2"); return 0; /* tells our caller to give up */ } sv_id = tvb_get_guint8(tvb, svoff+1); proto_tree_add_item(sv_tree, hf_trmac_sv_id, tvb, svoff+1, 1, ENC_NA); proto_item_append_text(sv_item, " (%s)", val_to_str(sv_id, subvector_vs, "Unknown subvector ID 0x%02X")); switch(sv_id) { case 0x01: /* Beacon Type */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } beacon_type = tvb_get_ntohs(tvb, svoff+2); proto_tree_add_uint_format_value(sv_tree, hf_trmac_beacon_type, tvb, svoff+2, sv_length-2, beacon_type, "%s", val_to_str(beacon_type, beacon_vs, "Illegal value: %d")); proto_item_append_text(sv_item, ": %s", val_to_str(beacon_type, beacon_vs, "Illegal value: %d")); break; case 0x02: /* Upstream Neighbor's Address */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_naun, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x03: /* Local Ring Number */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } ring = tvb_get_ntohs(tvb, svoff+2); proto_tree_add_item(sv_tree, hf_trmac_local_ring_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": 0x%04X (%d)", ring, ring); break; case 0x04: /* Assign Physical Drop Number */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6"); break; } proto_tree_add_item(sv_tree, hf_trmac_assign_physical_drop_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x05: /* Error Report Timer Value */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } error_report_timer_value = 10 * tvb_get_ntohs(tvb, svoff+2); proto_tree_add_uint_format_value(sv_tree, hf_trmac_error_report_timer_value, tvb, svoff+2, sv_length-2, error_report_timer_value, "%d ms", error_report_timer_value ); proto_item_append_text(sv_item, ": %d ms", error_report_timer_value ); break; case 0x06: /* Authorized Function Classes */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_authorized_function_classes, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x07: /* Authorized Access Priority */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_authorized_access_priority, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x09: /* Correlator */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_correlator, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x0A: /* SA of Last AMP or SMP Frame */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_sa_of_last_amp_or_smp_frame, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x0B: /* Physical Drop Number */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6"); break; } proto_tree_add_item(sv_tree, hf_trmac_physical_drop_number, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x20: /* Response Code */ if (sv_length != 4 && sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4 and != 6"); break; } if (sv_length == 4) { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Response Code: 0x%04X 0x%02X 0x%02x", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_guint8(tvb, svoff+5)); proto_item_append_text(sv_item, ": 0x%04X 0x%02X 0x%02x", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_guint8(tvb, svoff+5)); } else { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Response Code: 0x%04X 0x%02X 0x%06X", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_ntoh24(tvb, svoff+5)); proto_item_append_text(sv_item, ": 0x%04X 0x%02X 0x%06X", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_ntoh24(tvb, svoff+5)); } break; case 0x21: /* Individual Address Count */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_individual_address_count, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %u", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x22: /* Product Instance ID */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Product Instance ID: ..."); break; case 0x23: /* Ring Station Version Number */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Ring Station Version Number: ..."); break; case 0x26: /* Wrap data */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Wrap Data: ... (%u bytes)", sv_length - 2); break; case 0x27: /* Frame Forward */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Frame Forward: ... (%d bytes)", sv_length - 2); break; case 0x28: /* Station Identifier */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_station_identifier, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x29: /* Ring Station Status */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Ring Station Status: ..."); break; case 0x2A: /* Transmit Status Code */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_transmit_status_code, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x2B: /* Group Address */ if (sv_length != 6 && sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6 and != 8"); break; } if (sv_length == 6) { proto_tree_add_item(sv_tree, hf_trmac_group_address32, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %08X", tvb_get_ntohl(tvb, svoff+2) ); } else { proto_tree_add_item(sv_tree, hf_trmac_group_address_ether, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); } break; case 0x2C: /* Functional Addresses */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 6"); break; } proto_tree_add_item(sv_tree, hf_trmac_functional_addresses, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x2D: /* Isolating Error Counts */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } tvb_memcpy(tvb, errors, svoff+2, 6); ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_iso, tvb, svoff+2, sv_length-2, errors[0] + errors[1] + errors[2] + errors[3] + errors[4]); sv_subtree = proto_item_add_subtree(ti, ett_tr_ierr_cnt); proto_tree_add_uint(sv_subtree, hf_trmac_errors_line, tvb, svoff+2, 1, errors[0]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_internal, tvb, svoff+3, 1, errors[1]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_burst, tvb, svoff+4, 1, errors[2]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_ac, tvb, svoff+5, 1, errors[3]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_abort, tvb, svoff+6, 1, errors[4]); break; case 0x2E: /* Non-Isolating Error Counts */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 8"); break; } tvb_memcpy(tvb, errors, svoff+2, 6); ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_noniso, tvb, svoff+2, sv_length-2, errors[0] + errors[1] + errors[2] + errors[3] + errors[4]); sv_subtree = proto_item_add_subtree(ti, ett_tr_nerr_cnt); proto_tree_add_uint(sv_subtree, hf_trmac_errors_lost, tvb, svoff+2, 1, errors[0]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_congestion, tvb, svoff+3, 1, errors[1]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_fc, tvb, svoff+4, 1, errors[2]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_freq, tvb, svoff+5, 1, errors[3]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_token, tvb, svoff+6, 1, errors[4]); break; case 0x30: /* Error Code */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, &ei_trmac_sv_len, "Subvector length is != 4"); break; } proto_tree_add_item(sv_tree, hf_trmac_error_code, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; default: /* Unknown */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Unknown Subvector"); break; } return sv_length; }
static int dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len ) { int key2; const guchar *dst_addr; /*guint32 dst_addr1;*/ proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key2 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key2 == 1) { ssn = tvb_get_guint8(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset); mtp3_addr_dpc->type = 1; /* ITU_STANDARD */ mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); /*dst_addr = tvb_get_ptr(tvb, offset, msg_len-1); SET_ADDRESS(&pinfo->net_dst, AT_SS7PC, msg_len-1, dst_addr); SET_ADDRESS(&pinfo->dst, AT_SS7PC, msg_len-1, dst_addr);*/ if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key2 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_dpc->type = 1; /* ITU_STANDARD */ mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); } else if (key2 == 3) { if (msg_len%4 == 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); dst_addr = tvb_get_ptr(tvb, offset, 4); SET_ADDRESS(&pinfo->net_dst, AT_IPv4, 4, dst_addr); SET_ADDRESS(&pinfo->dst, AT_IPv4, 4, dst_addr); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset,&value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, (guint8*)&value); dst_addr = tvb_get_ptr(tvb, offset, 6); SET_ADDRESS(&pinfo->net_dst, AT_IPv6, 6, dst_addr); SET_ADDRESS(&pinfo->dst, AT_IPv6, 6, dst_addr); } } else if (key2 == 4) { char *string; string = tvb_get_string(tvb, offset, msg_len); proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string); dst_addr = tvb_get_ptr(tvb, offset, msg_len); SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, msg_len, dst_addr); SET_ADDRESS(&pinfo->dst, AT_STRINGZ, msg_len, dst_addr); /*g_free(string);*/ } if (msg_len%4) msg_len = msg_len+(4-(msg_len%4)); offset += msg_len; return offset; }
/* generic juniper header dissector */ static int dissect_juniper_header(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_item *ti, guint8 *flags) { proto_item *tisub; guint8 direction,l2hdr_presence,proto,ext_type,ext_len; guint16 ext_total_len,ext_offset=6,hdr_len; guint32 magic_number,ext_val; proto_tree *juniper_ext_subtree = NULL, *juniper_ext_subtree_item = NULL; magic_number = tvb_get_ntoh24(tvb, 0); *flags = tvb_get_guint8(tvb, 3); direction = *flags & JUNIPER_FLAG_PKT_IN; l2hdr_presence = *flags & JUNIPER_FLAG_NO_L2; juniper_subtree = proto_item_add_subtree(ti, ett_juniper); /* be liberal with magic-number detection - * some older JUNOS releases (e.g. 6.4), * which are still in the field do not generate magic-numbers */ if (magic_number != JUNIPER_PCAP_MAGIC) { proto_tree_add_text (juniper_subtree, tvb, 0, 0, "no Magic-Number found !"); return 0; } proto_tree_add_text (juniper_subtree, tvb, 0, 3, "Magic-Number: 0x%06x", magic_number); proto_tree_add_uint_format (juniper_subtree, hf_juniper_direction, tvb, 3, 1, direction, "Direction: %s", val_to_str_const(direction,juniper_direction_vals,"Unknown")); proto_tree_add_uint_format (juniper_subtree, hf_juniper_l2hdr_presence, tvb, 3, 1, l2hdr_presence, "L2-header: %s", val_to_str_const(l2hdr_presence,juniper_l2hdr_presence_vals,"Unknown")); /* calculate hdr_len before cookie, payload */ /* meta-info extensions (JUNOS >= 7.5) ? */ if ((*flags & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) { ext_total_len = tvb_get_ntohs(tvb,4); hdr_len = 6 + ext_total_len; /* MGC,flags,ext_total_len */ tisub = proto_tree_add_uint (juniper_subtree, hf_juniper_ext_total_len, tvb, 4, 2, ext_total_len); juniper_ext_subtree = proto_item_add_subtree(tisub, ett_juniper); while (ext_total_len > EXT_TLV_HEADER_SIZE) { ext_type = tvb_get_guint8(tvb, ext_offset); ext_len = tvb_get_guint8(tvb, ext_offset+1); if (ext_len == 0 || ext_len > (ext_total_len - EXT_TLV_HEADER_SIZE)) /* a few sanity checks */ break; tisub = proto_tree_add_text (juniper_ext_subtree, tvb, ext_offset, EXT_TLV_HEADER_SIZE + ext_len, "%s Extension TLV #%u, length: %u", val_to_str_const(ext_type, ext_tlv_vals, "Unknown"), ext_type, ext_len); ext_val = juniper_ext_get_tlv_value(tvb, ext_type, ext_len, ext_offset+EXT_TLV_HEADER_SIZE); juniper_ext_subtree_item = proto_item_add_subtree(tisub, ett_juniper); switch (ext_type) { case EXT_TLV_IFD_MEDIATYPE: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifmt, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_TTP_IFD_MEDIATYPE: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifmt, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_IFL_ENCAPS: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifle, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_TTP_IFL_ENCAPS: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ttp_ifle, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_IFL_IDX: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifl, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_IFL_UNIT: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_unit, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_IFD_IDX: proto_tree_add_uint(juniper_ext_subtree_item, hf_juniper_ext_ifd, tvb, ext_offset+EXT_TLV_HEADER_SIZE, ext_len, ext_val); break; case EXT_TLV_IFD_NAME: /* FIXME print ifname string - lets fall-through for now */ default: proto_item_append_text(tisub, "Unknown"); break; } ext_offset += EXT_TLV_HEADER_SIZE + ext_len; ext_total_len -= EXT_TLV_HEADER_SIZE + ext_len; } } else hdr_len = 4; /* MGC,flags */ if ((*flags & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) { /* no link header present ? */ proto = tvb_get_letohl(tvb,hdr_len); /* proto is stored in host-order */ dissect_juniper_payload_proto(tvb, pinfo, tree, ti, proto, hdr_len + 4); return -1; } return hdr_len; /* bytes parsed */ }
static void dissect_itdm_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *itdm_ctl_item = NULL; proto_tree *itdm_ctl_tree = NULL; int offset; guint32 flowid; guint8 command; guint32 trans_id; guint32 paired_trans_id; guint32 allocd_flowid; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ITDM-Control"); flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET); command = tvb_get_guint8(tvb, ITDM_CTL_CMD_OFFSET); allocd_flowid = tvb_get_ntoh24(tvb, ITDM_CTL_FLOWID_OFFSET); trans_id = tvb_get_ntohl(tvb, ITDM_CTL_TRANSID_OFFSET); paired_trans_id = tvb_get_ntohl(tvb, ITDM_CTL_PAIRED_TRANSID_OFFSET); col_add_fstr(pinfo->cinfo, COL_INFO, "Flow %d Command %s ", flowid, val_to_str_const(command, itdm_ctl_command_vals, "Reserved")); if (command != ITDM_CTL_CMD_AFI_REQ ) { col_append_fstr(pinfo->cinfo, COL_INFO, " Alloc'd FlowID %d", allocd_flowid); } col_append_fstr(pinfo->cinfo, COL_INFO, " TransID 0x%x ", trans_id); if (command != ITDM_CTL_CMD_AFI_REQ ) { col_append_fstr(pinfo->cinfo, COL_INFO, " Paired TransID 0x%x", paired_trans_id); } offset = 0; if (tree) { itdm_ctl_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, ENC_NA); itdm_ctl_tree = proto_item_add_subtree(itdm_ctl_item, ett_itdm_ctl); /* These eventually should go into a SFP.0 dissector... */ proto_tree_add_item(itdm_ctl_tree, hf_itdm_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(itdm_ctl_tree, hf_itdm_sop_eop, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_ctl_tree, hf_itdm_last_pack, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_ctl_tree, hf_itdm_pktlen, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_chksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_uid, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_transid, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_command, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; if (command != ITDM_CTL_CMD_AFI_REQ) { proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_flowid, tvb, offset, 3, ENC_BIG_ENDIAN); } offset += 3; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_dm, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; /* rsvd.. */ offset += 1; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_emts, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_pktrate, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (command != ITDM_CTL_CMD_AFI_REQ) { proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_ptid, tvb, offset, 4, ENC_BIG_ENDIAN); } offset += 4; /* rsvd.. */ offset += 2; proto_tree_add_item(itdm_ctl_tree, hf_itdm_ctl_cksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(data_handle, next_tvb, pinfo, tree); }
/* Code to actually dissect the packets */ static void dissect_fcfzs_zoneset(tvbuff_t *tvb, proto_tree *tree, int offset) { int numzones, nummbrs, i, j, len; /* The zoneset structure has the following format */ /* zoneset name (len[not including pad], name, pad), * number of zones, * for each zone, * Zone name (len[not including pad], name, pad), num zone mbrs * for each zone mbr, * zone mbr id type, zone mbr id (len, name, pad) */ if (tree) { /* Zoneset Name */ len = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_zonesetnmlen, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcfzs_zonesetname, tvb, offset+4, len, ENC_ASCII|ENC_NA); offset += 4 + len + (4-(len % 4)); /* Number of zones */ numzones = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_numzones, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* For each zone... */ for (i = 0; i < numzones; i++) { len = tvb_get_guint8(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_zonenmlen, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcfzs_zonename, tvb, offset+4, len, ENC_ASCII|ENC_NA); offset += 4 + len + (4-(len % 4)); nummbrs = tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_fcfzs_nummbrentries, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; for (j = 0; j < nummbrs; j++) { proto_tree_add_item(tree, hf_fcfzs_mbrtype, tvb, offset, 1, ENC_BIG_ENDIAN); switch (tvb_get_guint8(tvb, offset)) { case FC_FZS_ZONEMBR_PWWN: case FC_FZS_ZONEMBR_NWWN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); break; case FC_FZS_ZONEMBR_DP: proto_tree_add_string_format(tree, hf_fcfzs_mbrid, tvb, offset+4, 3, " ", "0x%x", tvb_get_ntoh24(tvb, offset+4)); break; case FC_FZS_ZONEMBR_FCID: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 4, tvb_fc_to_str(tvb, offset+4)); break; case FC_FZS_ZONEMBR_PWWN_LUN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, tvb_fcwwn_to_str(tvb, offset+4)); proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb, offset+8, 8, ENC_NA); break; case FC_FZS_ZONEMBR_DP_LUN: proto_tree_add_string_format(tree, hf_fcfzs_mbrid, tvb, offset+4, 3, " ", "0x%x", tvb_get_ntoh24(tvb, offset+4)); proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb, offset+4, 8, ENC_NA); break; case FC_FZS_ZONEMBR_FCID_LUN: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 4, tvb_fc_to_str(tvb, offset+4)); proto_tree_add_item(tree, hf_fcfzs_mbrid_lun, tvb, offset+4, 8, ENC_NA); break; default: proto_tree_add_string(tree, hf_fcfzs_mbrid, tvb, offset+4, 8, "Unknown member type format"); } offset += 12; } } } }
static void dissect_sdh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_set_str(pinfo->cinfo, COL_PROTOCOL, "SDH"); col_clear(pinfo->cinfo,COL_INFO); if (tree) { proto_tree *sdh_tree; proto_item *sdh_item; int level = get_sdh_level(tvb); guint32 a1; guint32 a2; guint8 j0; guint8 b1; guint8 e1; guint8 f1; guint8 d1; guint8 d2; guint8 d3; guint8 h1; guint8 h2; guint16 au; guint32 b2; guint8 k1; guint8 k2; guint8 d4; guint8 d5; guint8 d6; guint8 d7; guint8 d8; guint8 d9; guint8 d10; guint8 d11; guint8 d12; guint8 s1; guint8 m1; guint8 e2; guint8 j1; sdh_item = proto_tree_add_protocol_format(tree, proto_sdh, tvb, 0, -1, "SDH"); sdh_tree = proto_item_add_subtree(sdh_item, ett_sdh); a1 = tvb_get_ntoh24(tvb, 0+(0*level*COLUMNS)); a2 = tvb_get_ntoh24(tvb, 3+(0*level*COLUMNS)); j0 = tvb_get_guint8(tvb, 6+(0*level*COLUMNS)); b1 = tvb_get_guint8(tvb, 0+(1*level*COLUMNS)); e1 = tvb_get_guint8(tvb, 3+(1*level*COLUMNS)); f1 = tvb_get_guint8(tvb, 6+(1*level*COLUMNS)); d1 = tvb_get_guint8(tvb, 0+(2*level*COLUMNS)); d2 = tvb_get_guint8(tvb, 3+(2*level*COLUMNS)); d3 = tvb_get_guint8(tvb, 6+(2*level*COLUMNS)); h1 = tvb_get_guint8(tvb, 0+(3*level*COLUMNS)); h2 = tvb_get_guint8(tvb, 3+(3*level*COLUMNS)); au = (h2 | ((0x03 & h1) << 8)); b2 = 0; b2 = tvb_get_guint8(tvb, 0+(4*level*COLUMNS)) << 16; b2 = tvb_get_guint8(tvb, (1*level)+(4*level*COLUMNS)) << 8; b2 = tvb_get_guint8(tvb, (2*level)+(4*level*COLUMNS)); k1 = tvb_get_guint8(tvb, 3+(4*level*COLUMNS)); k2 = tvb_get_guint8(tvb, 6+(4*level*COLUMNS)); d4 = tvb_get_guint8(tvb, 0+(5*level*COLUMNS)); d5 = tvb_get_guint8(tvb, 3+(5*level*COLUMNS)); d6 = tvb_get_guint8(tvb, 6+(5*level*COLUMNS)); d7 = tvb_get_guint8(tvb, 0+(6*level*COLUMNS)); d8 = tvb_get_guint8(tvb, 3+(6*level*COLUMNS)); d9 = tvb_get_guint8(tvb, 6+(6*level*COLUMNS)); d10 = tvb_get_guint8(tvb, 0+(7*level*COLUMNS)); d11 = tvb_get_guint8(tvb, 3+(7*level*COLUMNS)); d12 = tvb_get_guint8(tvb, 6+(7*level*COLUMNS)); s1 = tvb_get_guint8(tvb, 0+(8*level*COLUMNS)); m1 = tvb_get_guint8(tvb, 5+(8*level*COLUMNS)); e2 = tvb_get_guint8(tvb, 6+(8*level*COLUMNS)); j1 = tvb_get_guint8(tvb, au); proto_tree_add_uint_format(sdh_tree, hf_sdh_a1, tvb, 0, 3, a1, "A1 %x", a1); proto_tree_add_uint_format(sdh_tree, hf_sdh_a2, tvb, 3, 3, a2, "A2 %x", a2); proto_tree_add_uint_format(sdh_tree, hf_sdh_j0, tvb, 6, 1, j0, "J0 %d", j0); proto_tree_add_uint_format(sdh_tree, hf_sdh_b1, tvb, 0+(1*level*COLUMNS), 1, b1, "B1 %d", b1); proto_tree_add_uint_format(sdh_tree, hf_sdh_e1, tvb, 3+(1*level*COLUMNS), 1, e1, "E1 %d", e1); proto_tree_add_uint_format(sdh_tree, hf_sdh_f1, tvb, 6+(1*level*COLUMNS), 1, f1, "F1 %d", f1); proto_tree_add_uint_format(sdh_tree, hf_sdh_d1, tvb, 0+(2*level*COLUMNS), 1, d1, "D1 %d", d1); proto_tree_add_uint_format(sdh_tree, hf_sdh_d2, tvb, 3+(2*level*COLUMNS), 1, d2, "D2 %d", d2); proto_tree_add_uint_format(sdh_tree, hf_sdh_d3, tvb, 6+(2*level*COLUMNS), 1, d3, "D3 %d", d3); proto_tree_add_uint_format(sdh_tree, hf_sdh_au, tvb, 0+(3*level*COLUMNS), 9, au, "AU pointer %d h1 %d, h2 %d", au, h1, h2); proto_tree_add_uint_format(sdh_tree, hf_sdh_b2, tvb, 0+(4*level*COLUMNS), 1, b2, "B2 %d", b2); proto_tree_add_uint_format(sdh_tree, hf_sdh_k1, tvb, 3+(4*level*COLUMNS), 1, k1, "K1 %d", k1); proto_tree_add_uint_format(sdh_tree, hf_sdh_k2, tvb, 6+(4*level*COLUMNS), 1, k2, "K2 %d", k2); proto_tree_add_uint_format(sdh_tree, hf_sdh_d4, tvb, 0+(5*level*COLUMNS), 1, d4, "D4 %d", d4); proto_tree_add_uint_format(sdh_tree, hf_sdh_d5, tvb, 3+(5*level*COLUMNS), 1, d5, "D5 %d", d5); proto_tree_add_uint_format(sdh_tree, hf_sdh_d6, tvb, 6+(5*level*COLUMNS), 1, d6, "D6 %d", d6); proto_tree_add_uint_format(sdh_tree, hf_sdh_d7, tvb, 0+(6*level*COLUMNS), 1, d7, "D7 %d", d7); proto_tree_add_uint_format(sdh_tree, hf_sdh_d8, tvb, 3+(6*level*COLUMNS), 1, d8, "D8 %d", d8); proto_tree_add_uint_format(sdh_tree, hf_sdh_d9, tvb, 6+(6*level*COLUMNS), 1, d9, "D9 %d", d9); proto_tree_add_uint_format(sdh_tree, hf_sdh_d10, tvb, 0+(7*level*COLUMNS), 1, d10, "D10 %d", d10); proto_tree_add_uint_format(sdh_tree, hf_sdh_d11, tvb, 3+(7*level*COLUMNS), 1, d11, "D11 %d", d11); proto_tree_add_uint_format(sdh_tree, hf_sdh_d12, tvb, 6+(7*level*COLUMNS), 1, d12, "D12 %d", d12); proto_tree_add_uint_format(sdh_tree, hf_sdh_s1, tvb, 0+(8*level*COLUMNS), 1, s1, "S1 %d", s1); proto_tree_add_uint_format(sdh_tree, hf_sdh_m1, tvb, 5+(8*level*COLUMNS), 1, m1, "M1 %d", m1); proto_tree_add_uint_format(sdh_tree, hf_sdh_e2, tvb, 6+(7*level*COLUMNS), 1, e2, "E2 %d", e2); proto_tree_add_uint_format(sdh_tree, hf_sdh_j1, tvb, au, 1, j1, "J1 %d", j1); } }
static void dissect_itdm_125usec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { tvbuff_t *next_tvb; proto_item *itdm_item = NULL; proto_tree *itdm_tree = NULL; int offset; guint32 flowid; guint32 chanid; guint16 chloc1; guint16 chloc2; guint8 chcmd; guint8 actbit; guint8 ackbit; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ITDM"); flowid = tvb_get_ntoh24(tvb, ITDM_FLOWID_OFFSET); chanid = tvb_get_ntoh24(tvb, ITDM_CHANID_OFFSET); chcmd = tvb_get_guint8(tvb, ITDM_CHCMD_OFFSET); chloc1 = tvb_get_ntohs(tvb, ITDM_CHLOC1_OFFSET); actbit = (chcmd & 0x10) ? 1 : 0; ackbit = (chcmd & 0x20) ? 1 : 0; chcmd = chcmd & 0x0f; col_add_fstr(pinfo->cinfo, COL_INFO, "Flow %d Chan %d ACT %d ACK %d %s", flowid, chanid, actbit, ackbit, val_to_str_const(chcmd, chcmd_vals, "Reserved")); if (chcmd == ITDM_CMD_NEW_CHAN || chcmd == ITDM_CMD_CLOSE_CHAN || chcmd == ITDM_CMD_CYCLIC_REAF) { col_append_fstr(pinfo->cinfo, COL_INFO, " Loc1 %d", chloc1); } else if (chcmd == ITDM_CMD_RELOC_CHAN) { chloc2 = tvb_get_ntohs(tvb, ITDM_CHLOC2_OFFSET); col_append_fstr(pinfo->cinfo, COL_INFO, " Loc1 %d Loc2 %d", chloc1, chloc2); } offset = 0; if (tree) { itdm_item = proto_tree_add_item(tree, proto_itdm, tvb, 0, -1, ENC_NA); itdm_tree = proto_item_add_subtree(itdm_item, ett_itdm); proto_tree_add_item(itdm_tree, hf_itdm_timestamp, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_tree, hf_itdm_seqnum, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(itdm_tree, hf_itdm_sop_eop, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_last_pack, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_pktlen, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_tree, hf_itdm_chksum, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(itdm_tree, hf_itdm_uid, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; proto_tree_add_item(itdm_tree, hf_itdm_ack, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_act, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(itdm_tree, hf_itdm_chcmd, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(itdm_tree, hf_itdm_chid, tvb, offset, 3, ENC_BIG_ENDIAN); offset += 3; if (chcmd == ITDM_CMD_PACKET_RATE) { proto_tree_add_item(itdm_tree, hf_itdm_pktrate, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; } else { proto_tree_add_item(itdm_tree, hf_itdm_chloc1, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (chcmd == ITDM_CMD_CYCLIC_REAF || chcmd == ITDM_CMD_NEW_CHAN || chcmd == ITDM_CMD_CLOSE_CHAN) { proto_tree_add_item(itdm_tree, hf_itdm_cxnsize, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } else { proto_tree_add_item(itdm_tree, hf_itdm_chloc2, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; } } } next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector(data_handle, next_tvb, pinfo, tree); }
static int dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len) { int key1; proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key1 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key1 == 1) { proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN); /*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_opc->pc = (guint32 )tvb_get_ntoh24(tvb, offset); mtp3_addr_opc->type = 1; /* ITU_STANDARD */ mtp3_addr_opc->ni = 0; /*SET_ADDRESS(&pinfo->net_src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc);*/ SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key1 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN); /*src_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_opc = ep_alloc0(sizeof(mtp3_addr_pc_t)); mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_opc->type = 1; /* ITU_STANDARD */ mtp3_addr_opc->ni = 0; SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); } else if (key1 == 3) { if (msg_len%4 == 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv4, tvb, offset, 4); COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset, &value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, (guint8*)&value); TVB_SET_ADDRESS(&pinfo->net_src, AT_IPv6, tvb, offset, 6); COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src); } } else if (key1 == 4) { proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_BIG_ENDIAN|ENC_ASCII); TVB_SET_ADDRESS(&pinfo->net_src, AT_STRINGZ, tvb, offset, msg_len); COPY_ADDRESS_SHALLOW(&pinfo->src, &pinfo->net_src); } if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len; return offset; }
/* * Dissect SNAP header; used elsewhere, e.g. in the Frame Relay dissector. */ void dissect_snap(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, proto_tree *snap_tree, int control, int hf_oui, int hf_type, int hf_pid, int bridge_pad) { guint32 oui; guint16 etype; tvbuff_t *next_tvb; oui_info_t *oui_info; dissector_table_t subdissector_table; int hf; int mesh_header_len; /* * XXX - what about non-UI frames? */ oui = tvb_get_ntoh24(tvb, offset); etype = tvb_get_ntohs(tvb, offset+3); col_append_fstr(pinfo->cinfo, COL_INFO, "; SNAP, OUI 0x%06X (%s), PID 0x%04X", oui, val_to_str_const(oui, oui_vals, "Unknown"), etype); proto_tree_add_uint(snap_tree, hf_oui, tvb, offset, 3, oui); switch (oui) { case OUI_HP_2: oui_info = get_snap_oui_info(oui); hf = *oui_info->field_info->p_id; proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2, etype); next_tvb = tvb_new_subset_remaining(tvb, offset+5); if(!dissector_try_uint(hpteam_subdissector_table,etype, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, tree); break; case OUI_ENCAP_ETHER: case OUI_CISCO_90: case OUI_APPLE_ATALK: /* No, I have no idea why Apple used one of their own OUIs, rather than OUI_ENCAP_ETHER, and an Ethernet packet type as protocol ID, for AppleTalk data packets - but used OUI_ENCAP_ETHER and an Ethernet packet type for AARP packets. */ if (XDLC_IS_INFORMATION(control)) { if (tree) { proto_tree_add_uint(snap_tree, hf_type, tvb, offset+3, 2, etype); } next_tvb = tvb_new_subset_remaining(tvb, offset+5); if (!dissector_try_uint(ethertype_subdissector_table, etype, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, tree); } else { next_tvb = tvb_new_subset_remaining(tvb, offset+5); call_dissector(data_handle, next_tvb, pinfo, tree); } break; case OUI_IEEE_802_1: /* * MAC frames bridged over ATM (RFC 2684) or Frame Relay * (RFC 2427). * * We have to figure out how much padding to put * into the frame. We were handed a "bridge_pad" * argument which should be 0 for Frame Relay and * 2 for ATM; we add to that the amount of padding * common to both bridging types. */ if (tree) { proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2, etype); } switch (etype) { case BPID_ETH_WITH_FCS: next_tvb = tvb_new_subset_remaining(tvb, offset+5+bridge_pad); call_dissector(eth_withfcs_handle, next_tvb, pinfo, tree); break; case BPID_ETH_WITHOUT_FCS: next_tvb = tvb_new_subset_remaining(tvb, offset+5+bridge_pad); call_dissector(eth_withoutfcs_handle, next_tvb, pinfo, tree); break; case BPID_802_5_WITH_FCS: case BPID_802_5_WITHOUT_FCS: /* * We treat the last padding byte as the Access * Control byte, as that's what the Token * Ring dissector expects the first byte to * be. */ next_tvb = tvb_new_subset_remaining(tvb, offset+5+bridge_pad); call_dissector(tr_handle, next_tvb, pinfo, tree); break; case BPID_FDDI_WITH_FCS: case BPID_FDDI_WITHOUT_FCS: next_tvb = tvb_new_subset_remaining(tvb, offset+5+1+bridge_pad); call_dissector(fddi_handle, next_tvb, pinfo, tree); break; case BPID_BPDU: next_tvb = tvb_new_subset_remaining(tvb, offset+5); call_dissector(bpdu_handle, next_tvb, pinfo, tree); break; default: next_tvb = tvb_new_subset_remaining(tvb, offset+5); call_dissector(data_handle, next_tvb, pinfo, tree); break; } break; case OUI_CABLE_BPDU: /* DOCSIS cable modem spanning tree BPDU */ if (tree) { proto_tree_add_uint(snap_tree, hf_pid, tvb, offset+3, 2, etype); } next_tvb = tvb_new_subset_remaining(tvb, offset+5); call_dissector(bpdu_handle, next_tvb, pinfo, tree); break; case OUI_TURBOCELL: next_tvb = tvb_new_subset_remaining(tvb, offset+3); call_dissector(turbo_handle, next_tvb, pinfo, tree); break; case OUI_MARVELL: /* * OLPC packet. The PID is an Ethertype, but * there's a mesh header between the PID and * the payload. */ if (XDLC_IS_INFORMATION(control)) { if (tree) { proto_tree_add_uint(snap_tree, hf_type, tvb, offset+3, 2, etype); } next_tvb = tvb_new_subset_remaining(tvb, offset+5); mesh_header_len = call_dissector(mesh_handle, next_tvb, pinfo, tree); next_tvb = tvb_new_subset_remaining(tvb, offset+5+mesh_header_len); if (!dissector_try_uint(ethertype_subdissector_table, etype, next_tvb, pinfo, tree)) call_dissector(data_handle, next_tvb, pinfo, tree); } else { next_tvb = tvb_new_subset_remaining(tvb, offset+5); call_dissector(data_handle, next_tvb, pinfo, tree); } break; default: /* * Do we have information for this OUI? */ oui_info = get_snap_oui_info(oui); if (oui_info != NULL) { /* * Yes - use it. */ hf = *oui_info->field_info->p_id; subdissector_table = oui_info->table; } else { /* * No, use hf_pid for the PID and just dissect * the payload as data. */ hf = hf_pid; subdissector_table = NULL; } if (tree) { proto_tree_add_uint(snap_tree, hf, tvb, offset+3, 2, etype); } next_tvb = tvb_new_subset_remaining(tvb, offset+5); if (XDLC_IS_INFORMATION(control)) { if (subdissector_table != NULL) { /* do lookup with the subdissector table */ if (dissector_try_uint(subdissector_table, etype, next_tvb, pinfo, tree)) break; } } call_dissector(data_handle, next_tvb, pinfo, tree); break; } }
static void dissect_fcfcs (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ int offset = 0; proto_item *ti; proto_tree *fcfcs_tree = NULL; fc_ct_preamble cthdr; gboolean isreq = 1; conversation_t *conversation; fcfcs_conv_data_t *cdata; fcfcs_conv_key_t ckey, *req_key; int opcode, failed_opcode = 0; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "FC-FCS"); if (tree) { ti = proto_tree_add_protocol_format (tree, proto_fcfcs, tvb, 0, tvb_reported_length (tvb), "FCS"); fcfcs_tree = proto_item_add_subtree (ti, ett_fcfcs); } tvb_memcpy (tvb, (guint8 *)&cthdr, offset, FCCT_PRMBL_SIZE); cthdr.revision = tvb_get_guint8 (tvb, offset); cthdr.in_id = tvb_get_ntoh24 (tvb, offset+1); cthdr.opcode = g_ntohs (cthdr.opcode); opcode = tvb_get_ntohs (tvb, offset+8); cthdr.maxres_size = g_ntohs (cthdr.maxres_size); if ((opcode != FCCT_MSG_ACC) && (opcode != FCCT_MSG_RJT)) { conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->oxid, pinfo->rxid, NO_PORT2); if (!conversation) { conversation = conversation_new (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->oxid, pinfo->rxid, NO_PORT2); } ckey.conv_idx = conversation->index; cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash, &ckey); if (cdata) { /* Since we never free the memory used by an exchange, this maybe a * case of another request using the same exchange as a previous * req. */ cdata->opcode = opcode; } else { req_key = se_alloc (sizeof(fcfcs_conv_key_t)); req_key->conv_idx = conversation->index; cdata = se_alloc (sizeof(fcfcs_conv_data_t)); cdata->opcode = opcode; g_hash_table_insert (fcfcs_req_hash, req_key, cdata); } if (check_col (pinfo->cinfo, COL_INFO)) { col_add_str (pinfo->cinfo, COL_INFO, val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x")); } } else { /* Opcode is ACC or RJT */ conversation = find_conversation (pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->oxid, pinfo->rxid, NO_PORT2); isreq = 0; if (!conversation) { if (tree && (opcode == FCCT_MSG_ACC)) { if (check_col (pinfo->cinfo, COL_INFO)) { col_add_str (pinfo->cinfo, COL_INFO, val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x")); } /* No record of what this accept is for. Can't decode */ proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb), "No record of Exchg. Unable to decode MSG_ACC/RJT"); return; } } else { ckey.conv_idx = conversation->index; cdata = (fcfcs_conv_data_t *)g_hash_table_lookup (fcfcs_req_hash, &ckey); if (cdata != NULL) { if (opcode == FCCT_MSG_ACC) opcode = cdata->opcode; else failed_opcode = cdata->opcode; } if (check_col (pinfo->cinfo, COL_INFO)) { if (opcode != FCCT_MSG_RJT) { col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_ACC (%s)", val_to_str (opcode, fc_fcs_opcode_abbrev_val, "0x%x")); } else { col_add_fstr (pinfo->cinfo, COL_INFO, "MSG_RJT (%s)", val_to_str (failed_opcode, fc_fcs_opcode_abbrev_val, "0x%x")); } } if (tree) { if ((cdata == NULL) && (opcode != FCCT_MSG_RJT)) { /* No record of what this accept is for. Can't decode */ proto_tree_add_text (fcfcs_tree, tvb, 0, tvb_length (tvb), "No record of Exchg. Unable to decode MSG_ACC/RJT"); return; } } } } if (tree) { proto_tree_add_item (fcfcs_tree, hf_fcs_opcode, tvb, offset+8, 2, 0); proto_tree_add_item (fcfcs_tree, hf_fcs_maxres_size, tvb, offset+10, 2, 0); } switch (opcode) { case FCCT_MSG_RJT: dissect_fcfcs_rjt (tvb, fcfcs_tree); break; case FCFCS_GIEL: dissect_fcfcs_giel (tvb, fcfcs_tree, isreq); break; case FCFCS_GIET: dissect_fcfcs_giet (tvb, fcfcs_tree, isreq); break; case FCFCS_GDID: dissect_fcfcs_gdid (tvb, fcfcs_tree, isreq); break; case FCFCS_GMID: dissect_fcfcs_gmid (tvb, fcfcs_tree, isreq); break; case FCFCS_GFN: dissect_fcfcs_gfn (tvb, fcfcs_tree, isreq); break; case FCFCS_GIELN: dissect_fcfcs_gieln (tvb, fcfcs_tree, isreq); break; case FCFCS_GMAL: dissect_fcfcs_gmal (tvb, fcfcs_tree, isreq); break; case FCFCS_GIEIL: dissect_fcfcs_gieil (tvb, fcfcs_tree, isreq); break; case FCFCS_GPL: dissect_fcfcs_gpl (tvb, fcfcs_tree, isreq); break; case FCFCS_GPT: dissect_fcfcs_gpt (tvb, fcfcs_tree, isreq); break; case FCFCS_GPPN: dissect_fcfcs_gppn (tvb, fcfcs_tree, isreq); break; case FCFCS_GAPNL: dissect_fcfcs_gapnl (tvb, fcfcs_tree, isreq); break; case FCFCS_GPS: dissect_fcfcs_gps (tvb, fcfcs_tree, isreq); break; case FCFCS_GPLNL: dissect_fcfcs_gplnl (tvb, fcfcs_tree, isreq); break; case FCFCS_GPLT: dissect_fcfcs_gplt (tvb, fcfcs_tree, isreq); break; case FCFCS_GPLML: dissect_fcfcs_gplml (tvb, fcfcs_tree, isreq); break; case FCFCS_GNPL: dissect_fcfcs_gnpl (tvb, fcfcs_tree, isreq); break; case FCFCS_GPNL: dissect_fcfcs_gpnl (tvb, fcfcs_tree, isreq); break; case FCFCS_RIELN: dissect_fcfcs_rieln (tvb, fcfcs_tree, isreq); break; case FCFCS_RPL: dissect_fcfcs_rpl (tvb, fcfcs_tree, isreq); break; case FCFCS_RPLN: dissect_fcfcs_rpln (tvb, fcfcs_tree, isreq); break; case FCFCS_RPLT: dissect_fcfcs_rplt (tvb, fcfcs_tree, isreq); break; case FCFCS_RPLM: dissect_fcfcs_rplm (tvb, fcfcs_tree, isreq); break; case FCFCS_DPL: dissect_fcfcs_dpl (tvb, fcfcs_tree, isreq); break; case FCFCS_DPLN: dissect_fcfcs_dpln (tvb, fcfcs_tree, isreq); break; case FCFCS_DPLML: dissect_fcfcs_dplml (tvb, fcfcs_tree, isreq); break; case FCFCS_GCAP: dissect_fcfcs_gcap (tvb, fcfcs_tree, isreq); break; default: call_dissector (data_handle, tvb, pinfo, fcfcs_tree); break; } }
/* Sub-vectors */ static int sv_text(tvbuff_t *tvb, int svoff, packet_info *pinfo, proto_tree *tree) { guint sv_length, sv_id; guint16 beacon_type, ring; const char *beacon[] = { "Recovery mode set", "Signal loss error", "Streaming signal not Claim Token MAC frame", "Streaming signal, Claim Token MAC frame" }; proto_tree *sv_tree, *sv_subtree; proto_item *sv_item, *len_item, *ti; guchar errors[6]; /* isolating or non-isolating */ sv_length = tvb_get_guint8(tvb, svoff+0); /* Check the SV length; it must be at least 2, to include the subvector length and indicator. */ if (sv_length < 2) { ti = proto_tree_add_text(tree, tvb, svoff+0, 1, "Invalid subvector: length < 2"); sv_tree = proto_item_add_subtree(ti, ett_tr_sv); len_item = proto_tree_add_uint(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, sv_length); expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is zero"); return 0; /* tells our caller to give up */ } sv_item = proto_tree_add_text(tree, tvb, svoff+0, sv_length, "Subvector: length %u", sv_length); sv_tree = proto_item_add_subtree(sv_item, ett_tr_sv); len_item = proto_tree_add_uint(sv_tree, hf_trmac_sv_len, tvb, svoff+0, 1, sv_length); sv_id = tvb_get_guint8(tvb, svoff+1); proto_tree_add_uint(sv_tree, hf_trmac_sv_id, tvb, svoff+1, 1, sv_id); proto_item_set_text(sv_item, "%s", val_to_str(sv_id, subvector_vs, "Unknown subvector ID 0x%02X")); switch(sv_id) { case 0x01: /* Beacon Type */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } beacon_type = tvb_get_ntohs(tvb, svoff+2); if (beacon_type < array_length(beacon)) { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Beacon Type: %s", beacon[beacon_type] ); proto_item_append_text(sv_item, ": %s", beacon[beacon_type] ); } else { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Beacon Type: Illegal value: %d", beacon_type ); proto_item_append_text(sv_item, ": Illegal value: %d", beacon_type ); } break; case 0x02: /* Upstream Neighbor's Address */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 8"); break; } proto_tree_add_item(sv_tree, hf_trmac_naun, tvb, svoff+2, sv_length-2, ENC_NA); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x03: /* Local Ring Number */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } ring = tvb_get_ntohs(tvb, svoff+2); proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Local Ring Number: 0x%04X (%d)", ring, ring); proto_item_append_text(sv_item, ": 0x%04X (%d)", ring, ring); break; case 0x04: /* Assign Physical Drop Number */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 6"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Assign Physical Drop Number: 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); proto_item_append_text(sv_item, ": 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x05: /* Error Report Timer Value */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Error Report Timer Value: %d ms", 10 * tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %d ms", 10 * tvb_get_ntohs(tvb, svoff+2) ); break; case 0x06: /* Authorized Function Classes */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Authorized Function Classes: %04X", tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x07: /* Authorized Access Priority */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Authorized Access Priority: %04X", tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x09: /* Correlator */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Correlator: %04X", tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x0A: /* SA of Last AMP or SMP Frame */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 8"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "SA of Last AMP or SMP Frame: %s", tvb_ether_to_str(tvb, svoff+2)); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x0B: /* Physical Drop Number */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 6"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Physical Drop Number: 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); proto_item_append_text(sv_item, ": 0x%08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x20: /* Response Code */ if (sv_length != 4 && sv_length != 6) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4 and != 6"); break; } if (sv_length == 4) { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Response Code: 0x%04X 0x%02X 0x%02x", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_guint8(tvb, svoff+5)); proto_item_append_text(sv_item, ": 0x%04X 0x%02X 0x%02x", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_guint8(tvb, svoff+5)); } else { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Response Code: 0x%04X 0x%02X 0x%06X", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_ntoh24(tvb, svoff+5)); proto_item_append_text(sv_item, ": 0x%04X 0x%02X 0x%06X", tvb_get_ntohs(tvb, svoff+2), tvb_get_guint8(tvb, svoff+4), tvb_get_ntoh24(tvb, svoff+5)); } break; case 0x21: /* Individual Address Count */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Individual Address Count: %u", tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %u", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x22: /* Product Instance ID */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Product Instance ID: ..."); break; case 0x23: /* Ring Station Version Number */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Ring Station Version Number: ..."); break; case 0x26: /* Wrap data */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Wrap Data: ... (%u bytes)", sv_length - 2); break; case 0x27: /* Frame Forward */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Frame Forward: ... (%d bytes)", sv_length - 2); break; case 0x28: /* Station Identifier */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 8"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Station Identifier: %s", tvb_ether_to_str(tvb, svoff+2)); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); break; case 0x29: /* Ring Station Status */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Ring Station Status: ..."); break; case 0x2A: /* Transmit Status Code */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Transmit Status Code: %04X", tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; case 0x2B: /* Group Address */ if (sv_length != 6 && sv_length != 8) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 6 and != 8"); break; } if (sv_length == 6) { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Group Address: %08X", tvb_get_ntohl(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %08X", tvb_get_ntohl(tvb, svoff+2) ); } else { proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Group Address: %s", tvb_ether_to_str(tvb, svoff+2)); proto_item_append_text(sv_item, ": %s", tvb_ether_to_str(tvb, svoff+2)); } break; case 0x2C: /* Functional Addresses */ if (sv_length != 6) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 6"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Functional Addresses: %08X", tvb_get_ntohl(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %08X", tvb_get_ntohl(tvb, svoff+2) ); break; case 0x2D: /* Isolating Error Counts */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 8"); break; } tvb_memcpy(tvb, errors, svoff+2, 6); ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_iso, tvb, svoff+2, sv_length-2, errors[0] + errors[1] + errors[2] + errors[3] + errors[4]); sv_subtree = proto_item_add_subtree(ti, ett_tr_ierr_cnt); proto_tree_add_uint(sv_subtree, hf_trmac_errors_line, tvb, svoff+2, 1, errors[0]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_internal, tvb, svoff+3, 1, errors[1]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_burst, tvb, svoff+4, 1, errors[2]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_ac, tvb, svoff+5, 1, errors[3]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_abort, tvb, svoff+6, 1, errors[4]); break; case 0x2E: /* Non-Isolating Error Counts */ if (sv_length != 8) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 8"); break; } tvb_memcpy(tvb, errors, svoff+2, 6); ti = proto_tree_add_uint(sv_tree, hf_trmac_errors_noniso, tvb, svoff+2, sv_length-2, errors[0] + errors[1] + errors[2] + errors[3] + errors[4]); sv_subtree = proto_item_add_subtree(ti, ett_tr_nerr_cnt); proto_tree_add_uint(sv_subtree, hf_trmac_errors_lost, tvb, svoff+2, 1, errors[0]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_congestion, tvb, svoff+3, 1, errors[1]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_fc, tvb, svoff+4, 1, errors[2]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_freq, tvb, svoff+5, 1, errors[3]); proto_tree_add_uint(sv_subtree, hf_trmac_errors_token, tvb, svoff+6, 1, errors[4]); break; case 0x30: /* Error Code */ if (sv_length != 4) { expert_add_info_format(pinfo, len_item, PI_MALFORMED, PI_ERROR, "Subvector length is != 4"); break; } proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Error Code: %04X", tvb_get_ntohs(tvb, svoff+2) ); proto_item_append_text(sv_item, ": %04X", tvb_get_ntohs(tvb, svoff+2) ); break; default: /* Unknown */ proto_tree_add_text(sv_tree, tvb, svoff+2, sv_length-2, "Unknown Subvector"); break; } return sv_length; }
/* WiMax MAC to MAC protocol dissector */ static void dissect_m2m(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti = NULL; proto_item *m2m_item = NULL; proto_tree *m2m_tree = NULL; proto_tree *tlv_tree = NULL; gint burst_number = 0; gint length, offset = 0; gint tlv_count; gint tlv_type, tlv_len, tlv_offset, tlv_value; gint tlv_frag_type = 0; gint tlv_frag_number = 0; tlv_info_t m2m_tlv_info; gint hf; guint encoding; guint frame_number; int expected_len; /* display the M2M protocol name */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "WiMax"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); { /* we are being asked for details */ m2m_item = proto_tree_add_item(tree, proto_m2m, tvb, 0, -1, ENC_NA); m2m_tree = proto_item_add_subtree(m2m_item, ett_m2m); /* get the tvb reported length */ length = tvb_reported_length(tvb); /* add the size info */ /* proto_item_append_text(m2m_item, " (%u bytes) - Packet Sequence Number,Number of TLVs", length); */ proto_item_append_text(m2m_item, " (%u bytes)", length); /* display the sequence number */ proto_tree_add_item(m2m_tree, hf_m2m_sequence_number, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* display the TLV count */ proto_tree_add_item(m2m_tree, hf_m2m_tlv_count, tvb, offset, 2, ENC_BIG_ENDIAN); tlv_count = tvb_get_ntohs(tvb, offset); offset += 2; /* parses the TLVs within current packet */ while ( tlv_count > 0) { /* init MAC to MAC TLV information */ init_tlv_info(&m2m_tlv_info, tvb, offset); /* get the TLV type */ tlv_type = get_tlv_type(&m2m_tlv_info); /* get the TLV length */ tlv_len = get_tlv_length(&m2m_tlv_info); if(tlv_type == -1 || tlv_len > 64000 || tlv_len < 1) { /* invalid tlv info */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "M2M TLV error"); /* display the invalid TLV in HEX */ proto_tree_add_item(m2m_tree, hf_wimax_invalid_tlv, tvb, offset, (length - offset), ENC_NA); break; } /* get the TLV value offset */ tlv_offset = get_tlv_value_offset(&m2m_tlv_info); /* display TLV type */ ti = proto_tree_add_protocol_format(m2m_tree, proto_m2m, tvb, offset, (tlv_len + tlv_offset), "%s", val_to_str(tlv_type, tlv_name, "Unknown TLV")); /* add TLV subtree */ tlv_tree = proto_item_add_subtree(ti, ett_m2m_tlv); /* update the offset */ offset += tlv_offset; /* add the size info */ /* decode TLV content (TLV value) */ expected_len = 0; hf = 0; encoding = ENC_NA; switch (tlv_type) { case TLV_PROTO_VER: /* get the protocol version */ tlv_value = tvb_get_guint8( tvb, offset ); /* add the description */ proto_item_append_text(ti, ": %d", tlv_value); hf = hf_m2m_value_protocol_vers_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_BURST_NUM: /* get the burst number */ burst_number = tvb_get_guint8( tvb, offset ); /* add the description */ proto_item_append_text(ti, ": %d", burst_number); hf = hf_m2m_value_burst_num_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_FRAG_TYPE: /* add the description */ tlv_frag_type = tvb_get_guint8( tvb, offset ); proto_item_append_text(ti, ": %s", val_to_str(tlv_frag_type, tlv_frag_type_name, "Unknown")); hf = hf_m2m_value_frag_type_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_FRAG_NUM: /* get the fragment number */ tlv_frag_number = tvb_get_guint8( tvb, offset ); /* add the description */ proto_item_append_text(ti, ": %d", tlv_frag_number); hf = hf_m2m_value_frag_num_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_PDU_BURST: /* display PDU Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the PDU Burst */ pdu_burst_decoder(tree, tvb, offset, tlv_len, pinfo, burst_number, tlv_frag_type, tlv_frag_number); hf = hf_m2m_value_pdu_burst; encoding = ENC_NA; break; case TLV_FAST_FB: /* display the Fast Feedback Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the Fast Feedback Burst */ fast_feedback_burst_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_fast_fb; encoding = ENC_NA; break; case TLV_FRAME_NUM: /* get the frame number */ frame_number = tvb_get_ntoh24( tvb, offset ); /* add the description */ proto_tree_add_item(tlv_tree, hf_m2m_frame_number, tvb, offset, 3, ENC_BIG_ENDIAN); proto_item_append_text(ti, ": %d", frame_number); break; case TLV_FCH_BURST: /* add the description */ tlv_value = tvb_get_ntoh24( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); /* decode and display the TLV FCH burst */ fch_burst_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_fch_burst_uint24; encoding = ENC_BIG_ENDIAN; expected_len = 3; break; case TLV_CDMA_CODE: /* add the description */ tlv_value = tvb_get_ntoh24( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); /* decode and display the CDMA Code */ cdma_code_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_cdma_code_uint24; encoding = ENC_BIG_ENDIAN; expected_len = 3; break; case TLV_CRC16_STATUS: /* add the description */ tlv_value = tvb_get_guint8( tvb, offset ); proto_item_append_text(ti, ": %s", val_to_str(tlv_value, tlv_crc16_status, "Unknown")); hf = hf_m2m_value_crc16_status_uint8; encoding = ENC_BIG_ENDIAN; expected_len = 1; break; case TLV_BURST_POWER: /* add the description */ tlv_value = tvb_get_ntohs( tvb, offset ); proto_item_append_text(ti, ": %d", tlv_value); hf = hf_m2m_value_burst_power_uint16; encoding = ENC_BIG_ENDIAN; expected_len = 2; break; case TLV_BURST_CINR: /* add the description */ tlv_value = tvb_get_ntohs( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); hf = hf_m2m_value_burst_cinr_uint16; encoding = ENC_BIG_ENDIAN; expected_len = 2; break; case TLV_PREAMBLE: /* add the description */ tlv_value = tvb_get_ntohs( tvb, offset ); proto_item_append_text(ti, ": 0x%X", tlv_value); hf = hf_m2m_value_preamble_uint16; encoding = ENC_BIG_ENDIAN; expected_len = 2; break; case TLV_HARQ_ACK_BURST: /* display the Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the HARQ ACK Bursts */ harq_ack_bursts_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_value_harq_ack_burst_bytes; encoding = ENC_NA; break; case TLV_PHY_ATTRIBUTES: /* display the Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the PDU Burst Physical Attributes */ physical_attributes_decoder(tree, tvb, offset, tlv_len, pinfo); hf = hf_m2m_phy_attributes; encoding = ENC_NA; break; case TLV_EXTENDED_TLV: /* display the Burst length info */ proto_item_append_text(ti, " (%u bytes)", tlv_len); /* decode and display the Extended TLV */ extended_tlv_decoder(pinfo); break; default: /* update the info column */ col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", "Unknown TLV Type"); break; } /* expand the TLV detail */ if (hf) { if (offset - tlv_offset == expected_len) { proto_tree_add_tlv(&m2m_tlv_info, tvb, offset - tlv_offset, pinfo, tlv_tree, hf, encoding); } else { expert_add_info_format(pinfo, NULL, &ei_m2m_unexpected_length, "Expected length %d, got %d.", expected_len, offset - tlv_offset); } } offset += tlv_len; /* update tlv_count */ tlv_count--; } } }
/* Dissect a FEC header: * fec - ptr to the logical FEC packet representation to fill * hf - ptr to header fields array * ett - ptr to ett array * prefs - ptr to FEC prefs array * tvb - buffer * pinfo - packet info * tree - tree where to add FEC header subtree * offset - ptr to offset to use and update */ static int dissect_fec(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_item *ti; proto_tree *fec_tree; guint offset = 0; fec_data_exchange_t *fec = (fec_data_exchange_t*)data; guint8 encoding_id = 0; fec_packet_data_t *packet_data = (fec_packet_data_t*)p_get_proto_data(wmem_file_scope(), pinfo, proto_rmt_fec, 0); if (fec != NULL) { encoding_id = fec->encoding_id; } /* Create the FEC subtree */ ti = proto_tree_add_item(tree, proto_rmt_fec, tvb, offset, -1, ENC_NA); fec_tree = proto_item_add_subtree(ti, ett_main); proto_tree_add_uint(fec_tree, hf_encoding_id, tvb, offset, 0, encoding_id); if (encoding_id >= 128 && (packet_data != NULL)) proto_tree_add_uint(fec_tree, hf_instance_id, tvb, offset, 0, packet_data->instance_id); switch (encoding_id) { case 0: case 1: case 130: proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 2, ENC_BIG_ENDIAN); proto_tree_add_item(fec_tree, hf_esi, tvb, offset+2, 2, ENC_BIG_ENDIAN); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohs(tvb, offset)); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohs(tvb, offset+2)); offset += 4; break; case 2: case 128: case 132: proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(fec_tree, hf_esi, tvb, offset+4, 4, ENC_BIG_ENDIAN); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset)); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohl(tvb, offset+4)); offset += 8; break; case 3: case 4: proto_tree_add_item(fec_tree, hf_sbn_with_mask, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(fec_tree, hf_esi_with_mask, tvb, offset, 4, ENC_BIG_ENDIAN); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset) >> 20); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohl(tvb, offset) & 0xfffff); offset += 4; break; case 6: proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 1, ENC_BIG_ENDIAN); proto_tree_add_item(fec_tree, hf_esi, tvb, offset+1, 3, ENC_BIG_ENDIAN); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_guint8(tvb, offset)); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntoh24(tvb, offset+1)); offset += 4; break; case 129: proto_tree_add_item(fec_tree, hf_sbn, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(fec_tree, hf_sbl, tvb, offset+4, 2, ENC_BIG_ENDIAN); proto_tree_add_item(fec_tree, hf_esi, tvb, offset+6, 2, ENC_BIG_ENDIAN); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "SBN: %u", tvb_get_ntohl(tvb, offset)); col_append_sep_fstr(pinfo->cinfo, COL_INFO, " ", "ESI: 0x%X", tvb_get_ntohs(tvb, offset+6)); offset += 8; break; } return offset; }
static int dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset, guint16 msg_len ) { int key2; proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; key2 = tvb_get_ntohs(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (key2 == 1) { ssn = tvb_get_guint8(tvb, offset); proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t); mtp3_addr_dpc->pc = (guint32)tvb_get_ntoh24(tvb, offset); mtp3_addr_dpc->type = ITU_STANDARD; mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); if (msg_len%4) msg_len = msg_len + (4 - (msg_len%4)); offset += msg_len-1; return offset; } else if (key2 == 2) { proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN); /*dst_addr1 = (guint32 )tvb_get_ntoh24(tvb, offset);*/ mtp3_addr_dpc = wmem_new0(wmem_packet_scope(), mtp3_addr_pc_t); mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset); mtp3_addr_dpc->type = ITU_STANDARD; mtp3_addr_dpc->ni = 0; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); } else if (key2 == 3) { if (msg_len%4 == 0) { proto_tree_add_ipv4(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, tvb_get_ipv4(tvb, offset)); TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv4, tvb, offset, 4); COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst); } else { struct e_in6_addr value; tvb_get_ipv6(tvb, offset,&value); proto_tree_add_ipv6(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, (guint8*)&value); TVB_SET_ADDRESS(&pinfo->net_dst, AT_IPv6, tvb, offset, 6); COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst); } } else if (key2 == 4) { char *string; string = tvb_get_string(wmem_packet_scope(), tvb, offset, msg_len); proto_tree_add_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, string); TVB_SET_ADDRESS(&pinfo->net_dst, AT_STRINGZ, tvb, offset, msg_len); COPY_ADDRESS_SHALLOW(&pinfo->dst, &pinfo->net_dst); } if (msg_len%4) msg_len = msg_len+(4-(msg_len%4)); offset += msg_len; return offset; }
static void dissect_ieee802a(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *ieee802a_tree = NULL; proto_item *ti; tvbuff_t *next_tvb; guint32 oui; guint16 pid; oui_info_t *oui_info; dissector_table_t subdissector_table; int hf; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IEEE802a"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_ieee802a, tvb, 0, 5, ENC_NA); ieee802a_tree = proto_item_add_subtree(ti, ett_ieee802a); } oui = tvb_get_ntoh24(tvb, 0); pid = tvb_get_ntohs(tvb, 3); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "OUI 0x%06X (%s), PID 0x%04X", oui, val_to_str_const(oui, oui_vals, "Unknown"), pid); } if (tree) { proto_tree_add_uint(ieee802a_tree, hf_ieee802a_oui, tvb, 0, 3, oui); } /* * Do we have information for this OUI? */ if (oui_info_table != NULL && (oui_info = (oui_info_t *)g_hash_table_lookup(oui_info_table, GUINT_TO_POINTER(oui))) != NULL) { /* * Yes - use it. */ hf = *oui_info->field_info->p_id; subdissector_table = oui_info->table; } else { /* * No, use hf_ieee802a_pid for the PID and just dissect * the payload as data. */ hf = hf_ieee802a_pid; subdissector_table = NULL; } if (tree) proto_tree_add_uint(ieee802a_tree, hf, tvb, 3, 2, pid); next_tvb = tvb_new_subset_remaining(tvb, 5); if (subdissector_table != NULL) { /* do lookup with the subdissector table */ if (dissector_try_uint(subdissector_table, pid, next_tvb, pinfo, tree)) return; } call_dissector(data_handle, next_tvb, pinfo, tree); }
proto_tree *add_protocol_subtree(tlv_info_t *self, gint idx, proto_tree *tree, int hfindex, tvbuff_t *tvb, gint start, gint length _U_, const char *label) { /* Declare local variables */ proto_tree *tlv_tree; proto_item *tlv_item; gint tlv_value_length, tlv_val_offset; guint8 size_of_tlv_length_field; guint8 tlv_type; guint32 tlv_value; const gchar *hex_fmt; /* Make sure we're dealing with a valid TLV here */ if (get_tlv_type(self) < 0) return tree; /* Retrieve the necessary TLV information */ tlv_val_offset = get_tlv_value_offset(self); tlv_value_length = get_tlv_length(self); size_of_tlv_length_field = get_tlv_size_of_length(self); tlv_type = get_tlv_type(self); /* display the TLV name and display the value in hex. Highlight type, length, and value. */ tlv_item = proto_tree_add_protocol_format(tree, hfindex, tvb, start, tlv_value_length+tlv_val_offset, "%s (%u byte(s))", label, tlv_value_length); tlv_tree = proto_item_add_subtree(tlv_item, ett_tlv[tlv_type]); proto_tree_add_uint(tlv_tree, hf_tlv_type, tvb, start, 1, tlv_type); if (size_of_tlv_length_field > 0) /* It is */ { /* display the length of the length field TLV */ proto_tree_add_uint(tlv_tree, hf_tlv_length_size, tvb, start+1, 1, size_of_tlv_length_field); /* display the TLV length */ proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+2, size_of_tlv_length_field, tlv_value_length); } else { /* It is not */ /* display the TLV length */ proto_tree_add_uint(tlv_tree, hf_tlv_length, tvb, start+1, 1, tlv_value_length); } /* display the TLV value and make it a subtree */ switch (tlv_value_length) { case 1: tlv_value = tvb_get_guint8(tvb, start+tlv_val_offset); hex_fmt = tlv_val_1byte; break; case 2: tlv_value = tvb_get_ntohs(tvb, start+tlv_val_offset); hex_fmt = tlv_val_2byte; break; case 3: tlv_value = tvb_get_ntoh24(tvb, start+tlv_val_offset); hex_fmt = tlv_val_3byte; break; case 4: tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset); hex_fmt = tlv_val_4byte; break; default: tlv_value = tvb_get_ntohl(tvb, start+tlv_val_offset); hex_fmt = tlv_val_5byte; break; } /* Show "TLV value: " */ tlv_item = proto_tree_add_text(tlv_tree, tvb, start+tlv_val_offset, tlv_value_length, hex_fmt, label, tlv_value); tlv_tree = proto_item_add_subtree(tlv_item, idx); /* Return a pointer to the value level */ return tlv_tree; }