static void dissect_UDPExtStatus(tvbuff_t *tvb, proto_tree *adwin_tree) { const gchar *processor_type, *system_type; if (! adwin_tree) return; proto_tree_add_item(adwin_tree, hf_adwin_config_mac, tvb, 0, 6, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 6, 2, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_pattern, tvb, 8, 4, ENC_BIG_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_version, tvb, 12, 4, ENC_BIG_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_description, tvb, 16, 16, ENC_ASCII|ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_timerresets, tvb, 32, 4, ENC_BIG_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_socketshutdowns, tvb, 36, 4, ENC_BIG_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_disk_free, tvb, 40, 4, ENC_BIG_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_disk_size, tvb, 44, 4, ENC_BIG_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_date, tvb, 48, 8, ENC_ASCII|ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_revision, tvb, 56, 8, ENC_ASCII|ENC_NA); /* add the processor type raw values to the tree, to allow filtering */ proto_tree_add_item(adwin_tree, hf_adwin_config_processor_type, tvb, 64, 2, ENC_ASCII|ENC_NA); /* add the processor type as a pretty printed string */ processor_type = tvb_get_string_enc(wmem_packet_scope(), tvb, 64, 2, ENC_ASCII|ENC_NA); processor_type = str_to_str(processor_type, processor_type_mapping, "Unknown (%s)"); proto_tree_add_text(adwin_tree, tvb, 64, 2, "Processor Type: %s", processor_type); /* add system type as raw value and pretty printed string */ proto_tree_add_item(adwin_tree, hf_adwin_config_system_type, tvb, 66, 2, ENC_ASCII|ENC_NA); system_type = tvb_get_string_enc(wmem_packet_scope(), tvb, 66, 2, ENC_ASCII|ENC_NA); system_type = str_to_str(system_type, system_type_mapping, "Unknown (%s)"); proto_tree_add_text(adwin_tree, tvb, 66, 2, "System Type: %s", system_type); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 68, 364, ENC_NA); }
static void dissect_UDPExtStatus(tvbuff_t *tvb, proto_tree *adwin_tree) { const gchar *processor_type, *system_type; if (! adwin_tree) return; ADWIN_ADD_BE(adwin_tree, mac, 0, 6); ADWIN_ADD_LE(adwin_tree, unused, 6, 2); ADWIN_ADD_BE(adwin_tree, pattern, 8, 4); ADWIN_ADD_BE(adwin_tree, version, 12, 4); ADWIN_ADD_LE(adwin_tree, description, 16, 16); ADWIN_ADD_BE(adwin_tree, timerresets, 32, 4); ADWIN_ADD_BE(adwin_tree, socketshutdowns, 36, 4); ADWIN_ADD_BE(adwin_tree, disk_free, 40, 4); ADWIN_ADD_BE(adwin_tree, disk_size, 44, 4); ADWIN_ADD_LE(adwin_tree, date, 48, 8); ADWIN_ADD_LE(adwin_tree, revision, 56, 8); /* add the processor type raw values to the tree, to allow filtering */ ADWIN_ADD_LE(adwin_tree, processor_type, 64, 2); /* add the processor type as a pretty printed string */ processor_type = tvb_get_ephemeral_string(tvb, 64, 2); processor_type = str_to_str(processor_type, processor_type_mapping, "Unknown (%s)"); proto_tree_add_text(adwin_tree, tvb, 64, 2, "Processor Type: %s", processor_type); /* add system type as raw value and pretty printed string */ ADWIN_ADD_LE(adwin_tree, system_type, 66, 2); system_type = tvb_get_ephemeral_string(tvb, 66, 2); system_type = str_to_str(system_type, system_type_mapping, "Unknown (%s)"); proto_tree_add_text(adwin_tree, tvb, 66, 2, "System Type: %s", system_type); ADWIN_ADD_LE(adwin_tree, unused, 68,364); }
static bool test_str_to_str(void){ char dst[3]; // normal memset( dst, 'x', 3 ); test( str_to_str( dst, 3, "12" ) ); test( 0 == memcmp( dst, "12\x00", 3 ) ); // dst size NOT enought memset( dst, 'x', 3 ); test( !str_to_str( dst, 3, "123" ) ); test( 0 == memcmp( dst, "12\x00", 3 ) ); // dst size is 1 memset( dst, 'x', 3 ); test( !str_to_str( dst, 1, "12" ) ); test( 0 == memcmp( dst, "\x00xx", 3 ) ); // src len is 0 memset( dst, 'x', 3 ); test( str_to_str( dst, 3, "" ) ); test( 0 == memcmp( dst, "\x00xx", 3 ) ); return true; }
static bool test_append_str(void){ char dst[10]; const int dst_size = sizeof(dst); // 正常append memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( append_str( dst, dst_size, "123" ) ); test( 0 == memcmp( dst, "ab123\x00xxxx", 10 ) ); // 边界条件,buff长度正好容纳 memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( append_str( dst, 6, "123" ) ); test( 0 == memcmp( dst, "ab123\x00xxxx", 10 ) ); // 边界条件, buff长度比完整拷贝少一个字节 memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( !append_str( dst, 5, "123" ) ); test( 0 == memcmp( dst, "ab12\x00xxxxx", 10 ) ); // 边界条件,buff长度比dst字符串长度小 memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( !append_str( dst, 1, "123" ) ); // 'b' = 0x62 test( 0 == memcmp( dst, "\x00\x62\x00xxxxxxx", 10 ) ); // 边界条件,buff长度即dst字符串长度 memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( !append_str( dst, 2, "123" ) ); test( 0 == memcmp( dst, "a\x00\x00xxxxxxx", 10 ) ); // 边界条件,buff长度即dst字符串长度+1 memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( !append_str( dst, 3, "123" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); // 特殊条件,src字符串为空 memset( dst, 'x', dst_size ); test( str_to_str( dst, dst_size, "ab" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); test( append_str( dst, 5, "" ) ); test( 0 == memcmp( dst, "ab\x00xxxxxxx", 10 ) ); memset( dst, 'x', dst_size ); test( str_to_str( dst, 3, "" ) ); test( 0 == memcmp( dst, "\x00xx", 3 ) ); return true; }
static void dissect_UDPMessage(tvbuff_t *tvb, proto_tree *adwin_tree) { const gchar *processor_type, *system_type; if (! adwin_tree) return; ADWIN_ADD_LE(adwin_tree, command, 0, 4); ADWIN_ADD_LE(adwin_tree, version, 4, 4); ADWIN_ADD_LE(adwin_tree, mac, 8, 6); ADWIN_ADD_LE(adwin_tree, unused, 14, 2); ADWIN_ADD_LE(adwin_tree, server_ip, 16, 4); ADWIN_ADD_LE(adwin_tree, unused, 20, 4); ADWIN_ADD_LE(adwin_tree, netmask, 24, 4); ADWIN_ADD_LE(adwin_tree, unused, 28, 4); ADWIN_ADD_LE(adwin_tree, gateway, 32, 4); ADWIN_ADD_LE(adwin_tree, unused, 36, 4); ADWIN_ADD_LE(adwin_tree, dhcp, 40, 4); ADWIN_ADD_LE(adwin_tree, port32, 44, 4); ADWIN_ADD_LE(adwin_tree, password, 48, 10); ADWIN_ADD_LE(adwin_tree, bootloader, 58, 1); ADWIN_ADD_LE(adwin_tree, unused, 59, 5); ADWIN_ADD_LE(adwin_tree, description, 64, 16); ADWIN_ADD_LE(adwin_tree, date, 80, 8); ADWIN_ADD_LE(adwin_tree, revision, 88, 8); /* add the processor type raw values to the tree, to allow filtering */ ADWIN_ADD_LE(adwin_tree, processor_type, 96, 2); /* add the processor type as a pretty printed string */ processor_type = tvb_get_ephemeral_string(tvb, 96, 2); processor_type = str_to_str(processor_type, processor_type_mapping, "Unknown"); proto_tree_add_text(adwin_tree, tvb, 96, 2, "Processor Type: %s", processor_type); /* add system type as raw value and pretty printed string */ ADWIN_ADD_LE(adwin_tree, system_type, 98, 2); system_type = tvb_get_ephemeral_string(tvb, 98, 2); system_type = str_to_str(system_type, system_type_mapping, "Unknown"); proto_tree_add_text(adwin_tree, tvb, 98, 2, "System Type: %s", system_type); }
static void dissect_UDPMessage(tvbuff_t *tvb, proto_tree *adwin_tree) { const gchar *processor_type, *system_type; if (! adwin_tree) return; proto_tree_add_item(adwin_tree, hf_adwin_config_command, tvb, 0, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_version, tvb, 4, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_mac, tvb, 8, 6, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 14, 2, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_server_ip, tvb, 16, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 20, 4, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_netmask, tvb, 24, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 28, 4, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_gateway, tvb, 32, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 36, 4, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_dhcp, tvb, 40, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_port32, tvb, 44, 4, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_password, tvb, 48, 10, ENC_ASCII|ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_bootloader, tvb, 58, 1, ENC_LITTLE_ENDIAN); proto_tree_add_item(adwin_tree, hf_adwin_config_unused, tvb, 59, 5, ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_description, tvb, 64, 16, ENC_ASCII|ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_date, tvb, 80, 8, ENC_ASCII|ENC_NA); proto_tree_add_item(adwin_tree, hf_adwin_config_revision, tvb, 88, 8, ENC_ASCII|ENC_NA); /* add the processor type raw values to the tree, to allow filtering */ proto_tree_add_item(adwin_tree, hf_adwin_config_processor_type, tvb, 96, 2, ENC_ASCII|ENC_NA); /* add the processor type as a pretty printed string */ processor_type = tvb_get_string_enc(wmem_packet_scope(), tvb, 96, 2, ENC_ASCII|ENC_NA); processor_type = str_to_str(processor_type, processor_type_mapping, "Unknown"); proto_tree_add_text(adwin_tree, tvb, 96, 2, "Processor Type: %s", processor_type); /* add system type as raw value and pretty printed string */ proto_tree_add_item(adwin_tree, hf_adwin_config_system_type, tvb, 98, 2, ENC_ASCII|ENC_NA); system_type = tvb_get_string_enc(wmem_packet_scope(), tvb, 98, 2, ENC_ASCII|ENC_NA); system_type = str_to_str(system_type, system_type_mapping, "Unknown"); proto_tree_add_text(adwin_tree, tvb, 98, 2, "System Type: %s", system_type); }
// dst中原为字符串,本函数尽量将src append在dst尾部,并判断append是否成功。 // 保证操作不会超过dst_size,而且,一定会在dst后添加'\0' // return: 是否src完全append进dst中 bool append_str( char *dst, int dst_size, const char* src ){ const int dst_len = strlen(dst); const int src_len = strlen(src); char* const p = dst + dst_len; // 指向要拷贝的起始地址 const int buff_len_for_copy = dst_size - dst_len; uverify( NULL != dst ); uverify( NULL != src ); uverify( 0 != dst_size ); if( (dst_len+1) > dst_size ){ // 如果dst字符串超过了缓冲区长度,认为系统发生错误, // 按照缓冲区长度值进行截断。 dst[dst_size-1] = '\0'; return false; } str_to_str( p, buff_len_for_copy, src ); return (dst_len + src_len) == strlen(dst); }
static char *arg_to_str(struct event_filter *filter, struct filter_arg *arg) { char *str; switch (arg->type) { case FILTER_ARG_BOOLEAN: str = malloc_or_die(6); if (arg->boolean.value) strcpy(str, "TRUE"); else strcpy(str, "FALSE"); return str; case FILTER_ARG_OP: return op_to_str(filter, arg); case FILTER_ARG_NUM: return num_to_str(filter, arg); case FILTER_ARG_STR: return str_to_str(filter, arg); case FILTER_ARG_VALUE: return val_to_str(filter, arg); case FILTER_ARG_FIELD: return field_to_str(filter, arg); case FILTER_ARG_EXP: return exp_to_str(filter, arg); default: /* ?? */ return NULL; } }
/* ---------------------------------------------- */ static void dissect_fix_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { /* Set up structures needed to add the protocol subtree and manage it */ proto_item *ti; proto_tree *fix_tree; int pdu_len; int offset = 0; int field_offset, ctrla_offset; int tag_value; char *value; char *tag_str; fix_parameter *tag; /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "FIX"); col_clear(pinfo->cinfo, COL_INFO); /* get at least the fix version: 8=FIX.x.x */ if (fix_marker(tvb, 0) != 0) { /* not a fix packet start but it's a fix packet */ col_set_str(pinfo->cinfo, COL_INFO, "[FIX continuation]"); ti = proto_tree_add_item(tree, proto_fix, tvb, 0, -1, ENC_NA); fix_tree = proto_item_add_subtree(ti, ett_fix); proto_tree_add_item(fix_tree, hf_fix_data, tvb, 0, -1, ENC_NA); return; } pdu_len = tvb_reported_length(tvb); ti = proto_tree_add_item(tree, proto_fix, tvb, 0, -1, ENC_NA); fix_tree = proto_item_add_subtree(ti, ett_fix); /* begin string */ ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01); if (ctrla_offset == -1) { return; } offset = ctrla_offset + 1; /* msg length */ ctrla_offset = tvb_find_guint8(tvb, offset, -1, 0x01); if (ctrla_offset == -1) { return; } offset = ctrla_offset + 1; /* msg type */ if (!(tag = fix_param(tvb, offset)) || tag->value_len < 1) { return; } if (check_col(pinfo->cinfo, COL_INFO)) { const char *msg_type; value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len); msg_type = str_to_str(value, messages_val, "FIX Message (%s)"); col_add_str(pinfo->cinfo, COL_INFO, msg_type); } /* In the interest of speed, if "tree" is NULL, don't do any work not * necessary to generate protocol tree items. */ field_offset = 0; while(field_offset < pdu_len && (tag = fix_param(tvb, field_offset)) ) { int i, found; if (tag->tag_len < 1) { field_offset = tag->ctrla_offset + 1; continue; } tag_str = tvb_get_ephemeral_string(tvb, field_offset, tag->tag_len); tag_value = atoi(tag_str); if (tag->value_len < 1) { proto_tree *field_tree; /* XXX - put an error indication here. It's too late to return FALSE; we've already started dissecting, and if a heuristic dissector starts dissecting (either updating the columns or creating a protocol tree) and then gives up, it leaves crud behind that messes up other dissectors that might process the packet. */ ti = proto_tree_add_text(fix_tree, tvb, field_offset, tag->field_len, "%i: <missing value>", tag_value); field_tree = proto_item_add_subtree(ti, ett_badfield); proto_tree_add_uint(field_tree, hf_fix_field_tag, tvb, field_offset, tag->tag_len, tag_value); field_offset = tag->ctrla_offset + 1; continue; } /* fix_fields array is sorted by tag_value */ found = 0; if ((i = tag_search(tag_value)) >= 0) { found = 1; } value = tvb_get_ephemeral_string(tvb, tag->value_offset, tag->value_len); if (found) { if (fix_fields[i].table) { if (tree) { switch (fix_fields[i].type) { case 1: /* strings */ proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value, "%s (%s)", value, str_to_str(value, fix_fields[i].table, "unknown %s")); break; case 2: /* char */ proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value, "%s (%s)", value, val_to_str(*value, fix_fields[i].table, "unknown %d")); break; default: proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value, "%s (%s)", value, val_to_str(atoi(value), fix_fields[i].table, "unknown %d")); break; } } } else { proto_item *item; /* checksum */ switch(tag_value) { case 10: { proto_tree *checksum_tree; guint8 sum = 0; const guint8 *data = tvb_get_ptr(tvb, 0, field_offset); gboolean sum_ok; int j; for (j = 0; j < field_offset; j++, data++) { sum += *data; } sum_ok = (atoi(value) == sum); if (sum_ok) { item = proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value, "%s [correct]", value); } else { item = proto_tree_add_string_format_value(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value, "%s [incorrect should be %d]", value, sum); } checksum_tree = proto_item_add_subtree(item, ett_checksum); item = proto_tree_add_boolean(checksum_tree, hf_fix_checksum_good, tvb, field_offset, tag->field_len, sum_ok); PROTO_ITEM_SET_GENERATED(item); item = proto_tree_add_boolean(checksum_tree, hf_fix_checksum_bad, tvb, field_offset, tag->field_len, !sum_ok); PROTO_ITEM_SET_GENERATED(item); if (!sum_ok) expert_add_info_format(pinfo, item, PI_CHECKSUM, PI_ERROR, "Bad checksum"); } break; default: proto_tree_add_string(fix_tree, fix_fields[i].hf_id, tvb, field_offset, tag->field_len, value); break; } } } else if (tree) { proto_tree *field_tree; /* XXX - it could be -1 if the tag isn't a number */ ti = proto_tree_add_text(fix_tree, tvb, field_offset, tag->field_len, "%i: %s", tag_value, value); field_tree = proto_item_add_subtree(ti, ett_unknow); proto_tree_add_uint(field_tree, hf_fix_field_tag, tvb, field_offset, tag->tag_len, tag_value); proto_tree_add_item(field_tree, hf_fix_field_value, tvb, tag->value_offset, tag->value_len, ENC_ASCII|ENC_NA); } field_offset = tag->ctrla_offset + 1; tag_str = NULL; } return; }