void DNS::skip_to_section_end(InputMemoryStream& stream, const uint32_t num_records) const { for (uint32_t i = 0; i < num_records; ++i) { skip_to_dname_end(stream); stream.skip(sizeof(uint16_t) * 2 + sizeof(uint32_t)); uint16_t data_size = stream.read_be<uint16_t>(); if (!stream.can_read(data_size)) { throw malformed_packet(); } stream.skip(data_size); } }
void Dot11::parse_tagged_parameters(InputMemoryStream& stream) { if (stream) { while (stream.size() >= 2) { OptionTypes opcode = static_cast<OptionTypes>(stream.read<uint8_t>()); uint8_t length = stream.read<uint8_t>(); if (!stream.can_read(length)) { throw malformed_packet(); } add_tagged_option(opcode, length, stream.pointer()); stream.skip(length); } } }
void try_parse_icmp_extensions(InputMemoryStream& stream, uint32_t payload_length, ICMPExtensionsStructure& extensions) { if (!stream) { return; } // Check if this is one of the types defined in RFC 4884 const uint32_t minimum_payload = ICMPExtensionsStructure::MINIMUM_ICMP_PAYLOAD; // Check if we actually have this amount of data and whether it's more than // the minimum encapsulated packet size const uint8_t* extensions_ptr; uint32_t extensions_size; if (stream.can_read(payload_length) && payload_length >= minimum_payload) { extensions_ptr = stream.pointer() + payload_length; extensions_size = stream.size() - payload_length; } else if (stream.can_read(minimum_payload)) { // This packet might be non-rfc compliant. In that case the length // field can contain garbage. extensions_ptr = stream.pointer() + minimum_payload; extensions_size = stream.size() - minimum_payload; } else { // No more special cases, this doesn't have extensions return; } if (ICMPExtensionsStructure::validate_extensions(extensions_ptr, extensions_size)) { extensions = ICMPExtensionsStructure(extensions_ptr, extensions_size); stream.size(stream.size() - extensions_size); } }
void DNS::skip_to_dname_end(InputMemoryStream& stream) const { while (stream) { uint8_t value = stream.read<uint8_t>(); if (value == 0) { // Found the ending null byte, we're done break; } else { if ((value & 0xc0)) { // This is an offset label, skip the second byte and we're done stream.skip(1); break; } else { // This is an actual label, skip its contents stream.skip(value); } } } }