static void dissect_nmpi(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *nmpi_tree = NULL; proto_item *ti; int offset = 0; guint8 opcode; guint8 nmpi_name_type; char name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int name_type; char node_name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int node_name_type = 0; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NMPI"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { ti = proto_tree_add_item(tree, proto_nmpi, tvb, offset, 68, FALSE); nmpi_tree = proto_item_add_subtree(ti, ett_nmpi); add_routers(nmpi_tree, tvb, offset); } offset += 32; /* * XXX - we don't use "node_name" or "node_name_type". */ opcode = tvb_get_guint8(tvb, offset); nmpi_name_type = tvb_get_guint8(tvb, offset+1); name_type = get_netbios_name(tvb, offset+4, name, (NETBIOS_NAME_LEN - 1)*4 + 1); node_name_type = get_netbios_name(tvb, offset+20, node_name, (NETBIOS_NAME_LEN - 1)*4 + 1); if (check_col(pinfo->cinfo, COL_INFO)) { switch (opcode) { case INAME_CLAIM: col_add_fstr(pinfo->cinfo, COL_INFO, "Claim name %s<%02x>", name, name_type); break; case INAME_DELETE: col_add_fstr(pinfo->cinfo, COL_INFO, "Delete name %s<%02x>", name, name_type); break; case INAME_QUERY: col_add_fstr(pinfo->cinfo, COL_INFO, "Query name %s<%02x>", name, name_type); break; case INAME_FOUND: col_add_fstr(pinfo->cinfo, COL_INFO, "Name %s<%02x> found", name, name_type); break; case IMSG_HANGUP: col_add_fstr(pinfo->cinfo, COL_INFO, "Messenger hangup on %s<%02x>", name, name_type); break; case IMSLOT_SEND: col_add_fstr(pinfo->cinfo, COL_INFO, "Mailslot write to %s<%02x>", name, name_type); break; case IMSLOT_FIND: col_add_fstr(pinfo->cinfo, COL_INFO, "Find mailslot name %s<%02x>", name, name_type); break; case IMSLOT_NAME: col_add_fstr(pinfo->cinfo, COL_INFO, "Mailslot name %s<%02x> found", name, name_type); break; default: col_add_fstr(pinfo->cinfo, COL_INFO, "Unknown NMPI op 0x%02x: name %s<%02x>", opcode, name, name_type); break; } } if (tree) { proto_tree_add_text(nmpi_tree, tvb, offset, 1, "Opcode: %s (0x%02x)", val_to_str(opcode, nmpi_opcode_vals, "Unknown"), opcode); proto_tree_add_text(nmpi_tree, tvb, offset+1, 1, "Name Type: %s (0x%02x)", val_to_str(nmpi_name_type, nmpi_name_type_vals, "Unknown"), nmpi_name_type); proto_tree_add_text(nmpi_tree, tvb, offset+2, 2, "Message ID: 0x%04x", tvb_get_letohs(tvb, offset+2)); netbios_add_name("Requested name", tvb, offset+4, nmpi_tree); netbios_add_name("Source name", tvb, offset+20, nmpi_tree); } offset += 1 + 1 + 2 + NETBIOS_NAME_LEN + NETBIOS_NAME_LEN; if (opcode == IMSLOT_SEND && tvb_offset_exists(tvb, offset)) { next_tvb = tvb_new_subset_remaining(tvb, offset); dissect_netbios_payload(next_tvb, pinfo, tree); } }
static int dissect_dtpt_sockaddr(tvbuff_t *tvb, guint offset, proto_tree *tree, int hfindex, int sockaddr_type) { guint32 sockaddr_length = 0; proto_item *sockaddr_item = NULL; proto_tree *sockaddr_tree = NULL; guint32 sockaddr_len1 = 0; guint32 sockaddr_len2 = 0; switch (sockaddr_type) { case SOCKADDR_WITH_LEN: sockaddr_len1=4; sockaddr_len2=16; break; case SOCKADDR_CONNECT: sockaddr_len1=0; sockaddr_len2=30; break; } if (sockaddr_type == SOCKADDR_WITH_LEN) sockaddr_length = tvb_get_letohl(tvb, offset + 0); if (tree) { sockaddr_item = proto_tree_add_text(tree, tvb, offset, sockaddr_len1+sockaddr_len2, "%s", proto_registrar_get_name(hfindex)); if (sockaddr_item) sockaddr_tree = proto_item_add_subtree(sockaddr_item, ett_dtpt_sockaddr); if (sockaddr_tree) { if (sockaddr_type == SOCKADDR_WITH_LEN) proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_length, tvb, offset+0, 4, sockaddr_length); } } offset += sockaddr_len1; if (sockaddr_tree) { switch (sockaddr_type) { case SOCKADDR_WITH_LEN: { guint16 family; family = tvb_get_letohs(tvb, offset); proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_family, tvb, offset, 2, family); switch (family) { case WINSOCK_AF_INET: { guint16 port; guint32 addr; port = tvb_get_ntohs(tvb,offset+2); proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_port, tvb, offset+2,2,port); addr = tvb_get_ipv4(tvb,offset+4); proto_tree_add_ipv4(sockaddr_tree, hf_dtpt_sockaddr_address, tvb, offset+4,4,addr); proto_tree_add_text(sockaddr_tree, tvb, offset+8, 8, "Padding"); proto_item_append_text(sockaddr_item, ": %s:%d", ip_to_str((guint8*)&addr), port); } break; } } break; case SOCKADDR_CONNECT: { guint32 family; family = tvb_get_letohl(tvb, offset+0); proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_family, tvb, offset+0, 4, family); switch (family) { case WINSOCK_AF_INET: { guint16 port; guint32 addr; proto_tree_add_text(sockaddr_tree, tvb, offset+4, 4, "Padding"); port = tvb_get_ntohs(tvb,offset+8); proto_tree_add_uint(sockaddr_tree, hf_dtpt_sockaddr_port, tvb, offset+8,2,port); addr = tvb_get_ipv4(tvb,offset+10); proto_tree_add_ipv4(sockaddr_tree, hf_dtpt_sockaddr_address, tvb, offset+10,4,addr); proto_tree_add_text(sockaddr_tree, tvb, offset+14, 16, "Padding"); proto_item_append_text(sockaddr_item, ": %s:%d", ip_to_str((guint8*)&addr), port); } break; } } break; } } offset += sockaddr_len2; return offset; }
gboolean dissect_mailslot_smb(tvbuff_t *mshdr_tvb, tvbuff_t *setup_tvb, tvbuff_t *tvb, const char *mailslot, packet_info *pinfo, proto_tree *parent_tree, smb_info_t* smb_info) { smb_transact_info_t *tri; int trans_subcmd; proto_tree *tree = NULL; proto_item *item = NULL; guint16 opcode; int offset = 0; int len; if (!proto_is_protocol_enabled(find_protocol_by_id(proto_smb_msp))) { return FALSE; } pinfo->current_proto = "SMB Mailslot"; col_set_str(pinfo->cinfo, COL_PROTOCOL, "SMB Mailslot"); if ((tvb==NULL) || (tvb_reported_length(tvb)==0)) { /* Interim reply */ col_set_str(pinfo->cinfo, COL_INFO, "Interim reply"); return TRUE; } col_clear(pinfo->cinfo, COL_INFO); if (smb_info->sip != NULL && smb_info->sip->extra_info_type == SMB_EI_TRI) tri = (smb_transact_info_t *)smb_info->sip->extra_info; else tri = NULL; /* check which mailslot this is about */ trans_subcmd=MAILSLOT_UNKNOWN; if(smb_info->request){ if(strncmp(mailslot,"BROWSE",6) == 0){ trans_subcmd=MAILSLOT_BROWSE; } else if(strncmp(mailslot,"LANMAN",6) == 0){ trans_subcmd=MAILSLOT_LANMAN; } else if(strncmp(mailslot,"NET",3) == 0){ trans_subcmd=MAILSLOT_NET; } else if(strncmp(mailslot,"TEMP\\NETLOGON",13) == 0){ trans_subcmd=MAILSLOT_TEMP_NETLOGON; } else if(strncmp(mailslot,"MSSP",4) == 0){ trans_subcmd=MAILSLOT_MSSP; } if (!pinfo->fd->flags.visited) { if (tri != NULL) tri->trans_subcmd = trans_subcmd; } } else { if(!tri){ return FALSE; } else { trans_subcmd = tri->trans_subcmd; } } /* Only do these ones if we have them. For fragmented SMB Transactions we may only have the setup area for the first fragment */ if(mshdr_tvb && setup_tvb){ if (parent_tree) { item = proto_tree_add_item(parent_tree, proto_smb_msp, mshdr_tvb, 0, -1, ENC_NA); tree = proto_item_add_subtree(item, ett_smb_msp); } /* do the opcode field */ opcode = tvb_get_letohs(setup_tvb, offset); col_add_str(pinfo->cinfo, COL_INFO, val_to_str(opcode, opcode_vals, "Unknown opcode: 0x%04x")); /* These are in the setup words; use "setup_tvb". */ /* opcode */ proto_tree_add_uint(tree, hf_opcode, setup_tvb, offset, 2, opcode); offset += 2; /* priority */ proto_tree_add_item(tree, hf_priority, setup_tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; /* class */ proto_tree_add_item(tree, hf_class, setup_tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; /* These are in the rest of the data; use "mshdr_tvb", which starts at the same place "setup_tvb" does. */ /* size */ /* this is actually bytecount in the SMB Transaction command */ proto_tree_add_item(tree, hf_size, mshdr_tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; /* mailslot name */ len = tvb_strsize(mshdr_tvb, offset); proto_tree_add_item(tree, hf_name, mshdr_tvb, offset, len, ENC_ASCII|ENC_NA); offset += len; proto_item_set_len(item, offset); } switch(trans_subcmd){ case MAILSLOT_BROWSE: call_dissector(mailslot_browse_handle, tvb, pinfo, parent_tree); break; case MAILSLOT_LANMAN: call_dissector(mailslot_lanman_handle, tvb, pinfo, parent_tree); break; case MAILSLOT_NET: case MAILSLOT_TEMP_NETLOGON: case MAILSLOT_MSSP: call_dissector(netlogon_handle, tvb, pinfo, parent_tree); break; default: /* * We dissected the mailslot header, but we don't know * how to dissect the message; dissect the latter as data, * but indicate that we successfully dissected the mailslot * stuff. */ call_dissector(data_handle ,tvb, pinfo, parent_tree); break; } return TRUE; }
/* Dissect a TS2 packet */ static void dissect_ts2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { ts2_conversation *conversation_data; guint16 type = tvb_get_letohs(tvb, 2); guint16 klass = tvb_get_letohs(tvb, 0); conversation_data = ts2_get_conversation(pinfo); col_set_str(pinfo->cinfo, COL_PROTOCOL, "TS2"); if(klass==TS2C_ACK) col_add_fstr(pinfo->cinfo, COL_INFO, "Class: %s", val_to_str(klass, classnames, "Unknown (0x%02x)")); else col_add_fstr(pinfo->cinfo, COL_INFO, "Type: %s, Class: %s", val_to_str(type, typenames, "Unknown (0x%02x)"), val_to_str(klass, classnames, "Unknown (0x%02x)")); /* XXX: We need to do all the non GUI stuff whether or not if(tree) */ /* Do only once by checking visited ? */ /* ToDo: Rewrite ?? */ if (!tree) { switch(klass) { case TS2C_CONNECTION: switch(type) { case TS2T_LOGINREQUEST: conversation_data->server_port=pinfo->destport; conversation_data->server_addr=pinfo->dst; break; } break; case TS2C_STANDARD: ts2_standard_dissect(tvb, pinfo, tree, conversation_data); break; } } if (tree) { /* we are being asked for details */ proto_item *ti = NULL; proto_tree *ts2_tree = NULL; ti = proto_tree_add_item(tree, proto_ts2, tvb, 0, -1, ENC_NA); ts2_tree = proto_item_add_subtree(ti, ett_ts2); proto_tree_add_item(ts2_tree, hf_ts2_class, tvb, 0, 2, ENC_LITTLE_ENDIAN); if(klass==TS2C_ACK) proto_tree_add_item(ts2_tree, hf_ts2_resend_count, tvb, 2, 2, ENC_LITTLE_ENDIAN); else proto_tree_add_item(ts2_tree, hf_ts2_type, tvb, 2, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(ts2_tree, hf_ts2_sessionkey, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(ts2_tree, hf_ts2_clientid, tvb, 8, 4, ENC_LITTLE_ENDIAN); switch(klass) { case TS2C_CONNECTION: proto_tree_add_item(ts2_tree, hf_ts2_seqnum, tvb, 12, 4, ENC_LITTLE_ENDIAN); ts2_add_checked_crc32(ts2_tree, hf_ts2_crc32, tvb, 16, tvb_get_letohl(tvb, 16)); switch(type) { case TS2T_PING: break; case TS2T_PINGREPLY: proto_tree_add_item(ts2_tree, hf_ts2_ackto, tvb, 20, 4, ENC_LITTLE_ENDIAN); break; case TS2T_LOGINREQUEST: proto_tree_add_item(ts2_tree, hf_ts2_protocol_string, tvb, 20, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_platform_string, tvb, 50, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, 80, 9, ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_registeredlogin, tvb, 90, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(ts2_tree, hf_ts2_name, tvb, 90, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_password, tvb, 120, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_nick, tvb, 150, 1, ENC_ASCII|ENC_NA); conversation_data->server_port=pinfo->destport; conversation_data->server_addr=pinfo->dst; break; case TS2T_LOGINREPLY: proto_tree_add_item(ts2_tree, hf_ts2_server_name, tvb, 20, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_platform_string, tvb, 50, 1, ENC_ASCII|ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, 80, 9, ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_badlogin, tvb, 89, 3, ENC_LITTLE_ENDIAN); proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, 92, 80, ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_sessionkey, tvb, 172, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(ts2_tree, hf_ts2_unknown, tvb, 178, 3, ENC_NA); proto_tree_add_item(ts2_tree, hf_ts2_server_welcome_message, tvb, 180, 1, ENC_ASCII|ENC_NA); break; } break; case TS2C_ACK: /* Ignore the type for ACK, it's always zero and clashes with CELP_5_1 */ proto_tree_add_item(ts2_tree, hf_ts2_seqnum, tvb, 12, 4, ENC_LITTLE_ENDIAN); break; case TS2C_STANDARD: ts2_standard_dissect(tvb, pinfo, ts2_tree, conversation_data); break; } } /* if (tree) */ }
static int hf_egd_stat = -1; static int hf_egd_csig = -1; static int hf_egd_resv = -1; static gint ett_egd = -1; static gint ett_status_item = -1; static int dissect_egd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) { /* replace UDP with EGD in display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "EGD"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); col_add_fstr(pinfo->cinfo, COL_INFO, "Data Msg: ExchangeID=0x%08X, RequestID=%05u", tvb_get_letohl(tvb, 8), tvb_get_letohs(tvb, 2)); if (tree) { proto_item *ti = NULL; proto_item *notime = NULL; proto_tree *egd_tree = NULL; tvbuff_t *next_tvb = NULL; gint offset, data_length; guint32 sectime; nstime_t egd_time; memset(&egd_time, 0, sizeof(nstime_t)); offset = 0; ti = proto_tree_add_item(tree, proto_egd, tvb, 0, -1, ENC_NA);
/*FUNCTION:------------------------------------------------------ * NAME * zdp_parse_bind_table_entry * DESCRIPTION * Parses and displays a single binding table entry. * PARAMETERS * tvbuff_t *tvb - pointer to buffer containing raw packet. * packet_into *pinfo - pointer to packet information fields * proto_tree *tree - pointer to data tree Wireshark uses to display packet. * RETURNS * void *--------------------------------------------------------------- */ void zdp_parse_bind_table_entry(proto_tree *tree, tvbuff_t *tvb, guint *offset, guint8 version) { proto_item *ti = NULL; guint len = 0; guint64 src64; guint8 src_ep; guint16 cluster; guint8 mode; guint64 dst64; guint16 dst; guint8 dst_ep; /* Add the source address. */ src64 = tvb_get_letoh64(tvb, *offset + len); if (tree) ti = proto_tree_add_text(tree, tvb, *offset, 0, "Bind {Src: %s", ep_eui64_to_display(src64)); len += (int)sizeof(guint64); /* Add the source endpoint. */ src_ep = tvb_get_guint8(tvb, *offset + len); if (tree) proto_item_append_text(ti, ", Src Endpoint: %d", src_ep); len += (int)sizeof(guint8); /* Add the cluster ID. */ if (version >= ZBEE_VERSION_2007) { cluster = tvb_get_letohs(tvb, *offset + len); len += (int)sizeof(guint16); } else { cluster = tvb_get_guint8(tvb, *offset + len); len += (int)sizeof(guint8); } if (tree) proto_item_append_text(ti, ", Cluster: %d", cluster); /* Get the destination address mode. */ if (version >= ZBEE_VERSION_2007) { mode = tvb_get_guint8(tvb, *offset + len); len += (int)sizeof(guint8); } else { /* Mode field doesn't exist and always uses unicast in 2003 & earlier. */ mode = ZBEE_ZDP_ADDR_MODE_UNICAST; } /* Add the destination address. */ if (mode == ZBEE_ZDP_ADDR_MODE_GROUP) { dst = tvb_get_letohs(tvb, *offset + len); if (tree) proto_item_append_text(ti, ", Dst: 0x%04x}", dst); len += (int)sizeof(guint16); } else if (mode == ZBEE_ZDP_ADDR_MODE_UNICAST) { dst64 = tvb_get_letoh64(tvb, *offset + len); if (tree) proto_item_append_text(ti, ", Dst: %s", ep_eui64_to_display(dst64)); len += (int)sizeof(guint64); dst_ep = tvb_get_guint8(tvb, *offset + len); if (tree) proto_item_append_text(ti, ", Dst Endpoint: %d}", dst_ep); len += (int)sizeof(guint8); } else { if (tree) proto_item_append_text(ti, "}"); } if (tree) { proto_item_set_len(ti, len); } *offset += len; } /* zdp_parse_bind_table_entry */
{ 0, NULL } }; static const value_string disc_status_vals[] = { { 0x0000, "Success" }, { 0x0001, "Invalid Controller ID" }, { 0x0002, "Failed - No Physical Link exists and no Physical Link creation is in progress" }, { 0, NULL } }; static int dissect_comrej(tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree) { guint16 reason; reason = tvb_get_letohs(tvb, offset); proto_tree_add_item(tree, hf_btamp_rej_reason, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; switch (reason) { case 0x0000: /* Command not understood */ break; default: break; } return offset; } static int
static void NvVarHeaderFormater(tvbuff_t *tvb, gint offset, char *szText, int nMax) { g_snprintf ( szText, nMax, "Variable - Id = %d, Length = %d", tvb_get_letohs(tvb, offset), tvb_get_letohs(tvb, offset+4)); }
static void dissect_nv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *nv_tree, *nv_header_tree, *nv_var_tree,*nv_varheader_tree; gint offset = 0; char szText[200]; int nMax = (int)sizeof(szText)-1; gint i; col_set_str(pinfo->cinfo, COL_PROTOCOL, "TC-NV"); col_clear(pinfo->cinfo, COL_INFO); NvSummaryFormater(tvb, offset, szText, nMax); col_append_str(pinfo->cinfo, COL_INFO, szText); if (tree) { guint16 nv_count; ti = proto_tree_add_item(tree, proto_nv, tvb, 0, -1, ENC_NA); nv_tree = proto_item_add_subtree(ti, ett_nv); proto_item_append_text(ti,": %s",szText); ti = proto_tree_add_item(nv_tree, hf_nv_header, tvb, offset, NvParserHDR_Len, ENC_NA); nv_header_tree = proto_item_add_subtree(ti, ett_nv_header); ti= proto_tree_add_item(nv_header_tree, hf_nv_publisher, tvb, offset, (int)sizeof(guint8)*6, ENC_NA); NvPublisherFormater(tvb, offset, szText, nMax); proto_item_set_text(ti, "%s", szText); offset+=((int)sizeof(guint8)*6); proto_tree_add_item(nv_header_tree, hf_nv_count, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); nv_count = tvb_get_letohs(tvb, offset); offset+=(int)sizeof(guint16); proto_tree_add_item(nv_header_tree, hf_nv_cycleindex, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); offset = NvParserHDR_Len; for ( i=0; i < nv_count; i++ ) { guint16 var_length = tvb_get_letohs(tvb, offset+4); ti = proto_tree_add_item(nv_tree, hf_nv_variable, tvb, offset, ETYPE_88A4_NV_DATA_HEADER_Len+var_length, ENC_NA); NvVarHeaderFormater(tvb, offset, szText, nMax); proto_item_set_text(ti, "%s", szText); nv_var_tree = proto_item_add_subtree(ti, ett_nv_var); ti = proto_tree_add_item(nv_var_tree, hf_nv_varheader, tvb, offset, ETYPE_88A4_NV_DATA_HEADER_Len, ENC_NA); nv_varheader_tree = proto_item_add_subtree(ti, ett_nv_varheader); proto_tree_add_item(nv_varheader_tree, hf_nv_id, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); offset+=(int)sizeof(guint16); proto_tree_add_item(nv_varheader_tree, hf_nv_hash, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); offset+=(int)sizeof(guint16); proto_tree_add_item(nv_varheader_tree, hf_nv_length, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); offset+=(int)sizeof(guint16); proto_tree_add_item(nv_varheader_tree, hf_nv_quality, tvb, offset, (int)sizeof(guint16), ENC_LITTLE_ENDIAN); offset+=(int)sizeof(guint16); proto_tree_add_item(nv_var_tree, hf_nv_data, tvb, offset, var_length, ENC_NA); offset+=var_length; } } }
static int dissect_groupd(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data) { guint length; int offset; /* int sub_length; */ gboolean little_endian; proto_tree *tree; proto_item *item; guint16 msg_type; length = tvb_length(tvb); #define length_groupd ( (4 * 3) + 2 + 2 + 4 + 4 + 8 + GROUPD_MAX_NAMELEN ) if (length < (length_groupd)) return 0; /* if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, "groupd"); */ /* if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO); */ if (check_col(pinfo->cinfo, COL_INFO)) col_append_sep_str(pinfo->cinfo, COL_INFO, " ", "groupd"); if (!parent_tree) goto out; /* */ little_endian = TRUE; offset = 0; item = proto_tree_add_item(parent_tree, proto_groupd, tvb, offset, -1, little_endian); tree = proto_item_add_subtree(item, ett_groupd); /* TODO: Version check */ offset += 0; proto_tree_add_item(tree, hf_groupd_msg_version_major, tvb, offset, 4, little_endian); offset += 4; proto_tree_add_item(tree, hf_groupd_msg_version_minor, tvb, offset, 4, little_endian); offset += 4; proto_tree_add_item(tree, hf_groupd_msg_version_patch, tvb, offset, 4, little_endian); offset += 4; proto_tree_add_item(tree, hf_groupd_msg_type, tvb, offset, 2, little_endian); msg_type = tvb_get_letohs(tvb, offset); offset += 2; proto_tree_add_item(tree, hf_groupd_msg_level, tvb, offset, 2, little_endian); offset += 2; proto_tree_add_item(tree, hf_groupd_msg_length, tvb, offset, 4, little_endian); offset += 4; { proto_item* sub_item; proto_tree* sub_tree; sub_item = proto_tree_add_item(tree, hf_groupd_msg_global_id, tvb, offset, 4, little_endian); sub_tree = proto_item_add_subtree(sub_item, ett_groupd_msg_global_id); if (msg_type != GROUPD_MSG_GLOBAL_ID) { proto_item_append_text(sub_item, " (may not be used)"); } /* Dissect global_id global_id & 0x0000FFFF => to_nodeid ((global_id >> 16) & 0x0000FFFF) => counter */ proto_tree_add_item(sub_tree, hf_groupd_msg_global_id_to_nodeid, tvb, offset, 2, little_endian); proto_tree_add_item(sub_tree, hf_groupd_msg_global_id_counter, tvb, offset + 2, 2, little_endian); } offset += 4; { proto_item* sub_item; proto_tree* sub_tree; sub_item = proto_tree_add_item(tree, hf_groupd_msg_event_id, tvb, offset, 8, little_endian); sub_tree = proto_item_add_subtree(sub_item, ett_groupd_msg_event_id); proto_tree_add_item(sub_tree, hf_groupd_msg_event_id_type, tvb, offset, 2, little_endian); proto_tree_add_item(sub_tree, hf_groupd_msg_event_id_member_count, tvb, offset + 2, 2, little_endian); proto_tree_add_item(sub_tree, hf_groupd_msg_event_id_nodeid, tvb, offset + 2 + 2, 4, little_endian); } offset += 8; proto_tree_add_item(tree, hf_groupd_msg_name, tvb, offset, GROUPD_MAX_NAMELEN, little_endian); offset += GROUPD_MAX_NAMELEN; out: return length; }
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_interlink(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { int offset = 0; proto_tree *il_tree = NULL; proto_tree *ilh_tree = NULL; proto_tree *ilb_tree = NULL; guint8 ilb_type; guint8 ilb_version; guint16 type_version = 0; dissector_handle_t handle; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "INTERLINK"); col_clear(pinfo->cinfo, COL_INFO); if (tree) { proto_item *il_item; il_item = proto_tree_add_item(tree, proto_interlink, tvb, 0, 16, FALSE); if (il_item) il_tree = proto_item_add_subtree(il_item, ett_interlink); } if (il_tree) { proto_item *ilh_item = NULL; ilh_item = proto_tree_add_text(il_tree, tvb, 0, 12, "Interlink Header"); if (ilh_item) ilh_tree = proto_item_add_subtree(ilh_item, ett_interlink_header); } if (ilh_tree) { proto_tree_add_item(ilh_tree, hf_interlink_id, tvb, offset, 4, FALSE); offset += 4; proto_tree_add_item(ilh_tree, hf_interlink_version, tvb, offset, 2, TRUE); offset += 2; proto_tree_add_item(ilh_tree, hf_interlink_cmd, tvb, offset, 2, TRUE); offset += 2; proto_tree_add_item(ilh_tree, hf_interlink_seq, tvb, offset, 2, TRUE); offset += 2; } else { offset += 10; } if (ilh_tree) { proto_item *flags_item; proto_tree *flags_tree = NULL; flags_item = proto_tree_add_item(ilh_tree, hf_interlink_flags, tvb, offset, 2, TRUE); if (flags_item) { flags_tree = proto_item_add_subtree(flags_item, ett_interlink_flags); } if (flags_tree) { guint16 il_flags; il_flags = tvb_get_letohs(tvb, offset); proto_tree_add_boolean(flags_tree, hf_interlink_flags_req_ack, tvb, offset, 2, il_flags); proto_tree_add_boolean(flags_tree, hf_interlink_flags_inc_ack_port, tvb, offset, 2, il_flags); } } offset += 2; if (tree) { proto_item *ilb_item; ilb_item = proto_tree_add_text(il_tree, tvb, offset, 4, "Block Header"); if (ilb_item) ilb_tree = proto_item_add_subtree(ilb_item, ett_interlink_block); } ilb_type = tvb_get_guint8(tvb, offset); ilb_version = tvb_get_guint8(tvb, offset + 1); type_version = ilb_type << 8 | ilb_version; col_append_fstr(pinfo->cinfo, COL_INFO, "Type: 0x%02x, Version: %d", ilb_type, ilb_version); if (ilb_tree) { proto_tree_add_item(ilb_tree, hf_interlink_block_type, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(ilb_tree, hf_interlink_block_version, tvb, offset, 1, FALSE); offset += 1; proto_tree_add_item(ilb_tree, hf_interlink_block_length, tvb, offset, 2, TRUE); offset += 2; } else { offset += 4; } /* Generate a new tvb for the rest. */ next_tvb = tvb_new_subset_remaining(tvb, offset); /* Probably a sub-dissector exists for this type/version combination. */ handle = dissector_get_port_handle(subdissector_table, type_version); /* Without a proper sub-dissector, we use "data". */ if (handle == NULL) handle = data_handle; /* Call the sub-dissector. */ call_dissector(handle, next_tvb, pinfo, tree); }
gchar *curr_str; /* these are temporary intermediate values, used in the individual cases below */ guint32 t_lat, t_lon, t_alt, t_alt_gnd; guint32 t_herr, t_verr, t_terr; guint32 t_appspecific_num; /* initialize the timestamp value(s) */ gps_timestamp.secs = gps_timestamp.nsecs = already_processed_fractime = 0; /* Clear out stuff in the info column */ col_clear(pinfo->cinfo,COL_INFO); /* pull out the first three fields of the BASE-GEOTAG-HEADER */ version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+2); present = tvb_get_letohl(tvb, offset+4); /* Setup basic column info */ col_add_fstr(pinfo->cinfo, COL_INFO, "PPI_GPS Capture v%u, Length %u", version, length); /* Create the basic dissection tree*/ gps_line = proto_tree_add_protocol_format(tree, proto_ppi_gps, tvb, 0, length, "GPS:"); ppi_gps_tree = proto_item_add_subtree(gps_line, ett_ppi_gps); version_item = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_version, tvb, offset, 1, version); proto_tree_add_item(ppi_gps_tree, hf_ppi_gps_pad, tvb, offset + 1, 1, ENC_LITTLE_ENDIAN); length_item = proto_tree_add_uint(ppi_gps_tree, hf_ppi_gps_length, tvb, offset + 2, 2, length); /* We support v1 and v2 of GPS tags (identical) */ if (! (version == 1 || version == 2) ) { expert_add_info_format(pinfo, version_item, &ei_ppi_gps_version, "Invalid version (got %d, expected 1 or 2)", version);
static int dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; proto_tree *wlan_tree = NULL, *opmode_tree; proto_item *ti; tvbuff_t *next_tvb; int offset; guint8 version; guint16 length; guint32 phy_type; guint32 flags; guint32 channel; gint calc_channel; gint32 rssi; guint8 rate; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+1); col_add_fstr(pinfo->cinfo, COL_INFO, "NetMon WLAN Capture v%u, Length %u", version, length); if (version != 2) { /* XXX - complain */ goto skip; } if (length < MIN_HEADER_LEN) { /* XXX - complain */ goto skip; } /* Dissect the packet */ ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, ENC_NA); wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN); opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; flags = tvb_get_letohl(tvb, offset); offset += 4; if (flags != 0xffffffff) { phy_type = tvb_get_letohl(tvb, offset); switch (phy_type) { case PHY_TYPE_11B: phdr->phy = PHDR_802_11_PHY_11B; break; case PHY_TYPE_11A: phdr->phy = PHDR_802_11_PHY_11A; phdr->phy_info.info_11a.presence_flags = 0; break; case PHY_TYPE_11G: phdr->phy = PHDR_802_11_PHY_11G; phdr->phy_info.info_11g.presence_flags = 0; break; case PHY_TYPE_11N: phdr->phy = PHDR_802_11_PHY_11N; phdr->phy_info.info_11n.presence_flags = 0; break; default: phdr->phy = PHDR_802_11_PHY_UNKNOWN; break; } proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; channel = tvb_get_letohl(tvb, offset); if (channel < 1000) { if (channel == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel, "Unknown"); } else { guint frequency; phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = channel; proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel); switch (phdr->phy) { case PHDR_802_11_PHY_11B: case PHDR_802_11_PHY_11G: /* 2.4 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, TRUE); break; case PHDR_802_11_PHY_11A: /* 5 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, FALSE); break; default: frequency = 0; break; } if (frequency != 0) { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = frequency; } } } else { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = channel; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, tvb, offset, 4, channel, "%u Mhz", channel); calc_channel = ieee80211_mhz_to_chan(channel); if (calc_channel != -1) { phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = calc_channel; } } offset += 4; rssi = tvb_get_letohl(tvb, offset); if (rssi == 0) { proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; phdr->signal_dbm = rssi; proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "%d dBm", rssi); } offset += 4; rate = tvb_get_guint8(tvb, offset); if (rate == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE; phdr->data_rate = rate; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "%f Mb/s", rate*.5); } offset += 1; } else offset += 13; phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset); proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); /*offset += 8;*/ skip: offset = length; /* dissect the 802.11 packet next */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr); return offset; }
static int dissect_netmon_802_11(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { struct ieee_802_11_phdr *phdr = (struct ieee_802_11_phdr *)data; proto_tree *wlan_tree = NULL, *opmode_tree; proto_item *ti; tvbuff_t *next_tvb; int offset; guint8 version; guint16 length; guint32 phy_type; guint32 flags; guint32 channel; gint calc_channel; gint32 rssi; guint8 rate; col_set_str(pinfo->cinfo, COL_PROTOCOL, "WLAN"); col_clear(pinfo->cinfo, COL_INFO); offset = 0; version = tvb_get_guint8(tvb, offset); length = tvb_get_letohs(tvb, offset+1); col_add_fstr(pinfo->cinfo, COL_INFO, "NetMon WLAN Capture v%u, Length %u", version, length); if (version != 2) { /* XXX - complain */ goto skip; } if (length < MIN_HEADER_LEN) { /* XXX - complain */ goto skip; } /* Dissect the packet */ ti = proto_tree_add_item(tree, proto_netmon_802_11, tvb, 0, length, ENC_NA); wlan_tree = proto_item_add_subtree(ti, ett_netmon_802_11); /* * XXX - is this the NDIS_OBJECT_HEADER structure: * * https://msdn.microsoft.com/en-us/library/windows/hardware/ff566588(v=vs.85).aspx * * at the beginning of a DOT11_EXTSTA_RECV_CONTEXT structure: * * https://msdn.microsoft.com/en-us/library/windows/hardware/ff548626(v=vs.85).aspx * * If so, the byte at an offset of 0 would be the appropriate type for the * structure following it, i.e. NDIS_OBJECT_TYPE_DEFAULT. */ proto_tree_add_item(wlan_tree, hf_netmon_802_11_version, tvb, offset, 1, ENC_LITTLE_ENDIAN); offset += 1; proto_tree_add_item(wlan_tree, hf_netmon_802_11_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; /* * This isn't in the DOT11_EXTSTA_RECV_CONTEXT structure. */ ti = proto_tree_add_item(wlan_tree, hf_netmon_802_11_op_mode, tvb, offset, 4, ENC_LITTLE_ENDIAN); opmode_tree = proto_item_add_subtree(ti, ett_netmon_802_11_op_mode); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_ap, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_sta_ext, tvb, offset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(opmode_tree, hf_netmon_802_11_op_mode_mon, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* * uReceiveFlags? */ flags = tvb_get_letohl(tvb, offset); offset += 4; if (flags != 0xffffffff) { /* * uPhyId? */ phy_type = tvb_get_letohl(tvb, offset); switch (phy_type) { case PHY_TYPE_UNKNOWN: phdr->phy = PHDR_802_11_PHY_UNKNOWN; break; case PHY_TYPE_FHSS: phdr->phy = PHDR_802_11_PHY_11_FHSS; phdr->phy_info.info_11_fhss.presence_flags = 0; break; case PHY_TYPE_IR_BASEBAND: phdr->phy = PHDR_802_11_PHY_11_IR; break; case PHY_TYPE_DSSS: phdr->phy = PHDR_802_11_PHY_11_DSSS; break; case PHY_TYPE_HR_DSSS: phdr->phy = PHDR_802_11_PHY_11B; phdr->phy_info.info_11b.presence_flags = 0; break; case PHY_TYPE_OFDM: phdr->phy = PHDR_802_11_PHY_11A; phdr->phy_info.info_11a.presence_flags = 0; break; case PHY_TYPE_ERP: phdr->phy = PHDR_802_11_PHY_11G; phdr->phy_info.info_11g.presence_flags = 0; break; case PHY_TYPE_HT: phdr->phy = PHDR_802_11_PHY_11N; phdr->phy_info.info_11n.presence_flags = 0; break; case PHY_TYPE_VHT: phdr->phy = PHDR_802_11_PHY_11AC; phdr->phy_info.info_11ac.presence_flags = 0; break; default: phdr->phy = PHDR_802_11_PHY_UNKNOWN; break; } proto_tree_add_item(wlan_tree, hf_netmon_802_11_phy_type, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; /* * uChCenterFrequency? */ channel = tvb_get_letohl(tvb, offset); if (channel < 1000) { if (channel == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel, "Unknown"); } else { guint frequency; phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = channel; proto_tree_add_uint(wlan_tree, hf_netmon_802_11_channel, tvb, offset, 4, channel); switch (phdr->phy) { case PHDR_802_11_PHY_11B: case PHDR_802_11_PHY_11G: /* 2.4 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, TRUE); break; case PHDR_802_11_PHY_11A: /* 5 GHz channel */ frequency = ieee80211_chan_to_mhz(channel, FALSE); break; default: frequency = 0; break; } if (frequency != 0) { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = frequency; } } } else { phdr->presence_flags |= PHDR_802_11_HAS_FREQUENCY; phdr->frequency = channel; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_frequency, tvb, offset, 4, channel, "%u Mhz", channel); calc_channel = ieee80211_mhz_to_chan(channel); if (calc_channel != -1) { phdr->presence_flags |= PHDR_802_11_HAS_CHANNEL; phdr->channel = calc_channel; } } offset += 4; /* * usNumberOfMPDUsReceived is missing. */ /* * lRSSI? */ rssi = tvb_get_letohl(tvb, offset); if (rssi == 0) { proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_SIGNAL_DBM; phdr->signal_dbm = rssi; proto_tree_add_int_format_value(wlan_tree, hf_netmon_802_11_rssi, tvb, offset, 4, rssi, "%d dBm", rssi); } offset += 4; /* * ucDataRate? */ rate = tvb_get_guint8(tvb, offset); if (rate == 0) { proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "Unknown"); } else { phdr->presence_flags |= PHDR_802_11_HAS_DATA_RATE; phdr->data_rate = rate; proto_tree_add_uint_format_value(wlan_tree, hf_netmon_802_11_datarate, tvb, offset, 1, rate, "%f Mb/s", rate*.5); } offset += 1; } else offset += 13; /* * ullTimestamp? * * If so, should this check the presense flag in flags? */ phdr->presence_flags |= PHDR_802_11_HAS_TSF_TIMESTAMP; phdr->tsf_timestamp = tvb_get_letoh64(tvb, offset); proto_tree_add_item(wlan_tree, hf_netmon_802_11_timestamp, tvb, offset, 8, ENC_LITTLE_ENDIAN); /*offset += 8;*/ skip: offset = length; /* dissect the 802.11 packet next */ next_tvb = tvb_new_subset_remaining(tvb, offset); call_dissector_with_data(ieee80211_radio_handle, next_tvb, pinfo, tree, phdr); return offset; }
int dissect_xdlc_control(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *xdlc_tree, int hf_xdlc_control, gint ett_xdlc_control, const xdlc_cf_items *cf_items_nonext, const xdlc_cf_items *cf_items_ext, const value_string *u_modifier_short_vals_cmd, const value_string *u_modifier_short_vals_resp, gboolean is_response, gboolean is_extended, gboolean append_info) { guint16 control; int control_len; const xdlc_cf_items *cf_items; const char *control_format; guint16 poll_final; char *info; proto_tree *tc, *control_tree; const gchar *frame_type = NULL; const gchar *modifier; info=ep_alloc(80); switch (tvb_get_guint8(tvb, offset) & 0x03) { case XDLC_S: /* * Supervisory frame. */ if (is_extended) { control = tvb_get_letohs(tvb, offset); control_len = 2; cf_items = cf_items_ext; control_format = "Control field: %s (0x%04X)"; } else { control = tvb_get_guint8(tvb, offset); control_len = 1; cf_items = cf_items_nonext; control_format = "Control field: %s (0x%02X)"; } switch (control & XDLC_S_FTYPE_MASK) { case XDLC_RR: frame_type = "RR"; break; case XDLC_RNR: frame_type = "RNR"; break; case XDLC_REJ: frame_type = "REJ"; break; case XDLC_SREJ: frame_type = "SREJ"; break; } if (is_extended) { poll_final = (control & XDLC_P_F_EXT); g_snprintf(info, 80, "S%s, func=%s, N(R)=%u", (poll_final ? (is_response ? " F" : " P") : ""), frame_type, (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT); } else { poll_final = (control & XDLC_P_F); g_snprintf(info, 80, "S%s, func=%s, N(R)=%u", (poll_final ? (is_response ? " F" : " P") : ""), frame_type, (control & XDLC_N_R_MASK) >> XDLC_N_R_SHIFT); } if (check_col(pinfo->cinfo, COL_INFO)) { if (append_info) { col_append_str(pinfo->cinfo, COL_INFO, ", "); col_append_str(pinfo->cinfo, COL_INFO, info); } else col_add_str(pinfo->cinfo, COL_INFO, info); } if (xdlc_tree) { tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb, offset, control_len, control, control_format, info, control); control_tree = proto_item_add_subtree(tc, ett_xdlc_control); proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_n_r, tvb, offset, control_len, control); if (poll_final) { proto_tree_add_boolean(control_tree, (is_response ? *cf_items->hf_xdlc_f : *cf_items->hf_xdlc_p), tvb, offset, control_len, control); } proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_s_ftype, tvb, offset, control_len, control); /* This will always say it's a supervisory frame */ proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u, tvb, offset, control_len, control); } break; case XDLC_U: /* * Unnumbered frame. * * XXX - is this two octets, with a P/F bit, in HDLC extended * operation? It's one octet in LLC, even though the control * field of I and S frames is a 2-byte extended-operation field * in LLC. Given that there are no sequence numbers in the * control field of a U frame, there doesn't appear to be any * need for it to be 2 bytes in extended operation. */ if (u_modifier_short_vals_cmd == NULL) u_modifier_short_vals_cmd = modifier_short_vals_cmd; if (u_modifier_short_vals_resp == NULL) u_modifier_short_vals_resp = modifier_short_vals_resp; control = tvb_get_guint8(tvb, offset); control_len = 1; cf_items = cf_items_nonext; control_format = "Control field: %s (0x%02X)"; if (is_response) { modifier = val_to_str(control & XDLC_U_MODIFIER_MASK, u_modifier_short_vals_resp, "Unknown"); } else { modifier = val_to_str(control & XDLC_U_MODIFIER_MASK, u_modifier_short_vals_cmd, "Unknown"); } poll_final = (control & XDLC_P_F); g_snprintf(info, 80, "U%s, func=%s", (poll_final ? (is_response ? " F" : " P") : ""), modifier); if (check_col(pinfo->cinfo, COL_INFO)) { if (append_info) { col_append_str(pinfo->cinfo, COL_INFO, ", "); col_append_str(pinfo->cinfo, COL_INFO, info); } else col_add_str(pinfo->cinfo, COL_INFO, info); } if (xdlc_tree) { tc = proto_tree_add_uint_format(xdlc_tree, hf_xdlc_control, tvb, offset, control_len, control, control_format, info, control); control_tree = proto_item_add_subtree(tc, ett_xdlc_control); if (poll_final) { proto_tree_add_boolean(control_tree, (is_response ? *cf_items->hf_xdlc_f: *cf_items->hf_xdlc_p), tvb, offset, control_len, control); } proto_tree_add_uint(control_tree, (is_response ? *cf_items->hf_xdlc_u_modifier_resp : *cf_items->hf_xdlc_u_modifier_cmd), tvb, offset, control_len, control); /* This will always say it's an unnumbered frame */ proto_tree_add_uint(control_tree, *cf_items->hf_xdlc_ftype_s_u, tvb, offset, control_len, control); } break; default: /* * Information frame. */ if (is_extended) { control = tvb_get_letohs(tvb, offset); control_len = 2; cf_items = cf_items_ext; control_format = "Control field: %s (0x%04X)"; poll_final = (control & XDLC_P_F_EXT); g_snprintf(info, 80, "I%s, N(R)=%u, N(S)=%u", ((control & XDLC_P_F_EXT) ? " P" : ""), (control & XDLC_N_R_EXT_MASK) >> XDLC_N_R_EXT_SHIFT, (control & XDLC_N_S_EXT_MASK) >> XDLC_N_S_EXT_SHIFT); } else {
/* possibly dissect a CSF_SDU related PN-RT packet */ static gboolean dissect_CSF_SDU_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint16 u16FrameID; guint16 u16SFCRC16; guint8 u8SFPosition; guint8 u8SFDataLength = 255; guint8 u8SFCycleCounter; guint8 u8SFDataStatus; int offset = 0; guint32 u32SubStart; proto_item *sub_item; proto_tree *sub_tree; proto_item *item; guint16 crc; /* the sub tvb will NOT contain the frame_id here! */ u16FrameID = GPOINTER_TO_UINT(pinfo->private_data); /* possible FrameID ranges for DFP */ if ((u16FrameID >= 0x0500 && u16FrameID < 0x05ff) || (u16FrameID >= 0x0600 && u16FrameID < 0x07ff) || (u16FrameID >= 0x4800 && u16FrameID < 0x4fff) || (u16FrameID >= 0x5800 && u16FrameID < 0x5fff) || (u16FrameID >= 0x6800 && u16FrameID < 0x6fff) || (u16FrameID >= 0x7800 && u16FrameID < 0x7fff)) { /* can't check this CRC, as the checked data bytes are not available */ u16SFCRC16 = tvb_get_letohs(tvb, offset); proto_tree_add_uint(tree, hf_pn_rt_sf_crc16, tvb, offset, 2, u16SFCRC16); offset += 2; while(1) { sub_item = proto_tree_add_item(tree, hf_pn_rt_sf, tvb, offset, 0, FALSE); sub_tree = proto_item_add_subtree(sub_item, ett_pn_rt_sf); u32SubStart = offset; u8SFPosition = tvb_get_guint8(tvb, offset); proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position_control, tvb, offset, 1, u8SFPosition); proto_tree_add_uint(sub_tree, hf_pn_rt_sf_position, tvb, offset, 1, u8SFPosition); offset += 1; u8SFDataLength = tvb_get_guint8(tvb, offset); proto_tree_add_uint(sub_tree, hf_pn_rt_sf_data_length, tvb, offset, 1, u8SFDataLength); offset += 1; if(u8SFDataLength == 0) { proto_item_append_text(sub_item, ": Pos:%u, Length:%u", u8SFPosition, u8SFDataLength); proto_item_set_len(sub_item, offset - u32SubStart); break; } u8SFCycleCounter = tvb_get_guint8(tvb, offset); proto_tree_add_uint(sub_tree, hf_pn_rt_sf_cycle_counter, tvb, offset, 1, u8SFCycleCounter); offset += 1; u8SFDataStatus = tvb_get_guint8(tvb, offset); dissect_DataStatus(tvb, offset, sub_tree, u8SFDataStatus); offset += 1; offset = dissect_pn_user_data(tvb, offset, pinfo, sub_tree, u8SFDataLength, "DataItem"); u16SFCRC16 = tvb_get_letohs(tvb, offset); item = proto_tree_add_uint(sub_tree, hf_pn_rt_sf_crc16, tvb, offset, 2, u16SFCRC16); if(u8SFPosition & 0x80) { crc = crc16_plain_tvb_offset(tvb, u32SubStart, offset-u32SubStart); if(crc != u16SFCRC16) { proto_item_append_text(item, " [Preliminary check: incorrect, should be: %u]", crc); expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum"); } else { proto_item_append_text(item, " [Preliminary check: Correct]"); } } else { proto_item_append_text(item, " [No preliminary check, Control bit not set]"); } offset += 2; proto_item_append_text(sub_item, ": Pos:%u, Length:%u, Cycle:%u, Status: 0x%02x (%s,%s,%s,%s)", u8SFPosition, u8SFDataLength, u8SFCycleCounter, u8SFDataStatus, (u8SFDataStatus & 0x04) ? "Valid" : "Invalid", (u8SFDataStatus & 0x01) ? "Primary" : "Backup", (u8SFDataStatus & 0x20) ? "Ok" : "Problem", (u8SFDataStatus & 0x10) ? "Run" : "Stop"); proto_item_set_len(sub_item, offset - u32SubStart); } return TRUE; } return FALSE; }
static void dissect_quakeworld_GamePacket(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int direction) { proto_tree *game_tree = NULL; guint32 seq1; guint32 seq2; int rel1; int rel2; int offset; guint rest_length; direction = (pinfo->destport == gbl_quakeworldServerPort) ? DIR_C2S : DIR_S2C; if (tree) { proto_item *game_item; game_item = proto_tree_add_text(tree, tvb, 0, -1, "Game"); game_tree = proto_item_add_subtree(game_item, ett_quakeworld_game); } offset = 0; seq1 = tvb_get_letohl(tvb, offset); rel1 = seq1 & 0x80000000 ? 1 : 0; seq1 &= ~0x80000000; if (game_tree) { proto_item *seq1_item = proto_tree_add_text(game_tree, tvb, offset, 4, "Current Sequence: %u (%s)", seq1, val_to_str(rel1,names_reliable,"%u")); proto_tree *seq1_tree = proto_item_add_subtree( seq1_item, ett_quakeworld_game_seq1); proto_tree_add_uint(seq1_tree, hf_quakeworld_game_seq1, tvb, offset, 4, seq1); proto_tree_add_boolean(seq1_tree, hf_quakeworld_game_rel1, tvb, offset+3, 1, rel1); } offset += 4; seq2 = tvb_get_letohl(tvb, offset); rel2 = seq2 & 0x80000000 ? 1 : 0; seq2 &= ~0x80000000; if (game_tree) { proto_item *seq2_item = proto_tree_add_text(game_tree, tvb, offset, 4, "Acknowledge Sequence: %u (%s)", seq2, val_to_str(rel2,names_reliable,"%u")); proto_tree *seq2_tree = proto_item_add_subtree(seq2_item, ett_quakeworld_game_seq2); proto_tree_add_uint(seq2_tree, hf_quakeworld_game_seq2, tvb, offset, 4, seq2); proto_tree_add_boolean(seq2_tree, hf_quakeworld_game_rel2, tvb, offset+3, 1, rel2); } offset += 4; if (direction == DIR_C2S) { /* client to server */ guint16 qport = tvb_get_letohs(tvb, offset); if (game_tree) { proto_tree_add_uint(game_tree, hf_quakeworld_game_qport, tvb, offset, 2, qport); } offset +=2; } /* all the rest is pure game data */ rest_length = tvb_reported_length(tvb) - offset; if (rest_length) { tvbuff_t *next_tvb = tvb_new_subset_remaining(tvb, offset); if (direction == DIR_C2S) { proto_tree *c_tree = NULL; if (tree) { proto_item *c_item; c_item = proto_tree_add_text(game_tree, next_tvb, 0, -1, "Client Commands"); c_tree = proto_item_add_subtree(c_item, ett_quakeworld_game_clc); } dissect_quakeworld_client_commands(next_tvb, pinfo, c_tree); } else { proto_tree *c_tree = NULL; if (tree) { proto_item *c_item; c_item = proto_tree_add_text(game_tree, next_tvb, 0, -1, "Server Commands"); c_tree = proto_item_add_subtree(c_item, ett_quakeworld_game_svc); } dissect_quakeworld_server_commands(next_tvb, pinfo, c_tree); } } }
static void dissect_mtp3_routing_label(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mtp3_tree, mtp3_addr_pc_t *mtp3_addr_opc, mtp3_addr_pc_t *mtp3_addr_dpc) { guint32 label, dpc, opc; proto_item *label_dpc_item, *label_opc_item; proto_item *hidden_item; proto_tree *label_tree; proto_tree *pc_subtree; int hf_dpc_string; int hf_opc_string; switch (mtp3_standard) { case ITU_STANDARD: label_tree = proto_tree_add_subtree(mtp3_tree, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, ett_mtp3_label, NULL, "Routing label"); label = tvb_get_letohl(tvb, ROUTING_LABEL_OFFSET); opc = (label & ITU_OPC_MASK) >> 14; dpc = label & ITU_DPC_MASK; hidden_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_pc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, opc); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_pc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, dpc); PROTO_ITEM_SET_HIDDEN(hidden_item); label_dpc_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_dpc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, label); if (mtp3_pc_structured()) proto_item_append_text(label_dpc_item, " (%s)", mtp3_pc_to_str(dpc)); if(mtp3_addr_dpc->ni == MTP3_NI_INT0) { pc_subtree = proto_item_add_subtree(label_dpc_item, ett_mtp3_label_dpc); analyze_q708_ispc(tvb, pc_subtree, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, dpc); } label_opc_item = proto_tree_add_uint(label_tree, hf_mtp3_itu_opc, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, label); if (mtp3_pc_structured()) proto_item_append_text(label_opc_item, " (%s)", mtp3_pc_to_str(opc)); if(mtp3_addr_opc->ni == MTP3_NI_INT0) { pc_subtree = proto_item_add_subtree(label_opc_item, ett_mtp3_label_opc); analyze_q708_ispc(tvb, pc_subtree, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, opc); } proto_tree_add_uint(label_tree, hf_mtp3_itu_sls, tvb, ROUTING_LABEL_OFFSET, ITU_ROUTING_LABEL_LENGTH, label); break; case ANSI_STANDARD: case CHINESE_ITU_STANDARD: if (mtp3_standard == ANSI_STANDARD) { hf_dpc_string = hf_mtp3_ansi_dpc; hf_opc_string = hf_mtp3_ansi_opc; } else /* CHINESE_ITU_STANDARD */ { hf_dpc_string = hf_mtp3_chinese_dpc; hf_opc_string = hf_mtp3_chinese_opc; } /* Create the Routing Label Tree */ label_tree = proto_tree_add_subtree(mtp3_tree, tvb, ROUTING_LABEL_OFFSET, ANSI_ROUTING_LABEL_LENGTH, ett_mtp3_label, NULL, "Routing label"); /* create and fill the DPC tree */ dissect_mtp3_3byte_pc(tvb, ANSI_DPC_OFFSET, label_tree, ett_mtp3_label_dpc, hf_dpc_string, hf_mtp3_dpc_network, hf_mtp3_dpc_cluster, hf_mtp3_dpc_member, hf_mtp3_24bit_dpc, hf_mtp3_24bit_pc); /* Store dpc for mtp3_addr below */ dpc = tvb_get_letoh24(tvb, ANSI_DPC_OFFSET); /* create and fill the OPC tree */ dissect_mtp3_3byte_pc(tvb, ANSI_OPC_OFFSET, label_tree, ett_mtp3_label_opc, hf_opc_string, hf_mtp3_opc_network, hf_mtp3_opc_cluster, hf_mtp3_opc_member, hf_mtp3_24bit_opc, hf_mtp3_24bit_pc); /* Store opc for mtp3_addr below */ opc = tvb_get_letoh24(tvb, ANSI_OPC_OFFSET); /* SLS */ if (mtp3_standard == ANSI_STANDARD) { if (mtp3_use_ansi_5_bit_sls) proto_tree_add_item(label_tree, hf_mtp3_ansi_5_bit_sls, tvb, ANSI_SLS_OFFSET, SLS_LENGTH, ENC_NA); else proto_tree_add_item(label_tree, hf_mtp3_ansi_8_bit_sls, tvb, ANSI_SLS_OFFSET, SLS_LENGTH, ENC_NA); } else /* CHINESE_ITU_STANDARD */ { proto_tree_add_item(label_tree, hf_mtp3_chinese_itu_sls, tvb, ANSI_SLS_OFFSET, SLS_LENGTH, ENC_NA); } break; case JAPAN_STANDARD: label_tree = proto_tree_add_subtree(mtp3_tree, tvb, ROUTING_LABEL_OFFSET, JAPAN_ROUTING_LABEL_LENGTH, ett_mtp3_label, NULL, "Routing label"); label_dpc_item = proto_tree_add_item(label_tree, hf_mtp3_japan_dpc, tvb, ROUTING_LABEL_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN); dpc = tvb_get_letohs(tvb, ROUTING_LABEL_OFFSET); if (mtp3_pc_structured()) { proto_item_append_text(label_dpc_item, " (%s)", mtp3_pc_to_str(dpc)); } label_opc_item = proto_tree_add_item(label_tree, hf_mtp3_japan_opc, tvb, JAPAN_OPC_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN); opc = tvb_get_letohs(tvb, JAPAN_OPC_OFFSET); if (mtp3_pc_structured()) { proto_item_append_text(label_opc_item, " (%s)", mtp3_pc_to_str(opc)); } hidden_item = proto_tree_add_item(label_tree, hf_mtp3_japan_pc, tvb, ROUTING_LABEL_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN); PROTO_ITEM_SET_HIDDEN(hidden_item); hidden_item = proto_tree_add_item(label_tree, hf_mtp3_japan_pc, tvb, JAPAN_OPC_OFFSET, JAPAN_PC_LENGTH, ENC_LITTLE_ENDIAN); PROTO_ITEM_SET_HIDDEN(hidden_item); if (mtp3_use_japan_5_bit_sls) { proto_tree_add_item(label_tree, hf_mtp3_japan_5_bit_sls, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA); proto_tree_add_item(label_tree, hf_mtp3_japan_5_bit_sls_spare, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA); } else { proto_tree_add_item(label_tree, hf_mtp3_japan_4_bit_sls, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA); proto_tree_add_item(label_tree, hf_mtp3_japan_4_bit_sls_spare, tvb, JAPAN_SLS_OFFSET, JAPAN_SLS_SPARE_LENGTH, ENC_NA); } break; default: DISSECTOR_ASSERT_NOT_REACHED(); } mtp3_addr_opc->type = (Standard_Type)mtp3_standard; mtp3_addr_opc->pc = opc; SET_ADDRESS(&pinfo->src, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_opc); mtp3_addr_dpc->type = (Standard_Type)mtp3_standard; mtp3_addr_dpc->pc = dpc; SET_ADDRESS(&pinfo->dst, AT_SS7PC, sizeof(mtp3_addr_pc_t), (guint8 *) mtp3_addr_dpc); }
static const value_string meta_direction_vals[] = { { 0, "Up" }, { 1, "Down" }, { 0, NULL } }; static guint16 skip_item(proto_tree *meta_tree, tvbuff_t *tvb, packet_info *pinfo _U_, guint16 offs) { guint16 id; guint8 type; guint16 len, aligned_len, total_len; proto_tree *item_tree; proto_item *subti; id = tvb_get_letohs(tvb, offs); offs += 2; type = tvb_get_guint8(tvb, offs); offs++; len = tvb_get_guint8(tvb, offs); offs++; aligned_len = (len + 3) & 0xfffc; total_len = aligned_len + 4; /* 4: id, type, len fields */ subti = proto_tree_add_item(meta_tree, hf_meta_item, tvb, offs - 4, aligned_len + 4, ENC_NA); item_tree = proto_item_add_subtree(subti, ett_meta_item); proto_tree_add_uint(item_tree, hf_meta_item_id, tvb, offs - 4, 2, id); proto_tree_add_uint(item_tree, hf_meta_item_type, tvb, offs - 2, 1, type); proto_tree_add_uint(item_tree, hf_meta_item_len, tvb, offs - 1, 1, len); if (len > 0) proto_tree_add_item(item_tree, hf_meta_item_data, tvb, offs, len, ENC_NA);
/* * Dissect a standard (reliable) ts2 packet, reassembling if required. */ static void ts2_standard_dissect(tvbuff_t *tvb, packet_info *pinfo, proto_tree *ts2_tree, ts2_conversation *conversation_data) { guint8 save_fragmented; tvbuff_t *new_tvb, *next_tvb; fragment_head *frag_msg ; guint16 fragment_number; ts2_frag *frag; gboolean outoforder; guint16 type = tvb_get_letohs(tvb, 2); /*guint16 klass = tvb_get_letohs(tvb, 0);*/ proto_tree_add_item(ts2_tree, hf_ts2_seqnum, tvb, 12, 4, ENC_LITTLE_ENDIAN); /* XXX: Following fragmentation stuff should be separate from the GUI stuff ?? */ /* Get our stored fragmentation data or create one! */ if ( ! ( frag = (ts2_frag *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ts2, 0) ) ) { frag = wmem_new(wmem_file_scope(), ts2_frag); frag->frag_num=0; } /* decide if the packet is server to client or client to server * then check its fragmentation */ if(!(pinfo->fd->flags.visited)) { if(conversation_data->server_port == pinfo->srcport) { frag->fragmented = ts2_standard_find_fragments(tvb, &conversation_data->last_inorder_server_frame, &conversation_data->server_frag_size, &conversation_data->server_frag_num, &outoforder); frag->frag_num=conversation_data->server_frag_num; frag->frag_size=conversation_data->server_frag_size; } else { frag->fragmented = ts2_standard_find_fragments(tvb, &conversation_data->last_inorder_client_frame, &conversation_data->client_frag_size, &conversation_data->client_frag_num, &outoforder); frag->frag_num=conversation_data->client_frag_num; frag->frag_size=conversation_data->client_frag_size; } frag->outoforder=outoforder; p_add_proto_data(wmem_file_scope(), pinfo, proto_ts2, 0, frag); } /* Get our stored fragmentation data */ frag = (ts2_frag *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ts2, 0); proto_tree_add_item(ts2_tree, hf_ts2_resend_count, tvb, 16, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(ts2_tree, hf_ts2_fragmentnumber, tvb, 18, 2, ENC_LITTLE_ENDIAN); ts2_add_checked_crc32(ts2_tree, hf_ts2_crc32, tvb, 20, tvb_get_letohl(tvb, 20)); /* Reassemble the packet if it's fragmented */ new_tvb = NULL; if(frag && frag->fragmented) { save_fragmented = pinfo->fragmented; frag_msg = NULL; pinfo->fragmented = TRUE; fragment_number = tvb_get_letohs(tvb, 18); frag_msg = fragment_add_seq_check(&msg_reassembly_table, tvb, 24, pinfo, type, NULL, frag->frag_num, tvb_length_remaining(tvb, 24), fragment_number); new_tvb = process_reassembled_data(tvb, 24, pinfo,"Reassembled TeamSpeak2", frag_msg, &msg_frag_items, NULL, ts2_tree); if (frag_msg) /* XXX: should be if (new_tvb) ?? */ { /* Reassembled */ col_append_str(pinfo->cinfo, COL_INFO, " (Message Reassembled)"); } else { /* Not last packet of reassembled Short Message */ col_append_fstr(pinfo->cinfo, COL_INFO," (Message fragment %u)", frag->frag_num); } if (new_tvb) next_tvb = new_tvb; else next_tvb = tvb_new_subset_remaining(tvb, 24); pinfo->fragmented = save_fragmented; } else next_tvb = tvb_new_subset_remaining(tvb, 24); /* If we have a full packet now dissect it */ if((new_tvb || !frag->fragmented) && !frag->outoforder) { switch(type) { case TS2T_LOGINPART2: ts2_parse_loginpart2(next_tvb, ts2_tree); break; case TS2T_CHANNELLIST: ts2_parse_channellist(next_tvb, ts2_tree); break; case TS2T_PLAYERLIST: ts2_parse_playerlist(next_tvb, ts2_tree); break; case TS2T_NEWPLAYERJOINED: ts2_parse_newplayerjoined(next_tvb, ts2_tree); break; case TS2T_KNOWNPLAYERUPDATE: ts2_parse_knownplayerupdate(next_tvb, ts2_tree); break; case TS2T_PLAYERLEFT: ts2_parse_playerleft(next_tvb, ts2_tree); break; case TS2T_PLAYERKICKED: ts2_parse_playerleft(next_tvb, ts2_tree); break; case TS2T_LOGINEND: ts2_parse_loginend(next_tvb, ts2_tree); break; case TS2T_CHANGESTATUS: ts2_parse_changestatus(next_tvb, ts2_tree); break; case TS2T_SWITCHCHANNEL: ts2_parse_switchchannel(next_tvb, ts2_tree); break; case TS2T_CHANNELCHANGE: ts2_parse_channelchange(next_tvb, ts2_tree); break; } } /* The packet is out of order, update the cinfo and ignore the packet */ if(frag->outoforder) col_append_str(pinfo->cinfo, COL_INFO, " (Out Of Order, ignored)"); }
body's length) */ static gint dissect_ac_if_hdr_body(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree, usb_conv_info_t *usb_conv_info) { gint offset_start; guint16 bcdADC; guint8 ver_major; double ver; guint8 if_in_collection, i; audio_conv_info_t *audio_conv_info; offset_start = offset; bcdADC = tvb_get_letohs(tvb, offset); ver_major = USB_AUDIO_BCD44_TO_DEC(bcdADC>>8); ver = ver_major + USB_AUDIO_BCD44_TO_DEC(bcdADC&0xFF) / 100.0; proto_tree_add_double_format_value(tree, hf_ac_if_hdr_ver, tvb, offset, 2, ver, "%2.2f", ver); audio_conv_info = (audio_conv_info_t *)usb_conv_info->class_data; if(!audio_conv_info) { audio_conv_info = wmem_new(wmem_file_scope(), audio_conv_info_t); usb_conv_info->class_data = audio_conv_info; /* XXX - set reasonable default values for all components that are not filled in by this function */ } audio_conv_info->ver_major = ver_major; offset += 2;
static gint dissect_adb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data) { proto_item *main_item; proto_tree *main_tree; proto_item *arg0_item; proto_tree *arg0_tree; proto_item *arg1_item; proto_tree *arg1_tree; proto_item *magic_item; proto_item *crc_item; proto_tree *crc_tree = NULL; proto_item *sub_item; gint offset = 0; guint32 command; guint32 arg0; guint32 arg1; guint32 data_length = 0; guint32 crc32 = 0; usb_conv_info_t *usb_conv_info = NULL; wmem_tree_key_t key[5]; guint32 interface_id; guint32 bus_id; guint32 device_address; guint32 side_id; guint32 frame_number; gboolean is_command = TRUE; gboolean is_next_fragment = FALSE; gboolean is_service = FALSE; gint proto; gint direction = P2P_DIR_UNKNOWN; wmem_tree_t *wmem_tree; command_data_t *command_data = NULL; service_data_t *service_data = NULL; col_set_str(pinfo->cinfo, COL_PROTOCOL, "ADB"); col_clear(pinfo->cinfo, COL_INFO); main_item = proto_tree_add_item(tree, proto_adb, tvb, offset, -1, ENC_NA); main_tree = proto_item_add_subtree(main_item, ett_adb); frame_number = pinfo->fd->num; /* XXX: Why? If interface is USB only first try is correct * (and seems strange...), in other cases standard check for * previous protocol is correct */ proto = (gint) GPOINTER_TO_INT(wmem_list_frame_data(/*wmem_list_frame_prev*/(wmem_list_tail(pinfo->layers)))); if (proto != proto_usb) { proto = (gint) GPOINTER_TO_INT(wmem_list_frame_data(wmem_list_frame_prev(wmem_list_tail(pinfo->layers)))); } if (proto == proto_usb) { usb_conv_info = (usb_conv_info_t *) data; DISSECTOR_ASSERT(usb_conv_info); direction = usb_conv_info->direction; } else if (proto == proto_tcp) { if (pinfo->destport == ADB_TCP_PORT) direction = P2P_DIR_SENT; else direction = P2P_DIR_RECV; } else { return offset; } if (pinfo->phdr->presence_flags & WTAP_HAS_INTERFACE_ID) interface_id = pinfo->phdr->interface_id; else interface_id = 0; if (proto == proto_usb) { bus_id = usb_conv_info->bus_id; device_address = usb_conv_info->device_address; key[0].length = 1; key[0].key = &interface_id; key[1].length = 1; key[1].key = &bus_id; key[2].length = 1; key[2].key = &device_address; key[3].length = 0; key[3].key = NULL; } else { /* tcp */ key[0].length = 1; key[0].key = &interface_id; key[1].length = 1; key[2].length = 1; if (direction == P2P_DIR_SENT) { key[1].key = &pinfo->srcport; key[2].key = &pinfo->destport; } else { key[1].key = &pinfo->destport; key[2].key = &pinfo->srcport; } key[3].length = 0; key[3].key = NULL; } wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(command_info, key); if (wmem_tree) { command_data = (command_data_t *) wmem_tree_lookup32_le(wmem_tree, frame_number); if (command_data && command_data->completed_in_frame >= frame_number && command_data->command_in_frame <= frame_number) { if (command_data->command_in_frame != frame_number) { is_command = FALSE; is_next_fragment = TRUE; } data_length = command_data->data_length; crc32 = command_data->crc32; if (direction == P2P_DIR_SENT) if (command_data->command == A_CLSE) side_id = command_data->arg1; /* OUT: local id */ else side_id = command_data->arg0; /* OUT: local id */ else if (command_data->command == A_OKAY) { side_id = command_data->arg1; /* IN: remote id */ } else side_id = command_data->arg1; /* IN: remote id */ key[3].length = 1; key[3].key = &side_id; key[4].length = 0; key[4].key = NULL; wmem_tree = (wmem_tree_t *) wmem_tree_lookup32_array(service_info, key); if (wmem_tree) { service_data = (service_data_t *) wmem_tree_lookup32_le(wmem_tree, frame_number); if (service_data && command_data->command == A_OPEN) { is_service = TRUE; } } } } /* Simple heuristics to check if packet is command or data */ if ((command_data && command_data->completed_in_frame <= frame_number) || !command_data) { if (tvb_reported_length(tvb) < 24) { is_command = FALSE; } else if (tvb_reported_length(tvb) >= 24) { command = tvb_get_letohl(tvb, offset); if (command != A_SYNC && command != A_CLSE && command != A_WRTE && command != A_AUTH && command != A_CNXN && command != A_OPEN && command != A_OKAY) is_command = FALSE; else if (command != (0xFFFFFFFF ^ tvb_get_letohl(tvb, offset + 20))) is_command = FALSE; if (is_command) { data_length = tvb_get_letohl(tvb, offset + 12); crc32 = tvb_get_letohl(tvb, offset + 16); } if (command == A_OPEN) is_service = TRUE; } } if (service_data && !(command_data->command == A_OPEN && is_next_fragment)) { sub_item = proto_tree_add_string(main_tree, hf_service, tvb, offset, 0, service_data->service); PROTO_ITEM_SET_GENERATED(sub_item); } if (service_data) { sub_item = proto_tree_add_uint(main_tree, hf_service_start_in_frame, tvb, offset, 0, service_data->start_in_frame); PROTO_ITEM_SET_GENERATED(sub_item); if (service_data->close_local_in_frame < max_in_frame) { sub_item = proto_tree_add_uint(main_tree, hf_close_local_in_frame, tvb, offset, 0, service_data->close_local_in_frame); PROTO_ITEM_SET_GENERATED(sub_item); } if (service_data->close_remote_in_frame < max_in_frame) { sub_item = proto_tree_add_uint(main_tree, hf_close_remote_in_frame, tvb, offset, 0, service_data->close_remote_in_frame); PROTO_ITEM_SET_GENERATED(sub_item); } } if (is_command) { proto_tree_add_item(main_tree, hf_command, tvb, offset, 4, ENC_LITTLE_ENDIAN); command = tvb_get_letohl(tvb, offset); offset += 4; col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(command, command_vals, "Unknown command")); arg0_item = proto_tree_add_item(main_tree, hf_argument_0, tvb, offset, 4, ENC_LITTLE_ENDIAN); arg0_tree = proto_item_add_subtree(arg0_item, ett_adb_arg0); arg0 = tvb_get_letohl(tvb, offset); offset += 4; arg1_item = proto_tree_add_item(main_tree, hf_argument_1, tvb, offset, 4, ENC_LITTLE_ENDIAN); arg1_tree = proto_item_add_subtree(arg1_item, ett_adb_arg1); arg1 = tvb_get_letohl(tvb, offset); offset += 4; switch (command) { case A_CNXN: proto_tree_add_item(arg0_tree, hf_version, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(arg1_tree, hf_max_data, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "(version=%u.%u.%u, max_data=%u)", tvb_get_guint8(tvb, offset - 5), tvb_get_guint8(tvb, offset - 6), tvb_get_letohs(tvb, offset - 7), tvb_get_letohl(tvb, offset - 4)); break; case A_AUTH: proto_tree_add_item(arg0_tree, hf_auth_type, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(arg1_tree, hf_zero, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "(type=%s, 0)", val_to_str_const(tvb_get_letohl(tvb, offset - 8), auth_type_vals, "Unknown")); break; case A_OPEN: proto_tree_add_item(arg0_tree, hf_local_id, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(arg1_tree, hf_zero, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "(local=%u, 0)", tvb_get_letohl(tvb, offset - 8)); break; case A_WRTE: proto_tree_add_item(arg0_tree, hf_zero, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(arg1_tree, hf_remote_id, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "(0, remote=%u)", tvb_get_letohl(tvb, offset - 4)); break; case A_CLSE: case A_OKAY: proto_tree_add_item(arg0_tree, hf_local_id, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(arg1_tree, hf_remote_id, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "(local=%u, remote=%u)", tvb_get_letohl(tvb, offset - 8), tvb_get_letohl(tvb, offset - 4)); break; case A_SYNC: proto_tree_add_item(arg0_tree, hf_online, tvb, offset - 8, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(arg1_tree, hf_sequence, tvb, offset - 4, 4, ENC_LITTLE_ENDIAN); col_append_fstr(pinfo->cinfo, COL_INFO, "(online=%s, sequence=%u)", tvb_get_letohl(tvb, offset - 8) ? "Yes": "No", tvb_get_letohl(tvb, offset - 4)); break; } proto_tree_add_item(main_tree, hf_data_length, tvb, offset, 4, ENC_LITTLE_ENDIAN); offset += 4; if (data_length > 0) col_append_fstr(pinfo->cinfo, COL_INFO, " length=%u ", data_length); crc_item = proto_tree_add_item(main_tree, hf_data_crc32, tvb, offset, 4, ENC_LITTLE_ENDIAN); crc_tree = proto_item_add_subtree(crc_item, ett_adb_crc); crc32 = tvb_get_letohl(tvb, offset); offset += 4; magic_item = proto_tree_add_item(main_tree, hf_magic, tvb, offset, 4, ENC_LITTLE_ENDIAN); if ((tvb_get_letohl(tvb, offset) ^ 0xFFFFFFFF) != command) { proto_tree *expert_tree; expert_tree = proto_item_add_subtree(magic_item, ett_adb_magic); proto_tree_add_expert(expert_tree, pinfo, &ei_invalid_magic, tvb, offset, 4); } if (!pinfo->fd->flags.visited) save_command(command, arg0, arg1, data_length, crc32, service_data, proto, data, pinfo, &service_data, &command_data); offset += 4; } if (!pinfo->fd->flags.visited && command_data) { if (command_data->command_in_frame != frame_number) { is_command = FALSE; is_next_fragment = TRUE; } data_length = command_data->data_length; crc32 = command_data->crc32; if ((command_data->command_in_frame != frame_number && tvb_captured_length(tvb) == data_length) || (command_data->command_in_frame == frame_number && tvb_captured_length(tvb) == data_length + 24) ) { command_data->reassemble_data_length = command_data->data_length; command_data->completed_in_frame = frame_number; } } if (is_next_fragment && command_data) { sub_item = proto_tree_add_uint(main_tree, hf_command_in_frame, tvb, offset, 0, command_data->command_in_frame); PROTO_ITEM_SET_GENERATED(sub_item); sub_item = proto_tree_add_uint(main_tree, hf_command, tvb, offset, 0, command_data->command); PROTO_ITEM_SET_GENERATED(sub_item); sub_item = proto_tree_add_uint(main_tree, hf_data_length, tvb, offset, 0, command_data->data_length); PROTO_ITEM_SET_GENERATED(sub_item); crc_item = proto_tree_add_uint(main_tree, hf_data_crc32, tvb, offset, 0, command_data->crc32); crc_tree = proto_item_add_subtree(crc_item, ett_adb_crc); PROTO_ITEM_SET_GENERATED(crc_item); } if (command_data && command_data->completed_in_frame != frame_number) { sub_item = proto_tree_add_uint(main_tree, hf_completed_in_frame, tvb, offset, 0, command_data->completed_in_frame); PROTO_ITEM_SET_GENERATED(sub_item); } if (tvb_captured_length_remaining(tvb, offset) > 0 && (!is_command || data_length > 0)) { guint32 crc = 0; guint32 i_offset; if ((!pinfo->fd->flags.visited && command_data && command_data->reassemble_data_length < command_data->data_length) || data_length > (guint32) tvb_captured_length_remaining(tvb, offset)) { /* need reassemble */ if (!pinfo->fd->flags.visited && command_data && command_data->reassemble_data_length < command_data->data_length) { tvb_memcpy(tvb, command_data->reassemble_data + command_data->reassemble_data_length, offset, tvb_captured_length_remaining(tvb, offset)); command_data->reassemble_data_length += tvb_captured_length_remaining(tvb, offset); if (command_data->reassemble_data_length >= command_data->data_length) command_data->completed_in_frame = frame_number; } proto_tree_add_item(main_tree, hf_data_fragment, tvb, offset, -1, ENC_NA); col_append_str(pinfo->cinfo, COL_INFO, "Data Fragment"); offset = tvb_captured_length(tvb); if (service_data && command_data && command_data->reassemble_data_length >= command_data->data_length && frame_number == command_data->completed_in_frame) { tvbuff_t *next_tvb; adb_service_data_t adb_service_data; next_tvb = tvb_new_child_real_data(tvb, command_data->reassemble_data, command_data->reassemble_data_length, command_data->reassemble_data_length); add_new_data_source(pinfo, next_tvb, "ADB Reassembled Data"); adb_service_data.service = service_data->service; adb_service_data.direction = direction; adb_service_data.session_key_length = 3; adb_service_data.session_key = (guint32 *) wmem_alloc(wmem_packet_scope(), adb_service_data.session_key_length * sizeof(guint32)); adb_service_data.session_key[0] = interface_id; if (proto == proto_usb) { adb_service_data.session_key[1] = usb_conv_info->bus_id; adb_service_data.session_key[2] = usb_conv_info->device_address; } else { /* tcp */ if (direction == P2P_DIR_SENT) { adb_service_data.session_key[1] = pinfo->srcport; adb_service_data.session_key[2] = pinfo->destport; } else { adb_service_data.session_key[1] = pinfo->destport; adb_service_data.session_key[2] = pinfo->srcport; } } call_dissector_with_data(adb_service_handle, next_tvb, pinfo, tree, &adb_service_data); } } else { /* full message */ for (i_offset = 0; i_offset < data_length; ++i_offset) crc += tvb_get_guint8(tvb, offset + i_offset); if (crc32 > 0 && crc32 != crc) proto_tree_add_expert(crc_tree, pinfo, &ei_invalid_crc, tvb, offset, -1); if (is_service) { proto_tree_add_item(main_tree, hf_service, tvb, offset, -1, ENC_ASCII | ENC_NA); if (!pinfo->fd->flags.visited && service_data) { service_data->service = tvb_get_stringz_enc(wmem_file_scope(), tvb, offset, NULL, ENC_ASCII); } col_append_fstr(pinfo->cinfo, COL_INFO, "Service: %s", tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, NULL, ENC_ASCII)); offset = tvb_captured_length(tvb); } else if (command_data && command_data->command == A_CNXN) { gchar *info; gint len; info = tvb_get_stringz_enc(wmem_packet_scope(), tvb, offset, &len, ENC_ASCII); col_append_fstr(pinfo->cinfo, COL_INFO, "Connection Info: %s", info); proto_tree_add_item(main_tree, hf_connection_info, tvb, offset, len, ENC_ASCII | ENC_NA); offset += len; } else { col_append_str(pinfo->cinfo, COL_INFO, "Data"); /* Decode service payload */ if (service_data) { tvbuff_t *next_tvb; adb_service_data_t adb_service_data; adb_service_data.service = service_data->service; adb_service_data.direction = direction; adb_service_data.session_key_length = 3; adb_service_data.session_key = (guint32 *) wmem_alloc(wmem_packet_scope(), adb_service_data.session_key_length * sizeof(guint32)); adb_service_data.session_key[0] = interface_id; if (proto == proto_usb) { adb_service_data.session_key[1] = usb_conv_info->bus_id; adb_service_data.session_key[2] = usb_conv_info->device_address; } else { /* tcp */ if (direction == P2P_DIR_SENT) { adb_service_data.session_key[1] = pinfo->srcport; adb_service_data.session_key[2] = pinfo->destport; } else { adb_service_data.session_key[1] = pinfo->destport; adb_service_data.session_key[2] = pinfo->srcport; } } next_tvb = tvb_new_subset(tvb, offset, tvb_captured_length_remaining(tvb, offset), tvb_captured_length_remaining(tvb, offset)); call_dissector_with_data(adb_service_handle, next_tvb, pinfo, tree, &adb_service_data); } else { proto_item *data_item; gchar *data_str; data_item = proto_tree_add_item(main_tree, hf_data, tvb, offset, data_length, ENC_NA); data_str = tvb_format_text(tvb, offset, data_length); proto_item_append_text(data_item, ": %s", data_str); col_append_fstr(pinfo->cinfo, COL_INFO, " Raw: %s", data_str); } offset = tvb_captured_length(tvb); } } } return offset; }
/* * This function for CRC16 only is based on the decode_fcs of packet_ppp.c */ static tvbuff_t * mtp2_decode_crc16(tvbuff_t *tvb, proto_tree *fh_tree, packet_info *pinfo) { tvbuff_t *next_tvb; gint len, reported_len; int rx_fcs_offset; guint32 rx_fcs_exp; guint32 rx_fcs_got; int proto_offset=0; proto_item *cause; /* * Do we have the entire packet, and does it include a 2-byte FCS? */ len = tvb_length_remaining(tvb, proto_offset); reported_len = tvb_reported_length_remaining(tvb, proto_offset); if (reported_len < 2 || len < 0) { /* * The packet is claimed not to even have enough data for a 2-byte FCS, * or we're already past the end of the captured data. * Don't slice anything off. */ next_tvb = tvb_new_subset_remaining(tvb, proto_offset); } else if (len < reported_len) { /* * The packet is claimed to have enough data for a 2-byte FCS, but * we didn't capture all of the packet. * Slice off the 2-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 * length. */ reported_len -= 2; if (len > reported_len) len = reported_len; next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len); } else { /* * We have the entire packet, and it includes a 2-byte FCS. * Slice it off. */ len -= 2; reported_len -= 2; next_tvb = tvb_new_subset(tvb, proto_offset, len, reported_len); /* * Compute the FCS and put it into the tree. */ rx_fcs_offset = proto_offset + len; rx_fcs_exp = mtp2_fcs16(tvb); rx_fcs_got = tvb_get_letohs(tvb, rx_fcs_offset); if (rx_fcs_got != rx_fcs_exp) { cause=proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2, "FCS 16: 0x%04x [incorrect, should be 0x%04x]", rx_fcs_got, rx_fcs_exp); expert_add_info(pinfo, cause, &ei_mtp2_checksum_error); } else { proto_tree_add_text(fh_tree, tvb, rx_fcs_offset, 2, "FCS 16: 0x%04x [correct]", rx_fcs_got); } } return next_tvb; }
proto_tree_add_item(tree, hf_id, tvb, offset, length, encoding); offset += length; /* XXX: may be padding ? */ } return offset; } static gint dissect_counted_address(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree) { guint16 length; length = tvb_get_letohs(tvb, offset); proto_tree_add_item(tree, hf_tnef_value_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_tnef_attribute_display_name, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; length = tvb_get_letohs(tvb, offset); proto_tree_add_item(tree, hf_tnef_value_length, tvb, offset, 2, ENC_LITTLE_ENDIAN); offset += 2; proto_tree_add_item(tree, hf_tnef_attribute_email_address, tvb, offset, length, ENC_ASCII|ENC_NA); offset += length; return offset; }
static int hf_tali_sync_indicator = -1; static int hf_tali_opcode_indicator = -1; static int hf_tali_length_indicator = -1; static dissector_handle_t data_handle; /* Desegment TALI messages */ static gboolean tali_desegment = TRUE; /* Code to actually dissect the packets */ static guint get_tali_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) { guint16 length; length = tvb_get_letohs(tvb, offset + TALI_SYNC_LENGTH + TALI_OPCODE_LENGTH); return length+TALI_HEADER_LENGTH; } static void dissect_tali_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { char opcode[TALI_OPCODE_LENGTH+1]; /* TALI opcode */ guint16 length; /* TALI length */ tvbuff_t *payload_tvb = NULL; /* Set up structures needed to add the protocol subtree and manage it */ proto_item *tali_item = NULL; proto_tree *tali_tree = NULL; tvb_memcpy(tvb, (guint8*)opcode, TALI_SYNC_LENGTH, TALI_OPCODE_LENGTH);
static void dissect_nstrace(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *ns_tree = NULL, *flagtree = NULL; proto_item *ti = NULL, *flagitem = NULL; struct nstr_phdr *pnstr = &(pinfo->pseudo_header->nstr); tvbuff_t *next_tvb_eth_client; guint8 offset; guint i, bpos; wmem_strbuf_t *flags_strbuf = wmem_strbuf_new_label(wmem_packet_scope()); static const gchar *flags[] = {"FP", "FR", "DFD", "SRSS", "RSSH"}; gboolean first_flag = TRUE; guint8 flagoffset, flagval; guint8 src_vmname_len = 0, dst_vmname_len = 0; guint8 variable_ns_len = 0; guint flagval32; wmem_strbuf_append(flags_strbuf, "None"); if (pnstr->rec_type == NSPR_HEADER_VERSION205) { src_vmname_len = tvb_get_guint8(tvb,pnstr->src_vmname_len_offset); dst_vmname_len = tvb_get_guint8(tvb,pnstr->dst_vmname_len_offset); variable_ns_len = src_vmname_len + dst_vmname_len; pnstr->eth_offset += variable_ns_len; } ti = proto_tree_add_protocol_format(tree, proto_nstrace, tvb, 0, pnstr->eth_offset, "NetScaler Packet Trace"); ns_tree = proto_item_add_subtree(ti, ett_ns); proto_tree_add_item(ns_tree, hf_ns_dir, tvb, pnstr->dir_offset, pnstr->dir_len, ENC_LITTLE_ENDIAN); proto_tree_add_item(ns_tree, hf_ns_nicno, tvb, pnstr->nicno_offset, pnstr->nicno_len, ENC_LITTLE_ENDIAN); switch (pnstr->rec_type) { case NSPR_HEADER_VERSION206: flagoffset = pnstr->ns_activity_offset; flagval32 = tvb_get_letohl(tvb, flagoffset); flagitem = proto_tree_add_uint_format(ns_tree, hf_ns_activity, tvb, flagoffset, 4, flagval32, "Activity Flags: 0x%04x", flagval32); flagtree = proto_item_add_subtree(flagitem, ett_ns_activity_flags); proto_tree_add_item(flagtree, hf_ns_activity_perf_collection, tvb, flagoffset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(flagtree, hf_ns_activity_pcb_zombie, tvb, flagoffset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(flagtree, hf_ns_activity_natpcb_zombie, tvb, flagoffset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(flagtree, hf_ns_activity_lbstats_sync, tvb, flagoffset, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(flagtree, hf_ns_activity_stats_req, tvb, flagoffset, 4, ENC_LITTLE_ENDIAN); case NSPR_HEADER_VERSION205: if(src_vmname_len){ proto_tree_add_item(ns_tree,hf_ns_src_vm,tvb,pnstr->data_offset,src_vmname_len,ENC_LITTLE_ENDIAN); } if(dst_vmname_len){ proto_tree_add_item(ns_tree,hf_ns_dst_vm,tvb,pnstr->data_offset+src_vmname_len,dst_vmname_len,ENC_LITTLE_ENDIAN); } case NSPR_HEADER_VERSION204: flagoffset = pnstr->clflags_offset; flagval = tvb_get_guint8(tvb, flagoffset); for (i = 0; i < 5; i++) { bpos = 1 << i; if (flagval & bpos) { if (first_flag) { wmem_strbuf_truncate(flags_strbuf, 0); } wmem_strbuf_append_printf(flags_strbuf, "%s%s", first_flag ? "" : ", ", flags[i]); first_flag = FALSE; } } proto_tree_add_item(ns_tree, hf_ns_snode, tvb, pnstr->srcnodeid_offset, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(ns_tree, hf_ns_dnode, tvb, pnstr->destnodeid_offset, 2, ENC_LITTLE_ENDIAN); flagitem = proto_tree_add_uint_format_value(ns_tree, hf_ns_clflags, tvb, flagoffset, 1, flagval, "0x%02x (%s)", flagval, wmem_strbuf_get_str(flags_strbuf)); flagtree = proto_item_add_subtree(flagitem, ett_ns_flags); proto_tree_add_boolean(flagtree, hf_ns_clflags_res, tvb, flagoffset, 1, flagval); proto_tree_add_boolean(flagtree, hf_ns_clflags_rssh, tvb, flagoffset, 1, flagval); proto_tree_add_boolean(flagtree, hf_ns_clflags_rss, tvb, flagoffset, 1, flagval); proto_tree_add_boolean(flagtree, hf_ns_clflags_dfd, tvb, flagoffset, 1, flagval); proto_tree_add_boolean(flagtree, hf_ns_clflags_fr, tvb, flagoffset, 1, flagval); proto_tree_add_boolean(flagtree, hf_ns_clflags_fp, tvb, flagoffset, 1, flagval); case NSPR_HEADER_VERSION203: proto_tree_add_item(ns_tree, hf_ns_coreid, tvb, pnstr->coreid_offset, 2, ENC_LITTLE_ENDIAN); /* fall through to next case */ case NSPR_HEADER_VERSION202: col_add_fstr(pinfo->cinfo, COL_8021Q_VLAN_ID, "%d", tvb_get_letohs(tvb, pnstr->vlantag_offset)); proto_tree_add_item(ns_tree, hf_ns_vlantag, tvb, pnstr->vlantag_offset, 2, ENC_LITTLE_ENDIAN); /* fall through to next case */ case NSPR_HEADER_VERSION201: proto_tree_add_item(ns_tree, hf_ns_pcbdevno, tvb, pnstr->pcb_offset, 4, ENC_LITTLE_ENDIAN); ti = proto_tree_add_item(ns_tree, hf_ns_devno, tvb, pnstr->pcb_offset, 4, ENC_LITTLE_ENDIAN); PROTO_ITEM_SET_HIDDEN(ti); proto_tree_add_item(ns_tree, hf_ns_l_pcbdevno, tvb, pnstr->l_pcb_offset, 4, ENC_LITTLE_ENDIAN); ti = proto_tree_add_item(ns_tree, hf_ns_devno, tvb, pnstr->l_pcb_offset, 4, ENC_LITTLE_ENDIAN); PROTO_ITEM_SET_HIDDEN(ti); break; default: break; } /* Dissect as Ethernet */ offset = pnstr->eth_offset; next_tvb_eth_client = tvb_new_subset_remaining(tvb, offset); call_dissector(eth_withoutfcs_handle, next_tvb_eth_client, pinfo, tree); }
static void dissect_turbocell(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_item *ti, *name_item; proto_tree *turbocell_tree = NULL, *network_tree; tvbuff_t *next_tvb; int i=0; guint8 packet_type; guint8 * str_name; guint str_len; gint remaining_length; packet_type = tvb_get_guint8(tvb, 0); if (!(packet_type & 0x0F)){ col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Beacon)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } else if ( packet_type == TURBOCELL_TYPE_MANAGEMENT ) { col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Management)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } else if ( packet_type == TURBOCELL_TYPE_DATA ) { col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Data)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } else { col_set_str(pinfo->cinfo, COL_INFO, "Turbocell Packet (Unknown)"); col_set_str(pinfo->cinfo, COL_PROTOCOL, "Turbocell"); } if (tree) { ti = proto_tree_add_item(tree, proto_turbocell, tvb, 0, 20, ENC_NA); turbocell_tree = proto_item_add_subtree(ti, ett_turbocell); proto_tree_add_item(turbocell_tree, hf_turbocell_type, tvb, 0, 1, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_satmode, tvb, 1, 1, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_nwid, tvb, 1, 1, ENC_BIG_ENDIAN); /* it seem when we have this magic number,that means an alternate header version */ if (tvb_get_bits64(tvb, 64,48,ENC_BIG_ENDIAN) != G_GINT64_CONSTANT(0x000001fe23dc45ba)){ proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x02, 2, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x04, 6, ENC_NA); proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x0A, 3, ENC_BIG_ENDIAN); } else { proto_tree_add_item(turbocell_tree, hf_turbocell_timestamp, tvb, 0x02, 3, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_counter, tvb, 0x05, 3, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_dst, tvb, 0x08, 6, ENC_NA); } proto_tree_add_item(turbocell_tree, hf_turbocell_unknown, tvb, 0x0E, 2, ENC_BIG_ENDIAN); proto_tree_add_item(turbocell_tree, hf_turbocell_ip, tvb, 0x10, 4, ENC_BIG_ENDIAN); } remaining_length=tvb_length_remaining(tvb, 0x14); if (remaining_length > 6) { /* If the first character is a printable character that means we have a payload with network info */ /* I couldn't find anything in the header that would definitvely indicate if payload is either data or network info */ /* Since the frame size is limited this should work ok */ if (tvb_get_guint8(tvb, 0x14)>=0x20){ name_item = proto_tree_add_item(turbocell_tree, hf_turbocell_name, tvb, 0x14, 30, ENC_ASCII|ENC_NA); network_tree = proto_item_add_subtree(name_item, ett_network); str_name=tvb_get_stringz(wmem_packet_scope(), tvb, 0x14, &str_len); col_append_fstr(pinfo->cinfo, COL_INFO, ", Network=\"%s\"",format_text(str_name, str_len-1)); while(tvb_get_guint8(tvb, 0x34 + 8*i)==0x00 && (tvb_length_remaining(tvb,0x34 + 8*i) > 6) && (i<32)) { proto_tree_add_item(network_tree, hf_turbocell_station[i], tvb, 0x34+8*i, 6, ENC_NA); i++; } /*Couldn't make sense of the apparently random data in the end*/ next_tvb = tvb_new_subset_remaining(tvb, 0x34 + 8*i); call_dissector(data_handle, next_tvb, pinfo, tree); } else { tvbuff_t *volatile msdu_tvb = NULL; guint32 msdu_offset = 0x04; guint16 j = 1; guint16 msdu_length; proto_item *parent_item; proto_tree *mpdu_tree; proto_tree *subframe_tree; next_tvb = tvb_new_subset(tvb, 0x14, -1, tvb_get_ntohs(tvb, 0x14)); parent_item = proto_tree_add_protocol_format(tree, proto_aggregate, next_tvb, 0, tvb_reported_length_remaining(next_tvb, 0), "Turbocell Aggregate Frames"); mpdu_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_parent_tree); proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_len, next_tvb, 0x00, 2, ENC_BIG_ENDIAN); proto_tree_add_item(mpdu_tree, hf_turbocell_aggregate_unknown1, next_tvb, 0x02, 2, ENC_BIG_ENDIAN); remaining_length=tvb_length_remaining(next_tvb, msdu_offset); do { msdu_length = (tvb_get_letohs(next_tvb, msdu_offset) & 0x0FFF); if (msdu_length==0) break; parent_item = proto_tree_add_uint_format(mpdu_tree, hf_turbocell_aggregate_msdu_header_text, next_tvb,msdu_offset, msdu_length + 0x02,j, "A-MSDU Subframe #%u", j); subframe_tree = proto_item_add_subtree(parent_item, ett_msdu_aggregation_subframe_tree); j++; proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_msdu_len, next_tvb, msdu_offset, 2, ENC_LITTLE_ENDIAN); proto_tree_add_item(subframe_tree, hf_turbocell_aggregate_unknown2, next_tvb, msdu_offset+1, 1, ENC_BIG_ENDIAN); msdu_offset += 0x02; remaining_length -= 0x02; msdu_tvb = tvb_new_subset(next_tvb, msdu_offset, (msdu_length>remaining_length)?remaining_length:msdu_length, msdu_length); call_dissector(eth_handle, msdu_tvb, pinfo, subframe_tree); msdu_offset += msdu_length; remaining_length -= msdu_length; } while (remaining_length > 6); if (remaining_length > 2) { next_tvb = tvb_new_subset_remaining(next_tvb, msdu_offset); call_dissector(data_handle, next_tvb, pinfo, tree); } } } }
{ 3, "Ack" }, { 4, "Nack" }, { 0, NULL } }; void proto_reg_handoff_op_uavtalk(void); #define UAVTALK_HEADER_SIZE 8 #define UAVTALK_TRAILER_SIZE 1 static int dissect_op_uavtalk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) { gint offset = 0; guint8 packet_type = tvb_get_guint8(tvb, 1) & 0x7; guint32 objid = tvb_get_letohl(tvb, 4); guint32 payload_length = tvb_get_letohs(tvb, 2) - UAVTALK_HEADER_SIZE - UAVTALK_TRAILER_SIZE; guint32 reported_length = tvb_reported_length(tvb); col_set_str(pinfo->cinfo, COL_PROTOCOL, "UAVTALK"); /* Clear out stuff in the info column */ col_clear(pinfo->cinfo, COL_INFO); col_append_fstr(pinfo->cinfo, COL_INFO, "%s: 0x%08x", val_to_str_const(packet_type, uavtalk_packet_types, ""), objid); if (objid & 0x1) { col_append_str(pinfo->cinfo, COL_INFO, "(META)"); } if (tree) { /* we are being asked for details */ proto_tree *op_uavtalk_tree = NULL; ptvcursor_t * cursor;
static void dissect_nbipx(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { gboolean has_routes; proto_tree *nbipx_tree = NULL; proto_item *ti = NULL; int offset = 0; guint8 packet_type; guint8 name_type_flag; proto_tree *name_type_flag_tree; proto_item *tf; char name[(NETBIOS_NAME_LEN - 1)*4 + 1]; int name_type; gboolean has_payload; tvbuff_t *next_tvb; col_set_str(pinfo->cinfo, COL_PROTOCOL, "NBIPX"); col_clear(pinfo->cinfo, COL_INFO); if (pinfo->ipxptype == IPX_PACKET_TYPE_WANBCAST) { /* * This is a WAN Broadcast packet; we assume it will have * 8 IPX addresses at the beginning. */ has_routes = TRUE; } else { /* * This isn't a WAN Broadcast packet, but it still might * have the 8 addresses. * * If it's the right length for a name operation, * and, if we assume it has routes, the packet type * is a name operation, assume it has routes. * * NOTE: this will throw an exception if the byte that * would be the packet type byte if this has the 8 * addresses isn't present; if that's the case, we don't * know how to interpret this packet, so we can't dissect * it anyway. */ has_routes = FALSE; /* start out assuming it doesn't */ if (tvb_reported_length(tvb) == 50) { packet_type = tvb_get_guint8(tvb, offset + 32 + 1); switch (packet_type) { case NBIPX_FIND_NAME: case NBIPX_NAME_RECOGNIZED: case NBIPX_CHECK_NAME: case NBIPX_NAME_IN_USE: case NBIPX_DEREGISTER_NAME: has_routes = TRUE; break; } } } if (tree) { ti = proto_tree_add_item(tree, proto_nbipx, tvb, 0, -1, FALSE); nbipx_tree = proto_item_add_subtree(ti, ett_nbipx); } if (has_routes) { if (tree) add_routers(nbipx_tree, tvb, 0); offset += 32; } packet_type = tvb_get_guint8(tvb, offset + 1); switch (packet_type) { case NBIPX_FIND_NAME: case NBIPX_NAME_RECOGNIZED: case NBIPX_CHECK_NAME: case NBIPX_NAME_IN_USE: case NBIPX_DEREGISTER_NAME: name_type_flag = tvb_get_guint8(tvb, offset); name_type = get_netbios_name(tvb, offset+2, name, (NETBIOS_NAME_LEN - 1)*4 + 1); if (check_col(pinfo->cinfo, COL_INFO)) { col_add_fstr(pinfo->cinfo, COL_INFO, "%s %s<%02x>", val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown"), name, name_type); } if (nbipx_tree) { tf = proto_tree_add_text(nbipx_tree, tvb, offset, 1, "Name type flag: 0x%02x", name_type_flag); name_type_flag_tree = proto_item_add_subtree(tf, ett_nbipx_name_type_flags); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x80, 8, "Group name", "Unique name")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x40, 8, "Name in use", "Name not used")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x04, 8, "Name registered", "Name not registered")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x02, 8, "Name duplicated", "Name not duplicated")); proto_tree_add_text(name_type_flag_tree, tvb, offset, 1, "%s", decode_boolean_bitfield(name_type_flag, 0x01, 8, "Name deregistered", "Name not deregistered")); } offset += 1; dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; if (nbipx_tree) netbios_add_name("Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; /* * No payload to be interpreted by another protocol. */ has_payload = FALSE; break; case NBIPX_SESSION_DATA: case NBIPX_SESSION_END: case NBIPX_SESSION_END_ACK: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown")); } dissect_conn_control(tvb, offset, nbipx_tree); offset += 1; dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Source connection ID: 0x%04X", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Destination connection ID: 0x%04X", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Send sequence number: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Total data length: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Offset: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Data length: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Receive sequence number: %u", tvb_get_letohs(tvb, offset)); } offset += 2; if (nbipx_tree) { proto_tree_add_text(nbipx_tree, tvb, offset, 2, "Bytes received: %u", tvb_get_letohs(tvb, offset)); } offset += 2; /* * We may have payload to dissect. */ has_payload = TRUE; break; case NBIPX_DIRECTED_DATAGRAM: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown")); } dissect_conn_control(tvb, offset, nbipx_tree); offset += 1; dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; if (nbipx_tree) netbios_add_name("Receiver's Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; if (nbipx_tree) netbios_add_name("Sender's Name", tvb, offset, nbipx_tree); offset += NETBIOS_NAME_LEN; /* * We may have payload to dissect. */ has_payload = TRUE; break; default: if (check_col(pinfo->cinfo, COL_INFO)) { col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type, nbipx_data_stream_type_vals, "Unknown")); } /* * We don't know what the first byte is. */ offset += 1; /* * The second byte is a data stream type byte. */ dissect_packet_type(tvb, offset, packet_type, nbipx_tree); offset += 1; /* * We don't know what the rest of the packet is. */ has_payload = FALSE; } /* * Set the length of the NBIPX tree item. */ if (ti != NULL) proto_item_set_len(ti, offset); if (has_payload && tvb_offset_exists(tvb, offset)) { next_tvb = tvb_new_subset_remaining(tvb, offset); dissect_netbios_payload(next_tvb, pinfo, tree); } }