static void dissect_airopeek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *airopeek_tree = NULL; proto_item *ti; guint8 data_rate; guint8 signal_level; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "AiroPeek"); col_clear(pinfo->cinfo, COL_INFO); /* Dissect the header */ if (tree) { ti = proto_tree_add_item(tree, proto_airopeek, tvb, 0, 4, ENC_NA); airopeek_tree = proto_item_add_subtree(ti, ett_airopeek); } data_rate = tvb_get_guint8(tvb, 0); /* Add the radio information to the column information */ col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u", data_rate / 2, data_rate & 1 ? 5 : 0); if (tree) { proto_tree_add_uint64_format_value(airopeek_tree, hf_data_rate, tvb, 0, 1, (guint64)data_rate * 500000, "%u.%u Mb/s", data_rate / 2, data_rate & 1 ? 5 : 0); } if (tree) proto_tree_add_item(airopeek_tree, hf_channel, tvb, 1, 1, ENC_NA); signal_level = tvb_get_guint8(tvb, 2); /* * This is signal strength as a percentage of the maximum, i.e. * (RXVECTOR RSSI/RXVECTOR RSSI_Max)*100, or, at least, that's * what I infer it is, given what the WildPackets note "Converting * Signal Strength Percentage to dBm Values" says. * * It also says that the conversion the percentage to a dBm value is * an adapter-dependent process, so, as we don't know what type of * adapter was used to do the capture, we can't do the conversion. */ col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", signal_level); proto_tree_add_uint_format_value(airopeek_tree, hf_signal_strength, tvb, 2, 1, signal_level, "%u%%", signal_level); /* dissect the 802.11 header next */ pinfo->current_proto = "IEEE 802.11"; next_tvb = tvb_new_subset_remaining(tvb, 4); call_dissector(ieee80211_handle, next_tvb, pinfo, tree); }
/* * Dissect 802.11 with a variable-length link-layer header and a pseudo- * header containing radio information. */ static void dissect_radio (tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree) { proto_item *ti = NULL; proto_tree *radio_tree = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "Radio"); col_clear(pinfo->cinfo, COL_INFO); /* Add the radio information to the column information */ col_add_fstr(pinfo->cinfo, COL_TX_RATE, "%u.%u", pinfo->pseudo_header->ieee_802_11.data_rate / 2, pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0); /* * For tagged Peek files, this is presumably signal strength as a * percentage of the maximum, as it is for classic Peek files, * i.e. (RXVECTOR RSSI/RXVECTOR RSSI_Max)*100, or, at least, that's * what I infer it is, given what the WildPackets note "Converting * Signal Strength Percentage to dBm Values" says. * * It also says that the conversion the percentage to a dBm value is * an adapter-dependent process, so, as we don't know what type of * adapter was used to do the capture, we can't do the conversion. * * It's *probably* something similar for other capture file formats. */ col_add_fstr(pinfo->cinfo, COL_RSSI, "%u%%", pinfo->pseudo_header->ieee_802_11.signal_level); if (tree) { ti = proto_tree_add_item(tree, proto_radio, tvb, 0, 0, ENC_NA); radio_tree = proto_item_add_subtree (ti, ett_radio); proto_tree_add_uint64_format_value(radio_tree, hf_data_rate, tvb, 0, 0, (guint64)pinfo->pseudo_header->ieee_802_11.data_rate * 500000, "%u.%u Mb/s", pinfo->pseudo_header->ieee_802_11.data_rate / 2, pinfo->pseudo_header->ieee_802_11.data_rate & 1 ? 5 : 0); proto_tree_add_uint(radio_tree, hf_channel, tvb, 0, 0, pinfo->pseudo_header->ieee_802_11.channel); proto_tree_add_uint_format_value(radio_tree, hf_signal_strength, tvb, 0, 0, pinfo->pseudo_header->ieee_802_11.signal_level, "%u%%", pinfo->pseudo_header->ieee_802_11.signal_level); } /* dissect the 802.11 header next */ pinfo->current_proto = "IEEE 802.11"; call_dissector(ieee80211_handle, tvb, pinfo, tree); }
static int dissect_data_segment(proto_tree *ltp_tree, tvbuff_t *tvb,packet_info *pinfo,int frame_offset,int ltp_type, guint64 session_num) { guint64 client_id; guint64 data_offset; guint64 data_length; guint64 chkp_sno = 0; guint64 rpt_sno = 0; guint64 sda_client_id = 0; unsigned segment_size = 0; int sdnv_length; int sdnv_status; proto_tree *ltp_data_tree; proto_item *ti; fragment_head *frag_msg = NULL; gboolean more_frags = TRUE; tvbuff_t *new_tvb = NULL; /* Create a subtree for data segment and add the other fields under it */ ltp_data_tree = proto_tree_add_subtree(ltp_tree, tvb, frame_offset, tvb_captured_length_remaining(tvb, frame_offset), ett_data_segm, NULL, "Data Segment"); /* Client ID - 0 = Bundle Protocol, 1 = CCSDS LTP Service Data Aggregation */ sdnv_status = evaluate_sdnv64(tvb, frame_offset, &sdnv_length, &client_id); ti = proto_tree_add_uint64_format_value(ltp_data_tree, hf_ltp_data_clid, tvb, frame_offset, sdnv_length, client_id, "%" G_GINT64_MODIFIER "u (%s)", client_id, val_to_str_const((const guint32) client_id, client_service_id_info, "Invalid")); if (!sdnv_status) { expert_add_info(pinfo, ti, &ei_ltp_sdnv_length); return 0; } frame_offset += sdnv_length; segment_size += sdnv_length; /* data segment offset */ if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_offset, &data_offset, &ti)) > 0) { frame_offset += sdnv_length; segment_size += sdnv_length; } else { return 0; } /* data segment length */ if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_length, &data_length, &ti)) > 0) { frame_offset += sdnv_length; segment_size += sdnv_length; /* add in the data length also */ segment_size += (unsigned int) data_length; } else { return 0; } more_frags = FALSE; if (ltp_type != 0 && ltp_type < 4) { /* checkpoint serial number - 32 bits per CCSDS */ if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_chkp, &chkp_sno, &ti)) > 0) { frame_offset += sdnv_length; segment_size += sdnv_length; if (chkp_sno > 4294967295U) { /* just a warning - continue processing */ expert_add_info(pinfo, ti, &ei_ltp_sno_larger_than_ccsds); } } else { return 0; } /* report serial number - 32 bits per CCSDS */ if ((sdnv_length = add_sdnv64_to_tree(ltp_data_tree, tvb, pinfo, frame_offset, hf_ltp_data_rpt, &rpt_sno, &ti)) > 0) { frame_offset += sdnv_length; segment_size += sdnv_length; if (rpt_sno > 4294967295U) { /* just a warning - continue processing */ expert_add_info(pinfo, ti, &ei_ltp_sno_larger_than_ccsds); } } else { return 0; } } else if (ltp_type != 7) { more_frags = TRUE; } if (segment_size >= tvb_captured_length(tvb)) { /* did not capture the entire packet */ proto_tree_add_string(ltp_data_tree, hf_ltp_partial_packet, tvb, 0, 0, "<increase capture size?>"); return tvb_captured_length(tvb); } frag_msg = fragment_add_check(<p_reassembly_table, tvb, frame_offset, pinfo, (guint32)session_num, NULL, (guint32)data_offset, (guint32)data_length, more_frags); if(frag_msg) { /* Checking if the segment is completely reassembled */ if(!(frag_msg->flags & FD_PARTIAL_REASSEMBLY)) { /* if the segment has not been fragmented, then no reassembly is needed */ if(!more_frags && data_offset == 0) { new_tvb = tvb_new_subset_remaining(tvb, frame_offset); } else { new_tvb = process_reassembled_data(tvb, frame_offset, pinfo, "Reassembled LTP Segment", frag_msg, <p_frag_items,NULL, ltp_data_tree); } } } if(new_tvb) { int data_count = 1; int parse_length; int parse_offset = 0; parse_length = tvb_captured_length(new_tvb); while(parse_offset < parse_length) { int bundle_size; int sda_header_size; proto_tree *ltp_data_data_tree; tvbuff_t *datatvb; ltp_data_data_tree = proto_tree_add_subtree_format(ltp_data_tree, tvb,frame_offset, 0, ett_data_data_segm, NULL, "Data[%d]",data_count); sda_header_size = 0; if (client_id == 2) { sdnv_status = evaluate_sdnv64(tvb, frame_offset+parse_offset, &sdnv_length, &sda_client_id); ti = proto_tree_add_uint64_format_value(ltp_data_data_tree, hf_ltp_data_sda_clid, tvb, frame_offset+parse_offset, sdnv_length, sda_client_id, "%" G_GINT64_MODIFIER "u (%s)", sda_client_id, val_to_str_const((const guint32) sda_client_id, client_service_id_info, "Invalid")); if (!sdnv_status) { expert_add_info(pinfo, ti, &ei_ltp_sdnv_length); return 0; } sda_header_size = sdnv_length; parse_offset += sdnv_length; if (parse_offset == parse_length) { col_set_str(pinfo->cinfo, COL_INFO, "CCSDS LTP SDA Protocol Error"); return 0; /* Give up*/ } } datatvb = tvb_new_subset_length_caplen(new_tvb, parse_offset, (int)parse_length - parse_offset, tvb_captured_length(new_tvb)); bundle_size = call_dissector(bundle_handle, datatvb, pinfo, ltp_data_data_tree); if(bundle_size == 0) { /*Couldn't parse bundle*/ col_set_str(pinfo->cinfo, COL_INFO, "Dissection Failed"); return 0; /*Give up*/ } /* update the length of the data set */ proto_item_set_len(ltp_data_data_tree, bundle_size+sda_header_size); parse_offset += bundle_size; data_count++; } } else { if(frag_msg && more_frags) { col_append_frame_number(pinfo, COL_INFO, "[Reassembled in %d] ",frag_msg->reassembled_in); } else { col_append_str(pinfo->cinfo, COL_INFO, "[Unfinished LTP Segment] "); } } return segment_size; }
/* 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_tree = proto_tree_add_subtree(tree, tvb, svoff+0, 1, ett_tr_sv, &sv_item, "Subvector"); 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_BIG_ENDIAN); /* 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_BIG_ENDIAN); proto_item_append_text(sv_item, " (%s)", val_to_str_ext(sv_id, &subvector_vs_ext, "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_item(sv_tree, hf_trmac_beacon_type, tvb, svoff+2, sv_length-2, ENC_BIG_ENDIAN); 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, "%u ms", error_report_timer_value ); proto_item_append_text(sv_item, ": %u 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_uint_format_value(sv_tree, hf_trmac_response_code32, tvb, svoff+2, sv_length-2, tvb_get_ntohl(tvb, svoff+2), "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_uint64_format_value(sv_tree, hf_trmac_response_code48, tvb, svoff+2, sv_length-2, tvb_get_ntoh48(tvb, svoff+2), "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_item(sv_tree, hf_trmac_product_instance_id, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x23: /* Ring Station Version Number */ proto_tree_add_item(sv_tree, hf_trmac_ring_station_version_number, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x26: /* Wrap data */ proto_tree_add_item(sv_tree, hf_trmac_wrap_data, tvb, svoff+2, sv_length-2, ENC_NA); break; case 0x27: /* Frame Forward */ proto_tree_add_item(sv_tree, hf_trmac_frame_forward, tvb, svoff+2, sv_length-2, ENC_NA); 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_item(sv_tree, hf_trmac_ring_station_status, tvb, svoff+2, sv_length-2, ENC_NA); 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_item(sv_tree, hf_trmac_unknown_subvector, tvb, svoff+2, sv_length-2, ENC_NA); break; } return sv_length; }