diff options
Diffstat (limited to 'asn1/c1222/packet-c1222-template.c')
-rw-r--r-- | asn1/c1222/packet-c1222-template.c | 1449 |
1 files changed, 0 insertions, 1449 deletions
diff --git a/asn1/c1222/packet-c1222-template.c b/asn1/c1222/packet-c1222-template.c deleted file mode 100644 index 42f0ab8a40..0000000000 --- a/asn1/c1222/packet-c1222-template.c +++ /dev/null @@ -1,1449 +0,0 @@ -/* packet-c1222.c - * Routines for ANSI C12.22 packet dissection - * Copyright 2010, Edward J. Beroset, edward.beroset@elster.com - * - * Wireshark - Network traffic analyzer - * By Gerald Combs <gerald@wireshark.org> - * Copyright 1998 Gerald Combs - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "config.h" - -#include <epan/packet.h> -#include <epan/conversation.h> -#include <epan/expert.h> -#include <epan/prefs.h> -#include <epan/strutil.h> -#include <epan/uat.h> -#include <epan/oids.h> -#include <wsutil/eax.h> -#include "packet-ber.h" -#include "packet-tcp.h" -#include "packet-c1222.h" - -#define PNAME "ANSI C12.22" -#define PSNAME "C12.22" -#define PFNAME "c1222" -#define C1222_PORT 1153 /* TCP port */ - -/* C12.22 flag definitions */ -#define C1222_EPSEM_FLAG_RESERVED 0x80 -#define C1222_EPSEM_FLAG_RECOVERY_SESSION 0x40 -#define C1222_EPSEM_FLAG_PROXY_SERVICE_USED 0x20 -#define C1222_EPSEM_FLAG_ED_CLASS_INCLUDED 0x10 -#define C1222_EPSEM_FLAG_SECURITY_MODE 0x0c -#define C1222_EPSEM_FLAG_RESPONSE_CONTROL 0x03 - -/* if the packet is encrypted, it can be - * good, bad, or simply not checked - */ -#define C1222_EPSEM_CRYPTO_GOOD 0x01 -#define C1222_EPSEM_CRYPTO_BAD 0x02 - -/* these defines are for each of the C12.22 services */ -#define C1222_CMD_IDENTIFY 0x20 -#define C1222_CMD_TERMINATE 0x21 -#define C1222_CMD_DISCONNECT 0x22 -#define C1222_CMD_FULL_READ 0x30 -#define C1222_CMD_DEFAULT_READ 0x3E -#define C1222_CMD_PARTIAL_READ_OFFSET 0x3F -#define C1222_CMD_FULL_WRITE 0x40 -#define C1222_CMD_DEFAULT_WRITE 0x4E -#define C1222_CMD_PARTIAL_WRITE_OFFSET 0x4F -#define C1222_CMD_LOGON 0x50 -#define C1222_CMD_SECURITY 0x51 -#define C1222_CMD_LOGOFF 0x52 -#define C1222_CMD_AUTHENTICATE 0x53 -#define C1222_CMD_NEGOTIATE 0x60 -#define C1222_CMD_WAIT 0x70 -#define C1222_CMD_TIMING_SETUP 0x71 - -void proto_register_c1222(void); - -static dissector_handle_t c1222_handle=NULL; -static dissector_handle_t c1222_udp_handle=NULL; - -/* Initialize the protocol and registered fields */ -static int proto_c1222 = -1; - -#include "packet-c1222-hf.c" -/* These are the EPSEM pieces */ -/* first, the flag components */ -static int hf_c1222_epsem_flags = -1; -static int hf_c1222_epsem_flags_reserved = -1; -static int hf_c1222_epsem_flags_recovery = -1; -static int hf_c1222_epsem_flags_proxy = -1; -static int hf_c1222_epsem_flags_ed_class = -1; -static int hf_c1222_epsem_flags_security_modes = -1; -static int hf_c1222_epsem_flags_response_control = -1; -/* and the structure of the flag components */ -static const int *c1222_flags[] = { - &hf_c1222_epsem_flags_reserved, - &hf_c1222_epsem_flags_recovery, - &hf_c1222_epsem_flags_proxy, - &hf_c1222_epsem_flags_ed_class, - &hf_c1222_epsem_flags_security_modes, - &hf_c1222_epsem_flags_response_control, - NULL -}; -/* next the optional ed_class */ -static int hf_c1222_epsem_ed_class = -1; -/* now the aggregate epsem */ -static int hf_c1222_epsem_total = -1; -/* generic command */ -static int hf_c1222_cmd = -1; -static int hf_c1222_err = -1; -static int hf_c1222_data = -1; -/* individual epsem fields */ -static int hf_c1222_logon_id = -1; -static int hf_c1222_logon_user = -1; -static int hf_c1222_security_password = -1; -static int hf_c1222_auth_len = -1; -static int hf_c1222_auth_data = -1; -static int hf_c1222_read_table = -1; -static int hf_c1222_read_offset = -1; -static int hf_c1222_read_count = -1; -static int hf_c1222_write_table = -1; -static int hf_c1222_write_offset = -1; -static int hf_c1222_write_size = -1; -static int hf_c1222_write_data = -1; -static int hf_c1222_procedure_num = -1; -static int hf_c1222_write_chksum = -1; -static int hf_c1222_wait_secs = -1; -static int hf_c1222_neg_pkt_size = -1; -static int hf_c1222_neg_nbr_pkts = -1; -static int hf_c1222_timing_setup_traffic = -1; -static int hf_c1222_timing_setup_inter_char = -1; -static int hf_c1222_timing_setup_resp_to = -1; -static int hf_c1222_timing_setup_nbr_retries = -1; - -/* the MAC */ -static int hf_c1222_epsem_mac = -1; - -/* crypto result flags */ -static int hf_c1222_epsem_crypto_good = -1; -static int hf_c1222_epsem_crypto_bad = -1; - -/* Initialize the subtree pointers */ -static int ett_c1222 = -1; -static int ett_c1222_epsem = -1; -static int ett_c1222_flags = -1; -static int ett_c1222_crypto = -1; -static int ett_c1222_cmd = -1; - -#ifdef HAVE_LIBGCRYPT -/* these pointers are for the header elements that may be needed to verify the crypto */ -static guint8 *aSO_context = NULL; -static guint8 *called_AP_title = NULL; -static guint8 *called_AP_invocation_id = NULL; -static guint8 *calling_AE_qualifier = NULL; -static guint8 *calling_AP_invocation_id = NULL; -static guint8 *mechanism_name = NULL; -static guint8 *calling_authentication_value = NULL; -static guint8 *user_information = NULL; -static guint8 *calling_AP_title = NULL; -static guint8 *key_id_element = NULL; -static guint8 *iv_element = NULL; - -/* these are the related lengths */ -static guint32 aSO_context_len = 0; -static guint32 called_AP_title_len = 0; -static guint32 called_AP_invocation_id_len = 0; -static guint32 calling_AE_qualifier_len = 0; -static guint32 calling_AP_invocation_id_len = 0; -static guint32 mechanism_name_len = 0; -static guint32 calling_authentication_value_len = 0; -static guint32 user_information_len = 0; -static guint32 calling_AP_title_len = 0; -static guint32 key_id_element_len = 0; -static guint32 iv_element_len = 0; -#endif /* HAVE_LIBGCRYPT */ - -#include "packet-c1222-ett.c" - -static expert_field ei_c1222_command_truncated = EI_INIT; -static expert_field ei_c1222_bad_checksum = EI_INIT; -static expert_field ei_c1222_epsem_missing = EI_INIT; -#ifdef HAVE_LIBGCRYPT -static expert_field ei_c1222_epsem_failed_authentication = EI_INIT; -#else -static expert_field ei_c1222_epsem_not_authenticated = EI_INIT; -#endif -static expert_field ei_c1222_epsem_not_decryped = EI_INIT; -static expert_field ei_c1222_ed_class_missing = EI_INIT; -static expert_field ei_c1222_epsem_ber_length_error = EI_INIT; -static expert_field ei_c1222_epsem_field_length_error = EI_INIT; -static expert_field ei_c1222_mac_missing = EI_INIT; - -/* Preferences */ -static int global_c1222_port = C1222_PORT; -static gboolean c1222_desegment = TRUE; -#ifdef HAVE_LIBGCRYPT -static gboolean c1222_decrypt = TRUE; -#endif -static const gchar *c1222_baseoid_str = NULL; -static guint8 *c1222_baseoid = NULL; -static guint c1222_baseoid_len = 0; - -/*------------------------------ - * Data Structures - *------------------------------ - */ -static const value_string c1222_security_modes[] = { - { 0x00, "Cleartext"}, - { 0x01, "Cleartext with authentication"}, - { 0x02, "Ciphertext with authentication"}, - { 0, NULL } -}; - -static const value_string c1222_response_control[] = { - { 0x00, "Always respond"}, - { 0x01, "Respond on exception"}, - { 0x02, "Never respond"}, - { 0, NULL } -}; - -static const value_string tableflags[] = { - { 0x00, "ST" }, - { 0x08, "MT" }, - { 0x10, "Pending ST" }, - { 0x18, "Pending MT" }, - { 0, NULL } -}; - -static const value_string procflags[] = { - { 0x00, "SF" }, - { 0x08, "MF" }, - { 0, NULL } -}; - -static const value_string commandnames[] = { -/* error codes are in the range 0x00 - 0x1f inclusive */ - { 0x00, "OK" }, - { 0x01, "Error" }, - { 0x02, "Service Not Supported" }, - { 0x03, "Insufficient Security Clearance" }, - { 0x04, "Operation Not Possible" }, - { 0x05, "Inappropriate Action Requested" }, - { 0x06, "Device Busy" }, - { 0x07, "Data Not Ready" }, - { 0x08, "Data Locked" }, - { 0x09, "Renegotiate Request" }, - { 0x0A, "Invalid Service Sequence State" }, - { 0x0B, "Security Mechanism Error" }, - { 0x0C, "Unknown Application Title" }, - { 0x0D, "Network Time-out" }, - { 0x0E, "Network Not Reachable" }, - { 0x0F, "Request Too Large" }, - { 0x10, "Response Too Large" }, - { 0x11, "Segmentation Not Possible" }, - { 0x12, "Segmentation Error" }, -/* commands are in the range 0x20 - 0x7f inclusive */ - {C1222_CMD_IDENTIFY, "Identify" }, - {C1222_CMD_TERMINATE, "Terminate" }, - {C1222_CMD_DISCONNECT, "Disconnect" }, - {C1222_CMD_FULL_READ, "Full Read" }, - {C1222_CMD_DEFAULT_READ, "Default Read" }, - {C1222_CMD_PARTIAL_READ_OFFSET, "Partial Read Offset" }, - {C1222_CMD_FULL_WRITE, "Full Write" }, - {C1222_CMD_DEFAULT_WRITE, "Default Write" }, - {C1222_CMD_PARTIAL_WRITE_OFFSET, "Partial Write Offset" }, - {C1222_CMD_LOGON, "Logon" }, - {C1222_CMD_SECURITY, "Security" }, - {C1222_CMD_LOGOFF, "Logoff" }, - {C1222_CMD_AUTHENTICATE, "Authenticate" }, - {C1222_CMD_NEGOTIATE, "Negotiate" }, - {C1222_CMD_NEGOTIATE | 0x1, "Negotiate w/ 1 Baud Rate" }, - {C1222_CMD_NEGOTIATE | 0x2, "Negotiate w/ 2 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x3, "Negotiate w/ 3 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x4, "Negotiate w/ 4 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x5, "Negotiate w/ 5 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x6, "Negotiate w/ 6 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x7, "Negotiate w/ 7 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x8, "Negotiate w/ 8 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0x9, "Negotiate w/ 9 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0xA, "Negotiate w/ 10 Baud Rates" }, - {C1222_CMD_NEGOTIATE | 0xB, "Negotiate w/ 11 Baud Rates" }, - {C1222_CMD_WAIT, "Wait" }, - {C1222_CMD_TIMING_SETUP, "Timing Setup" }, - { 0, NULL } -}; - -#ifdef HAVE_LIBGCRYPT -/* these are for the key tables */ -typedef struct _c1222_uat_data { - guint keynum; - guchar *key; - guint keylen; -} c1222_uat_data_t; - -UAT_HEX_CB_DEF(c1222_users, keynum, c1222_uat_data_t) -UAT_BUFFER_CB_DEF(c1222_users, key, c1222_uat_data_t, key, keylen) - -static c1222_uat_data_t *c1222_uat_data = NULL; -static guint num_c1222_uat_data = 0; -static uat_t *c1222_uat; - -/* these macros ares used to populate fields needed to verify crypto */ -#define FILL_START int length, start_offset = offset; -#define FILL_TABLE(fieldname) \ - length = offset - start_offset; \ - fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \ - fieldname##_len = length; -#define FILL_TABLE_TRUNCATE(fieldname, len) \ - length = 1 + 2*(offset - start_offset); \ - fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \ - fieldname##_len = len; -#define FILL_TABLE_APTITLE(fieldname) \ - length = offset - start_offset; \ - switch (tvb_get_guint8(tvb, start_offset)) { \ - case 0x80: /* relative OID */ \ - tvb_ensure_bytes_exist(tvb, start_offset, length); \ - fieldname##_len = length + c1222_baseoid_len; \ - fieldname = (guint8 *)wmem_alloc(wmem_packet_scope(), fieldname##_len); \ - fieldname[0] = 0x06; /* create absolute OID tag */ \ - fieldname[1] = (fieldname##_len - 2) & 0xff; \ - memcpy(&(fieldname[2]), c1222_baseoid, c1222_baseoid_len); \ - tvb_memcpy(tvb, &(fieldname[c1222_baseoid_len+2]), start_offset+2, length-2); \ - break; \ - case 0x06: /* absolute OID */ \ - default: \ - fieldname = (guint8 *)tvb_memdup(wmem_packet_scope(), tvb, start_offset, length); \ - fieldname##_len = length; \ - break; \ - } -#else /* HAVE_LIBGCRYPT */ -#define FILL_TABLE(fieldname) -#define FILL_TABLE_TRUNCATE(fieldname, len) -#define FILL_TABLE_APTITLE(fieldname) -#define FILL_START -#endif /* HAVE_LIBGCRYPT */ - -/*------------------------------ - * Function Prototypes - *------------------------------ - */ -void proto_reg_handoff_c1222(void); - - -/*------------------------------ - * Code - *------------------------------ - */ - -/** - * Calculates simple one's complement checksum. - * - * \param tvb pointer to tvbuff containing data to be checksummed - * \param offset offset within tvbuff to beginning of data - * \param len length of data to be checksummed - * \returns calculated checksum - */ -static guint8 -c1222_cksum(tvbuff_t *tvb, gint offset, int len) -{ - guint8 sum; - for (sum = 0; len; offset++, len--) - sum += tvb_get_guint8(tvb, offset); - return ~sum + 1; -} -/** - * Dissects C12.22 packet in detail (with a tree). - * - * \param tvb input buffer containing packet to be dissected - * \param pinfo the packet info of the current data - * \param tree the tree to append this item to - * \param length length of data - * \param offset the offset in the tvb - */ -static void -parse_c1222_detailed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int cmd, guint32 *length, int *offset) -{ - guint16 user_id = 0; - guint8 *user_name = NULL; - guint8 *password = NULL; - guint8 auth_len = 0; - gchar *auth_req = NULL; - guint16 table = 0; - guint16 tblsize = 0; - guint8 chksum = 0; - guint16 calcsum = 0; - guint8 wait_seconds = 0; - int numrates = 0; - guint16 packet_size; - guint16 procedure_num = 0; - guint8 nbr_packet; - /* timing setup parameters */ - guint8 traffic; - guint8 inter_char; - guint8 resp_to; - guint8 nbr_retries; - proto_item *item = NULL; - - /* special case to simplify handling of Negotiate service */ - if ((cmd & 0xF0) == C1222_CMD_NEGOTIATE) { - numrates = cmd & 0x0F; - cmd = C1222_CMD_NEGOTIATE; - } - proto_tree_add_uint(tree, cmd >= 0x20 ? hf_c1222_cmd : hf_c1222_err, tvb, *offset, 1, cmd); - (*offset)++; - (*length)--; - switch (cmd) { - case C1222_CMD_LOGON: - if (*length >= 12) { - user_id = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_logon_id, tvb, *offset, 2, user_id); - *offset += 2; - user_name = tvb_get_string_enc(wmem_packet_scope(),tvb, *offset, 10, ENC_ASCII); - proto_tree_add_string(tree, hf_c1222_logon_user, tvb, *offset, 10, user_name); - *offset += 10; - *length -= 12; - proto_item_set_text(tree, "C12.22 EPSEM: %s (id %d, user \"%s\")", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), user_id, user_name); - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 LOGON command truncated"); - } - break; - case C1222_CMD_SECURITY: - if (*length >= 20) { - password = tvb_get_string_enc(wmem_packet_scope(),tvb, *offset, 20, ENC_ASCII); - proto_tree_add_string(tree, hf_c1222_security_password, tvb, *offset, 20, password); - *offset += 20; - *length -= 20; - if (*length >= 2) { - user_id = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_logon_id, tvb, *offset, 2, user_id); - *offset += 2; - *length -= 2; - proto_item_set_text(tree, "C12.22 EPSEM: %s (password \"%s\", id %d)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), password, user_id); - } else { - proto_item_set_text(tree, "C12.22 EPSEM: %s (password \"%s\")", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), password); - } - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 SECURITY command truncated"); - } - break; - case C1222_CMD_AUTHENTICATE: - if (*length >= 1) { - auth_len = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_auth_len, tvb, *offset, 1, auth_len); - *offset += 1; - if (*length >= auth_len) { - auth_req = tvb_bytes_to_str(wmem_packet_scope(), tvb, *offset, auth_len); - proto_tree_add_item(tree, hf_c1222_auth_data, tvb, *offset, auth_len, ENC_NA); - *offset += auth_len; - *length -= auth_len + 1; - proto_item_set_text(tree, "C12.22 EPSEM: %s (%d bytes: %s)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), auth_len, auth_req); - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 AUTHENTICATE command truncated"); - } - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 AUTHENTICATE command truncated"); - } - break; - case C1222_CMD_FULL_READ: - if (*length >= 2) { - table = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_read_table, tvb, *offset, 2, table); - proto_item_set_text(tree, "C12.22 EPSEM: %s (%s-%d)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), - val_to_str((table >> 8) & 0xF8, tableflags,"Unknown (0x%04x)"), table & 0x7FF); - *offset += 2; - *length -= 2; - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 READ command truncated"); - } - break; - case C1222_CMD_PARTIAL_READ_OFFSET: - if (*length >= 7) { - table = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_read_table, tvb, *offset, 2, table); - *offset += 2; - *length -= 2; - proto_tree_add_item(tree, hf_c1222_read_offset, tvb, *offset, 3, ENC_BIG_ENDIAN); - *offset += 3; - *length -= 3; - proto_tree_add_item(tree, hf_c1222_read_count, tvb, *offset, 2, ENC_BIG_ENDIAN); - *offset += 2; - *length -= 2; - proto_item_set_text(tree, "C12.22 EPSEM: %s (%s-%d)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), - val_to_str((table >> 8) & 0xF8, tableflags,"Unknown (0x%04x)"), table & 0x7FF); - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 READ command truncated"); - } - break; - case C1222_CMD_FULL_WRITE: - if (*length >= 5) { - table = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_write_table, tvb, *offset, 2, table); - *offset += 2; - *length -= 2; - tblsize = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_write_size, tvb, *offset, 2, tblsize); - *offset += 2; - *length -= 2; - if (*length >= tblsize+1U) { - if (table == 7) {/* is it a procedure call? */ - procedure_num = tvb_get_letohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_procedure_num, tvb, *offset, 2, procedure_num); - *offset += 2; - *length -= 2; - tblsize -= 2; - } - proto_tree_add_item(tree, hf_c1222_write_data, tvb, *offset, tblsize, ENC_NA); - *offset += tblsize; - *length -= tblsize; - chksum = tvb_get_guint8(tvb, *offset); - item = proto_tree_add_uint(tree, hf_c1222_write_chksum, tvb, *offset, 1, chksum); - if (table == 7) {/* is it a procedure call? */ - calcsum = c1222_cksum(tvb, (*offset)-tblsize-2, tblsize+2); - } else { - calcsum = c1222_cksum(tvb, (*offset)-tblsize, tblsize); - } - if (chksum != calcsum) { - expert_add_info_format(pinfo, item, &ei_c1222_bad_checksum, "Bad checksum [should be 0x%02x]", calcsum); - } - if (table == 7) {/* is it a procedure call? */ - proto_item_set_text(tree, "C12.22 EPSEM: %s (%s-%d, %s-%d)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), - val_to_str((table >> 8) & 0xF8, tableflags,"Unknown (0x%04x)"), table & 0x7FF, - val_to_str((procedure_num >> 8) & 0xF8, procflags,"Unknown (0x%04x)"), procedure_num & 0x7FF); - } else { - proto_item_set_text(tree, "C12.22 EPSEM: %s (%s-%d)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), - val_to_str((table >> 8) & 0xF8, tableflags,"Unknown (0x%04x)"), table & 0x7FF); - } - *offset += 1; - *length -= 1; - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 WRITE command truncated"); - } - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 WRITE command truncated"); - } - break; - case C1222_CMD_PARTIAL_WRITE_OFFSET: - if (*length >= 8) { - table = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_write_table, tvb, *offset, 2, table); - *offset += 2; - *length -= 2; - proto_tree_add_item(tree, hf_c1222_write_offset, tvb, *offset, 3, ENC_BIG_ENDIAN); - *offset += 3; - *length -= 3; - tblsize = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_write_size, tvb, *offset, 2, tblsize); - *offset += 2; - *length -= 2; - if (*length >= tblsize+1U) { - proto_tree_add_item(tree, hf_c1222_write_data, tvb, *offset, tblsize, ENC_NA); - *offset += tblsize; - *length -= tblsize; - chksum = tvb_get_guint8(tvb, *offset); - item = proto_tree_add_uint(tree, hf_c1222_write_chksum, tvb, *offset, 1, chksum); - calcsum = c1222_cksum(tvb, (*offset)-tblsize, tblsize); - if (chksum != calcsum) { - expert_add_info_format(pinfo, item, &ei_c1222_bad_checksum, "Bad checksum [should be 0x%02x]", calcsum); - } - proto_item_set_text(tree, "C12.22 EPSEM: %s (%s-%d)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), - val_to_str((table >> 8) & 0xF8, tableflags,"Unknown (0x%04x)"), table & 0x7FF); - *offset += 1; - *length -= 1; - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 WRITE command truncated"); - } - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 WRITE command truncated"); - } - break; - case C1222_CMD_WAIT: - if (*length >= 1) { - wait_seconds = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_wait_secs, tvb, *offset, 1, wait_seconds); - *offset += 1; - *length -= 1; - proto_item_set_text(tree, "C12.22 EPSEM: %s (%d seconds)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), wait_seconds); - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 WAIT command truncated"); - } - break; - case C1222_CMD_NEGOTIATE: - if (*length >= 3) { - packet_size = tvb_get_ntohs(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_neg_pkt_size, tvb, *offset, 2, packet_size); - *offset += 2; - *length -= 2; - nbr_packet = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_neg_nbr_pkts, tvb, *offset, 1, nbr_packet); - *offset += 1; - *length -= 1; - proto_item_set_text(tree, "C12.22 EPSEM: %s (pkt size %d, num pkts %d, with %d baud rates)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), packet_size, nbr_packet, numrates); - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 NEGOTIATE command truncated"); - } - break; - case C1222_CMD_TIMING_SETUP: - if (*length >= 4) { - traffic = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_timing_setup_traffic, tvb, *offset, 1, traffic); - *offset += 1; - *length -= 1; - inter_char = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_timing_setup_inter_char, tvb, *offset, 1, inter_char); - *offset += 1; - *length -= 1; - resp_to = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_timing_setup_resp_to, tvb, *offset, 1, resp_to); - *offset += 1; - *length -= 1; - nbr_retries = tvb_get_guint8(tvb, *offset); - proto_tree_add_uint(tree, hf_c1222_timing_setup_nbr_retries, tvb, *offset, 1, nbr_retries); - *offset += 1; - *length -= 1; - proto_item_set_text(tree, "C12.22 EPSEM: %s (traffic to %d s, inter-char to %d s, response to %d s, %d retries)", - val_to_str(cmd,commandnames,"Unknown (0x%02x)"), traffic, inter_char, resp_to, nbr_retries); - } else { - expert_add_info_format(pinfo, tree, &ei_c1222_command_truncated, "C12.22 NEGOTIATE command truncated"); - } - break; - - default: - /* don't do anything */ - proto_item_set_text(tree, "C12.22 EPSEM: %s", val_to_str(cmd, commandnames, "Unknown (0x%02x)")); - if (*length) { - proto_tree_add_item(tree, hf_c1222_data, tvb, *offset, *length, ENC_NA); - } - break; - } -} - -#ifdef HAVE_LIBGCRYPT -typedef struct tagTOP_ELEMENT_CONTROL -{ - /* TRUE if this tag is required */ - gboolean required; - /* TRUE if we must truncate this tag */ - gboolean truncate; - /* actual hex value of the tag we're seeking */ - guint8 tag; - /* if TRUE, add tag and length before copying */ - gboolean addtag; - /* pointer to pointer to memory copy of element */ - guint8 **element; - /* pointer to element length */ - guint32 *length; -} TOP_ELEMENT_CONTROL; - -static const TOP_ELEMENT_CONTROL canonifyTable[] = { - { FALSE, FALSE, 0xA1, TRUE, &aSO_context, &aSO_context_len }, - { TRUE , FALSE, 0xA2, TRUE, &called_AP_title, &called_AP_title_len }, - { FALSE, FALSE, 0xA4, TRUE, &called_AP_invocation_id, &called_AP_invocation_id_len }, - { FALSE, FALSE, 0xA7, TRUE, &calling_AE_qualifier, &calling_AE_qualifier_len }, - { TRUE, FALSE, 0xA8, TRUE, &calling_AP_invocation_id, &calling_AP_invocation_id_len }, - { FALSE, FALSE, 0x8B, TRUE, &mechanism_name, &mechanism_name_len }, - { FALSE, FALSE, 0xAC, TRUE, &calling_authentication_value, &calling_authentication_value_len }, - { TRUE , TRUE , 0xBE, TRUE, &user_information, &user_information_len }, - { FALSE, FALSE, 0xA6, TRUE, &calling_AP_title, &calling_AP_title_len }, - { FALSE, FALSE, 0xAC, FALSE, &key_id_element, &key_id_element_len }, - { FALSE, FALSE, 0xAC, FALSE, &iv_element, &iv_element_len }, - { FALSE, FALSE, 0x0, TRUE, NULL, NULL } -}; - -static void -clear_canon(void) -{ - const TOP_ELEMENT_CONTROL *t = canonifyTable; - - for (t = canonifyTable; t->element != NULL; t++) { - *(t->length) = 0; - *(t->element) = NULL; - } -} - -/** - * Calculates the size of the passed number n as encoded as a BER length field. - * - * \param n is the length value to be BER encoded - * \returns the sized of the encoding - */ -static guint32 -get_ber_len_size(guint32 n) -{ - guint32 len = 1; - if (n > 0x7f) len++; - if (n > 0xff) len++; - if (n > 0xffff) len++; - if (n > 0xffffff) len++; - return len; -} -/** - * Encodes the passed value n as a BER-encoded length at puts it in memory. - * - * \param ptr points to the buffer to be written - * \param n is the length to be BER encoded - * \param maxsize is the maximum number of bytes we're allowed to write - * \returns length of encoded value in bytes - */ -static int -encode_ber_len(guint8 *ptr, guint32 n, int maxsize) -{ - int len = get_ber_len_size(n); - if (len > maxsize) return 0; - if (len == 1) { - *ptr = 0x7f & n; - } else { - *ptr = (len -1) | 0x80; - for (ptr += len-1; n; n >>= 8) - *ptr-- = n & 0xff; - } - return len; - -} - -/** - * Checks a new encryption table item for validity. - * - * \param n points to the new record - * \param err is updated to point to an error string if needed - * \return FALSE if error; TRUE otherwise - */ -static gboolean -c1222_uat_data_update_cb(void* n, char** err) -{ - c1222_uat_data_t* new_rec = (c1222_uat_data_t *)n; - - if (new_rec->keynum > 0xff) { - *err = g_strdup("Invalid key number; must be less than 256"); - return FALSE; - } - if (new_rec->keylen != EAX_SIZEOF_KEY) { - *err = g_strdup("Invalid key size; must be 16 bytes"); - return FALSE; - } - return TRUE; -} - -/** - * Canonifies header fields in preparation for authenticating and/or decrypting the packet. - * - * \param buff points to the allocated canonization buffer - * \param offset points to start of unallocated space in buffer and - is updated as we put bytes into buffer - * \param buffsize total size of allocated buffer - * \return FALSE if element is required and not present; otherwise TRUE - */ -static gboolean -canonify_unencrypted_header(guchar *buff, guint32 *offset, guint32 buffsize) -{ - const TOP_ELEMENT_CONTROL *t = canonifyTable; - guint32 len; - - for (t = canonifyTable; t->element != NULL; t++) - { - len = *(t->length); - if (t->required && *(t->element) == NULL) - return FALSE; - if (*(t->element) != NULL) { - if (t->addtag) { - /* recreate original tag and length */ - buff[(*offset)++] = t->tag; - (*offset) += encode_ber_len(&buff[*offset], len, 4); - } - if (t->truncate) { - len = 3+2*get_ber_len_size(len); - } - /* bail out if the cannonization buffer is too small */ - /* this should never happen! */ - if (buffsize < *offset + len) { - return FALSE; - } - memcpy(&buff[*offset], *(t->element), len); - (*offset) += len; - if (t->addtag) { - *(t->element) = NULL; - } - } - } - return TRUE; -} - -/** - * Looks up the required key in the key table. - * - * \param keybuff is updated with a copy of the key data if successful lookup. - * \param keyid is the ID number of the desired key - * \returns TRUE if key was found; otherwise FALSE - */ -static gboolean -keylookup(guint8 *keybuff, guint8 keyid) -{ - guint i; - - if (c1222_uat_data == NULL) - return FALSE; - for (i = 0; i < num_c1222_uat_data; i++) { - if (c1222_uat_data[i].keynum == keyid) { - memcpy(keybuff, c1222_uat_data[i].key, EAX_SIZEOF_KEY); - return TRUE; - } - } - return FALSE; -} - -/** - * Authenticates and decrypts the passed packet. - * - * \param buffer points to a memory copy of the packet to be authenticated/decrypted - * and contains the decrypted value on successful return. - * \param length lenth of input packet - * \param decrypt TRUE if packet is to be authenticated and decrypted; FALSE if authentication only is requested - * \returns TRUE if the requested operation was successful; otherwise FALSE - */ -static gboolean -decrypt_packet(guchar *buffer, guint32 length, gboolean decrypt) -{ -#define CANONBUFFSIZE 300U - guchar canonbuff[CANONBUFFSIZE]; - guint8 c1222_key[EAX_SIZEOF_KEY]; - guchar key_id = 0; - guint32 offset = 0; - gboolean status = FALSE; - - /* must be at least 4 bytes long to include the MAC */ - if (length < 4) - return status; - if (key_id_element != NULL) - key_id = key_id_element[0]; - /* extract unencrypted header information */ - if (!canonify_unencrypted_header(canonbuff, &offset, CANONBUFFSIZE)) - return status; - /* decrypt and authenticate in place */ -/* PARAMETERS: pN : Pointer to ClearText (Input, Canonified form). */ -/* pK : Pointer to secret key (Input). */ -/* pC : Pointer to CipherText (Input/Output). */ -/* SizeN : Byte length of ClearText buffer. */ -/* SizeK : Byte length of secret key. */ -/* SizeC : Byte length of CipherText buffer. */ -/* pMac : Four byte Message Authentication Code. */ -/* Mode : Operating mode (See EAX_MODE_xxx). */ -/* RETURNS: TRUE if message has been authenticated. */ -/* FALSE if not authenticated, invalid Mode, or error. */ - if (offset) { - if (!keylookup((guint8 *)&c1222_key, key_id)) - return FALSE; - status = Eax_Decrypt(canonbuff, c1222_key, buffer, - offset, EAX_SIZEOF_KEY, length-4, - (MAC_T *)&buffer[length-4], - decrypt ? EAX_MODE_CIPHERTEXT_AUTH : EAX_MODE_CLEARTEXT_AUTH); - } - return status; -} -#endif /* HAVE_LIBGCRYPT */ - -/** - * Checks to make sure that a complete, valid BER-encoded length is in the buffer. - * - * \param tvb contains the buffer to be examined - * \param offset is the offset within the buffer at which the BER-encoded length begins - * \returns TRUE if a complete, valid BER-encoded length is in the buffer; otherwise FALSE - */ -static gboolean -ber_len_ok(tvbuff_t *tvb, int offset) -{ - guint8 ch; - - if (tvb_offset_exists(tvb, offset)) { - ch = tvb_get_guint8(tvb, offset); - offset++; - if (!(ch & 0x80)) { - return TRUE; - } else if (tvb_offset_exists(tvb, offset)) { - ch = tvb_get_guint8(tvb, offset); - offset++; - if (!(ch & 0x80)) { - return TRUE; - } else if (tvb_offset_exists(tvb, offset)) { - ch = tvb_get_guint8(tvb, offset); - offset++; - if (!(ch & 0x80)) { - return TRUE; - } else if (tvb_offset_exists(tvb, offset)) { - ch = tvb_get_guint8(tvb, offset); - /*offset++;*/ - if (!(ch & 0x80)) { - return TRUE; - } - } - } - } - } - return FALSE; -} - -/** - * Dissects the EPSEM portion of the User-information part of a C12.22 message. - * - * \param tvb the tv buffer of the current data - * \param offset the offset in the tvb - * \param len length of data - * \param pinfo the packet info of the current data - * \param tree the tree to append this item to - */ -static int -dissect_epsem(tvbuff_t *tvb, int offset, guint32 len, packet_info *pinfo, proto_tree *tree) -{ - proto_tree *cmd_tree = NULL; - proto_tree *ct = NULL; - proto_tree *crypto_tree = NULL; - proto_tree *yt = NULL; - proto_item *item = NULL; - guint8 flags; - int local_offset; - gint len2; - int cmd_err; - gboolean ind; -#ifdef HAVE_LIBGCRYPT - guchar *buffer; -#endif - tvbuff_t *epsem_buffer = NULL; - gboolean crypto_good = FALSE; - gboolean crypto_bad = FALSE; - gboolean hasmac = FALSE; - gboolean encrypted = FALSE; - - if ((tvb == NULL) && (len == 0)) { - expert_add_info(pinfo, tree, &ei_c1222_epsem_missing); - return offset; - } - /* parse the flags byte which is always unencrypted */ - flags = tvb_get_guint8(tvb, offset); - proto_tree_add_bitmask(tree, tvb, offset, hf_c1222_epsem_flags, ett_c1222_flags, c1222_flags, ENC_BIG_ENDIAN); - offset++; - switch ((flags & C1222_EPSEM_FLAG_SECURITY_MODE) >> 2) { - case EAX_MODE_CIPHERTEXT_AUTH: - /* mode is ciphertext with authentication */ - hasmac = TRUE; - len2 = tvb_reported_length_remaining(tvb, offset); - if (len2 <= 0) - return offset; - encrypted = TRUE; -#ifdef HAVE_LIBGCRYPT - if (c1222_decrypt) { - buffer = (guchar *)tvb_memdup(wmem_packet_scope(), tvb, offset, len2); - if (!decrypt_packet(buffer, len2, TRUE)) { - crypto_bad = TRUE; - } else { - epsem_buffer = tvb_new_real_data(buffer, len2, len2); - tvb_set_child_real_data_tvbuff(tvb, epsem_buffer); - add_new_data_source(pinfo, epsem_buffer, "Decrypted EPSEM Data"); - crypto_good = TRUE; - encrypted = FALSE; - } - } -#endif - break; - case EAX_MODE_CLEARTEXT_AUTH: - /* mode is cleartext with authentication */ - hasmac = TRUE; - len2 = tvb_reported_length_remaining(tvb, offset); - if (len2 <= 0) - return offset; - epsem_buffer = tvb_new_subset_remaining(tvb, offset); -#ifdef HAVE_LIBGCRYPT - buffer = (guchar *)tvb_memdup(wmem_packet_scope(), tvb, offset, len2); - if (c1222_decrypt) { - if (!decrypt_packet(buffer, len2, FALSE)) { - crypto_bad = TRUE; - expert_add_info(pinfo, tree, &ei_c1222_epsem_failed_authentication); - } else { - crypto_good = TRUE; - } - } -#else /* HAVE_LIBGCRYPT */ - expert_add_info(pinfo, tree, &ei_c1222_epsem_not_authenticated); -#endif /* HAVE_LIBGCRYPT */ - break; - default: - /* it's not encrypted */ - epsem_buffer = tvb_new_subset_remaining(tvb, offset); - } - /* it's only encrypted if we have an undecrypted payload */ - if (encrypted) { - proto_tree_add_item(tree, hf_c1222_epsem_total, tvb, offset, -1, ENC_NA); - expert_add_info(pinfo, tree, &ei_c1222_epsem_not_decryped); - local_offset = offset+len2-4; - epsem_buffer = tvb; - } else { /* it's not (now) encrypted */ - local_offset = 0; - /* retrieve the ed_class if it's there */ - if (flags & C1222_EPSEM_FLAG_ED_CLASS_INCLUDED) { - if (tvb_offset_exists(epsem_buffer, local_offset+4-1)) { - proto_tree_add_item(tree, hf_c1222_epsem_ed_class, epsem_buffer, local_offset, 4, ENC_NA); - local_offset += 4; - } else { - expert_add_info(pinfo, tree, &ei_c1222_ed_class_missing); - } - } - /* what follows are one or more <epsem-data> elements possibly followed by - * a <mac>. Each <epsem-data> element is defined as <service-length><res-req>, - * so we fetch such pairs until there isn't anything left (except possibly - * the <mac>). - */ - while (tvb_offset_exists(epsem_buffer, local_offset+(hasmac?5:1))) { - if (ber_len_ok(epsem_buffer, local_offset)) { - local_offset = dissect_ber_length(pinfo, tree, epsem_buffer, local_offset, (guint32 *)&len2, &ind); - } else { - expert_add_info(pinfo, tree, &ei_c1222_epsem_ber_length_error); - return offset+len; - } - if (tvb_offset_exists(epsem_buffer, local_offset+len2-1)) { - cmd_err = tvb_get_guint8(epsem_buffer, local_offset); - ct = proto_tree_add_item(tree, hf_c1222_epsem_total, epsem_buffer, local_offset, len2, ENC_NA); - cmd_tree = proto_item_add_subtree(ct, ett_c1222_cmd); - parse_c1222_detailed(epsem_buffer, pinfo, cmd_tree, cmd_err, (guint32 *)&len2, &local_offset); - local_offset += len2; - } else { - expert_add_info(pinfo, tree, &ei_c1222_epsem_field_length_error); - return offset+len; - } - } - } - if (hasmac) { - if (tvb_offset_exists(epsem_buffer, local_offset+4-1)) { - yt = proto_tree_add_item(tree, hf_c1222_epsem_mac, epsem_buffer, local_offset, 4, ENC_NA); - /* now we have enough information to fill in the crypto subtree */ - crypto_tree = proto_item_add_subtree(yt, ett_c1222_crypto); - item = proto_tree_add_boolean(crypto_tree, hf_c1222_epsem_crypto_good, tvb, local_offset, 4, crypto_good); - PROTO_ITEM_SET_GENERATED(item); - item = proto_tree_add_boolean(crypto_tree, hf_c1222_epsem_crypto_bad, tvb, local_offset, 4, crypto_bad); - PROTO_ITEM_SET_GENERATED(item); - } else { - expert_add_info(pinfo, tree, &ei_c1222_mac_missing); - return offset+len; - } - } - return offset; -} - -#include "packet-c1222-fn.c" - -/** - * Dissects a a full (reassembled) C12.22 message. - * - * \param tvb the tv buffer of the current data - * \param pinfo the packet info of the current data - * \param tree the tree to append this item to - */ -static int -dissect_c1222_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) -{ - proto_item *c1222_item = NULL; - proto_tree *c1222_tree = NULL; - - /* make entry in the Protocol column on summary display */ - col_set_str(pinfo->cinfo, COL_PROTOCOL, PNAME); - - /* create the c1222 protocol tree */ - c1222_item = proto_tree_add_item(tree, proto_c1222, tvb, 0, -1, ENC_NA); - c1222_tree = proto_item_add_subtree(c1222_item, ett_c1222); - return dissect_MESSAGE_PDU(tvb, pinfo, c1222_tree, NULL); -} - -/** - * Fetches the length of an entire C12.22 message to assist in reassembly. - * - * \param pinfo the packet info of the current data - * \param tvb the tv buffer of the current data - * \param offset the offset in the tvb - * \returns length of entire C12.22 message - */ -static guint -get_c1222_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset, void *data _U_) -{ - int orig_offset; - guint length; - gboolean ind; - - orig_offset = offset; - /* note that this assumes a Tag length of 1 which is always valid for C12.22 */ - offset = dissect_ber_length(pinfo, NULL, tvb, offset+1, &length, &ind); - return length+(offset - orig_offset); -} - -/** - * Reassembles and dissects C12.22 messages. - * - * \param tvb the tv buffer of the current data - * \param pinfo the packet info of the current data - * \param tree the tree to append this item to - */ -static int -dissect_c1222(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) -{ - tcp_dissect_pdus(tvb, pinfo, tree, c1222_desegment, 5, - get_c1222_message_len, dissect_c1222_common, data); - return tvb_captured_length(tvb); -} - -/*--- proto_register_c1222 -------------------------------------------*/ -void proto_register_c1222(void) { - - /* List of fields */ - static hf_register_info hf[] = { - { &hf_c1222_epsem_flags, - { "C12.22 EPSEM Flags", "c1222.epsem.flags", - FT_UINT8, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_epsem_flags_reserved, - { "C12.22 Reserved Flag", "c1222.epsem.flags.reserved", - FT_BOOLEAN, 8, - NULL, C1222_EPSEM_FLAG_RESERVED, - NULL, HFILL } - }, - { &hf_c1222_epsem_flags_recovery, - { "C12.22 Recovery Flag", "c1222.epsem.flags.recovery", - FT_BOOLEAN, 8, - NULL, C1222_EPSEM_FLAG_RECOVERY_SESSION, - NULL, HFILL } - }, - { &hf_c1222_epsem_flags_proxy, - { "C12.22 Proxy Service Used Flag", "c1222.epsem.flags.proxy", - FT_BOOLEAN, 8, - NULL, C1222_EPSEM_FLAG_PROXY_SERVICE_USED, - NULL, HFILL } - }, - { &hf_c1222_epsem_flags_ed_class, - { "C12.22 ED Class Flag", "c1222.epsem.flags.ed_class", - FT_BOOLEAN, 8, - NULL, C1222_EPSEM_FLAG_ED_CLASS_INCLUDED, - NULL, HFILL } - }, - { &hf_c1222_epsem_flags_security_modes, - { "C12.22 Security Mode Flags", "c1222.epsem.flags.security", - FT_UINT8, BASE_HEX, - VALS(c1222_security_modes), C1222_EPSEM_FLAG_SECURITY_MODE, - NULL, HFILL } - }, - { &hf_c1222_epsem_flags_response_control, - { "C12.22 Response Control Flags", "c1222.epsem.flags.response_control", - FT_UINT8, BASE_HEX, - VALS(c1222_response_control), C1222_EPSEM_FLAG_RESPONSE_CONTROL, - NULL, HFILL } - }, - { &hf_c1222_epsem_ed_class, - { "C12.22 EPSEM ED Class", "c1222.epsem.edclass", - FT_BYTES, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_epsem_total, - { "C12.22 EPSEM", "c1222.epsem.data", - FT_BYTES, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_epsem_mac, - { "C12.22 EPSEM MAC", "c1222.epsem.mac", - FT_BYTES, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_cmd, - { "C12.22 Command", "c1222.cmd", - FT_UINT8, BASE_HEX, - VALS(commandnames), 0x0, - NULL, HFILL } - }, - { &hf_c1222_err, - { "C12.22 Response", "c1222.err", - FT_UINT8, BASE_HEX, - VALS(commandnames), 0x0, - NULL, HFILL } - }, - { &hf_c1222_logon_id, - { "C12.22 Logon User-Id", "c1222.logon.id", - FT_UINT16, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_logon_user, - { "C12.22 Logon User", "c1222.logon.user", - FT_STRING, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_security_password, - { "C12.22 Security Password", "c1222.security.password", - FT_STRING, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_auth_len, - { "C12.22 Authenticate Request Length", "c1222.authenticate.len", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_auth_data, - { "C12.22 Authenticate Data", "c1222.authenticate.data", - FT_BYTES, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_read_table, - { "C12.22 Table", "c1222.read.table", - FT_UINT16, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_read_offset, - { "C12.22 Offset", "c1222.read.offset", - FT_UINT24, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_read_count, - { "C12.22 Count", "c1222.read.count", - FT_UINT16, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_write_table, - { "C12.22 Table", "c1222.write.table", - FT_UINT16, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_write_offset, - { "C12.22 Offset", "c1222.write.offset", - FT_UINT24, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_write_size, - { "C12.22 Table Size", "c1222.write.size", - FT_UINT16, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_write_data, - { "C12.22 Table Data", "c1222.write.data", - FT_BYTES, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_write_chksum, - { "C12.22 Table Data Checksum", "c1222.write.chksum", - FT_UINT8, BASE_HEX, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_procedure_num, - { "C12.22 Procedure Number", "c1222.procedure.num", - FT_UINT16, BASE_DEC, - NULL, 0x7ff, - NULL, HFILL } - }, - { &hf_c1222_neg_pkt_size, - { "C12.22 Negotiate Packet Size", "c1222.negotiate.pktsize", - FT_UINT16, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_neg_nbr_pkts, - { "C12.22 Negotiate Number of Packets", "c1222.negotiate.numpkts", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_wait_secs, - { "C12.22 Wait Seconds", "c1222.wait.seconds", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_timing_setup_traffic, - { "C12.22 Timing Setup Channel Traffic Timeout", "c1222.timingsetup.traffic", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_timing_setup_inter_char, - { "C12.22 Timing Setup Intercharacter Timeout", "c1222.timingsetup.interchar", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_timing_setup_resp_to, - { "C12.22 Timing Setup Response Timeout", "c1222.timingsetup.respto", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_timing_setup_nbr_retries, - { "C12.22 Timing Setup Number of Retries", "c1222.timingsetup.nbrretries", - FT_UINT8, BASE_DEC, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_data, - { "C12.22 data", "c1222.data", - FT_BYTES, BASE_NONE, - NULL, 0x0, - NULL, HFILL } - }, - { &hf_c1222_epsem_crypto_good, - { "Crypto good", "c1222.crypto_good", - FT_BOOLEAN, BASE_NONE, - NULL, 0x0, - "True: crypto ok; False: doesn't match or not checked", HFILL } - }, - { &hf_c1222_epsem_crypto_bad, - { "Crypto bad", "c1222.crypto_bad", - FT_BOOLEAN, BASE_NONE, - NULL, 0x0, - "True: crypto bad; False: crypto ok or not checked", HFILL } - }, -#include "packet-c1222-hfarr.c" - }; - - /* List of subtrees */ - static gint *ett[] = { - &ett_c1222, - &ett_c1222_epsem, - &ett_c1222_flags, - &ett_c1222_crypto, - &ett_c1222_cmd, -#include "packet-c1222-ettarr.c" - }; - - static ei_register_info ei[] = { - { &ei_c1222_command_truncated, { "c1222.command_truncated", PI_MALFORMED, PI_ERROR, "C12.22 command truncated", EXPFILL }}, - { &ei_c1222_bad_checksum, { "c1222.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }}, - { &ei_c1222_epsem_missing, { "c1222.epsem.missing", PI_MALFORMED, PI_ERROR, "C12.22 EPSEM missing", EXPFILL }}, -#ifdef HAVE_LIBGCRYPT - { &ei_c1222_epsem_failed_authentication, { "c1222.epsem.failed_authentication", PI_SECURITY, PI_ERROR, "C12.22 EPSEM failed authentication", EXPFILL }}, -#else - { &ei_c1222_epsem_not_authenticated, { "c1222.epsem.not_authenticated", PI_SECURITY, PI_WARN, "C12.22 EPSEM could not be authenticated", EXPFILL }}, -#endif - { &ei_c1222_epsem_not_decryped, { "c1222.epsem.not_decryped", PI_UNDECODED, PI_WARN, "C12.22 EPSEM could not be decrypted", EXPFILL }}, - { &ei_c1222_ed_class_missing, { "c1222.ed_class_missing", PI_SECURITY, PI_ERROR, "C12.22 ED Class missing", EXPFILL }}, - { &ei_c1222_epsem_ber_length_error, { "c1222.epsem.ber_length_error", PI_MALFORMED, PI_ERROR, "C12.22 EPSEM BER length error", EXPFILL }}, - { &ei_c1222_epsem_field_length_error, { "c1222.epsem.field_length_error", PI_MALFORMED, PI_ERROR, "C12.22 EPSEM field length error", EXPFILL }}, - { &ei_c1222_mac_missing, { "c1222.mac_missing", PI_MALFORMED, PI_ERROR, "C12.22 MAC missing", EXPFILL }}, - }; - - expert_module_t* expert_c1222; - module_t *c1222_module; - -#ifdef HAVE_LIBGCRYPT - static uat_field_t c1222_uat_flds[] = { - UAT_FLD_HEX(c1222_users,keynum,"Key ID","Key identifier in hexadecimal"), - UAT_FLD_BUFFER(c1222_users, key, "Key", "Encryption key as 16-byte hex string"), - UAT_END_FIELDS - }; -#endif /* HAVE_LIBGCRYPT */ - - /* Register protocol */ - proto_c1222 = proto_register_protocol(PNAME, PSNAME, PFNAME); - /* Register fields and subtrees */ - proto_register_field_array(proto_c1222, hf, array_length(hf)); - proto_register_subtree_array(ett, array_length(ett)); - expert_c1222 = expert_register_protocol(proto_c1222); - expert_register_field_array(expert_c1222, ei, array_length(ei)); - c1222_module = prefs_register_protocol(proto_c1222, proto_reg_handoff_c1222); - prefs_register_bool_preference(c1222_module, "desegment", - "Reassemble all C12.22 messages spanning multiple TCP segments", - "Whether the C12.22 dissector should reassemble all messages spanning multiple TCP segments", - &c1222_desegment); - prefs_register_string_preference(c1222_module, "baseoid", "Base OID to use for relative OIDs", - "Base object identifier for use in resolving relative object identifiers", - &c1222_baseoid_str); -#ifdef HAVE_LIBGCRYPT - prefs_register_bool_preference(c1222_module, "decrypt", - "Verify crypto for all applicable C12.22 messages", - "Whether the C12.22 dissector should verify the crypto for all relevant messages", - &c1222_decrypt); - - c1222_uat = uat_new("Decryption Table", - sizeof(c1222_uat_data_t), /* record size */ - "c1222_decryption_table", /* filename */ - TRUE, /* from_profile */ - &c1222_uat_data, /* data_ptr */ - &num_c1222_uat_data, /* numitems_ptr */ - UAT_AFFECTS_DISSECTION, /* affects dissection of packets, but not set of named fields */ - NULL, /* help */ - NULL, /* copy callback */ - c1222_uat_data_update_cb, /* update callback */ - NULL, /* free callback */ - NULL, /* post update callback */ - c1222_uat_flds); /* UAT field definitions */ - - prefs_register_uat_preference(c1222_module, - "decryption_table", - "Decryption Table", - "Table of security parameters for decryption of C12.22 packets", - c1222_uat); -#endif /* HAVE_LIBGCRYPT */ -} - -/*--- proto_reg_handoff_c1222 ---------------------------------------*/ -void -proto_reg_handoff_c1222(void) -{ - static gboolean initialized = FALSE; - guint8 *temp = NULL; - - if( !initialized ) { - c1222_handle = create_dissector_handle(dissect_c1222, proto_c1222); - c1222_udp_handle = create_dissector_handle(dissect_c1222_common, proto_c1222); - dissector_add_uint("tcp.port", global_c1222_port, c1222_handle); - dissector_add_uint("udp.port", global_c1222_port, c1222_udp_handle); - initialized = TRUE; - } - if (c1222_baseoid_str && (c1222_baseoid_str[0] != '\0') && - ((c1222_baseoid_len = oid_string2encoded(NULL, c1222_baseoid_str, &temp)) != 0)) { - c1222_baseoid = (guint8 *)wmem_realloc(wmem_epan_scope(), c1222_baseoid, c1222_baseoid_len); - memcpy(c1222_baseoid, temp, c1222_baseoid_len); - wmem_free(NULL, temp); - } else if (c1222_baseoid) { - wmem_free(wmem_epan_scope(), c1222_baseoid); - c1222_baseoid = NULL; - c1222_baseoid_len = 0; - } -} -/* - * Editor modelines - http://www.wireshark.org/tools/modelines.html - * - * Local variables: - * c-basic-offset: 2 - * tab-width: 8 - * indent-tabs-mode: nil - * End: - * - * vi: set shiftwidth=2 tabstop=8 expandtab: - * :indentSize=2:tabSize=8:noTabs=true: - */ |