inline void _filter<OSIFrameType, ParentFilterType>::parse(const_helper<typename ParentFilterType::frame_type> parent_helper) const { _base_filter<OSIFrameType>::clear_last_helper(); if (frame_parent_match<OSIFrameType, typename ParentFilterType::frame_type>(parent_helper)) { try { const_helper<OSIFrameType> helper(parent_helper.payload()); if (check_frame(helper)) { if (_base_filter<OSIFrameType>::filter_frame(helper)) { if (bridge_filter_frame(parent_helper, helper)) { _base_filter<OSIFrameType>::frame_handled(helper); } } } } catch (std::logic_error&) { } } }
boost::optional<boost::asio::const_buffer> proxy<arp_frame>::process_frame(const_helper<ethernet_frame> ethernet_helper, const_helper<arp_frame> arp_helper, boost::asio::mutable_buffer response_buffer) const { if (arp_helper.operation() == ARP_REQUEST_OPERATION) { const entry_map_type::const_iterator entry_it = m_entry_map.find(arp_helper.target_logical_address()); ethernet_address_type eth_addr; bool should_answer = false; if (entry_it != m_entry_map.end()) { eth_addr = entry_it->second; should_answer = true; } else { if (m_arp_request_callback) { should_answer = m_arp_request_callback(arp_helper.target_logical_address(), eth_addr); } } if (should_answer) { size_t payload_size; builder<arp_frame> arp_builder(response_buffer); payload_size = arp_builder.write( ARP_REPLY_OPERATION, boost::asio::buffer(eth_addr.data()), arp_helper.target_logical_address(), arp_helper.sender_hardware_address(), arp_helper.sender_logical_address() ); builder<ethernet_frame> ethernet_builder(response_buffer, payload_size); payload_size = ethernet_builder.write( ethernet_helper.sender(), ethernet_helper.target(), ethernet_helper.protocol() ); return boost::make_optional<boost::asio::const_buffer>(response_buffer + (boost::asio::buffer_size(response_buffer) - payload_size)); } } return boost::optional<boost::asio::const_buffer>(); }
void proxy<arp_frame>::do_handle_frame(const_helper<ethernet_frame> ethernet_helper, const_helper<arp_frame> arp_helper) { if (arp_helper.operation() == ARP_REQUEST_OPERATION) { entry_map_type::const_iterator entry_it = m_entry_map.find(arp_helper.target_logical_address()); ethernet_address_type eth_addr; bool should_answer = false; if (entry_it != m_entry_map.end()) { eth_addr = entry_it->second; should_answer = true; } else { if (m_arp_request_callback) { should_answer = m_arp_request_callback(arp_helper.target_logical_address(), eth_addr); } } if (should_answer) { size_t payload_size; builder<arp_frame> arp_builder(response_buffer()); payload_size = arp_builder.write( ARP_REPLY_OPERATION, boost::asio::buffer(eth_addr.data()), arp_helper.target_logical_address(), arp_helper.sender_hardware_address(), arp_helper.sender_logical_address() ); builder<ethernet_frame> ethernet_builder(response_buffer(), payload_size); payload_size = ethernet_builder.write( ethernet_helper.sender(), ethernet_helper.target(), ethernet_helper.protocol() ); data_available(get_truncated_response_buffer(payload_size)); } } }
inline bool check_frame(const_helper<ipv4_frame> frame) { return ((frame.version() == IP_PROTOCOL_VERSION_4) && (frame.ihl() >= 5)); }
inline bool frame_parent_match<ipv4_frame>(const_helper<ethernet_frame> parent) { return (parent.protocol() == IP_PROTOCOL); }
inline bool filter<ipv4_frame, ParentFilterType>::checksum_filter(const_helper<ipv4_frame> helper) { return helper.verify_checksum(); }
/** * \brief Get the payload length. * \param parent_frame The parent frame. * \return The payload length. */ typename _base_helper_impl::buffer_type payload_length(const_helper<ipv6_frame> parent_frame) const { return parent_frame.payload_length() - header_length(); }
/** * \brief Check if a frame is valid. * \param frame The frame. * \return true on success. */ inline bool check_frame(const_helper<dhcp_frame> frame) { return (frame.magic_cookie() == DHCP_MAGIC_COOKIE) && frame.check_options(); }
inline bool frame_parent_match<dhcp_frame>(const_helper<bootp_frame> parent) { return (boost::asio::buffer_size(parent.options()) >= sizeof(DHCP_MAGIC_COOKIE)); }