mfontanini / libtins

High-level, multiplatform C++ network packet sniffing and crafting library.
http://libtins.github.io/
BSD 2-Clause "Simplified" License
1.91k stars 377 forks source link

Ethernet broadcast packets ignored in EthernetII::matches_response #418

Open markousaj opened 4 years ago

markousaj commented 4 years ago

Broadcast messages are being ignored in EthernetII::matches_response function because dest (broadcast) address is being compared to src (iface mac) address before checking if dest represents a multicast address:

    if (address_type(header_.src_mac) == address_type(eth_ptr->dst_mac)) {
        if (address_type(header_.src_mac) == address_type(eth_ptr->dst_mac) || 
           !dst_addr().is_unicast()) {
            return inner_pdu() ? 
                   inner_pdu()->matches_response(ptr + sizeof(header_), total_sz - sizeof(header_)) : 
                   true;
        }
    }

If the first if is removed then processing works as expected.

This is applicable, for example, in DHCP negotiation case where DHCP offer is being broadcasted and couldn't be retrieved with send_recv function due to this issue, as in following example:

Tins::EthernetII pdu =
    Tins::EthernetII(Tins::EthernetII::BROADCAST, Tins::EthernetII::address_type(mac)) /
    Tins::IP(Tins::IP::address_type::broadcast, Tins::IP::address_type(0u)) /
    Tins::UDP(DHCP_SERVER_PORT, DHCP_CLIENT_PORT) /
    Tins::DHCP();
Tins::DHCP & dhcp_pdu = pdu.rfind_pdu<Tins::DHCP>();
dhcp_pdu.chaddr(Tins::EthernetII::address_type(mac));
dhcp_pdu.type(Tins::DHCP::Flags::DISCOVER);
dhcp_pdu.end();

Tins::NetworkInterface iface(iface_name);
Tins::PacketSender sender(iface);
std::unique_ptr<Tins::PDU> received_pdu(sender.send_recv(pdu));