}
// merge in everything from the command line config
-void SnortConfig::merge(SnortConfig* cmd_line)
+void SnortConfig::merge(const SnortConfig* cmd_line_conf)
{
- if ( !cmd_line->log_dir.empty() )
- log_dir = cmd_line->log_dir;
+ // -D / -H / -Q / -r / -T / -x / --alert-before-pass / --create-pidfile / --enable-inline-test / --mem-check /
+ // --nolock-pidfile / --pause / --pcap-file / --pcap-dir / --pcap-list / --pcap-show / --pedantic / --piglet /
+ // --shell / --show-file-codes
+ run_flags |= cmd_line_conf->run_flags;
- if ( log_dir.empty() )
- log_dir = DEFAULT_LOG_DIR;
-
- run_prefix = cmd_line->run_prefix;
- id_offset = cmd_line->id_offset;
- id_subdir = cmd_line->id_subdir;
- id_zero = cmd_line->id_zero;
-
- /* Used because of a potential chroot */
- orig_log_dir = log_dir;
- event_log_id = cmd_line->event_log_id;
+ // -A / -C / -d / -e / -f / -O / -U / -X / -y / --nostamps
+ output_flags |= cmd_line_conf->output_flags;
- run_flags |= cmd_line->run_flags;
- output_flags |= cmd_line->output_flags;
+ // -B
+ if (cmd_line_conf->obfuscation_net.get_family() != 0)
+ memcpy(&obfuscation_net, &cmd_line_conf->obfuscation_net, sizeof(obfuscation_net));
- include_path = cmd_line->include_path;
- stdin_rules = cmd_line->stdin_rules;
+ // -g
+ if (cmd_line_conf->group_id != -1)
+ group_id = cmd_line_conf->group_id;
- // only set by cmd_line to override other conf output settings
- output = cmd_line->output;
+ // -G / --logid
+ event_log_id = cmd_line_conf->event_log_id;
- /* Merge checksum flags. If command line modified them, use from the
- * command line, else just use from config_file. */
+ // -i / -s / --daq / --daq-batch-size / --daq-dir / --daq-list / --daq-mode / --daq-var / --snaplen
+ daq_config->overlay(cmd_line_conf->daq_config);
- int cl_chk = cmd_line->policy_map->get_network_policy()->checksum_eval;
- int cl_drop = cmd_line->policy_map->get_network_policy()->checksum_drop;
-
- NetworkPolicy* nw_policy = nullptr;
-
- for ( unsigned idx = 0; idx < policy_map->network_policy_count(); ++idx )
+ // -k (only configures eval, not drop)
+ int cl_chk = cmd_line_conf->policy_map->get_network_policy()->checksum_eval;
+ if (!(cl_chk & CHECKSUM_FLAG__DEF))
{
- nw_policy = policy_map->get_network_policy(idx);
-
- if ( !(cl_chk & CHECKSUM_FLAG__DEF) )
- nw_policy->checksum_eval = cl_chk;
-
- if ( !(cl_drop & CHECKSUM_FLAG__DEF) )
- nw_policy->checksum_drop = cl_drop;
+ for (unsigned idx = 0; idx < policy_map->network_policy_count(); ++idx)
+ {
+ NetworkPolicy* nw_policy = policy_map->get_network_policy(idx);
+ if (!(cl_chk & CHECKSUM_FLAG__DEF))
+ nw_policy->checksum_eval = cl_chk;
+ }
}
- /* FIXIT-L do these belong in network policy? */
- if (cmd_line->num_layers != 0)
- num_layers = cmd_line->num_layers;
-
- if (cmd_line->max_ip6_extensions != 0)
- max_ip6_extensions = cmd_line->max_ip6_extensions;
-
- if (cmd_line->max_ip_layers != 0)
- max_ip_layers = cmd_line->max_ip_layers;
+ // -l
+ if ( !cmd_line_conf->log_dir.empty() )
+ log_dir = cmd_line_conf->log_dir;
- if (cmd_line->obfuscation_net.get_family() != 0)
- memcpy(&obfuscation_net, &cmd_line->obfuscation_net, sizeof(obfuscation_net));
+ // -L (output is only set by cmd_line_conf to override other conf output settings)
+ output = cmd_line_conf->output;
- if (cmd_line->homenet.get_family() != 0)
- memcpy(&homenet, &cmd_line->homenet, sizeof(homenet));
+ // -m
+ if (cmd_line_conf->file_mask != 0)
+ file_mask = cmd_line_conf->file_mask;
- if ( !cmd_line->bpf_file.empty() )
- bpf_file = cmd_line->bpf_file;
+ // -n
+ if (cmd_line_conf->pkt_cnt != 0)
+ pkt_cnt = cmd_line_conf->pkt_cnt;
- if ( !cmd_line->bpf_filter.empty() )
- bpf_filter = cmd_line->bpf_filter;
+ // -t
+ if (!cmd_line_conf->chroot_dir.empty())
+ chroot_dir = cmd_line_conf->chroot_dir;
- if (cmd_line->pkt_cnt != 0)
- pkt_cnt = cmd_line->pkt_cnt;
+ // -u
+ if (cmd_line_conf->user_id != -1)
+ user_id = cmd_line_conf->user_id;
- if (cmd_line->pkt_skip != 0)
- pkt_skip = cmd_line->pkt_skip;
+ // --bpf
+ if (!cmd_line_conf->bpf_filter.empty())
+ bpf_filter = cmd_line_conf->bpf_filter;
- if (cmd_line->pkt_pause_cnt != 0)
- pkt_pause_cnt = cmd_line->pkt_pause_cnt;
+ // --dirty-pig
+ if (cmd_line_conf->dirty_pig)
+ dirty_pig = cmd_line_conf->dirty_pig;
- if (cmd_line->group_id != -1)
- group_id = cmd_line->group_id;
+ // --id-offset
+ id_offset = cmd_line_conf->id_offset;
+ // --id-subdir
+ id_subdir = cmd_line_conf->id_subdir;
+ // --id-zero
+ id_zero = cmd_line_conf->id_zero;
- if (cmd_line->user_id != -1)
- user_id = cmd_line->user_id;
+ // --include-path
+ include_path = cmd_line_conf->include_path;
- /* Only configurable on command line */
- if (cmd_line->file_mask != 0)
- file_mask = cmd_line->file_mask;
+ // --metadata-filter
+ if (!cmd_line_conf->metadata_filter.empty())
+ metadata_filter = cmd_line_conf->metadata_filter;
- if ( !cmd_line->chroot_dir.empty() )
- chroot_dir = cmd_line->chroot_dir;
+ // --pause-after-n
+ if (cmd_line_conf->pkt_pause_cnt != 0)
+ pkt_pause_cnt = cmd_line_conf->pkt_pause_cnt;
- if ( cmd_line->dirty_pig )
- dirty_pig = cmd_line->dirty_pig;
+ // --process-all-events
+ if (cmd_line_conf->run_flags & RUN_FLAG__PROCESS_ALL_EVENTS)
+ event_queue_config->process_all_events = 1;
- if ( !cmd_line->metadata_filter.empty() )
- metadata_filter = cmd_line->metadata_filter;
+ // --run-prefix
+ run_prefix = cmd_line_conf->run_prefix;
- daq_config->overlay(cmd_line->daq_config);
+ // --skip
+ if (cmd_line_conf->pkt_skip != 0)
+ pkt_skip = cmd_line_conf->pkt_skip;
- if (cmd_line->run_flags & RUN_FLAG__PROCESS_ALL_EVENTS)
- event_queue_config->process_all_events = 1;
+ // --stdin-rules
+ stdin_rules = cmd_line_conf->stdin_rules;
#ifdef SHELL
- if ( cmd_line->remote_control_port )
- remote_control_port = cmd_line->remote_control_port;
- else if ( !cmd_line->remote_control_socket.empty() )
- remote_control_socket = cmd_line->remote_control_socket;
+ // -j
+ if (cmd_line_conf->remote_control_port)
+ remote_control_port = cmd_line_conf->remote_control_port;
+ // --control-socket
+ else if (!cmd_line_conf->remote_control_socket.empty())
+ remote_control_socket = cmd_line_conf->remote_control_socket;
#endif
+ // Finalize the log directory, save a copy in case we need to chroot
+ if ( log_dir.empty() )
+ log_dir = DEFAULT_LOG_DIR;
+ orig_log_dir = log_dir;
+
+ // Initialize the slotted state memory for threads
assert(!state);
num_slots = offload_threads + ThreadConfig::get_instance_max();
state = new std::vector<void*>[num_slots];
{
"total",
"other",
- "discards"
+ "discards",
+ "depth_exceeded"
}
};
// Private helper functions
//-------------------------------------------------------------------------
-static inline void push_layer(Packet* p,
- ProtocolId prot_id,
- const uint8_t* hdr_start,
- uint32_t len)
+inline bool PacketManager::push_layer(Packet* p, CodecData& codec_data, ProtocolId prot_id,
+ const uint8_t* hdr_start, uint32_t len)
{
- // We check to ensure num_layer < MAX_LAYERS before this function call
+ if ( p->num_layers == CodecManager::get_max_layers() )
+ {
+ if (!(codec_data.codec_flags & CODEC_LAYERS_EXCEEDED))
+ {
+ codec_data.codec_flags |= CODEC_LAYERS_EXCEEDED;
+ DetectionEngine::queue_event(GID_DECODE, DECODE_TOO_MANY_LAYERS);
+ s_stats[depth_exceeded]++;
+ }
+ return false;
+ }
+
Layer& lyr = p->layers[p->num_layers++];
lyr.prot_id = prot_id;
lyr.start = hdr_start;
lyr.length = (uint16_t)len;
// lyr.invalid_bits = p->byte_skip; -- currently unused
+
+ return true;
+}
+
+inline Codec* PacketManager::get_layer_codec(const Layer& lyr, int idx)
+{
+ ProtocolIndex mapped_prot;
+ // prot_id == ProtocolId::FINISHED_DECODE is a special case for root codecs not registering a protocol ID
+ if (idx == 0 && (lyr.prot_id == CodecManager::grinder_id || lyr.prot_id == ProtocolId::FINISHED_DECODE))
+ mapped_prot = CodecManager::grinder;
+ else
+ mapped_prot = CodecManager::s_proto_map[to_utype(lyr.prot_id)];
+ return CodecManager::s_protocols[mapped_prot];
}
void PacketManager::pop_teredo(Packet* p, RawData& raw)
raw.len += lyr_len;
}
+void PacketManager::handle_decode_failure(Packet* p, RawData& raw, const CodecData& codec_data,
+ const DecodeData& unsure_encap_ptrs, ProtocolId prev_prot_id)
+{
+ if (codec_data.codec_flags & CODEC_UNSURE_ENCAP)
+ {
+ p->ptrs = unsure_encap_ptrs;
+
+ switch (p->layers[p->num_layers - 1].prot_id)
+ {
+ case ProtocolId::ESP:
+ // Hardcoding ESP because we trust iff the layer
+ // immediately preceding the fail is ESP.
+ p->ptrs.decode_flags |= DECODE_PKT_TRUST;
+ break;
+
+ case ProtocolId::TEREDO:
+ // if we just decoded teredo and the next
+ // layer fails, we made a mistake. Therefore,
+ // remove this bit.
+ pop_teredo(p, raw);
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+
+ if ( (p->num_layers > 0) && (p->layers[p->num_layers - 1].prot_id == ProtocolId::TEREDO) &&
+ (prev_prot_id == ProtocolId::IPV6) )
+ {
+ pop_teredo(p, raw);
+ }
+
+ // if the codec exists, it failed
+ if (CodecManager::s_proto_map[to_utype(prev_prot_id)])
+ {
+ s_stats[discards]++;
+ }
+ else
+ {
+ s_stats[other_codecs]++;
+
+ if ( (to_utype(ProtocolId::MIN_UNASSIGNED_IP_PROTO) <= to_utype(prev_prot_id)) &&
+ (to_utype(prev_prot_id) <= std::numeric_limits<uint8_t>::max()) )
+ {
+ DetectionEngine::queue_event(GID_DECODE, DECODE_IP_UNASSIGNED_PROTO);
+ }
+ }
+}
+
static inline bool payload_offset_from_daq_mismatch(const uint8_t* pkt, const RawData& raw)
{
const DAQ_PktDecodeData_t* pdd =
RawData raw(p->daq_msg, pkt, pktlen);
CodecData codec_data(p->context->conf, ProtocolId::FINISHED_DECODE);
- if ( cooked )
+ if (cooked)
codec_data.codec_flags |= CODEC_STREAM_REBUILT;
// initialize all Packet information
// loop until the protocol id is no longer valid
while (CodecManager::s_protocols[mapped_prot]->decode(raw, codec_data, p->ptrs))
{
- debug_logf(decode_trace, nullptr, "Codec %s (protocol_id: %hu) "
- "ip header starts at: %p, length is %d\n",
+ debug_logf(decode_trace, nullptr,
+ "Codec %s (0x%0*hx) starts at %u, length is %hu\n",
CodecManager::s_protocols[mapped_prot]->get_name(),
- static_cast<uint16_t>(codec_data.next_prot_id), pkt, codec_data.lyr_len);
+ (static_cast<uint16_t>(prev_prot_id) < 0xFF) ? 2 : 4,
+ static_cast<uint16_t>(prev_prot_id),
+ pktlen - raw.len, codec_data.lyr_len);
+
+ if (codec_data.codec_flags & CODEC_COMPOUND)
+ {
+ for (int idx = 0; idx < codec_data.compound_layer_cnt; idx++)
+ {
+ CompoundLayer* clyr = &codec_data.compound_layers[idx];
+
+ // If this was an IP layer, stash the next protocol in the Packet for later
+ if (clyr->proto_bits & (PROTO_BIT__IP | PROTO_BIT__IP6_EXT) &&
+ idx + 1 < codec_data.compound_layer_cnt)
+ {
+ CompoundLayer* nclyr = &codec_data.compound_layers[idx + 1];
+ p->ip_proto_next = convert_protocolid_to_ipprotocol(nclyr->layer.prot_id);
+ }
+ p->proto_bits |= clyr->proto_bits;
+
+ // If we have reached the MAX_LAYERS, we keep decoding
+ // but no longer keep track of the layers.
+ if (!push_layer(p, codec_data, clyr->layer.prot_id, clyr->layer.start, clyr->layer.length))
+ continue;
+
+ // Cache the index of the vlan layer for quick access.
+ if (clyr->proto_bits == PROTO_BIT__VLAN)
+ p->vlan_idx = p->num_layers - 1;
+ }
+ codec_data.codec_flags &= ~CODEC_COMPOUND;
+ }
+ else
+ {
+ // If this was an IP layer, stash the next protocol in the Packet for later
+ if (codec_data.proto_bits & (PROTO_BIT__IP | PROTO_BIT__IP6_EXT))
+ {
+ // FIXIT-M refactor when ip_proto's become an array
+ if (p->is_fragment())
+ {
+ if (prev_prot_id == ProtocolId::FRAGMENT)
+ {
+ const ip::IP6Frag* const fragh = reinterpret_cast<const ip::IP6Frag*>(raw.data);
+ p->ip_proto_next = fragh->next();
+ }
+ else
+ p->ip_proto_next = p->ptrs.ip_api.get_ip4h()->proto();
+ }
+ else
+ {
+ if (codec_data.next_prot_id != ProtocolId::FINISHED_DECODE)
+ p->ip_proto_next = convert_protocolid_to_ipprotocol(codec_data.next_prot_id);
+ }
+ }
+
+ // If we have reached the MAX_LAYERS, we keep decoding
+ // but no longer keep track of the layers.
+ if (push_layer(p, codec_data, prev_prot_id, raw.data, codec_data.lyr_len))
+ {
+ // Cache the index of the vlan layer for quick access.
+ if (codec_data.proto_bits == PROTO_BIT__VLAN)
+ p->vlan_idx = p->num_layers - 1;
+ }
+ }
- if ( codec_data.tunnel_bypass )
+ if (codec_data.tunnel_bypass)
{
p->active->set_tunnel_bypass();
codec_data.tunnel_bypass = false;
}
- if ( codec_data.codec_flags & CODEC_ETHER_NEXT )
+ // Sanity check the next protocol ID is a valid ethertype
+ if (codec_data.codec_flags & CODEC_ETHER_NEXT)
{
- if ( codec_data.next_prot_id < ProtocolId::ETHERTYPE_MINIMUM )
+ if (codec_data.next_prot_id < ProtocolId::ETHERTYPE_MINIMUM)
{
DetectionEngine::queue_event(GID_DECODE, DECODE_BAD_ETHER_TYPE);
break;
codec_data.codec_flags &= ~CODEC_SAVE_LAYER;
unsure_encap_ptrs = p->ptrs;
}
- else
- {
+ else if (codec_data.codec_flags & CODEC_UNSURE_ENCAP)
codec_data.codec_flags &= ~CODEC_UNSURE_ENCAP;
- }
-
- if (codec_data.proto_bits & (PROTO_BIT__IP | PROTO_BIT__IP6_EXT))
- {
- // FIXIT-M refactor when ip_proto's become an array
- if ( p->is_fragment() )
- {
- if ( prev_prot_id == ProtocolId::FRAGMENT )
- {
- const ip::IP6Frag* const fragh =
- reinterpret_cast<const ip::IP6Frag*>(raw.data);
- p->ip_proto_next = fragh->next();
- }
- else
- {
- p->ip_proto_next = p->ptrs.ip_api.get_ip4h()->proto();
- }
- }
- else
- {
- if(codec_data.next_prot_id != ProtocolId::FINISHED_DECODE)
- p->ip_proto_next = convert_protocolid_to_ipprotocol(codec_data.next_prot_id);
- }
- }
-
- // If we have reached the MAX_LAYERS, we keep decoding
- // but no longer keep track of the layers.
- if ( p->num_layers == CodecManager::max_layers )
- DetectionEngine::queue_event(GID_DECODE, DECODE_TOO_MANY_LAYERS);
- else
- {
- push_layer(p, prev_prot_id, raw.data, codec_data.lyr_len);
-
- // Cache the index of the vlan layer for quick access.
- if ( codec_data.proto_bits == PROTO_BIT__VLAN )
- p->vlan_idx = p->num_layers-1;
- }
// internal statistics and record keeping
s_stats[mapped_prot + stat_offset]++; // add correct decode for previous layer
mapped_prot = CodecManager::s_proto_map[to_utype(codec_data.next_prot_id)];
prev_prot_id = codec_data.next_prot_id;
- // set for next call
+ // Shrink the buffer of undecoded data
const uint16_t curr_lyr_len = codec_data.lyr_len + codec_data.invalid_bytes;
assert(curr_lyr_len <= raw.len);
raw.len -= curr_lyr_len;
raw.data += curr_lyr_len;
+
p->proto_bits |= codec_data.proto_bits;
+
+ // Reset the volatile part of the codec data for the next codec to decode into
codec_data.next_prot_id = ProtocolId::FINISHED_DECODE;
codec_data.lyr_len = 0;
codec_data.invalid_bytes = 0;
codec_data.proto_bits = 0;
}
- debug_logf(decode_trace, nullptr, "Codec %s (protocol_id: %hu) ip header"
- " starts at: %p, length is %lu\n",
- CodecManager::s_protocols[mapped_prot]->get_name(),
- static_cast<uint16_t>(prev_prot_id), pkt, (unsigned long)codec_data.lyr_len);
+ debug_logf(decode_trace, nullptr, "Payload starts at %u, length is %u\n", pktlen - raw.len, raw.len);
- if ( p->num_layers > 0 )
+ if (p->num_layers > 0)
s_stats[mapped_prot + stat_offset]++;
// if the final protocol ID is not the default codec, a Codec failed
- if (prev_prot_id != ProtocolId::FINISHED_DECODE or p->num_layers == 0 )
- {
- if (codec_data.codec_flags & CODEC_UNSURE_ENCAP)
- {
- p->ptrs = unsure_encap_ptrs;
+ if (prev_prot_id != ProtocolId::FINISHED_DECODE || p->num_layers == 0 )
+ handle_decode_failure(p, raw, codec_data, unsure_encap_ptrs, prev_prot_id);
- switch (p->layers[p->num_layers-1].prot_id)
- {
- case ProtocolId::ESP:
- // Hardcoding ESP because we trust iff the layer
- // immediately preceding the fail is ESP.
- p->ptrs.decode_flags |= DECODE_PKT_TRUST;
- break;
-
- case ProtocolId::TEREDO:
- // if we just decoded teredo and the next
- // layer fails, we made a mistake. Therefore,
- // remove this bit.
- pop_teredo(p, raw);
- break;
- default:
- ;
- } /* switch */
- }
- else
- {
- if ( (p->num_layers > 0) &&
- (p->layers[p->num_layers-1].prot_id == ProtocolId::TEREDO) &&
- (prev_prot_id == ProtocolId::IPV6) )
- {
- pop_teredo(p, raw);
- }
-
- // if the codec exists, it failed
- if (CodecManager::s_proto_map[to_utype(prev_prot_id)])
- {
- s_stats[discards]++;
- }
- else
- {
- s_stats[other_codecs]++;
-
- if ( (to_utype(ProtocolId::MIN_UNASSIGNED_IP_PROTO) <= to_utype(prev_prot_id)) &&
- (to_utype(prev_prot_id) <= std::numeric_limits<uint8_t>::max()) )
- {
- DetectionEngine::queue_event(GID_DECODE, DECODE_IP_UNASSIGNED_PROTO);
- }
- }
- }
- }
-
- if ( payload_offset_from_daq_mismatch(pkt, raw) )
+ if (payload_offset_from_daq_mismatch(pkt, raw))
p->active->set_tunnel_bypass();
// set any final Packet fields
p->dsize = (uint16_t)raw.len;
p->proto_bits |= codec_data.proto_bits;
- if ( !p->proto_bits )
+ if (!p->proto_bits)
p->proto_bits = PROTO_BIT__OTHER;
}
for (int i = outer_layer; i > inner_layer; --i)
{
const Layer& l = lyrs[i];
- ProtocolIndex mapped_prot =
- i ? CodecManager::s_proto_map[to_utype(l.prot_id)] : CodecManager::grinder;
- if (!CodecManager::s_protocols[mapped_prot]->encode(l.start, l.length, enc, buf, p->flow))
- {
+ Codec* cd = get_layer_codec(l, i);
+ if (!cd->encode(l.start, l.length, enc, buf, p->flow))
return false;
- }
}
outer_layer = inner_layer;
// inner_layer is set in 'layer::set_inner_ip_api'
for (int i = outer_layer; i >= 0; --i)
{
const Layer& l = lyrs[i];
- ProtocolIndex mapped_prot =
- i ? CodecManager::s_proto_map[to_utype(l.prot_id)] : CodecManager::grinder;
-
- if (!CodecManager::s_protocols[mapped_prot]->encode(l.start, l.length, enc, buf, p->flow))
- {
+ Codec* cd = get_layer_codec(l, i);
+ if (!cd->encode(l.start, l.length, enc, buf, p->flow))
return false;
- }
}
return true;
init_daq_pkthdr(p, c, phdr, opaque);
// copy raw packet data to clone
- Layer* lyr = (Layer*)p->layers + num_layers - 1;
+ Layer* lyr = &p->layers[num_layers - 1];
int len = lyr->start - p->pkt + lyr->length;
memcpy((void*)c->pkt, p->pkt, len);
for ( int i = 0; i < num_layers; i++ )
{
const uint8_t* b = c->pkt + (p->layers[i].start - p->pkt); // == c->pkt + p->layers[i].len
- lyr = c->layers + i;
+ lyr = &c->layers[i];
lyr->prot_id = p->layers[i].prot_id;
lyr->length = p->layers[i].length;
// NOTE: this must always go from outer to inner
// to ensure a valid ip header
- ProtocolIndex mapped_prot =
- i ? CodecManager::s_proto_map[to_utype(lyr->prot_id)] : CodecManager::grinder;
-
- CodecManager::s_protocols[mapped_prot]->format(
- reverse, const_cast<uint8_t*>(lyr->start), c->ptrs);
+ Codec* cd = get_layer_codec(*lyr, i);
+ cd->format(reverse, const_cast<uint8_t*>(lyr->start), c->ptrs);
}
if ( update_ip4_len )
{
- lyr = (Layer*)c->layers + num_layers - 1;
+ lyr = &c->layers[num_layers - 1];
ip::IP4Hdr* ip4h = reinterpret_cast<ip::IP4Hdr*>(const_cast<uint8_t*>(lyr->start));
lyr->length = ip::IP4_HEADER_LEN;
ip4h->set_ip_len(ip::IP4_HEADER_LEN);
for (int i = outer_layer; i > inner_layer; --i)
{
const Layer& l = lyr[i];
- ProtocolIndex mapped_prot = i ?
- CodecManager::s_proto_map[to_utype(l.prot_id)] : CodecManager::grinder;
-
- CodecManager::s_protocols[mapped_prot]->update(
- tmp_api, flags, const_cast<uint8_t*>(l.start), l.length, len);
+ Codec* cd = get_layer_codec(l, i);
+ cd->update(tmp_api, flags, const_cast<uint8_t*>(l.start), l.length, len);
}
outer_layer = inner_layer;
// inner_layer is set in 'layer::set_inner_ip_api'
std::vector<const char*> pkt_names;
// zero out the default codecs
- g_stats[3] = 0;
+ g_stats[stat_offset] = 0;
g_stats[CodecManager::s_proto_map[to_utype(ProtocolId::FINISHED_DECODE)] + stat_offset] = 0;
for (unsigned int i = 0; i < stat_names.size(); i++)
if (num_layers != 0)
{
- // Grinder is not in the layer array
- Codec* cd = CodecManager::s_protocols[CodecManager::grinder];
-
- TextLog_Print(text_log, "%-.6s(DLT): ", cd->get_name());
- cd->log(text_log, lyr[0].start, lyr[0].length);
+ int i = 0;
+ // Special case for root codecs not registering a protocol ID
+ if (lyr[0].prot_id == CodecManager::grinder_id || lyr[0].prot_id == ProtocolId::FINISHED_DECODE)
+ {
+ Codec* cd = CodecManager::s_protocols[CodecManager::grinder];
+ TextLog_Print(text_log, "%s(DLT): ", cd->get_name());
+ cd->log(text_log, lyr[0].start, lyr[0].length);
+ i++;
+ }
- for (int i = 1; i < num_layers; i++)
+ for (; i < num_layers; i++)
{
const auto protocol = to_utype(lyr[i].prot_id);
const uint8_t codec_offset = CodecManager::s_proto_map[protocol];
- cd = CodecManager::s_protocols[codec_offset];
+ Codec* cd = CodecManager::s_protocols[codec_offset];
TextLog_NewLine(text_log);
- TextLog_Print(text_log, "%-.*s", 6, cd->get_name());
+ TextLog_Print(text_log, "%s", cd->get_name());
if (protocol <= 0xFF)
TextLog_Print(text_log, "(0x%02x)", protocol);