pub fn handle_ipv4_packet(program_args: &Arguments, packet: &Ipv4Packet) -> Option<Vec<u8>> {
    // The nth address in the virtual network if the request's TTL is used as n
    let nth_address_from_ttl = ip_addrs::get_nth_address_in_network4(
        packet.get_ttl() as u32,
        ip_addrs::calc_netmask_size_with_n_hosts4(program_args.n_hosts),
        &packet.get_destination(),
    );

    // if the packet has exceeded its hop limit but not yet reached its goal, terminate it early
    if (packet.get_ttl() as usize) < program_args.n_hosts
        && nth_address_from_ttl != packet.get_destination()
    {
        debug!("Received IPv4 packet with small TTL, sending time exceeded response");
        Some(build_ipv4_response(
            &packet,
            nth_address_from_ttl,
            icmp::build_icmp_time_exceeded_response(&packet),
        ))
    }
    // otherwise continue parsing the next layer
    else {
        // we know how to handle ICMP so try to parse and handle it
        if packet.get_next_level_protocol() == IpNextHeaderProtocols::Icmp {
            match IcmpPacket::new(packet.payload()) {
                None => {
                    warn!("Could not parse incoming ICMP packet even though IP header defined it as being ICMP");
                    None
                }
                Some(icmp_packet) => {
                    trace!(
                        "Recognized and parsed ICMP packet [packet={:?}]",
                        icmp_packet
                    );
                    match icmp::handle_icmp_packet(packet, &icmp_packet) {
                        None => None,
                        Some(icmp_response) => Some(build_ipv4_response(
                            packet,
                            packet.get_destination(),
                            icmp_response,
                        )),
                    }
                }
            }
        }
        // if we receive a UDP or TCP packet, we send an ICMP destination unreachable response
        // to indicate that the port is closed
        else if packet.get_next_level_protocol() == IpNextHeaderProtocols::Udp
            || packet.get_next_level_protocol() == IpNextHeaderProtocols::Tcp
        {
            debug!(
                "Received {} packet. Responding with destination unreachable",
                packet.get_next_level_protocol()
            );
            Some(build_ipv4_response(
                packet,
                packet.get_destination(),
                icmp::build_icmp_destination_unreachable_response(packet),
            ))
        }
        // all other upper layer protocols we don't know so we just don't respond at all
        else {
            debug!(
                "Received IPv4 packet with unhandled higher protocol [proto={}]",
                packet.get_next_level_protocol()
            );
            None
        }
    }
}
/// Handle incoming IPv4 packet and optionally return a response IPv4 packet
Handle incoming IPv4 packet and optionally return a response IPv4 packet
Handle incoming IPv4 packet and optionally return a response IPv4 packet
pub fn handle_ipv4_packet(program_args: &Arguments, packet: &Ipv4Packet) -> Option<Vec<u8>> {
    // The nth address in the virtual network if the request's TTL is used as n
    let nth_address_from_ttl = ip_addrs::get_nth_address_in_network4(
        packet.get_ttl() as u32,
        ip_addrs::calc_netmask_size_with_n_hosts4(program_args.n_hosts),
        &packet.get_destination(),
    );
    // if the packet has exceeded its hop limit but not yet reached its goal, terminate it early
    if (packet.get_ttl() as usize) < program_args.n_hosts
        && nth_address_from_ttl != packet.get_destination()
    {
        debug!("Received IPv4 packet with small TTL, sending time exceeded response");
        Some(build_ipv4_response(
            &packet,
            nth_address_from_ttl,
            icmp::build_icmp_time_exceeded_response(&packet),
        ))
    }
    // otherwise continue parsing the next layer
    else {
        // we know how to handle ICMP so try to parse and handle it
        if packet.get_next_level_protocol() == IpNextHeaderProtocols::Icmp {
            match IcmpPacket::new(packet.payload()) {
                None => {
                    warn!("Could not parse incoming ICMP packet even though IP header defined it as being ICMP");
                    None
                }
                Some(icmp_packet) => {
                    trace!(
                        "Recognized and parsed ICMP packet [packet={:?}]",
                        icmp_packet
                    );
                    match icmp::handle_icmp_packet(packet, &icmp_packet) {
                        None => None,
                        Some(icmp_response) => Some(build_ipv4_response(
                            packet,
                            packet.get_destination(),
                            icmp_response,
                        )),
                    }
                }
            }
        }
        // if we receive a UDP or TCP packet, we send an ICMP destination unreachable response
        // to indicate that the port is closed
        else if packet.get_next_level_protocol() == IpNextHeaderProtocols::Udp
            || packet.get_next_level_protocol() == IpNextHeaderProtocols::Tcp
        {
            debug!(
                "Received {} packet. Responding with destination unreachable",
                packet.get_next_level_protocol()
            );
            Some(build_ipv4_response(
                packet,
                packet.get_destination(),
                icmp::build_icmp_destination_unreachable_response(packet),
            ))
        }
        // all other upper layer protocols we don't know so we just don't respond at all
        else {
            debug!(
                "Received IPv4 packet with unhandled higher protocol [proto={}]",
                packet.get_next_level_protocol()
            );
            None
        }
    }
}
pub fn handle_ipv4_packet ( program_args : & Arguments , packet : & Ipv4Packet ) -> Option < Vec < u8 > > { // The nth address in the virtual network if the request's TTL is used as n let nth_address_from_ttl = ip_addrs :: get_nth_address_in_network4 ( packet . get_ttl ( ) as u32 , ip_addrs :: calc_netmask_size_with_n_hosts4 ( program_args . n_hosts ) , & packet . get_destination ( ) , ) ; // if the packet has exceeded its hop limit but not yet reached its goal, terminate it early if ( packet . get_ttl ( ) as usize ) < program_args . n_hosts && nth_address_from_ttl != packet . get_destination ( ) { debug ! ( " " ) ; Some ( build_ipv4_response ( & packet , nth_address_from_ttl , icmp :: build_icmp_time_exceeded_response ( & packet ) , ) ) } // otherwise continue parsing the next layer else { // we know how to handle ICMP so try to parse and handle it if packet . get_next_level_protocol ( ) == IpNextHeaderProtocols :: Icmp { match IcmpPacket :: new ( packet . payload ( ) ) { None => { warn ! ( " " ) ; None } Some ( icmp_packet ) => { trace ! ( " " icmp_packet ) ; match icmp :: handle_icmp_packet ( packet , & icmp_packet ) { None => None , Some ( icmp_response ) => Some ( build_ipv4_response ( packet , packet . get_destination ( ) , icmp_response , ) ) , } } } } // if we receive a UDP or TCP packet, we send an ICMP destination unreachable response // to indicate that the port is closed else if packet . get_next_level_protocol ( ) == IpNextHeaderProtocols :: Udp || packet . get_next_level_protocol ( ) == IpNextHeaderProtocols :: Tcp { debug ! ( " " packet get_next_level_protocol ( ) ) ; Some ( build_ipv4_response ( packet , packet . get_destination ( ) , icmp :: build_icmp_destination_unreachable_response ( packet ) , ) ) } // all other upper layer protocols we don't know so we just don't respond at all else { debug ! ( " " packet get_next_level_protocol ( ) ) ; None } } }
Handle incoming IPv4 packet and optionally return a response IPv4 packet
Handle incoming IPv4 packet and optionally return a response IPv4 packet
program_args
&Arguments
packet
&Ipv4Packet
program_args
&Arguments
packet
&Ipv4Packet