/* * Add an Ethernet trailer - which, for some captures, might be the FCS * rather than a pad-to-60-bytes trailer. * * If fcs_len is 0, we assume the frame has no FCS; if it's 4, we assume * it has an FCS; if it's anything else (such as -1, which means "maybe * it does, maybe it doesn't"), we try to infer whether it has an FCS. */ void add_ethernet_trailer(packet_info *pinfo, proto_tree *tree, proto_tree *fh_tree, int trailer_id, tvbuff_t *tvb, tvbuff_t *trailer_tvb, int fcs_len) { /* If there're some bytes left over, it could be a combination of: - padding to meet the minimum 64 byte frame length - an FCS, if present (if fcs_len is 0, we know it's not present; if fcs_len is 4, we know it's present; if fcs_len is -1, we need some heuristics to determine whether it's present) - information inserted by TAPs or other network monitoring equipment. If we don't know whether the FCS is present, then, if we don't have a network monitoring trailer, and if the Ethernet frame was claimed to have had 64 or more bytes - i.e., it was at least an FCS worth of data longer than the minimum payload size - we could assume the last 4 bytes of the trailer are an FCS. */ proto_item *item; proto_tree *checksum_tree; if (trailer_tvb && fh_tree) { guint trailer_length, trailer_reported_length; guint padding_length = 0; gboolean has_fcs = FALSE; tvbuff_t *real_trailer_tvb; trailer_length = tvb_length(trailer_tvb); trailer_reported_length = tvb_reported_length(trailer_tvb); /* There can not have been padding when the length of the frame (including the trailer) is less than 60 bytes. */ if (eth_assume_padding && pinfo->fd->pkt_len>=60) { /* Calculate the amount of padding needed for a minimum sized frame */ if ( (pinfo->fd->pkt_len - trailer_reported_length) < 60 ) padding_length = 60 - (pinfo->fd->pkt_len - trailer_reported_length); /* Add the padding to the tree, unless it should be treated as part of the trailer and therefor be handed over to (one of) the ethernet-trailer dissectors */ if (padding_length > 0) { tvb_ensure_bytes_exist(tvb, 0, padding_length); proto_tree_add_item(fh_tree, hf_eth_padding, trailer_tvb, 0, padding_length, ENC_NA); trailer_length -= padding_length; trailer_reported_length -= padding_length; } } if (fcs_len != 0) { /* If fcs_len is 4, we assume we definitely have an FCS. Otherwise, then, if the frame is big enough that, if we have a trailer, it probably inclues an FCS, and we have enough space in the trailer for the FCS, we assume we have an FCS. "Big enough" means 64 bytes or more; any frame that big needs no trailer, as there's no need to pad an Ethernet packet past 60 bytes. The trailer must be at least 4 bytes long to have enough space for an FCS. */ if (fcs_len == 4 || (tvb_reported_length(tvb) >= 64 && trailer_reported_length >= 4)) { /* Either we know we have an FCS, or we believe we have an FCS. */ if (trailer_length < trailer_reported_length) { /* The packet is claimed to have enough data for a 4-byte FCS, but we didn't capture all of the packet. Slice off the 4-byte FCS from the reported length, and trim the captured length so it's no more than the reported length; that will slice off what of the FCS, if any, is in the captured packet. */ trailer_reported_length -= 4; if (trailer_length > trailer_reported_length) trailer_length = trailer_reported_length; has_fcs = TRUE; } else { /* We captured all of the packet, including what appears to be a 4-byte FCS. Slice it off. */ trailer_length -= 4; trailer_reported_length -= 4; has_fcs = TRUE; } } } /* Create a new tvb without the padding and/or the (assumed) fcs */ if (fcs_len==4) real_trailer_tvb = tvb_new_subset(trailer_tvb, padding_length, trailer_length, trailer_reported_length); else real_trailer_tvb = tvb_new_subset_remaining(trailer_tvb, padding_length); /* Call all ethernet trailer dissectors to dissect the trailer if we actually have a trailer. */ if (tvb_reported_length(real_trailer_tvb) != 0) { if (dissector_try_heuristic(eth_trailer_subdissector_list, real_trailer_tvb, pinfo, tree, NULL) ) { /* If we're not sure that there is a FCS, all trailer data has been given to the ethernet-trailer dissector, so stop dissecting here */ if (fcs_len!=4) return; } else { /* No luck with the trailer dissectors, so just display the extra bytes as general trailer */ if (trailer_length != 0) { tvb_ensure_bytes_exist(tvb, 0, trailer_length); proto_tree_add_item(fh_tree, trailer_id, real_trailer_tvb, 0, trailer_length, ENC_NA); } } } if (has_fcs) { guint32 sent_fcs = tvb_get_ntohl(trailer_tvb, padding_length+trailer_length); if(eth_check_fcs){ guint32 fcs = crc32_802_tvb(tvb, tvb_length(tvb) - 4); if (fcs == sent_fcs) { item = proto_tree_add_uint_format(fh_tree, hf_eth_fcs, trailer_tvb, padding_length+trailer_length, 4, sent_fcs, "Frame check sequence: 0x%08x [correct]", sent_fcs); checksum_tree = proto_item_add_subtree(item, ett_eth_fcs); item = proto_tree_add_boolean(checksum_tree, hf_eth_fcs_good, trailer_tvb, padding_length+trailer_length, 4, TRUE); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_boolean(checksum_tree, hf_eth_fcs_bad, trailer_tvb, padding_length+trailer_length, 4, FALSE); PROTO_ITEM_SET_GENERATED(item); } else { item = proto_tree_add_uint_format(fh_tree, hf_eth_fcs, trailer_tvb, padding_length+trailer_length, 4, sent_fcs, "Frame check sequence: 0x%08x [incorrect, should be 0x%08x]", sent_fcs, fcs); checksum_tree = proto_item_add_subtree(item, ett_eth_fcs); item = proto_tree_add_boolean(checksum_tree, hf_eth_fcs_good, trailer_tvb, padding_length+trailer_length, 4, FALSE); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_boolean(checksum_tree, hf_eth_fcs_bad, trailer_tvb, padding_length+trailer_length, 4, TRUE); PROTO_ITEM_SET_GENERATED(item); expert_add_info(pinfo, item, &ei_eth_fcs_bad); col_append_str(pinfo->cinfo, COL_INFO, " [ETHERNET FRAME CHECK SEQUENCE INCORRECT]"); } }else{ item = proto_tree_add_uint_format(fh_tree, hf_eth_fcs, trailer_tvb, padding_length+trailer_length, 4, sent_fcs, "Frame check sequence: 0x%08x [validiation disabled]", sent_fcs); checksum_tree = proto_item_add_subtree(item, ett_eth_fcs); item = proto_tree_add_boolean(checksum_tree, hf_eth_fcs_good, trailer_tvb, padding_length+trailer_length, 4, FALSE); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_boolean(checksum_tree, hf_eth_fcs_bad, trailer_tvb, padding_length+trailer_length, 4, FALSE); PROTO_ITEM_SET_GENERATED(item); } trailer_length += 4; } proto_tree_set_appendix(fh_tree, tvb, tvb_length(tvb) - padding_length - trailer_length, padding_length + trailer_length); } }
col_set_str(pinfo->cinfo, COL_INFO, "Continuation"); if (tree) { proto_tree_add_item(tree, proto_tuxedo, tvb, 0, -1, ENC_NA); } } } } static gboolean dissect_tuxedo_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { if (tvb_captured_length(tvb) >= 8) { guint32 magic; magic = tvb_get_ntohl(tvb, 0); if (magic == TUXEDO_MAGIC || magic == TUXEDO_SMAGIC) { /* Register this dissector for this conversation */ conversation_t *conversation = NULL; conversation = find_or_create_conversation(pinfo); conversation_set_dissector(conversation, tuxedo_handle); dissect_tuxedo(tvb, pinfo, tree); return TRUE; } } return FALSE; } void
/* the UUID is the same as a GlusterFS GFID, except it's encoded per byte */ static int gluster_gd_mgmt_dissect_uuid(tvbuff_t *tvb, proto_tree *tree, int hfindex, int offset) { if (tree) { e_guid_t uuid; int start_offset = offset; uuid.data1 = (tvb_get_ntohl(tvb, offset) & 0xff) << 24 | (tvb_get_ntohl(tvb, offset+4) & 0xff) << 16 | (tvb_get_ntohl(tvb, offset+8) & 0xff) << 8 | (tvb_get_ntohl(tvb, offset+12) & 0xff); offset += 16; uuid.data2 = (tvb_get_ntohl(tvb, offset) & 0xff) << 8 | (tvb_get_ntohl(tvb, offset+4) & 0xff); offset += 8; uuid.data3 = (tvb_get_ntohl(tvb, offset) & 0xff) << 8 | (tvb_get_ntohl(tvb, offset+4) & 0xff); offset += 8; uuid.data4[0] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[1] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[2] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[3] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[4] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[5] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[6] = tvb_get_ntohl(tvb, offset); offset += 4; uuid.data4[7] = tvb_get_ntohl(tvb, offset); offset += 4; proto_tree_add_guid(tree, hfindex, tvb, start_offset, 4*16, &uuid); } else offset += 16 * 4; return offset; }
static void dissect_pgsql_fe_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree, pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; char *s; proto_tree *shrub; switch (type) { /* Password */ case 'p': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_passwd, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Simple query */ case 'Q': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Parse */ case 'P': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_query, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Bind */ case 'B': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_statement, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Result formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Execute */ case 'E': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_portal, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; i = tvb_get_ntohl(tvb, n); if (i == 0) proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "all rows"); else proto_tree_add_uint_format_value(tree, hf_return, tvb, n, 4, i, "%d rows", i); break; /* Describe, Close */ case 'D': case 'C': c = tvb_get_guint8(tvb, n); if (c == 'P') i = hf_portal; else i = hf_statement; n += 1; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, i, tvb, n, siz, s); break; /* Messages without a type identifier */ case '\0': i = tvb_get_ntohl(tvb, n); n += 4; length -= n; switch (i) { /* Startup message */ case 196608: while ((signed)length > 0) { siz = tvb_strsize(tvb, n); length -= siz; if ((signed)length <= 0) { break; } proto_tree_add_item(tree, hf_parameter_name, tvb, n, siz, ENC_ASCII|ENC_NA); i = tvb_strsize(tvb, n+siz); proto_tree_add_item(tree, hf_parameter_value, tvb, n + siz, i, ENC_ASCII|ENC_NA); length -= i; n += siz+i; if (length == 1 && tvb_get_guint8(tvb, n) == 0) break; } break; /* SSL request */ case 80877103: /* Next reply will be a single byte. */ conv_data->ssl_requested = TRUE; break; /* Cancellation request */ case 80877102: proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Copy failure */ case 'f': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_error, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Function call */ case 'F': proto_tree_add_item(tree, hf_oid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter formats: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameter values: %d", i); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_item(shrub, hf_val_length, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } proto_tree_add_item(tree, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); break; } }
static void dissect_ipxwan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *ipxwan_tree = NULL; int offset = 0; guint8 packet_type; guint8 num_options; guint8 option_number; proto_tree *option_tree; guint16 option_data_len; guint16 wan_link_delay; guint32 delay; guint32 throughput; guint32 delta_time; guint8 compression_type; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPX WAN"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_ipxwan, tvb, 0, -1, FALSE); ipxwan_tree = proto_item_add_subtree(ti, ett_ipxwan); } if (tree) { proto_tree_add_item(ipxwan_tree, hf_ipxwan_identifier, tvb, offset, 4, FALSE); } offset += 4; packet_type = tvb_get_guint8(tvb, offset); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, ipxwan_packet_type_vals, "Unknown packet type %u")); } if (tree) { proto_tree_add_uint(ipxwan_tree, hf_ipxwan_packet_type, tvb, offset, 1, packet_type); offset += 1; proto_tree_add_item(ipxwan_tree, hf_ipxwan_node_id, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ipxwan_tree, hf_ipxwan_sequence_number, tvb, offset, 1, FALSE); offset += 1; num_options = tvb_get_guint8(tvb, offset); proto_tree_add_uint(ipxwan_tree, hf_ipxwan_num_options, tvb, offset, 1, num_options); offset += 1; while (num_options != 0) { option_number = tvb_get_guint8(tvb, offset); ti = proto_tree_add_text(ipxwan_tree, tvb, offset, -1, "Option: %s", val_to_str(option_number, ipxwan_option_num_vals, "Unknown (%u)")); option_tree = proto_item_add_subtree(ti, ett_ipxwan_option); proto_tree_add_uint(option_tree, hf_ipxwan_option_num, tvb, offset, 1, option_number); offset += 1; proto_tree_add_item(option_tree, hf_ipxwan_accept_option, tvb, offset, 1, FALSE); offset += 1; option_data_len = tvb_get_ntohs(tvb, offset); proto_tree_add_uint(option_tree, hf_ipxwan_option_data_len, tvb, offset, 2, option_data_len); offset += 2; proto_item_set_len(ti, option_data_len+4); switch (option_number) { case OPT_ROUTING_TYPE: if (option_data_len != 1) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 1", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_routing_type, tvb, offset, 1, FALSE); } break; case OPT_RIP_SAP_INFO_EXCHANGE: if (option_data_len != 54) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 54", option_data_len); } else { wan_link_delay = tvb_get_ntohs(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_wan_link_delay, tvb, offset, 2, wan_link_delay, "WAN Link Delay: %ums", wan_link_delay); proto_tree_add_item(option_tree, hf_ipxwan_common_network_number, tvb, offset+2, 4, FALSE); proto_tree_add_item(option_tree, hf_ipxwan_router_name, tvb, offset+6, 48, FALSE); } break; case OPT_NLSP_INFORMATION: if (option_data_len != 8) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 8", option_data_len); } else { delay = tvb_get_ntohl(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_delay, tvb, offset, 4, delay, "Delay: %uus", delay); throughput = tvb_get_ntohl(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_throughput, tvb, offset, 4, throughput, "Throughput: %uus", throughput); } break; case OPT_NLSP_RAW_THROUGHPUT_DATA: if (option_data_len != 8) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 8", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_request_size, tvb, offset, 4, FALSE); delta_time = tvb_get_ntohl(tvb, offset); proto_tree_add_uint_format(option_tree, hf_ipxwan_delta_time, tvb, offset, 4, delta_time, "Delta Time: %uus", delta_time); } break; case OPT_EXTENDED_NODE_ID: if (option_data_len != 4) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 4", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_extended_node_id, tvb, offset, 4, FALSE); } break; case OPT_NODE_NUMBER: if (option_data_len != 6) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be 6", option_data_len); } else { proto_tree_add_item(option_tree, hf_ipxwan_node_number, tvb, offset, 6, FALSE); } break; case OPT_COMPRESSION: if (option_data_len < 1) { proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Bogus length: %u, should be >= 1", option_data_len); } else { compression_type = tvb_get_guint8(tvb, offset); proto_tree_add_uint(option_tree, hf_ipxwan_compression_type, tvb, offset, 1, compression_type); switch (compression_type) { case COMP_TYPE_TELEBIT: if (option_data_len < 3) { proto_tree_add_text(option_tree, tvb, offset+1, option_data_len-1, "Bogus length: %u, should be >= 3", option_data_len); } else { proto_tree_add_text( option_tree, tvb, offset+1, 1, "Compression options: 0x%02x", tvb_get_guint8(tvb, offset+1)); proto_tree_add_text( option_tree, tvb, offset+2, 1, "Number of compression slots: %u", tvb_get_guint8(tvb, offset+2)); } break; default: proto_tree_add_text(option_tree, tvb, offset+1, option_data_len-1, "Option parameters"); break; } } break; case OPT_PAD: proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Padding"); break; default: proto_tree_add_text(option_tree, tvb, offset, option_data_len, "Option value"); break; } offset += option_data_len; num_options--; } } }
static void dissect_nbd_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree) { guint32 magic, error, packet; guint32 handle[2]; guint64 from; int offset=0; proto_tree *tree=NULL; proto_item *item=NULL; conversation_t *conversation; nbd_conv_info_t *nbd_info; nbd_transaction_t *nbd_trans=NULL; emem_tree_key_t hkey[3]; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBD"); col_clear(pinfo->cinfo, COL_INFO); item = proto_tree_add_item(parent_tree, proto_nbd, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_nbd); magic=tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_nbd_magic, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; /* grab what we need to do the request/response matching */ switch(magic){ case NBD_REQUEST_MAGIC: case NBD_RESPONSE_MAGIC: handle[0]=tvb_get_ntohl(tvb, offset+4); handle[1]=tvb_get_ntohl(tvb, offset+8); break; default: return; } conversation = find_or_create_conversation(pinfo); /* * Do we already have a state structure for this conv */ nbd_info = conversation_get_proto_data(conversation, proto_nbd); if (!nbd_info) { /* No. Attach that information to the conversation, and add * it to the list of information structures. */ nbd_info = se_alloc(sizeof(nbd_conv_info_t)); nbd_info->unacked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_unacked_pdus"); nbd_info->acked_pdus=se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "nbd_acked_pdus"); conversation_add_proto_data(conversation, proto_nbd, nbd_info); } if(!pinfo->fd->flags.visited){ if(magic==NBD_REQUEST_MAGIC){ /* This is a request */ nbd_trans=se_alloc(sizeof(nbd_transaction_t)); nbd_trans->req_frame=pinfo->fd->num; nbd_trans->rep_frame=0; nbd_trans->req_time=pinfo->fd->abs_ts; nbd_trans->type=tvb_get_ntohl(tvb, offset); nbd_trans->datalen=tvb_get_ntohl(tvb, offset+20); hkey[0].length=2; hkey[0].key=handle; hkey[1].length=0; se_tree_insert32_array(nbd_info->unacked_pdus, hkey, (void *)nbd_trans); } else if(magic==NBD_RESPONSE_MAGIC){ hkey[0].length=2; hkey[0].key=handle; hkey[1].length=0; nbd_trans=se_tree_lookup32_array(nbd_info->unacked_pdus, hkey); if(nbd_trans){ nbd_trans->rep_frame=pinfo->fd->num; hkey[0].length=1; hkey[0].key=&nbd_trans->rep_frame; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans); hkey[0].length=1; hkey[0].key=&nbd_trans->req_frame; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; se_tree_insert32_array(nbd_info->acked_pdus, hkey, (void *)nbd_trans); } } } else { packet=pinfo->fd->num; hkey[0].length=1; hkey[0].key=&packet; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; nbd_trans=se_tree_lookup32_array(nbd_info->acked_pdus, hkey); } /* The bloody handles are reused !!! eventhough they are 64 bits. * So we must verify we got the "correct" one */ if( (magic==NBD_RESPONSE_MAGIC) && (nbd_trans) && (pinfo->fd->num<nbd_trans->req_frame) ){ /* must have been the wrong one */ nbd_trans=NULL; } if(!nbd_trans){ /* create a "fake" nbd_trans structure */ nbd_trans=ep_alloc(sizeof(nbd_transaction_t)); nbd_trans->req_frame=0; nbd_trans->rep_frame=0; nbd_trans->req_time=pinfo->fd->abs_ts; nbd_trans->type=0xff; nbd_trans->datalen=0; } /* print state tracking in the tree */ if(magic==NBD_REQUEST_MAGIC){ /* This is a request */ if(nbd_trans->rep_frame){ proto_item *it; it=proto_tree_add_uint(tree, hf_nbd_response_in, tvb, 0, 0, nbd_trans->rep_frame); PROTO_ITEM_SET_GENERATED(it); } } else if(magic==NBD_RESPONSE_MAGIC){ /* This is a reply */ if(nbd_trans->req_frame){ proto_item *it; nstime_t ns; it=proto_tree_add_uint(tree, hf_nbd_response_to, tvb, 0, 0, nbd_trans->req_frame); PROTO_ITEM_SET_GENERATED(it); nstime_delta(&ns, &pinfo->fd->abs_ts, &nbd_trans->req_time); it=proto_tree_add_time(tree, hf_nbd_time, tvb, 0, 0, &ns); PROTO_ITEM_SET_GENERATED(it); } } switch(magic){ case NBD_REQUEST_MAGIC: proto_tree_add_item(tree, hf_nbd_type, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; from=tvb_get_ntoh64(tvb, offset); proto_tree_add_item(tree, hf_nbd_from, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; proto_tree_add_item(tree, hf_nbd_len, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; if(check_col(pinfo->cinfo, COL_INFO)){ switch(nbd_trans->type){ case NBD_CMD_WRITE: col_add_fstr(pinfo->cinfo, COL_INFO, "Write Request Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen); break; case NBD_CMD_READ: col_add_fstr(pinfo->cinfo, COL_INFO, "Read Request Offset:0x%" G_GINT64_MODIFIER "x Length:%d", from, nbd_trans->datalen); break; case NBD_CMD_DISC: col_set_str(pinfo->cinfo, COL_INFO, "Disconnect Request"); break; } } if(nbd_trans->type==NBD_CMD_WRITE){ proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA); } break; case NBD_RESPONSE_MAGIC: item=proto_tree_add_uint(tree, hf_nbd_type, tvb, 0, 0, nbd_trans->type); PROTO_ITEM_SET_GENERATED(item); error=tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_nbd_error, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; proto_tree_add_item(tree, hf_nbd_handle, tvb, offset, 8, ENC_BIG_ENDIAN); offset+=8; if(check_col(pinfo->cinfo, COL_INFO)){ col_add_fstr(pinfo->cinfo, COL_INFO, "%s Response Error:%d", (nbd_trans->type==NBD_CMD_WRITE)?"Write":"Read", error); } if(nbd_trans->type==NBD_CMD_READ){ proto_tree_add_item(tree, hf_nbd_data, tvb, offset, nbd_trans->datalen, ENC_NA); } break; } return; }
static void dissect_pw_cesopsn( tvbuff_t * tvb_original ,packet_info * pinfo ,proto_tree * tree ,pwc_demux_type_t demux) { const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/ gint packet_size; gint payload_size; gint padding_size; int properties; packet_size = tvb_reported_length_remaining(tvb_original, 0); /* * FIXME * "4" below should be replaced by something like "min_packet_size_this_dissector" * Also call to dissect_try_cw_first_nibble() should be moved before this block */ if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */ { proto_item *item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); expert_add_info_format(pinfo, item, &ei_packet_size_too_small, "PW packet size (%d) is too small to carry sensible information" ,(int)packet_size); col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small"); return; } switch (demux) { case PWC_DEMUX_MPLS: if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree)) { return; } break; case PWC_DEMUX_UDP: break; default: DISSECTOR_ASSERT_NOT_REACHED(); return; } /* check how "good" is this packet */ /* also decide payload length from packet size and CW */ properties = PWC_PACKET_PROPERTIES_T_INITIALIZER; if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/)) { properties |= PWC_CW_BAD_BITS03; } if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/)) { properties |= PWC_CW_BAD_FRAG; } { /* RFC5086: * [LEN (bits (10 to 15) MAY be used to carry the length of the CESoPSN * packet (defined as the size of the CESoPSN header + the payload size) * if it is less than 64 bytes, and MUST be set to zero otherwise. * Note: If fixed RTP header is used in the encapsulation, it is * considered part of the CESoPSN header.] * * Note that this differs from RFC4385's definition of length: * [ If the MPLS payload is less than 64 bytes, the length field * MUST be set to the length of the PW payload...] * * We will use RFC5086's definition here. */ int cw_len; gint payload_size_from_packet; cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f; payload_size_from_packet = packet_size - encaps_size; if (cw_len != 0) { gint payload_size_from_cw; payload_size_from_cw = cw_len - encaps_size; /* * Assumptions for error case, * will be overwritten if no errors found: */ payload_size = payload_size_from_packet; padding_size = 0; if (payload_size_from_cw < 0) { properties |= PWC_CW_BAD_PAYLEN_LT_0; } else if (payload_size_from_cw > payload_size_from_packet) { properties |= PWC_CW_BAD_PAYLEN_GT_PACKET; } else if (payload_size_from_packet >= 64) { properties |= PWC_CW_BAD_LEN_MUST_BE_0; } else /* ok */ { payload_size = payload_size_from_cw; padding_size = payload_size_from_packet - payload_size_from_cw; /* >=0 */ } } else { payload_size = payload_size_from_packet; padding_size = 0; } } { guint8 cw_lm; cw_lm = tvb_get_guint8(tvb_original, 0) & 0x0b /*l+mod*/; if (NULL == try_val_to_str(cw_lm, vals_cw_lm)) { properties |= PWC_CW_SUSPECT_LM; } { guint8 l_bit, m_bits; l_bit = (cw_lm & 0x08) >> 3; m_bits = (cw_lm & 0x03) >> 0; if ((l_bit == 0 && m_bits == 0x0) /*CESoPSN data packet - normal situation*/ ||(l_bit == 0 && m_bits == 0x2) /*CESoPSN data packet - RDI on the AC*/ ) { if ((payload_size == 0) || ((payload_size % 8) != 0)) { properties |= PWC_PAY_SIZE_BAD; } } else if (l_bit == 1 && m_bits == 0x0) /*TDM data is invalid; payload MAY be omitted*/ { /*allow any size of payload*/ } else /*reserved combinations*/ { /*allow any size of payload*/ } } } /* fill up columns*/ col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname); col_clear(pinfo->cinfo, COL_INFO); if (properties & PWC_ANYOF_CW_BAD) { col_set_str(pinfo->cinfo, COL_INFO, "CW:Bad, "); } else if (properties & PWC_ANYOF_CW_SUSPECT) { col_append_str(pinfo->cinfo, COL_INFO, "CW:Suspect, "); } if (properties & PWC_PAY_SIZE_BAD) { col_append_str(pinfo->cinfo, COL_INFO, "Payload size:Bad, "); } col_append_fstr(pinfo->cinfo, COL_INFO, "TDM octets:%d", (int)payload_size); if (padding_size != 0) { col_append_fstr(pinfo->cinfo, COL_INFO, ", Padding:%d", (int)padding_size); } { proto_item* item; item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA); pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE); pwc_item_append_text_n_items(item,(int)payload_size,"octet"); { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; proto_item* item2; tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW); item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA); pwc_item_append_cw(item2,tvb_get_ntohl(tvb, 0),FALSE); { proto_tree* tree3; tree3 = proto_item_add_subtree(item, ett); { proto_item* item3; if (properties & PWC_CW_BAD_BITS03) /*display only if value is wrong*/ { item3 = proto_tree_add_item(tree3, hf_cw_bits03, tvb, 0, 1, ENC_BIG_ENDIAN); expert_add_info(pinfo, item3, &ei_cw_bits03); } item3 = proto_tree_add_item(tree3, hf_cw_lm, tvb, 0, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_SUSPECT_LM) { expert_add_info(pinfo, item3, &ei_cw_lm); } proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN); item3 = proto_tree_add_item(tree3, hf_cw_frg, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_FRAG) { expert_add_info(pinfo, item3, &ei_cw_frg); } item3 = proto_tree_add_item(tree3, hf_cw_len, tvb, 1, 1, ENC_BIG_ENDIAN); if (properties & PWC_CW_BAD_PAYLEN_LT_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: too small, must be > %d", (int)encaps_size); } if (properties & PWC_CW_BAD_PAYLEN_GT_PACKET) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be <= than PSN packet size (%d)", (int)packet_size); } if (properties & PWC_CW_BAD_LEN_MUST_BE_0) { expert_add_info_format(pinfo, item3, &ei_pref_cw_len, "Bad Length: must be 0 if CESoPSN packet size (%d) is > 64", (int)packet_size); } proto_tree_add_item(tree3, hf_cw_seq, tvb, 2, 2, ENC_BIG_ENDIAN); } } } } /* payload */ if (payload_size == 0) { if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_error, "CESoPSN payload: none found. Size of payload must be <> 0"); } else { expert_add_info_format(pinfo, item, &ei_payload_size_invalid_undecoded, "CESoPSN payload: omitted to conserve bandwidth"); } } else { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { proto_item* item2; tvbuff_t* tvb; tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size); item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA); pwc_item_append_text_n_items(item2,(int)payload_size,"octet"); if (properties & PWC_PAY_SIZE_BAD) { expert_add_info_format(pinfo, item2, &ei_payload_size_invalid_error, "CESoPSN packet payload size must be multiple of 8"); } tree2 = proto_item_add_subtree(item2, ett); call_data_dissector(tvb, pinfo, tree2); item2 = proto_tree_add_int(tree2, hf_payload_l, tvb, 0, 0 ,(int)payload_size); /* allow filtering */ PROTO_ITEM_SET_HIDDEN(item2); } } /* padding */ if (padding_size > 0) { proto_tree* tree2; tree2 = proto_item_add_subtree(item, ett); { tvbuff_t* tvb; tvb = tvb_new_subset(tvb_original, PWC_SIZEOF_CW + payload_size, padding_size, -1); call_dissector(pw_padding_handle, tvb, pinfo, tree2); } } } return; }
static void dissect_llrp_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 type, guint offset) { guint8 requested_data; guint16 antenna_id, gpi_port, gpo_port; guint32 spec_id; proto_item *ti; switch (type) { /* Simple cases just have normal TLV or TV parameters */ case LLRP_TYPE_CLOSE_CONNECTION_RESPONSE: case LLRP_TYPE_GET_READER_CAPABILITES_RESPONSE: case LLRP_TYPE_ADD_ROSPEC: case LLRP_TYPE_ADD_ROSPEC_RESPONSE: case LLRP_TYPE_DELETE_ROSPEC_RESPONSE: case LLRP_TYPE_START_ROSPEC_RESPONSE: case LLRP_TYPE_STOP_ROSPEC_RESPONSE: case LLRP_TYPE_ENABLE_ROSPEC_RESPONSE: case LLRP_TYPE_DISABLE_ROSPEC_RESPONSE: case LLRP_TYPE_GET_ROSPECS_RESPONSE: case LLRP_TYPE_ADD_ACCESSSPEC: case LLRP_TYPE_ADD_ACCESSSPEC_RESPONSE: case LLRP_TYPE_DELETE_ACCESSSPEC_RESPONSE: case LLRP_TYPE_ENABLE_ACCESSSPEC_RESPONSE: case LLRP_TYPE_DISABLE_ACCESSSPEC_RESPONSE: case LLRP_TYPE_GET_ACCESSSPECS: case LLRP_TYPE_CLIENT_REQUEST_OP: case LLRP_TYPE_CLIENT_RESQUEST_OP_RESPONSE: case LLRP_TYPE_RO_ACCESS_REPORT: case LLRP_TYPE_READER_EVENT_NOTIFICATION: case LLRP_TYPE_ERROR_MESSAGE: case LLRP_TYPE_GET_READER_CONFIG_RESPONSE: case LLRP_TYPE_SET_READER_CONFIG_RESPONSE: case LLRP_TYPE_SET_PROTOCOL_VERSION_RESPONSE: case LLRP_TYPE_GET_ACCESSSPECS_RESPONSE: case LLRP_TYPE_GET_REPORT: case LLRP_TYPE_ENABLE_EVENTS_AND_REPORTS: dissect_llrp_parameters(tvb, pinfo, tree, offset); break; /* Some just have an ROSpec ID */ case LLRP_TYPE_START_ROSPEC: case LLRP_TYPE_STOP_ROSPEC: case LLRP_TYPE_ENABLE_ROSPEC: case LLRP_TYPE_DISABLE_ROSPEC: case LLRP_TYPE_DELETE_ROSPEC: spec_id = tvb_get_ntohl(tvb, offset); if (spec_id == LLRP_ROSPEC_ALL) proto_tree_add_uint_format(tree, hf_llrp_rospec, tvb, offset, 4, spec_id, "All ROSpecs (%u)", spec_id); else proto_tree_add_item(tree, hf_llrp_rospec, tvb, offset, 4, ENC_BIG_ENDIAN); break; /* Some just have an AccessSpec ID */ case LLRP_TYPE_ENABLE_ACCESSSPEC: case LLRP_TYPE_DELETE_ACCESSSPEC: case LLRP_TYPE_DISABLE_ACCESSSPEC: spec_id = tvb_get_ntohl(tvb, offset); if (spec_id == LLRP_ACCESSSPEC_ALL) proto_tree_add_uint_format(tree, hf_llrp_accessspec, tvb, offset, 4, spec_id, "All Access Specs (%u)", spec_id); else proto_tree_add_item(tree, hf_llrp_accessspec, tvb, offset, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_llrp_accessspec, tvb, offset, 4, ENC_BIG_ENDIAN); break; case LLRP_TYPE_GET_READER_CAPABILITES: proto_tree_add_item(tree, hf_llrp_req_cap, tvb, offset, 1, ENC_NA); offset++; dissect_llrp_parameters(tvb, pinfo, tree, offset); break; /* GET_READER_CONFIG is complicated */ case LLRP_TYPE_GET_READER_CONFIG: requested_data = tvb_get_guint8(tvb, offset + 2); switch (requested_data) { case LLRP_CONF_ALL: antenna_id = tvb_get_ntohs(tvb, offset); if (antenna_id == LLRP_ANTENNA_ALL) proto_tree_add_uint_format(tree, hf_llrp_antenna_id, tvb, offset, 2, antenna_id, "All Antennas (%u)", antenna_id); else proto_tree_add_item(tree, hf_llrp_antenna_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_llrp_req_conf, tvb, offset, 1, ENC_NA); offset++; gpi_port = tvb_get_ntohs(tvb, offset); if (gpi_port == LLRP_GPI_PORT_ALL) proto_tree_add_uint_format(tree, hf_llrp_gpi_port, tvb, offset, 2, gpi_port, "All GPI Ports (%u)", gpi_port); else proto_tree_add_item(tree, hf_llrp_gpi_port, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; gpo_port = tvb_get_ntohs(tvb, offset); if (gpo_port == LLRP_GPO_PORT_ALL) proto_tree_add_uint_format(tree, hf_llrp_gpo_port, tvb, offset, 2, gpo_port, "All GPO Ports (%u)", gpo_port); else proto_tree_add_item(tree, hf_llrp_gpo_port, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; break; case LLRP_CONF_ANTENNA_PROPERTIES: case LLRP_CONF_ANTENNA_CONFIGURATION: antenna_id = tvb_get_ntohs(tvb, offset); if (antenna_id == LLRP_ANTENNA_ALL) proto_tree_add_uint_format(tree, hf_llrp_antenna_id, tvb, offset, 2, antenna_id, "All Antennas (%u)", antenna_id); else proto_tree_add_item(tree, hf_llrp_antenna_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_llrp_req_conf, tvb, offset, 1, ENC_NA); offset++; offset += 4; /* Skip both GPI and GPO ports */ break; case LLRP_CONF_IDENTIFICATION: case LLRP_CONF_RO_REPORT_SPEC: case LLRP_CONF_READER_EVENT_NOTIFICATION_SPEC: case LLRP_CONF_ACCESS_REPORT_SPEC: case LLRP_CONF_LLRP_CONFIGURATION_STATE: case LLRP_CONF_KEEPALIVE_SPEC: case LLRP_CONF_EVENTS_AND_REPORTS: offset += 2; /* Skip antenna ID */ proto_tree_add_item(tree, hf_llrp_req_conf, tvb, offset, 1, ENC_NA); offset++; offset += 4; /* Skip both GPI and GPO ports */ break; case LLRP_CONF_GPI_PORT_CURRENT_STATE: offset += 2; /* Skip antenna ID */ proto_tree_add_item(tree, hf_llrp_req_conf, tvb, offset, 1, ENC_NA); offset++; gpi_port = tvb_get_ntohs(tvb, offset); if (gpi_port == LLRP_GPI_PORT_ALL) proto_tree_add_uint_format(tree, hf_llrp_gpi_port, tvb, offset, 2, gpi_port, "All GPI Ports (%u)", gpi_port); else proto_tree_add_item(tree, hf_llrp_gpi_port, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; offset += 2; /* Skip GPO Port */ break; case LLRP_CONF_GPO_WRITE_DATA: offset += 2; /* Skip antenna ID */ proto_tree_add_item(tree, hf_llrp_req_conf, tvb, offset, 1, ENC_NA); offset++; offset += 2; /* Skip GPI Port */ gpo_port = tvb_get_ntohs(tvb, offset); if (gpo_port == LLRP_GPO_PORT_ALL) proto_tree_add_uint_format(tree, hf_llrp_gpo_port, tvb, offset, 2, gpo_port, "All GPO Ports (%u)", gpo_port); else proto_tree_add_item(tree, hf_llrp_gpo_port, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; break; default: offset += 2; /* Skip antenna ID */ ti = proto_tree_add_item(tree, hf_llrp_req_conf, tvb, offset, 1, ENC_NA); expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR, "Unrecognized configuration request: %u", requested_data); offset++; offset += 4; /* Skip both GPI and GPO ports */ break; }; dissect_llrp_parameters(tvb, pinfo, tree, offset); break; /* END GET_READER_CONFIG */ /* Misc */ case LLRP_TYPE_SET_READER_CONFIG: proto_tree_add_item(tree, hf_llrp_rest_fact, tvb, offset, 1, ENC_NA); offset++; dissect_llrp_parameters(tvb, pinfo, tree, offset); break; case LLRP_TYPE_SET_PROTOCOL_VERSION: proto_tree_add_item(tree, hf_llrp_version, tvb, offset, 1, ENC_NA); break; case LLRP_TYPE_GET_SUPPORTED_VERSION_RESPONSE: proto_tree_add_item(tree, hf_llrp_cur_ver, tvb, offset, 1, ENC_NA); offset++; proto_tree_add_item(tree, hf_llrp_sup_ver, tvb, offset, 1, ENC_NA); offset++; dissect_llrp_parameters(tvb, pinfo, tree, offset); break; case LLRP_TYPE_CUSTOM_MESSAGE: proto_tree_add_item(tree, hf_llrp_vendor, tvb, offset, 4, ENC_BIG_ENDIAN); break; /* Some have no extra data expected */ case LLRP_TYPE_KEEPALIVE: case LLRP_TYPE_KEEPALIVE_ACK: case LLRP_TYPE_CLOSE_CONNECTION: case LLRP_TYPE_GET_ROSPECS: case LLRP_TYPE_GET_SUPPORTED_VERSION: break; default: /* We shouldn't be called if we don't already recognize the value */ DISSECTOR_ASSERT_NOT_REACHED(); }; }
static gboolean dissect_dcc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *dcc_tree, *dcc_optree, *dcc_opnumtree, *ti; proto_tree *dcc_tracetree; proto_item *hidden_item; int offset = 0; int client_is_le = 0; int op = 0; int i, is_response; if (pinfo->srcport != DCC_PORT && pinfo->destport != DCC_PORT) { /* Not the right port - not a DCC packet. */ return FALSE; } /* get at least a full packet structure */ if ( tvb_length(tvb) < sizeof(DCC_HDR) ) { /* Doesn't have enough bytes to contain packet header. */ return FALSE; } col_set_str(pinfo->cinfo, COL_PROTOCOL, "DCC"); offset = 0; is_response = pinfo->srcport == DCC_PORT; if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s: %s", is_response ? "Response" : "Request", val_to_str(tvb_get_guint8(tvb, offset+3), dcc_op_vals, "Unknown Op: %u") ); } if (tree) { ti = proto_tree_add_item(tree, proto_dcc, tvb, offset, -1, FALSE); dcc_tree = proto_item_add_subtree(ti, ett_dcc); proto_tree_add_item(dcc_tree, hf_dcc_len, tvb, offset, 2, FALSE); if ( tvb_length(tvb) < tvb_get_ntohs(tvb, offset)) { /* Doesn't have number of bytes that header claims. */ proto_tree_add_text(dcc_tree, tvb, offset, 2, "Error - packet is shorter than header claims!"); } offset += 2; proto_tree_add_item(dcc_tree, hf_dcc_pkt_vers, tvb, offset, 1, FALSE); offset += 1; op = tvb_get_guint8(tvb, offset); proto_tree_add_item(dcc_tree, hf_dcc_op, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(dcc_tree, hf_dcc_clientid, tvb, offset, 4, FALSE); offset += 4; ti = proto_tree_add_text(dcc_tree, tvb, offset, -1, "Operation Numbers (Opaque to Server)"); dcc_opnumtree = proto_item_add_subtree(ti, ett_dcc_opnums); /* Note - these are indeterminate - they are sortof considered opaque to the client */ /* Make some attempt to figure out if this data is little endian, not guaranteed to be correct if connection went through a firewall or similar. */ /* Very hokey check - if all three of pid/report/retrans look like little-endian numbers, host is probably little endian. Probably innacurate on super-heavily-used DCC clients though. This should be good enough for now. */ client_is_le = ( (tvb_get_guint8(tvb, offset+4) | tvb_get_guint8(tvb, offset+4)) && (tvb_get_guint8(tvb, offset+8) | tvb_get_guint8(tvb, offset+9)) && (tvb_get_guint8(tvb, offset+12) | tvb_get_guint8(tvb, offset+13)) ); proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_host, tvb, offset, 4, client_is_le); offset += 4; proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_pid, tvb, offset, 4, client_is_le); offset += 4; proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_report, tvb, offset, 4, client_is_le); offset += 4; proto_tree_add_item(dcc_opnumtree, hf_dcc_opnums_retrans, tvb, offset, 4, client_is_le); offset += 4; ti = proto_tree_add_text(dcc_tree, tvb, offset, -1, "Operation: %s", val_to_str(op, dcc_op_vals, "Unknown Op: %u")); dcc_optree = proto_item_add_subtree(ti, ett_dcc_op); switch(op) { case DCC_OP_NOP: D_SIGNATURE(); break; case DCC_OP_REPORT: D_TARGET(); for (i=0; i<=DCC_QUERY_MAX && tvb_bytes_exist(tvb, offset+sizeof(DCC_SIGNATURE),1); i++) { D_CHECKSUM(); } D_SIGNATURE(); break; case DCC_OP_QUERY_RESP: for (i=0; i<=DCC_QUERY_MAX && tvb_bytes_exist(tvb, offset+sizeof(DCC_SIGNATURE),1); i++) { D_TARGET(); } D_SIGNATURE(); break; case DCC_OP_ADMN: if ( is_response ) { int left_local = tvb_length_remaining(tvb, offset) - sizeof(DCC_SIGNATURE); if ( left_local == sizeof(DCC_ADMN_RESP_CLIENTS) ) { D_LABEL("Addr", 16); D_LABEL("Id", sizeof(DCC_CLNT_ID)); D_LABEL("Last Used", 4); D_LABEL("Requests", 4); } else { D_TEXT("Response Text", sizeof(DCC_SIGNATURE)); } D_SIGNATURE(); } else { int aop; D_DATE(); aop = tvb_get_guint8(tvb, offset+4); proto_tree_add_item(dcc_optree, hf_dcc_adminop, tvb, offset+4, 1, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str(tvb_get_guint8(tvb,offset+4), dcc_adminop_vals, "Unknown (%u)")); } if (aop == DCC_AOP_TRACE_ON || aop == DCC_AOP_TRACE_OFF ) { ti = proto_tree_add_item(dcc_optree, hf_dcc_trace, tvb, offset, 4, FALSE); dcc_tracetree = proto_item_add_subtree(ti, ett_dcc_trace); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_admin, tvb, offset, 4, FALSE); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_anon, tvb, offset, 4, FALSE); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_client, tvb, offset, 4, FALSE); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_rlim, tvb, offset, 4, FALSE); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_query, tvb, offset, 4, FALSE); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_ridc, tvb, offset, 4, FALSE); proto_tree_add_item(dcc_tracetree, hf_dcc_trace_flood, tvb, offset, 4, FALSE); } else if ( aop == DCC_AOP_FLOD ) { proto_tree_add_item(dcc_optree, hf_dcc_floodop, tvb, offset, 4, FALSE); if (check_col(pinfo->cinfo, COL_INFO)) { col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", val_to_str(tvb_get_ntohl(tvb,offset), dcc_floodop_vals, "Unknown (%u)")); } } else { proto_tree_add_item(dcc_optree, hf_dcc_adminval, tvb, offset, 4, FALSE); } offset += 4; offset += 1; /* admin op we did in reverse order */ D_LABEL("Pad", 3); D_SIGNATURE(); } break; case DCC_OP_OK: proto_tree_add_item(dcc_optree, hf_dcc_max_pkt_vers, tvb, offset, 1, FALSE); offset += 1; D_LABEL("Unused", 1); proto_tree_add_item(dcc_optree, hf_dcc_qdelay_ms, tvb, offset, 2, FALSE); offset += 2; proto_tree_add_item(dcc_optree, hf_dcc_brand, tvb, offset, sizeof(DCC_BRAND), FALSE); offset += sizeof(DCC_BRAND); D_SIGNATURE(); break; default: /* do nothing */ break; } } return TRUE; }
static void dissect_v2_link_status_message(tvbuff_t *message_data_tvb, packet_info *pinfo, proto_tree *m2pa_tree) { col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ", val_to_str_const(tvb_get_ntohl(message_data_tvb, STATUS_OFFSET), v2_link_status_values, "Unknown")); proto_tree_add_item(m2pa_tree, hf_v2_status, message_data_tvb, STATUS_OFFSET, STATUS_LENGTH, ENC_BIG_ENDIAN); }
static void dissect_omapi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *omapi_tree; ptvcursor_t* cursor; guint32 authlength; guint32 msglength; guint32 objlength; col_set_str(pinfo->cinfo, COL_PROTOCOL, "OMAPI"); col_clear(pinfo->cinfo, COL_INFO); ti = proto_tree_add_item(tree, proto_omapi, tvb, 0, -1, ENC_NA); omapi_tree = proto_item_add_subtree(ti, ett_omapi); cursor = ptvcursor_new(omapi_tree, tvb, 0); if (tvb_reported_length_remaining(tvb, 0) < 8) { /* Payload too small for OMAPI */ DISSECTOR_ASSERT_NOT_REACHED(); } else if (tvb_reported_length_remaining(tvb, 0) < 24) { /* This is a startup message */ ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); col_set_str(pinfo->cinfo, COL_INFO, "Status message"); proto_item_append_text(ti, ", Status message"); return; } else if ( !(tvb_get_ntohl(tvb, 8) || tvb_get_ntohl(tvb, 12)) ) { /* This is a startup message, and more */ ptvcursor_add(cursor, hf_omapi_version, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_hlength, 4, ENC_BIG_ENDIAN); col_append_str(pinfo->cinfo, COL_INFO, "Status message"); proto_item_append_text(ti, ", Status message"); } ptvcursor_add(cursor, hf_omapi_auth_id, 4, ENC_BIG_ENDIAN); authlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_auth_len, 4, ENC_BIG_ENDIAN); col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)")); proto_item_append_text(ti, ", Opcode: %s", val_to_str(tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)), omapi_opcode_vals, "Unknown opcode (0x%04x)")); ptvcursor_add(cursor, hf_omapi_opcode, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_handle, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_id, 4, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_rid, 4, ENC_BIG_ENDIAN); msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); while (msglength) { ptvcursor_add(cursor, hf_omapi_msg_name_len, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_msg_name, msglength, ENC_ASCII|ENC_NA); msglength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_msg_value_len, 4, ENC_BIG_ENDIAN); if (msglength == 0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string"); } else if (msglength == (guint32)~0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value"); } else { ptvcursor_add(cursor, hf_omapi_msg_value, msglength, ENC_ASCII|ENC_NA); } msglength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); } proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Message end tag"); ptvcursor_advance(cursor, 2); objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); while (objlength) { ptvcursor_add(cursor, hf_omapi_obj_name_len, 2, ENC_BIG_ENDIAN); ptvcursor_add(cursor, hf_omapi_obj_name, objlength, ENC_ASCII|ENC_NA); objlength = tvb_get_ntohl(tvb, ptvcursor_current_offset(cursor)); ptvcursor_add(cursor, hf_omapi_obj_value_len, 4, ENC_BIG_ENDIAN); if (objlength == 0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "Empty string"); } else if (objlength == (guint32)~0) { proto_tree_add_text(omapi_tree, tvb, 0, 0, "No value"); } else { ptvcursor_add(cursor, hf_omapi_obj_value, objlength, ENC_NA); } objlength = tvb_get_ntohs(tvb, ptvcursor_current_offset(cursor)); } proto_tree_add_text(omapi_tree, tvb, ptvcursor_current_offset(cursor), 2, "Object end tag"); ptvcursor_advance(cursor, 2); if (authlength > 0) { ptvcursor_add(cursor, hf_omapi_signature, authlength, ENC_NA); } }
static void dissect_fcp_cmnd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, proto_tree *tree, conversation_t *conversation, fc_hdr *fchdr, fcp_conv_data_t *fcp_conv_data) { int offset = 0; int add_len = 0; guint8 flags, rwflags, lun0; guint16 lun = 0xffff; tvbuff_t *cdb_tvb; int tvb_len, tvb_rlen; itl_nexus_t *itl = NULL; proto_item *hidden_item; /* Determine the length of the FCP part of the packet */ flags = tvb_get_guint8(tvb, offset+10); if (flags) { add_len = tvb_get_guint8(tvb, offset+11) & 0x7C; add_len = add_len >> 2; } hidden_item = proto_tree_add_uint(tree, hf_fcp_type, tvb, offset, 0, 0); PROTO_ITEM_SET_HIDDEN(hidden_item); lun0 = tvb_get_guint8(tvb, offset); /* Display single-level LUNs in decimal for clarity */ /* I'm taking a shortcut here by assuming that if the first byte of the * LUN field is 0, it is a single-level LUN. This is not true. For a * real single-level LUN, all 8 bytes except byte 1 must be 0. */ if (lun0) { proto_tree_add_item(tree, hf_fcp_multilun, tvb, offset, 8, ENC_NA); lun = tvb_get_guint8(tvb, offset) & 0x3f; lun <<= 8; lun |= tvb_get_guint8(tvb, offset+1); } else { proto_tree_add_item(tree, hf_fcp_singlelun, tvb, offset+1, 1, ENC_BIG_ENDIAN); lun = tvb_get_guint8(tvb, offset+1); } if (fchdr->itlq) fchdr->itlq->lun = lun; itl = (itl_nexus_t *)se_tree_lookup32(fcp_conv_data->luns, lun); if (!itl) { itl = se_alloc(sizeof(itl_nexus_t)); itl->cmdset = 0xff; itl->conversation = conversation; se_tree_insert32(fcp_conv_data->luns, lun, itl); } proto_tree_add_item(tree, hf_fcp_crn, tvb, offset+8, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcp_taskattr, tvb, offset+9, 1, ENC_BIG_ENDIAN); dissect_task_mgmt_flags(pinfo, tree, tvb, offset+10); proto_tree_add_item(tree, hf_fcp_addlcdblen, tvb, offset+11, 1, ENC_BIG_ENDIAN); rwflags = tvb_get_guint8(tvb, offset+11); if (fchdr->itlq) { if (rwflags & 0x02) { fchdr->itlq->task_flags |= SCSI_DATA_READ; } if (rwflags & 0x01) { fchdr->itlq->task_flags |= SCSI_DATA_WRITE; } } proto_tree_add_item(tree, hf_fcp_rddata, tvb, offset+11, 1, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_fcp_wrdata, tvb, offset+11, 1, ENC_BIG_ENDIAN); tvb_len = tvb_length_remaining(tvb, offset+12); if (tvb_len > (16 + add_len)) tvb_len = 16 + add_len; tvb_rlen = tvb_reported_length_remaining(tvb, offset+12); if (tvb_rlen > (16 + add_len)) tvb_rlen = 16 + add_len; cdb_tvb = tvb_new_subset(tvb, offset+12, tvb_len, tvb_rlen); dissect_scsi_cdb(cdb_tvb, pinfo, parent_tree, SCSI_DEV_UNKNOWN, fchdr->itlq, itl); proto_tree_add_item(tree, hf_fcp_dl, tvb, offset+12+16+add_len, 4, ENC_BIG_ENDIAN); if (fchdr->itlq) { fchdr->itlq->data_length = tvb_get_ntohl(tvb, offset+12+16+add_len); } if ( ((rwflags & 0x03) == 0x03) && tvb_length_remaining(tvb, offset+12+16+add_len+4) >= 4) { proto_tree_add_item(tree, hf_fcp_bidir_dl, tvb, offset+12+16+add_len+4, 4, ENC_BIG_ENDIAN); if (fchdr->itlq) { fchdr->itlq->bidir_data_length = tvb_get_ntohl(tvb, offset+12+16+add_len+4); } } }
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree, pgsql_conn_data_t *conv_data) { guchar c; gint i, siz; char *s, *t; gint32 num_nonsupported_options; proto_item *ti; proto_tree *shrub; guint32 auth_type; switch (type) { /* Authentication request */ case 'R': proto_tree_add_item_ret_uint(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN, &auth_type); switch (auth_type) { case PGSQL_AUTH_TYPE_CRYPT: case PGSQL_AUTH_TYPE_MD5: n += 4; siz = (auth_type == PGSQL_AUTH_TYPE_CRYPT ? 2 : 4); proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA); break; case PGSQL_AUTH_TYPE_GSSAPI_SSPI_CONTINUE: conv_data->auth_state = PGSQL_AUTH_GSSAPI_SSPI_DATA; proto_tree_add_item(tree, hf_gssapi_sspi_data, tvb, n, length-8, ENC_NA); break; case PGSQL_AUTH_TYPE_SASL: conv_data->auth_state = PGSQL_AUTH_SASL_REQUESTED; n += 4; while ((guint)n < length) { siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_sasl_auth_mech, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; } break; case PGSQL_AUTH_TYPE_SASL_CONTINUE: case PGSQL_AUTH_TYPE_SASL_COMPLETE: conv_data->auth_state = PGSQL_AUTH_SASL_CONTINUE; n += 4; if ((guint)n < length) { proto_tree_add_item(tree, hf_sasl_auth_data, tvb, n, length-8, ENC_NA); } break; } break; /* Key data */ case 'K': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; /* Parameter status */ case 'S': s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s); n += siz; t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t); break; /* Parameter description */ case 't': i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Row description */ case 'T': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { proto_tree *twig; siz = tvb_strsize(tvb, n); ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA); twig = proto_item_add_subtree(ti, ett_values); n += siz; proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Data row */ case 'D': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } break; /* Command completion */ case 'C': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Ready */ case 'Z': proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_BIG_ENDIAN); break; /* Error, Notice */ case 'E': case 'N': length -= 4; while ((signed)length > 0) { c = tvb_get_guint8(tvb, n); if (c == '\0') break; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII); i = hf_text; switch (c) { case 'S': i = hf_severity; break; case 'C': i = hf_code; break; case 'M': i = hf_message; break; case 'D': i = hf_detail; break; case 'H': i = hf_hint; break; case 'P': i = hf_position; break; case 'p': i = hf_internal_position; break; case 'q': i = hf_internal_query; break; case 'W': i = hf_where; break; case 's': i = hf_schema_name; break; case 't': i = hf_table_name; break; case 'c': i = hf_column_name; break; case 'd': i = hf_type_name; break; case 'n': i = hf_constraint_name; break; case 'F': i = hf_file; break; case 'L': i = hf_line; break; case 'R': i = hf_routine; break; } proto_tree_add_string(tree, i, tvb, n, siz+1, s); length -= siz+1; n += siz+1; } break; /* NOTICE response */ case 'A': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); if (siz > 1) proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Copy in/out */ case 'G': case 'H': proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN); n += 1; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i); n += 2; while (i-- > 2) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Function call response */ case 'V': siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz); if (siz > 0) proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA); break; /* Negotiate Protocol Version */ case 'v': proto_tree_add_item(tree, hf_supported_minor_version, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item_ret_int(tree, hf_number_nonsupported_options, tvb, n, 4, ENC_BIG_ENDIAN, &num_nonsupported_options); n += 4; while (num_nonsupported_options > 0) { siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_nonsupported_option, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; num_nonsupported_options--; } break; } }
static void dissect_dsmcc_dii(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint offset) { guint8 module_info_len; guint16 modules, private_data_len; guint16 module_id; guint8 module_version; guint module_size; guint i; proto_item *pi; proto_tree *mod_tree; proto_tree_add_item(tree, hf_dsmcc_dii_download_id, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_dsmcc_dii_block_size, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_dsmcc_dii_window_size, tvb, offset, 1, ENC_BIG_ENDIAN); offset +=1; proto_tree_add_item(tree, hf_dsmcc_dii_ack_period, tvb, offset, 1, ENC_BIG_ENDIAN); offset +=1; proto_tree_add_item(tree, hf_dsmcc_dii_t_c_download_window, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_dsmcc_dii_t_c_download_scenario, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; offset += dissect_dsmcc_dii_compat_desc(tvb, pinfo, tree, offset); proto_tree_add_item(tree, hf_dsmcc_dii_number_of_modules, tvb, offset, 2, ENC_BIG_ENDIAN); modules = tvb_get_ntohs(tvb, offset); offset += 2; for (i = 0; i < modules; i++ ) { module_id = tvb_get_ntohs(tvb, offset); module_size = tvb_get_ntohl(tvb, 2+offset); module_version = tvb_get_guint8(tvb, 6+offset); pi = proto_tree_add_text(tree, tvb, offset, -1, "Module Id: 0x%x, Version: %u, Size: %u", module_id, module_version, module_size); mod_tree = proto_item_add_subtree(pi, ett_dsmcc_dii_module); proto_tree_add_item(mod_tree, hf_dsmcc_dii_module_id, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; proto_tree_add_item(mod_tree, hf_dsmcc_dii_module_size, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(mod_tree, hf_dsmcc_dii_module_version, tvb, offset, 1, ENC_BIG_ENDIAN); offset +=1; module_info_len = tvb_get_guint8(tvb, offset); proto_tree_add_item(mod_tree, hf_dsmcc_dii_module_info_length, tvb, offset, 1, ENC_BIG_ENDIAN); offset +=1; if (0 < module_info_len) { proto_tree_add_item(mod_tree, hf_etv_module_abs_path, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += module_info_len; } } private_data_len = tvb_get_ntohs(tvb, offset); proto_tree_add_item(tree, hf_dsmcc_dii_private_data_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; if (0 < private_data_len) { proto_tree_add_item(tree, hf_etv_dii_authority, tvb, offset, 1, ENC_ASCII|ENC_NA); offset += private_data_len; } }
static void dissect_hdfs_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint offset = 0; int success = 0; guint length = 0; col_set_str(pinfo->cinfo, COL_PROTOCOL, "HDFS"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); if (tree) { proto_item *ti = NULL; proto_tree *hdfs_tree = NULL; ti = proto_tree_add_item(tree, proto_hdfs, tvb, 0, -1, ENC_NA); hdfs_tree = proto_item_add_subtree(ti, ett_hdfs); /* Response */ if (pinfo->srcport == tcp_port) { /* 4 bytes = sequence number */ proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* 4 bytes = status -> 0000 = success, 0001 = error, ffff = fatal */ success = tvb_get_ntohl(tvb, offset); proto_tree_add_item(hdfs_tree, hf_hdfs_success, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; if (success != 0) { return; } if (!tvb_memeql(tvb, offset + 2, "long", 4)) { dissect_resp_long (tvb, hdfs_tree, offset); } else { /* name length = 2 B */ length = tvb_get_ntohs(tvb, offset); proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* length bytes = method name */ proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; /* get length that we just dissected */ length = tvb_get_ntohs(tvb, offset); /* 2 bytes = objects length */ proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* length bytes = object name */ proto_tree_add_item(hdfs_tree, hf_hdfs_objname, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; /* responses about block location info */ if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.LocatedBlocks", length)) { dissect_resp_locatedblocks (tvb, hdfs_tree, offset); /* responses about file statuses */ } else if (!tvb_memeql(tvb, offset - length, "org.apache.hadoop.hdfs.protocol.HdfsFileStatus", length)) { dissect_resp_filestatus (tvb, hdfs_tree, offset); } else { /* get length */ length = tvb_get_ntohs(tvb, offset); /* 2 bytes = parameter value length */ proto_tree_add_item(hdfs_tree, hf_hdfs_namelentwo, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; /* the value of the parameter */ proto_tree_add_item(hdfs_tree, hf_hdfs_paramval, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; } } /* Request to namenode */ } else { /* check the packet length */ guint auth = tvb_get_ntohl(tvb, offset); /* first setup packet starts with "hrpc" */ if (!tvb_memeql(tvb, offset, REQUEST_STR, sizeof(REQUEST_STR) - 1)) { proto_tree_add_item(hdfs_tree, hf_hdfs_sequenceno, tvb, offset, sizeof(REQUEST_STR) - 1, ENC_ASCII|ENC_NA); offset += sizeof(REQUEST_STR) - 1; proto_tree_add_item(hdfs_tree, hf_hdfs_pdu_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; proto_tree_add_item(hdfs_tree, hf_hdfs_flags, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; } else { /* second authentication packet */ if (auth + 4 != tvb_reported_length(tvb)) { /* authentication length (read out of first 4 bytes) */ length = tvb_get_ntohl(tvb, offset); proto_tree_add_item(hdfs_tree, hf_hdfs_authlen, tvb, offset, 4, ENC_ASCII|ENC_NA); offset += 4; /* authentication (length the number we just got) */ proto_tree_add_item(hdfs_tree, hf_hdfs_auth, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; } /* data packets */ /* 4 bytes = length */ proto_tree_add_item(hdfs_tree, hf_hdfs_len, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* 4 bytes = sequence number */ proto_tree_add_item(hdfs_tree, hf_hdfs_packetno, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; /* dissect packet data */ dissect_data (tvb, hdfs_tree, offset); } } } }
static void process_flags(proto_tree *sss_tree, tvbuff_t *tvb, guint32 foffset) { gchar flags_str[1024]; const gchar *sep; proto_item *tinew; proto_tree *flags_tree; guint32 i; guint32 bvalue = 0; guint32 flags = 0; bvalue = 0x00000001; flags_str[0]='\0'; sep=""; flags = tvb_get_ntohl(tvb, foffset); for (i = 0 ; i < 256; i++) { if (flags & bvalue) { g_strlcat(flags_str, sep, 1024); switch(bvalue) { case 0x00000001: g_strlcat(flags_str, "Enhanced Protection", 1024); break; case 0x00000002: g_strlcat(flags_str, "Create ID", 1024); break; case 0x00000004: g_strlcat(flags_str, "Remove Lock", 1024); break; case 0x00000008: g_strlcat(flags_str, "Repair", 1024); break; case 0x00000010: g_strlcat(flags_str, "Unicode", 1024); break; case 0x00000020: g_strlcat(flags_str, "EP Master Password Used", 1024); break; case 0x00000040: g_strlcat(flags_str, "EP Password Used", 1024); break; case 0x00000080: g_strlcat(flags_str, "Set Tree Name", 1024); break; case 0x00000100: g_strlcat(flags_str, "Get Context", 1024); break; case 0x00000200: g_strlcat(flags_str, "Destroy Context", 1024); break; case 0x00000400: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x00000800: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x00001000: g_strlcat(flags_str, "EP Lock", 1024); break; case 0x00002000: g_strlcat(flags_str, "Not Initialized", 1024); break; case 0x00004000: g_strlcat(flags_str, "Enhanced Protection", 1024); break; case 0x00008000: g_strlcat(flags_str, "Store Not Synced", 1024); break; case 0x00010000: g_strlcat(flags_str, "Admin Last Modified", 1024); break; case 0x00020000: g_strlcat(flags_str, "EP Password Present", 1024); break; case 0x00040000: g_strlcat(flags_str, "EP Master Password Present", 1024); break; case 0x00080000: g_strlcat(flags_str, "MP Disabled", 1024); break; case 0x00100000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x00200000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x00400000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x00800000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x01000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x02000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x04000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x08000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x10000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x20000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x40000000: g_strlcat(flags_str, "Not Defined", 1024); break; case 0x80000000: g_strlcat(flags_str, "Not Defined", 1024); break; default: break; } sep = ", "; } bvalue = bvalue*2; } tinew = proto_tree_add_uint_format(sss_tree, hf_flags, tvb, foffset, 4, flags, "%s 0x%08x", "Flags:", flags); flags_tree = proto_item_add_subtree(tinew, ett_nds); bvalue = 0x00000001; for (i = 0 ; i < 256; i++ ) { if (flags & bvalue) { switch(bvalue) { case 0x00000001: proto_tree_add_item(flags_tree, hfbit1, tvb, foffset, 4, FALSE); break; case 0x00000002: proto_tree_add_item(flags_tree, hfbit2, tvb, foffset, 4, FALSE); break; case 0x00000004: proto_tree_add_item(flags_tree, hfbit3, tvb, foffset, 4, FALSE); break; case 0x00000008: proto_tree_add_item(flags_tree, hfbit4, tvb, foffset, 4, FALSE); break; case 0x00000010: proto_tree_add_item(flags_tree, hfbit5, tvb, foffset, 4, FALSE); break; case 0x00000020: proto_tree_add_item(flags_tree, hfbit6, tvb, foffset, 4, FALSE); break; case 0x00000040: proto_tree_add_item(flags_tree, hfbit7, tvb, foffset, 4, FALSE); break; case 0x00000080: proto_tree_add_item(flags_tree, hfbit8, tvb, foffset, 4, FALSE); break; case 0x00000100: proto_tree_add_item(flags_tree, hfbit9, tvb, foffset, 4, FALSE); break; case 0x00000200: proto_tree_add_item(flags_tree, hfbit10, tvb, foffset, 4, FALSE); break; case 0x00000400: proto_tree_add_item(flags_tree, hfbit11, tvb, foffset, 4, FALSE); break; case 0x00000800: proto_tree_add_item(flags_tree, hfbit12, tvb, foffset, 4, FALSE); break; case 0x00001000: proto_tree_add_item(flags_tree, hfbit13, tvb, foffset, 4, FALSE); break; case 0x00002000: proto_tree_add_item(flags_tree, hfbit14, tvb, foffset, 4, FALSE); break; case 0x00004000: proto_tree_add_item(flags_tree, hfbit15, tvb, foffset, 4, FALSE); break; case 0x00008000: proto_tree_add_item(flags_tree, hfbit16, tvb, foffset, 4, FALSE); break; case 0x00010000: proto_tree_add_item(flags_tree, hfbit17, tvb, foffset, 4, FALSE); break; case 0x00020000: proto_tree_add_item(flags_tree, hfbit18, tvb, foffset, 4, FALSE); break; case 0x00040000: proto_tree_add_item(flags_tree, hfbit19, tvb, foffset, 4, FALSE); break; case 0x00080000: proto_tree_add_item(flags_tree, hfbit20, tvb, foffset, 4, FALSE); break; case 0x00100000: proto_tree_add_item(flags_tree, hfbit21, tvb, foffset, 4, FALSE); break; case 0x00200000: proto_tree_add_item(flags_tree, hfbit22, tvb, foffset, 4, FALSE); break; case 0x00400000: proto_tree_add_item(flags_tree, hfbit23, tvb, foffset, 4, FALSE); break; case 0x00800000: proto_tree_add_item(flags_tree, hfbit24, tvb, foffset, 4, FALSE); break; case 0x01000000: proto_tree_add_item(flags_tree, hfbit25, tvb, foffset, 4, FALSE); break; case 0x02000000: proto_tree_add_item(flags_tree, hfbit26, tvb, foffset, 4, FALSE); break; case 0x04000000: proto_tree_add_item(flags_tree, hfbit27, tvb, foffset, 4, FALSE); break; case 0x08000000: proto_tree_add_item(flags_tree, hfbit28, tvb, foffset, 4, FALSE); break; case 0x10000000: proto_tree_add_item(flags_tree, hfbit29, tvb, foffset, 4, FALSE); break; case 0x20000000: proto_tree_add_item(flags_tree, hfbit30, tvb, foffset, 4, FALSE); break; case 0x40000000: proto_tree_add_item(flags_tree, hfbit31, tvb, foffset, 4, FALSE); break; case 0x80000000: proto_tree_add_item(flags_tree, hfbit32, tvb, foffset, 4, FALSE); break; default: break; } } bvalue = bvalue*2; } return; }
static guint get_bzr_prefixed_len(tvbuff_t *tvb, int offset) { guint header_len; header_len = tvb_get_ntohl(tvb, offset); return 4 + header_len; }
static int sss_string(tvbuff_t* tvb, int hfinfo, proto_tree *sss_tree, int offset, gboolean little, guint32 length) { int foffset = offset; guint32 str_length; char buffer[1024]; guint32 i; guint16 c_char; guint32 length_remaining = 0; if (length==0) { if (little) { str_length = tvb_get_letohl(tvb, foffset); } else { str_length = tvb_get_ntohl(tvb, foffset); } foffset += 4; } else { str_length = length; } length_remaining = tvb_length_remaining(tvb, foffset); if(str_length > (guint)length_remaining || str_length > 1024) { proto_tree_add_string(sss_tree, hfinfo, tvb, foffset, length_remaining + 4, "<String too long to process>"); foffset += length_remaining; return foffset; } if(str_length == 0) { proto_tree_add_string(sss_tree, hfinfo, tvb, offset, 4, "<Not Specified>"); return foffset; } for ( i = 0; i < str_length; i++ ) { c_char = tvb_get_guint8(tvb, foffset ); if (c_char<0x20 || c_char>0x7e) { if (c_char != 0x00) { c_char = 0x2e; buffer[i] = c_char & 0xff; } else { i--; str_length--; } } else { buffer[i] = c_char & 0xff; } foffset++; length_remaining--; if(length_remaining==1) { i++; break; } } buffer[i] = '\0'; if (length==0) { if (little) { str_length = tvb_get_letohl(tvb, offset); } else { str_length = tvb_get_ntohl(tvb, offset); } offset += 4; } else { str_length = length; } proto_tree_add_string(sss_tree, hfinfo, tvb, offset, str_length, buffer); return foffset; }
/* This function will try to determine the complete size of a PDU * based on the information in the header. */ static guint get_nbd_tcp_pdu_len(packet_info *pinfo, tvbuff_t *tvb, int offset) { guint32 magic, type, packet; conversation_t *conversation; nbd_conv_info_t *nbd_info; nbd_transaction_t *nbd_trans=NULL; emem_tree_key_t hkey[3]; guint32 handle[2]; magic=tvb_get_ntohl(tvb, offset); switch(magic){ case NBD_REQUEST_MAGIC: type=tvb_get_ntohl(tvb, offset+4); switch(type){ case NBD_CMD_WRITE: return tvb_get_ntohl(tvb, offset+24)+28; default: return 28; } case NBD_RESPONSE_MAGIC: /* * Do we have a conversation for this connection? */ conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype, pinfo->srcport, pinfo->destport, 0); if (conversation == NULL) { /* No, so just return the rest of the current packet */ return tvb_length(tvb); } /* * Do we have a state structure for this conv */ nbd_info = conversation_get_proto_data(conversation, proto_nbd); if (!nbd_info) { /* No, so just return the rest of the current packet */ return tvb_length(tvb); } if(!pinfo->fd->flags.visited){ /* * Do we have a state structure for this transaction */ handle[0]=tvb_get_ntohl(tvb, offset+8); handle[1]=tvb_get_ntohl(tvb, offset+12); hkey[0].length=2; hkey[0].key=handle; hkey[1].length=0; nbd_trans=se_tree_lookup32_array(nbd_info->unacked_pdus, hkey); if(!nbd_trans){ /* No, so just return the rest of the current packet */ return tvb_length(tvb); } } else { /* * Do we have a state structure for this transaction */ handle[0]=tvb_get_ntohl(tvb, offset+8); handle[1]=tvb_get_ntohl(tvb, offset+12); packet=pinfo->fd->num; hkey[0].length=1; hkey[0].key=&packet; hkey[1].length=2; hkey[1].key=handle; hkey[2].length=0; nbd_trans=se_tree_lookup32_array(nbd_info->acked_pdus, hkey); if(!nbd_trans){ /* No, so just return the rest of the current packet */ return tvb_length(tvb); } } /* If this is a read response we must add the datalen to * the pdu size */ if(nbd_trans->type==NBD_CMD_READ){ return 16+nbd_trans->datalen; } else { return 16; } default: break; } /* Did not really look like a NBD packet after all */ return 0; }
void dissect_sss_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ncp_tree, guint8 subfunc, ncp_req_hash_value *request_value) { guint32 foffset=0; guint32 subverb=0; guint32 msg_length=0; guint32 return_code=0; guint32 number_of_items=0; gint32 length_of_string=0; guint32 i = 0; proto_tree *atree; proto_item *aitem; proto_item *expert_item; foffset = 8; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NSSS"); if (tvb_length_remaining(tvb, foffset)<4) { return; } aitem = proto_tree_add_text(ncp_tree, tvb, foffset, -1, "Function: %s", val_to_str(subfunc, sss_func_enum, "val_to_str")); atree = proto_item_add_subtree(aitem, ett_sss); switch (subfunc) { case 1: proto_tree_add_item(atree, hf_flags, tvb, foffset, 4, TRUE); foffset += 4; proto_tree_add_item(atree, hf_sss_version, tvb, foffset, 4, TRUE); foffset += 4; break; case 2: if (request_value) { subverb = request_value->req_nds_flags; if (match_strval(subverb, sss_verb_enum)) { proto_tree_add_text(atree, tvb, foffset, tvb_length_remaining(tvb, foffset), "Verb: %s", match_strval(subverb, sss_verb_enum)); } } proto_tree_add_item(atree, hf_length, tvb, foffset, 4, TRUE); msg_length = tvb_get_letohl(tvb, foffset); return_code = tvb_get_ntohl(tvb, foffset+msg_length); foffset += 4; proto_tree_add_item(atree, hf_frag_handle, tvb, foffset, 4, TRUE); foffset += 4; msg_length -= 4; if ((tvb_get_letohl(tvb, foffset-4)==0xffffffff) && (msg_length > 4)) { foffset += 4; return_code = tvb_get_letohl(tvb, foffset); if ( match_strval(return_code, sss_errors_enum) != NULL ) { expert_item = proto_tree_add_item(atree, hf_return_code, tvb, foffset, 4, TRUE); expert_add_info_format(pinfo, expert_item, PI_RESPONSE_CODE, PI_ERROR, "SSS Error: %s", match_strval(return_code, sss_errors_enum)); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "R Error - %s", val_to_str(return_code, sss_errors_enum, "Unknown (%d)")); } foffset+=4; } else { proto_tree_add_text(atree, tvb, foffset, 4, "Return Code: Success (0x00000000)"); if (tvb_length_remaining(tvb, foffset) > 8) { foffset += 4; if (request_value && subverb == 6) { foffset += 4; number_of_items = tvb_get_letohl(tvb, foffset); foffset += 8; for (i=0; i<number_of_items; i++) { length_of_string = find_delimiter(tvb, foffset); if (length_of_string > tvb_length_remaining(tvb, foffset)) { return; } foffset = sss_string(tvb, hf_secret, atree, foffset, TRUE, length_of_string); if (tvb_length_remaining(tvb, foffset) < 8) { return; } foffset++; } } else { proto_tree_add_item(atree, hf_enc_data, tvb, foffset, tvb_length_remaining(tvb, foffset), TRUE); } } } } else { proto_tree_add_text(atree, tvb, foffset, 4, "Return Code: Success (0x00000000)"); if (tvb_length_remaining(tvb, foffset) > 8) { foffset += 4; proto_tree_add_item(atree, hf_enc_data, tvb, foffset, tvb_length_remaining(tvb, foffset), TRUE); } } break; case 3: break; default: break; } }
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; } } }
/* Broadcasts are searches, offers or promises. * * Searches are sent by * a peer when it needs a file (ie. while applying its policy, when it needs * files such as installers to install software.) * * Each broadcast relates to one file and each file is identified only by its * checksum - no file names are ever used. A search times out after 10 seconds * (configurable) and the peer will then attempt to act on any offers by * downloading (via push or pull - see dissect_ldss_transfer) from those peers. * * If no offers are received, the search fails and the peer fetches the file * from a remote server, generally a HTTP server on the other side of a WAN. * The protocol exists to minimize the number of WAN downloads needed. * * While downloading from WAN the peer sends promises to inform other peers * when it will be available for them to download. This prevents multiple peers * simultaneously downloading the same file. Promises also inform other peers * how much download bandwidth is being used by their download. Other peers use * this information and the configured knowledge of the WAN bandwidth to avoid * saturating the WAN link, as file downloads are a non-time-critical and * non-business-critical network function. LDSS is intended for networks of * 5-20 machines connected by slow WAN link. The current implementation of the * protocol allows administrator to configure "time windows" when WAN usage is * throttled/unthrottled, though this isn't visible in LDSS. * * Once a WAN download or a LAN transfer (see below above dissect_ldss_transfer) * has complete the peer will offer the file to other peers on the LAN so they * don't need to download it themselves. * * Peers also notify when they shut down in case any other peer is waiting for * a file. */ static int dissect_ldss_broadcast(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 messageID; guint8 digest_type; guint8 compression; guint32 cookie; guint8 *digest; guint64 size; guint64 offset; guint32 targetTime; guint16 port; guint16 rate; guint16 messageDetail = INFERRED_NONE; proto_tree *ti, *ldss_tree; const gchar *packet_type, *packet_detail; messageID = tvb_get_ntohs (tvb, 0); digest_type = tvb_get_guint8 (tvb, 2); compression = tvb_get_guint8 (tvb, 3); cookie = tvb_get_ntohl (tvb, 4); digest = (guint8 *)tvb_memdup (wmem_file_scope(), tvb, 8, DIGEST_LEN); size = tvb_get_ntoh64 (tvb, 40); offset = tvb_get_ntoh64 (tvb, 48); targetTime = tvb_get_ntohl (tvb, 56); port = tvb_get_ntohs (tvb, 64); rate = tvb_get_ntohs (tvb, 66); packet_type = val_to_str_const(messageID, ldss_message_id_value, "unknown"); if (messageID == MESSAGE_ID_WILLSEND) { if (cookie == 0) { /* Shutdown: Dishonor promises from this peer. Current * implementation abuses WillSend for this. */ messageDetail = INFERRED_PEERSHUTDOWN; } else if (size == 0 && offset == 0) { /* NeedFile search failed - going to WAN */ messageDetail = INFERRED_WANDOWNLOAD; } else if (size > 0) { /* Size is known (not always the case) */ if (size == offset) { /* File is available for pull on this peer's TCP port */ messageDetail = INFERRED_OFFER; } else { /* WAN download progress announcement from this peer */ messageDetail = INFERRED_PROMISE; } } } else if (messageID == MESSAGE_ID_NEEDFILE) { messageDetail = INFERRED_SEARCH; } packet_detail = val_to_str_const(messageDetail, ldss_inferred_info, "unknown"); /* Set the info column */ col_add_fstr(pinfo->cinfo, COL_INFO, "LDSS Broadcast (%s%s)", packet_type, packet_detail); /* If we have a non-null tree (ie we are building the proto_tree * instead of just filling out the columns), then give more detail. */ ti = proto_tree_add_item(tree, proto_ldss, tvb, 0, (tvb_captured_length(tvb) > 72) ? tvb_captured_length(tvb) : 72, ENC_NA); ldss_tree = proto_item_add_subtree(ti, ett_ldss_broadcast); proto_tree_add_item(ldss_tree, hf_ldss_message_id, tvb, 0, 2, ENC_BIG_ENDIAN); ti = proto_tree_add_uint(ldss_tree, hf_ldss_message_detail, tvb, 0, 0, messageDetail); PROTO_ITEM_SET_GENERATED(ti); proto_tree_add_item(ldss_tree, hf_ldss_digest_type, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(ldss_tree, hf_ldss_compression, tvb, 3, 1, ENC_BIG_ENDIAN); proto_tree_add_uint_format_value(ldss_tree, hf_ldss_cookie, tvb, 4, 4, FALSE, "0x%x%s", cookie, (cookie == 0) ? " - shutdown (promises from this peer are no longer valid)" : ""); proto_tree_add_item(ldss_tree, hf_ldss_digest, tvb, 8, DIGEST_LEN, ENC_NA); proto_tree_add_item(ldss_tree, hf_ldss_size, tvb, 40, 8, ENC_BIG_ENDIAN); proto_tree_add_item(ldss_tree, hf_ldss_offset, tvb, 48, 8, ENC_BIG_ENDIAN); proto_tree_add_uint_format_value(ldss_tree, hf_ldss_target_time, tvb, 56, 4, FALSE, "%d:%02d:%02d", (int)(targetTime / 3600), (int)((targetTime / 60) % 60), (int)(targetTime % 60)); proto_tree_add_item(ldss_tree, hf_ldss_reserved_1, tvb, 60, 4, ENC_BIG_ENDIAN); proto_tree_add_uint_format_value(ldss_tree, hf_ldss_port, tvb, 64, 2, FALSE, "%d%s", port, (messageID == MESSAGE_ID_WILLSEND && size > 0 && size == offset) ? " - file can be pulled at this TCP port" : (messageID == MESSAGE_ID_NEEDFILE ? " - file can be pushed to this TCP port" : "")); proto_tree_add_uint_format_value(ldss_tree, hf_ldss_rate, tvb, 66, 2, FALSE, "%ld", (rate > 0) ? (long)floor(exp(rate * G_LN2 / 2048)) : 0); proto_tree_add_item(ldss_tree, hf_ldss_priority, tvb, 68, 2, ENC_BIG_ENDIAN); proto_tree_add_item(ldss_tree, hf_ldss_property_count, tvb, 70, 2, ENC_BIG_ENDIAN); if (tvb_reported_length(tvb) > 72) { proto_tree_add_item(ldss_tree, hf_ldss_properties, tvb, 72, tvb_captured_length(tvb) - 72, ENC_NA); } /* Finally, store the broadcast and register ourselves to dissect * any pushes or pulls that result from this broadcast. All data * is pushed/pulled over TCP using the port from the broadcast * packet's port field. * Track each by a TCP conversation with the remote end wildcarded. * The TCP conv tracks back to a broadcast conv to determine what it * is in response to. * * These steps only need to be done once per packet, so a variable * tracks the highest frame number seen. Handles the case of first frame * being frame zero. */ if (messageDetail != INFERRED_PEERSHUTDOWN && (highest_num_seen == 0 || highest_num_seen < pinfo->num)) { ldss_broadcast_t *data; /* Populate data from the broadcast */ data = wmem_new0(wmem_file_scope(), ldss_broadcast_t); data->num = pinfo->num; data->ts = pinfo->abs_ts; data->message_id = messageID; data->message_detail = messageDetail; data->port = port; data->size = size; data->offset = offset; data->compression = compression; data->file = wmem_new0(wmem_file_scope(), ldss_file_t); data->file->digest = digest; data->file->digest_type = digest_type; data->broadcaster = wmem_new0(wmem_file_scope(), ldss_broadcaster_t); copy_address_wmem(wmem_file_scope(), &data->broadcaster->addr, &pinfo->src); data->broadcaster->port = port; /* Dissect any future pushes/pulls */ if (port > 0) { prepare_ldss_transfer_conv(data); } /* Record that the frame was processed */ highest_num_seen = pinfo->num; } return tvb_captured_length(tvb); }
static void dissect_pgsql_be_msg(guchar type, guint length, tvbuff_t *tvb, gint n, proto_tree *tree) { guchar c; gint i, siz; char *s, *t; proto_item *ti; proto_tree *shrub; switch (type) { /* Authentication request */ case 'R': proto_tree_add_item(tree, hf_authtype, tvb, n, 4, ENC_BIG_ENDIAN); i = tvb_get_ntohl(tvb, n); if (i == 4 || i == 5) { /* i -= (6-i); :-) */ n += 4; siz = (i == 4 ? 2 : 4); proto_tree_add_item(tree, hf_salt, tvb, n, siz, ENC_NA); } break; /* Key data */ case 'K': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); proto_tree_add_item(tree, hf_key, tvb, n+4, 4, ENC_BIG_ENDIAN); break; /* Parameter status */ case 'S': s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &siz, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_name, tvb, n, siz, s); n += siz; t = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n, &i, ENC_ASCII); proto_tree_add_string(tree, hf_parameter_value, tvb, n, i, t); break; /* Parameter description */ case 't': i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Parameters: %d", i); n += 2; while (i-- > 0) { proto_tree_add_item(shrub, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; } break; /* Row description */ case 'T': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { proto_tree *twig; siz = tvb_strsize(tvb, n); ti = proto_tree_add_item(shrub, hf_val_name, tvb, n, siz, ENC_ASCII|ENC_NA); twig = proto_item_add_subtree(ti, ett_values); n += siz; proto_tree_add_item(twig, hf_tableoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_idx, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_typeoid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_val_length, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; proto_tree_add_item(twig, hf_val_mod, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; proto_tree_add_item(twig, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Data row */ case 'D': i = tvb_get_ntohs(tvb, n); ti = proto_tree_add_item(tree, hf_field_count, tvb, n, 2, ENC_BIG_ENDIAN); shrub = proto_item_add_subtree(ti, ett_values); n += 2; while (i-- > 0) { siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(shrub, hf_val_length, tvb, n, 4, siz); n += 4; if (siz > 0) { proto_tree_add_item(shrub, hf_val_data, tvb, n, siz, ENC_NA); n += siz; } } break; /* Command completion */ case 'C': siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_tag, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Ready */ case 'Z': proto_tree_add_item(tree, hf_status, tvb, n, 1, ENC_BIG_ENDIAN); break; /* Error, Notice */ case 'E': case 'N': length -= 4; while ((signed)length > 0) { c = tvb_get_guint8(tvb, n); if (c == '\0') break; s = tvb_get_stringz_enc(wmem_packet_scope(), tvb, n+1, &siz, ENC_ASCII); i = hf_text; switch (c) { case 'S': i = hf_severity; break; case 'C': i = hf_code; break; case 'M': i = hf_message; break; case 'D': i = hf_detail; break; case 'H': i = hf_hint; break; case 'P': i = hf_position; break; case 'p': i = hf_internal_position; break; case 'q': i = hf_internal_query; break; case 'W': i = hf_where; break; case 's': i = hf_schema_name; break; case 't': i = hf_table_name; break; case 'c': i = hf_column_name; break; case 'd': i = hf_type_name; break; case 'n': i = hf_constraint_name; break; case 'F': i = hf_file; break; case 'L': i = hf_line; break; case 'R': i = hf_routine; break; } proto_tree_add_string(tree, i, tvb, n, siz+1, s); length -= siz+1; n += siz+1; } break; /* NOTICE response */ case 'A': proto_tree_add_item(tree, hf_pid, tvb, n, 4, ENC_BIG_ENDIAN); n += 4; siz = tvb_strsize(tvb, n); proto_tree_add_item(tree, hf_condition, tvb, n, siz, ENC_ASCII|ENC_NA); n += siz; siz = tvb_strsize(tvb, n); if (siz > 1) proto_tree_add_item(tree, hf_text, tvb, n, siz, ENC_ASCII|ENC_NA); break; /* Copy in/out */ case 'G': case 'H': proto_tree_add_item(tree, hf_format, tvb, n, 1, ENC_BIG_ENDIAN); n += 1; i = tvb_get_ntohs(tvb, n); shrub = proto_tree_add_subtree_format(tree, tvb, n, 2, ett_values, NULL, "Columns: %d", i); n += 2; while (i-- > 2) { proto_tree_add_item(shrub, hf_format, tvb, n, 2, ENC_BIG_ENDIAN); n += 2; } break; /* Copy data */ case 'd': proto_tree_add_item(tree, hf_copydata, tvb, n, length-n+1, ENC_NA); break; /* Function call response */ case 'V': siz = tvb_get_ntohl(tvb, n); proto_tree_add_int(tree, hf_val_length, tvb, n, 4, siz); if (siz > 0) proto_tree_add_item(tree, hf_val_data, tvb, n+4, siz, ENC_NA); break; } }
static void dissect_zrtp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *zrtp_tree; proto_tree *zrtp_msg_tree; proto_tree *zrtp_msg_data_tree; proto_tree *checksum_tree; proto_item *ti; int linelen; int checksum_offset; unsigned char message_type[9]; unsigned int prime_offset = 0; unsigned int msg_offset = 12; guint32 sent_crc, calc_crc; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ZRTP"); col_set_str(pinfo->cinfo, COL_INFO, "Unknown ZRTP Packet"); ti = proto_tree_add_protocol_format(tree, proto_zrtp, tvb, 0, -1, "ZRTP protocol"); zrtp_tree = proto_item_add_subtree(ti, ett_zrtp); proto_tree_add_item(zrtp_tree, hf_zrtp_rtpversion, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(zrtp_tree, hf_zrtp_rtppadding, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(zrtp_tree, hf_zrtp_rtpextension, tvb, prime_offset+0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(zrtp_tree, hf_zrtp_sequence, tvb, prime_offset+2, 2, ENC_BIG_ENDIAN); proto_tree_add_item(zrtp_tree, hf_zrtp_cookie, tvb, prime_offset+4, 4, ENC_ASCII|ENC_NA); proto_tree_add_item(zrtp_tree, hf_zrtp_source_id, tvb, prime_offset+8, 4, ENC_BIG_ENDIAN); linelen = tvb_reported_length_remaining(tvb, msg_offset); checksum_offset = linelen-4; ti = proto_tree_add_protocol_format(zrtp_tree, proto_zrtp, tvb, msg_offset, linelen-4, "Message"); zrtp_msg_tree = proto_item_add_subtree(ti, ett_zrtp_msg); proto_tree_add_item(zrtp_msg_tree, hf_zrtp_signature, tvb, msg_offset+0, 2, ENC_BIG_ENDIAN); proto_tree_add_item(zrtp_msg_tree, hf_zrtp_msg_length, tvb, msg_offset+2, 2, ENC_BIG_ENDIAN); tvb_memcpy(tvb, (void *)message_type, msg_offset+4, 8); message_type[8] = '\0'; proto_tree_add_item(zrtp_msg_tree, hf_zrtp_msg_type, tvb, msg_offset+4, 8, ENC_ASCII|ENC_NA); linelen = tvb_reported_length_remaining(tvb, msg_offset+12); if (!strncmp(message_type, "Hello ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_Hello(tvb, pinfo, zrtp_msg_data_tree); } else if (!strncmp(message_type, "HelloACK", 8)) { dissect_HelloACK(pinfo); } else if (!strncmp(message_type, "Commit ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_Commit(tvb, pinfo, zrtp_msg_data_tree); } else if (!strncmp(message_type, "DHPart1 ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_DHPart(tvb, pinfo, zrtp_msg_data_tree, 1); } else if (!strncmp(message_type, "DHPart2 ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_DHPart(tvb, pinfo, zrtp_msg_data_tree, 2); } else if (!strncmp(message_type, "Confirm1", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_Confirm(tvb, pinfo, zrtp_msg_data_tree, 1); } else if (!strncmp(message_type, "Confirm2", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_Confirm(tvb, pinfo, zrtp_msg_data_tree, 2); } else if (!strncmp(message_type, "Conf2ACK", 8)) { dissect_Conf2ACK(pinfo); } else if (!strncmp(message_type, "Error ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_Error(tvb, pinfo, zrtp_msg_data_tree); } else if (!strncmp(message_type, "ErrorACK", 8)) { dissect_ErrorACK(pinfo); } else if (!strncmp(message_type, "GoClear ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_GoClear(tvb, pinfo, zrtp_msg_data_tree); } else if (!strncmp(message_type, "ClearACK", 8)) { dissect_ClearACK(pinfo); } else if (!strncmp(message_type, "SASrelay", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_SASrelay(tvb, pinfo, zrtp_msg_data_tree); } else if (!strncmp(message_type, "RelayACK", 8)) { dissect_RelayACK(pinfo); } else if (!strncmp(message_type, "Ping ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_Ping(tvb, pinfo, zrtp_msg_data_tree); } else if (!strncmp(message_type, "PingACK ", 8)) { ti = proto_tree_add_protocol_format(zrtp_msg_tree, proto_zrtp, tvb, msg_offset+12, linelen-4, "Data"); zrtp_msg_data_tree = proto_item_add_subtree(ti, ett_zrtp_msg_data); dissect_PingACK(tvb, pinfo, zrtp_msg_data_tree); } sent_crc = tvb_get_ntohl(tvb, msg_offset+checksum_offset); calc_crc = ~crc32c_tvb_offset_calculate(tvb, 0, msg_offset+checksum_offset, CRC32C_PRELOAD); if (sent_crc == calc_crc) { ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc, "0x%04x [correct]", sent_crc); checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum); ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good, tvb, msg_offset+checksum_offset, 4, TRUE); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad, tvb, msg_offset+checksum_offset, 4, FALSE); PROTO_ITEM_SET_GENERATED(ti); } else { ti = proto_tree_add_uint_format_value(zrtp_tree, hf_zrtp_checksum, tvb, msg_offset+checksum_offset, 4, sent_crc, "0x%04x [incorrect, should be 0x%04x]", sent_crc, calc_crc); checksum_tree = proto_item_add_subtree(ti, ett_zrtp_checksum); ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_good, tvb, msg_offset+checksum_offset, 4, FALSE); PROTO_ITEM_SET_GENERATED(ti); ti = proto_tree_add_boolean(checksum_tree, hf_zrtp_checksum_bad, tvb, msg_offset+checksum_offset, 4, TRUE); PROTO_ITEM_SET_GENERATED(ti); } }
static void dissect_wtls_handshake(proto_tree *tree, tvbuff_t *tvb, guint offset, guint count) { char pdu_msg_type; nstime_t timeValue; int client_size = 0; guint value = 0; int size = 0; guint public_key = 0; char valStr[1024]; const char *valBulk = NULL; const char *valMac = NULL; proto_item *ti; proto_item *cli_key_item; proto_tree *wtls_msg_type_tree; proto_tree *wtls_msg_type_item_tree; proto_tree *wtls_msg_type_item_sub_tree; proto_tree *wtls_msg_type_item_sub_sub_tree; pdu_msg_type = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_uint(tree, hf_wtls_hands, tvb, offset,count, pdu_msg_type); wtls_msg_type_tree = proto_item_add_subtree(ti, ett_wtls_msg_type); proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_type, tvb,offset,1,ENC_BIG_ENDIAN); offset+=1; count = tvb_get_ntohs (tvb, offset); proto_tree_add_item (wtls_msg_type_tree, hf_wtls_hands_length, tvb,offset,2,ENC_BIG_ENDIAN); offset+=2; switch(pdu_msg_type) { case WTLS_HANDSHAKE_CLIENT_HELLO : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_cli_hello, tvb, offset, count, ENC_NA); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_version, tvb,offset,1,ENC_BIG_ENDIAN); offset++; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_gmt, tvb, offset, 4, &timeValue); offset+=4; proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_random, tvb,offset,12,ENC_NA); offset+=12; offset = add_session_id (wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_session, hf_wtls_hands_cli_hello_session_str, tvb, offset); /* process client_key_ids structure */ count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_cli_key_id, tvb, offset, count+2, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); /* display length of client_key_ids structure */ proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cli_key_len, tvb,offset,2,ENC_BIG_ENDIAN); offset+=2; /* cycle through client_key_ids entries */ for (;count > 0;count-=client_size) { /* get encryption suite id (one byte) */ value = tvb_get_guint8 (tvb, offset); cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, value); client_size=1; wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub_sub); proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_exchange_suite, tvb,offset,1,value); offset++; #ifdef DEBUG fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* get parameter index (one byte) */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_index, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* explicit parameters present in next field */ if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_set, tvb,offset,size+2,ENC_ASCII|ENC_NA); offset+=size+2; client_size+=size+2; } /* get identifier type */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_type, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* identifier present in next field */ /* note: value 0x0 means no identifier */ switch(value) { case IDENTIFIER_TEXT : /* text identifier */ /* not tested */ size = add_text_identifier( tvb, offset, hf_wtls_hands_cli_hello_key_identifier_charset, hf_wtls_hands_cli_hello_key_identifier_size, hf_wtls_hands_cli_hello_key_identifier_str, wtls_msg_type_item_sub_sub_tree); offset += size; client_size += size; break; case IDENTIFIER_BIN : /* binary identifier */ size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "binary id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; case IDENTIFIER_SHA_1 : /* SHA-1 hash of the public key */ proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,20,ENC_NA); offset+=20; client_size+=20; #ifdef DEBUG fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n", client_size); #endif /* DEBUG */ break; case IDENTIFIER_X509 : /* X.509 distinguished name */ /* not tested */ size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "X.509 name size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; } proto_item_set_len(cli_key_item, client_size); } /* process trusted_keys structure */ count = tvb_get_ntohs (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_trust_key_id, tvb, offset, count+2, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); /* display length of trusted_keys structure */ proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cli_key_len, tvb,offset,2,ENC_BIG_ENDIAN); offset+=2; for (;count > 0;count-=client_size) { /* get encryption suite id (one byte) */ value = tvb_get_guint8 (tvb, offset); cli_key_item = proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_key_exchange, tvb, offset,1, value); client_size=1; wtls_msg_type_item_sub_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub_sub); proto_tree_add_uint(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_exchange_suite, tvb,offset,1,value); offset++; #ifdef DEBUG fprintf(stderr, "encryption suite = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* get parameter index (one byte) */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_index, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "parameter index = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* explicit parameters present in next field */ if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_parameter_set, tvb,offset,size+2,ENC_ASCII|ENC_NA); offset+=size+2; client_size+=size+2; } /* get identifier type */ value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_type, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; #ifdef DEBUG fprintf(stderr, "identifier type = %d, client_size = %d\n", value, client_size); #endif /* DEBUG */ /* identifier present in next field */ /* note: value 0x0 means no identifier */ switch (value) { case IDENTIFIER_TEXT : /* text identifier */ /* not tested */ size = add_text_identifier( tvb, offset, hf_wtls_hands_cli_hello_key_identifier_charset, hf_wtls_hands_cli_hello_key_identifier_size, hf_wtls_hands_cli_hello_key_identifier_str, wtls_msg_type_item_sub_sub_tree); offset += size; client_size += size; break; case IDENTIFIER_BIN : /* binary identifier */ size = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "binary id size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; case IDENTIFIER_SHA_1 : /* SHA-1 hash of the public key */ proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,20,ENC_NA); offset+=20; client_size+=20; #ifdef DEBUG fprintf(stderr, "SHA-1 hash size = 20, client_size = %d\n", client_size); #endif /* DEBUG */ break; case IDENTIFIER_X509 : /* X.509 distinguished name */ /* not tested */ size = tvb_get_guint8 (tvb, offset); /* need to fetch identifier and display it */ proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier_size, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_sub_tree, hf_wtls_hands_cli_hello_key_identifier, tvb,offset,size,ENC_NA); offset+=size; client_size+=size+1; #ifdef DEBUG fprintf(stderr, "X.509 name size = %d, client_size = %d\n", size, client_size); #endif /* DEBUG */ break; } proto_item_set_len(cli_key_item, client_size); } /* process cipher_suites structure */ count = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_cipher_suite, tvb, offset, count+1, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); offset+=1; for (;count > 0;count-=client_size) { value = tvb_get_guint8 (tvb, offset); valBulk = try_val_to_str_ext(value, &wtls_vals_cipher_bulk_ext); offset++; client_size=1; valMac = try_val_to_str_ext(tvb_get_guint8 (tvb, offset), &wtls_vals_cipher_mac_ext); if (valBulk != NULL) { if (valMac != NULL) { g_snprintf(valStr,1024,"%s, %s",valBulk,valMac); } else { g_snprintf(valStr,1024,"%s, Unknown MAC (0x%02x)",valBulk,tvb_get_guint8 (tvb, offset)); } } else { if (valMac != NULL) { g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), %s",value,valMac); } else { g_snprintf(valStr,1024,"Unknown Bulk (0x%02x), Unknown MAC (0x%02x)",value, tvb_get_guint8 (tvb, offset)); } } offset++; client_size++; proto_tree_add_string(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_cipher_suite_item, tvb, offset-2,2, valStr); } count = tvb_get_guint8 (tvb, offset); ti = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_compression_methods, tvb, offset, count+1, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item_sub); offset+=1; for (;count > 0;count-=client_size) { client_size=0; proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_cli_hello_compression, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; } proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_sequence_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_cli_hello_key_refresh, tvb, offset, 1, ENC_LITTLE_ENDIAN); break; case WTLS_HANDSHAKE_SERVER_HELLO : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_serv_hello, tvb, offset, count, ENC_NA); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_version, tvb,offset,1,ENC_BIG_ENDIAN); offset++; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_gmt, tvb, offset, 4, &timeValue); offset+=4; proto_tree_add_item (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_random, tvb,offset,12,ENC_NA); offset+=12; offset = add_session_id (wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_session, hf_wtls_hands_serv_hello_session_str, tvb, offset); proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_cli_key_id, tvb,offset,1,ENC_BIG_ENDIAN); offset++; cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_cipher_suite_item, tvb, offset,2, ENC_NA); wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_serv_hello_cipher_bulk, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_serv_hello_cipher_mac, tvb,offset,1,ENC_BIG_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_compression, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_sequence_mode, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_serv_hello_key_refresh, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset++; break; case WTLS_HANDSHAKE_CERTIFICATE : ti = proto_tree_add_item(wtls_msg_type_tree, hf_wtls_hands_certificates, tvb, offset,count, ENC_NA); wtls_msg_type_item_tree = proto_item_add_subtree(ti, ett_wtls_msg_type_item); count = tvb_get_ntohs (tvb, offset); offset+=2; for (;count > 0;count-=client_size) { cli_key_item = proto_tree_add_item(wtls_msg_type_item_tree, hf_wtls_hands_certificate, tvb, offset,1, ENC_NA); client_size=0; wtls_msg_type_item_sub_tree = proto_item_add_subtree(cli_key_item, ett_wtls_msg_type_item_sub); proto_item_set_len(cli_key_item, client_size); value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; switch(value) { case CERTIFICATE_WTLS: proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_version, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_signature_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_issuer_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; switch (value) { case IDENTIFIER_NULL : break; case IDENTIFIER_TEXT : value = add_text_identifier(tvb, offset, hf_wtls_hands_certificate_wtls_issuer_charset, hf_wtls_hands_certificate_wtls_issuer_size, hf_wtls_hands_certificate_wtls_issuer_name, wtls_msg_type_item_sub_tree); offset += value; client_size += value; break; case IDENTIFIER_BIN : break; case IDENTIFIER_SHA_1 : break; case IDENTIFIER_X509 : break; } timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_valid_not_before, tvb, offset, 4, &timeValue); offset+=4; client_size+=4; timeValue.secs = tvb_get_ntohl (tvb, offset); timeValue.nsecs = 0; proto_tree_add_time (wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_valid_not_after, tvb, offset, 4, &timeValue); offset+=4; client_size+=4; value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_subject_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; switch (value) { case IDENTIFIER_NULL : break; case IDENTIFIER_TEXT : value = add_text_identifier(tvb, offset, hf_wtls_hands_certificate_wtls_subject_charset, hf_wtls_hands_certificate_wtls_subject_size, hf_wtls_hands_certificate_wtls_subject_name, wtls_msg_type_item_sub_tree); offset += value; client_size += value; break; case IDENTIFIER_BIN : break; case IDENTIFIER_SHA_1 : break; case IDENTIFIER_X509 : break; } public_key = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_public_key_type, tvb, offset,1, ENC_LITTLE_ENDIAN); offset++; client_size++; value = tvb_get_guint8 (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_key_parameter_index, tvb,offset,1,ENC_BIG_ENDIAN); offset++; client_size++; if (value == 0xff) { size = tvb_get_ntohs (tvb, offset); proto_tree_add_item(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_key_parameter_set, tvb,offset,size+2,ENC_ASCII|ENC_NA); offset+=size+2; client_size+=size+2; } switch (public_key) { case PUBLIC_KEY_RSA : value = tvb_get_ntohs (tvb, offset); proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_rsa_exponent, tvb,offset,value+2,value*8); offset+=2+value; client_size+=2+value; value = tvb_get_ntohs (tvb, offset); proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_rsa_modules, tvb,offset,value+2,value*8); offset+=2+value; client_size+=2+value; break; case PUBLIC_KEY_ECDH : break; case PUBLIC_KEY_ECDSA : break; } value = tvb_get_ntohs (tvb, offset); proto_tree_add_uint(wtls_msg_type_item_sub_tree, hf_wtls_hands_certificate_wtls_signature, tvb,offset,2+value,value*8); offset+=2+value; client_size+=2+value; break; case CERTIFICATE_X509: case CERTIFICATE_X968: value = tvb_get_ntohs (tvb, offset); offset+=2; client_size+=2; client_size += value; offset += value; break; case CERTIFICATE_URL: value = tvb_get_guint8 (tvb, offset); offset++; client_size++; client_size += value; offset += value; break; } proto_item_set_len(cli_key_item, client_size); } break; default: /*offset+=count;*/ break; } }
/* 5.1.1 Picture Start Code (PSC) (22 bits) PSC is a word of 22 bits. Its value is 0000 0000 0000 0000 1 00000. All picture start codes shall be byte aligned. ( 1000 00xx) End Of Sequence (EOS) (22 bits) A codeword of 22 bits. Its value is 0000 0000 0000 0000 1 11111. ( 1111 11xx ) Group of Block Start Code (GBSC) (17 bits) A word of 17 bits. Its value is 0000 0000 0000 0000 1. ( 1xxx xxxx ) End Of Sub-Bitstream code (EOSBS) (23 bits) The EOSBS code is a codeword of 23 bits. Its value is 0000 0000 0000 0000 1 11110 0. ( 1111 100x ) Slice Start Code (SSC) (17 bits) A word of 17 bits. Its value is 0000 0000 0000 0000 1. ( 1xxx xxxx ) */ static void dissect_h263_data( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree ) { guint offset = 0; proto_item *h263_payload_item = NULL; proto_tree *h263_payload_tree = NULL; guint32 data; guint8 startcode; int length; col_append_str( pinfo->cinfo, COL_INFO, "H263 payload "); if( tree ) { h263_payload_item = proto_tree_add_item( tree, proto_h263_data, tvb, offset, -1, ENC_NA ); h263_payload_tree = proto_item_add_subtree( h263_payload_item, ett_h263_payload ); } length = tvb_reported_length_remaining(tvb,0); if(length<4){ if( tree ) proto_tree_add_item( h263_payload_tree, hf_h263_data, tvb, offset, -1, ENC_NA ); return; } /* Check for PSC, PSC is a word of 22 bits. Its value is 0000 0000 0000 0000' 1000 00xx xxxx xxxx. */ data = tvb_get_ntohl(tvb, offset); if (( data & 0xffff8000) == 0x00008000 ) { /* Start Code found * * Startc code holds bit 17 -23 of the codeword */ startcode = tvb_get_guint8(tvb,offset+2)&0xfe; if (startcode & 0x80){ switch(startcode){ case 0xf8: /* End Of Sub-Bitstream code (EOSBS) * ( 1111 100. ) */ break; case 0x80: case 0x82: /* Picture Start Code (PSC) * ( 1000 00x.) */ col_append_str( pinfo->cinfo, COL_INFO, "(PSC) "); offset = dissect_h263_picture_layer( tvb, pinfo, h263_payload_tree, offset, -1, ENC_NA); break; case 0xfc: case 0xfe: /* End Of Sequence (EOS) * ( 1111 11x. ) */ default: /* Group of Block Start Code (GBSC) or * Slice Start Code (SSC) */ col_append_str( pinfo->cinfo, COL_INFO, "(GBSC) "); offset = dissect_h263_group_of_blocks_layer( tvb, h263_payload_tree, offset,FALSE); break; } }else{ /* Error */ } } if( tree ) proto_tree_add_item( h263_payload_tree, hf_h263_data, tvb, offset, -1, ENC_NA ); }
static void dissect_redback(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 l3off, dataoff, proto; proto_item *ti, *protocol_item; proto_tree *rbtree = NULL; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo,COL_PROTOCOL,"RBN"); dataoff = tvb_get_ntohs(tvb, 20); l3off = tvb_get_ntohs(tvb, 22); ti = proto_tree_add_item(tree, hfi_redback, tvb, 0, -1, ENC_NA); rbtree = proto_item_add_subtree(ti, ett_redback); proto_tree_add_item(rbtree, &hfi_redback_context, tvb, 0, 4, ENC_BIG_ENDIAN); proto_tree_add_item(rbtree, &hfi_redback_flags, tvb, 4, 4, ENC_BIG_ENDIAN); proto_tree_add_item(rbtree, &hfi_redback_circuit, tvb, 8, 8, ENC_BIG_ENDIAN); proto_tree_add_item(rbtree, &hfi_redback_length, tvb, 16, 2, ENC_BIG_ENDIAN); protocol_item = proto_tree_add_item(rbtree, &hfi_redback_protocol, tvb, 18, 2, ENC_BIG_ENDIAN); proto_tree_add_item(rbtree, &hfi_redback_dataoffset, tvb, 20, 2, ENC_BIG_ENDIAN); proto_tree_add_item(rbtree, &hfi_redback_l3offset, tvb, 22, 2, ENC_BIG_ENDIAN); if (dataoff > 24) { proto_tree_add_item(rbtree, &hfi_redback_padding, tvb, 24, dataoff-24, ENC_NA); } proto = tvb_get_ntohs(tvb, 18); switch(proto) { case 0x01: /* * IP on Ethernet - Incoming data points to an ethernet header * outgoing we have a pure IPv4 Packet */ next_tvb = tvb_new_subset_remaining(tvb, dataoff); if (dataoff == l3off) call_dissector(ipv4_handle, next_tvb, pinfo, tree); else if (dataoff+2 == l3off) call_dissector(ppp_handle, next_tvb, pinfo, tree); else if (dataoff+4 == l3off) call_dissector(ppphdlc_handle, next_tvb, pinfo, tree); else call_dissector(ethnofcs_handle, next_tvb, pinfo, tree); break; case 0x02: /* * This is ISIS - Either incoming with ethernet FCS * and CLNP - passed to the eth dissector or in case * of outgoing it's pure ISIS and the linecard attaches * the ethernet and CLNP headers ... * */ next_tvb = tvb_new_subset_remaining(tvb, dataoff); if (l3off > dataoff) { call_dissector(ethnofcs_handle, next_tvb, pinfo, tree); } else { guint8 nlpid = tvb_get_guint8(tvb, dataoff); if(dissector_try_uint(osinl_incl_subdissector_table, nlpid, next_tvb, pinfo, tree)) break; next_tvb = tvb_new_subset_remaining(tvb, dataoff+1); if(dissector_try_uint(osinl_excl_subdissector_table, nlpid, next_tvb, pinfo, tree)) break; next_tvb = tvb_new_subset_remaining(tvb, dataoff); call_dissector(data_handle, next_tvb, pinfo, tree); } break; case 0x06: { /* * PPP Messages e.g. LCP, IPCP etc - possibly on ethernet in case of PPPoE. * PPPoE messages are Protocol 8 ... */ guint32 flags; flags = tvb_get_ntohl(tvb, 4); if (flags & 0x04000000) { next_tvb = tvb_new_subset_remaining(tvb, dataoff); } else { if (tree) proto_tree_add_item(rbtree, &hfi_redback_unknown, tvb, dataoff, 4, ENC_NA); next_tvb = tvb_new_subset_remaining(tvb, dataoff+4); } if (l3off == dataoff) { call_dissector(ppp_handle, next_tvb, pinfo, tree); } else { call_dissector(ethnofcs_handle, next_tvb, pinfo, tree); } break; } case 0x03: /* Unicast Ethernet tx - Seen with PPPoE PADO */ case 0x04: /* Unicast Ethernet rx - Seen with ARP */ case 0x08: /* Broadcast Ethernet rx - Seen with PPPoE PADI */ next_tvb = tvb_new_subset_remaining(tvb, dataoff); call_dissector(ethnofcs_handle, next_tvb, pinfo, tree); break; case 0x09: /* IPv6 either encapsulated as ethernet or native ip */ next_tvb = tvb_new_subset_remaining(tvb, dataoff); if (dataoff == l3off) call_dissector(ipv6_handle, next_tvb, pinfo, tree); else call_dissector(ethnofcs_handle, next_tvb, pinfo, tree); break; default: expert_add_info(pinfo, protocol_item, &ei_redback_protocol); break; } return; }
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, *wsmdata_item; proto_tree *wsmp_tree, *wsmdata_tree; tvbuff_t *wsmdata_tvb; guint16 wsmlength, offset; guint32 psidLen, psid; guint8 elemenId, elemenLen, msb, supLen; /* 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_ntohl(tvb, offset); psid = psid & 0x00FFFF; /* three bytes */ } 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; elemenId = tvb_get_guint8(tvb, offset); while ((elemenId != WSMP) && (elemenId != WSMP_S) && (elemenId != WSMP_I)) { offset++; if (elemenId == CHANNUM) { /* channel number */ 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) { /* Data rate */ 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) { /* Transmit power */ 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_item = proto_tree_add_text (wsmp_tree, tvb, offset, wsmlength, "Wave Short Message"); wsmdata_tree = proto_item_add_subtree(wsmdata_item, ett_wsmdata); 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_kdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint body_len; guint8 version = 0; guint8 header_len = 0; guint8 packet_flags = 0; guint8 packet_errors = 0; guint32 sequence_number = G_MAXUINT32; guint32 ack_number = G_MAXUINT32; guint32 src_flowid = G_MAXUINT32; int offset; col_set_str(pinfo->cinfo, COL_PROTOCOL, "KDP"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { proto_item *ti; proto_tree *kdp_tree, *flags_tree; ti = NULL; kdp_tree = NULL; flags_tree = NULL; ti = proto_tree_add_item(tree, proto_kdp, tvb, 0, -1, ENC_NA); kdp_tree = proto_item_add_subtree(ti, ett_kdp); version = tvb_get_guint8(tvb, 0); if (version != 2) { /* Version other than 2 is really SDDP in UDP */ proto_tree_add_item(kdp_tree, hf_kdp_version, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(kdp_tree, hf_kdp_xml_body, tvb, 0, -1, ENC_ASCII|ENC_NA); } else { header_len = tvb_get_guint8(tvb, 1) * 4; body_len = tvb_reported_length(tvb); if (header_len > body_len) { body_len = 0; /* malformed packet */ } else { body_len = body_len - header_len; } packet_flags = tvb_get_guint8(tvb, 2); packet_errors = tvb_get_guint8(tvb, 3); proto_tree_add_item(kdp_tree, hf_kdp_version, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(kdp_tree, hf_kdp_headerlen, tvb, 1, 1, ENC_BIG_ENDIAN); ti = proto_tree_add_item(kdp_tree, hf_kdp_flags, tvb, 2, 1, ENC_BIG_ENDIAN); flags_tree = proto_item_add_subtree(ti, ett_kdp_flags); proto_tree_add_item(flags_tree, hf_kdp_drop_flag, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flags_tree, hf_kdp_syn_flag, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flags_tree, hf_kdp_ack_flag, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flags_tree, hf_kdp_rst_flag, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flags_tree, hf_kdp_bcst_flag, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(flags_tree, hf_kdp_dup_flag, tvb, 2, 1, ENC_BIG_ENDIAN); proto_tree_add_item(kdp_tree, hf_kdp_errors, tvb, 3, 1, ENC_BIG_ENDIAN); if (header_len > 4) { offset = 4; if (packet_flags & KDP_ACK_FLAG) { proto_tree_add_item(kdp_tree, hf_kdp_destflowid, tvb, offset, 4, ENC_BIG_ENDIAN); offset = offset + 4; } if (packet_flags & (KDP_SYN_FLAG | KDP_BCST_FLAG)) { proto_tree_add_item(kdp_tree, hf_kdp_srcflowid, tvb, offset, 4, ENC_BIG_ENDIAN); src_flowid = tvb_get_ntohl(tvb, offset); offset = offset + 4; } proto_tree_add_item(kdp_tree, hf_kdp_sequence, tvb, offset, 4, ENC_BIG_ENDIAN); sequence_number = tvb_get_ntohl(tvb, offset); offset = offset + 4; if (packet_flags & KDP_ACK_FLAG) { proto_tree_add_item(kdp_tree, hf_kdp_ack, tvb, offset, 4, ENC_BIG_ENDIAN); ack_number = tvb_get_ntohl(tvb, offset); offset = offset + 4; } if (packet_flags & KDP_SYN_FLAG) { proto_tree_add_item(kdp_tree, hf_kdp_maxsegmentsize, tvb, offset, 4, ENC_BIG_ENDIAN); offset = offset + 4; } while (offset < ((body_len > 0) ? header_len - 4 : header_len)) { guint8 option_number; guint8 option_len = 0; option_number = tvb_get_guint8(tvb, offset); proto_tree_add_item(kdp_tree, hf_kdp_optionnumber, tvb, offset, 1, ENC_BIG_ENDIAN); offset = offset + 1; if (option_number > 0) { option_len = tvb_get_guint8(tvb, offset); proto_tree_add_item(kdp_tree, hf_kdp_optionlen, tvb, offset, 1, ENC_BIG_ENDIAN); offset = offset + 1; } switch (option_number) { case 0: break; case 1: proto_tree_add_item(kdp_tree, hf_kdp_option1, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; break; case 2: proto_tree_add_item(kdp_tree, hf_kdp_option2, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; break; case 3: proto_tree_add_item(kdp_tree, hf_kdp_option3, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; break; case 4: proto_tree_add_item(kdp_tree, hf_kdp_option4, tvb, offset, 0, ENC_NA); break; case 5: proto_tree_add_item(kdp_tree, hf_kdp_option5, tvb, offset, 0, ENC_NA); break; case 6: proto_tree_add_item(kdp_tree, hf_kdp_option6, tvb, offset, option_len - 2, ENC_NA); offset = offset + option_len - 2; break; case 7: proto_tree_add_item(kdp_tree, hf_kdp_option7, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; break; case 8: proto_tree_add_item(kdp_tree, hf_kdp_option8, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; break; case 9: proto_tree_add_item(kdp_tree, hf_kdp_option9, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; break; default: proto_tree_add_item(kdp_tree, hf_kdp_option_unknown, tvb, offset, option_len - 2, ENC_NA); offset = offset + option_len - 2; break; } } if (body_len > 0) { proto_tree_add_item(kdp_tree, hf_kdp_fragment, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; proto_tree_add_item(kdp_tree, hf_kdp_fragtotal, tvb, offset, 2, ENC_BIG_ENDIAN); offset = offset + 2; proto_tree_add_item(kdp_tree, hf_kdp_body, tvb, offset, -1, ENC_NA); } } } } /* Now that we know sequence number and optional ack number, we can print more detailed summary info */ if (version != 2) { col_set_str(pinfo->cinfo, COL_INFO, "SDDP message"); } else { char ack_string[BUFFER_SIZE]; char seq_num_string[BUFFER_SIZE]; char src_flowid_string[BUFFER_SIZE]; if (packet_flags & KDP_ACK_FLAG) { g_snprintf(ack_string, sizeof(ack_string), "ACK=%x ", ack_number); } else { ack_string[0] = '\0'; } if (header_len > 4) { g_snprintf(seq_num_string, sizeof(seq_num_string), "SEQ=%x ", sequence_number); } else { seq_num_string[0] = '\0'; } if (packet_flags & (KDP_SYN_FLAG | KDP_BCST_FLAG)) { g_snprintf(src_flowid_string, sizeof(src_flowid_string), "SRC_FLOWID=%x ", src_flowid); } else { src_flowid_string[0] = '\0'; } col_add_fstr(pinfo->cinfo, COL_INFO, "%s%s%s%s%s%s%s%serrors=%d", ((packet_flags & KDP_DROP_FLAG) ? "DROP " : ""), ((packet_flags & KDP_SYN_FLAG) ? "SYN " : ""), ((packet_flags & KDP_RST_FLAG) ? "RST " : ""), ((packet_flags & KDP_BCST_FLAG) ? "BCST " : ""), ((packet_flags & KDP_DUP_FLAG) ? "DUP " : ""), ack_string, seq_num_string, src_flowid_string, packet_errors); } }
proto_tree *tree=NULL; proto_item *item=NULL; conversation_t *conversation; nbd_conv_info_t *nbd_info; nbd_transaction_t *nbd_trans=NULL; wmem_tree_key_t hkey[3]; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBD"); col_clear(pinfo->cinfo, COL_INFO); item = proto_tree_add_item(parent_tree, proto_nbd, tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_nbd); magic=tvb_get_ntohl(tvb, offset); proto_tree_add_item(tree, hf_nbd_magic, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; /* grab what we need to do the request/response matching */ switch(magic){ case NBD_REQUEST_MAGIC: case NBD_RESPONSE_MAGIC: handle[0]=tvb_get_ntohl(tvb, offset+4); handle[1]=tvb_get_ntohl(tvb, offset+8); break; default: return 4; }