pub fn handle_ipv6_packet(program_args: &Arguments, packet: &Ipv6Packet) -> 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_network6(
        packet.get_hop_limit() as usize,
        ip_addrs::calc_netmask_size_with_n_hosts6(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_hop_limit() as usize) < program_args.n_hosts
        && nth_address_from_ttl != packet.get_destination()
    {
        debug!(
            "Received IPv6 packet with small hop limit, sending time exceeded response [packet_hop_limit={}, n_hosts={}, v_addr={}]",
            packet.get_hop_limit(),
            program_args.n_hosts,
            nth_address_from_ttl
        );
        Some(build_ipv6_response(
            packet,
            nth_address_from_ttl,
            icmp6::build_icmp6_time_exceeded_response(
                packet,
                &nth_address_from_ttl,
                &packet.get_source(),
            ),
            Some(64),
        ))
    }
    // otherwise continue parsing the next layer
    else {
        // we know how to handle ICMP6 so try to parse and handle it
        if packet.get_next_header() == IpNextHeaderProtocols::Icmpv6 {
            match Icmpv6Packet::new(packet.payload()) {
                None => {
                    warn!("Could not parse incoming ICMP6 packet");
                    None
                }
                Some(icmp_packet) => {
                    trace!(
                        "Recognized and parsed ICMP6 packet [packet={:?}]",
                        icmp_packet
                    );
                    match icmp6::handle_icmp6_packet(
                        &icmp_packet,
                        &packet.get_destination(),
                        &packet.get_source(),
                    ) {
                        None => None,
                        Some(icmp_response) => Some(build_ipv6_response(
                            packet,
                            packet.get_destination(),
                            icmp_response,
                            None,
                        )),
                    }
                }
            }
        }
        // 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_header() == IpNextHeaderProtocols::Udp
            || packet.get_next_header() == IpNextHeaderProtocols::Tcp
        {
            Some(build_ipv6_response(
                packet,
                packet.get_destination(),
                icmp6::build_icmp6_destination_unreachable_response(
                    packet,
                    &packet.get_destination(),
                    &packet.get_source(),
                ),
                None,
            ))
        }
        // all other upper layer protocols we don't know so we just don't respond at all
        else {
            debug!(
                "Received IPv6 packet with unhandled higher protocol [proto={}]",
                packet.get_next_header()
            );
            None
        }
    }
}
/// Handle incoming IPv6 packet and optionally return a response IPv6 packet
Handle incoming IPv6 packet and optionally return a response IPv6 packet
Handle incoming IPv6 packet and optionally return a response IPv6 packet
pub fn handle_ipv6_packet(program_args: &Arguments, packet: &Ipv6Packet) -> 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_network6(
        packet.get_hop_limit() as usize,
        ip_addrs::calc_netmask_size_with_n_hosts6(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_hop_limit() as usize) < program_args.n_hosts
        && nth_address_from_ttl != packet.get_destination()
    {
        debug!(
            "Received IPv6 packet with small hop limit, sending time exceeded response [packet_hop_limit={}, n_hosts={}, v_addr={}]",
            packet.get_hop_limit(),
            program_args.n_hosts,
            nth_address_from_ttl
        );
        Some(build_ipv6_response(
            packet,
            nth_address_from_ttl,
            icmp6::build_icmp6_time_exceeded_response(
                packet,
                &nth_address_from_ttl,
                &packet.get_source(),
            ),
            Some(64),
        ))
    }
    // otherwise continue parsing the next layer
    else {
        // we know how to handle ICMP6 so try to parse and handle it
        if packet.get_next_header() == IpNextHeaderProtocols::Icmpv6 {
            match Icmpv6Packet::new(packet.payload()) {
                None => {
                    warn!("Could not parse incoming ICMP6 packet");
                    None
                }
                Some(icmp_packet) => {
                    trace!(
                        "Recognized and parsed ICMP6 packet [packet={:?}]",
                        icmp_packet
                    );
                    match icmp6::handle_icmp6_packet(
                        &icmp_packet,
                        &packet.get_destination(),
                        &packet.get_source(),
                    ) {
                        None => None,
                        Some(icmp_response) => Some(build_ipv6_response(
                            packet,
                            packet.get_destination(),
                            icmp_response,
                            None,
                        )),
                    }
                }
            }
        }
        // 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_header() == IpNextHeaderProtocols::Udp
            || packet.get_next_header() == IpNextHeaderProtocols::Tcp
        {
            Some(build_ipv6_response(
                packet,
                packet.get_destination(),
                icmp6::build_icmp6_destination_unreachable_response(
                    packet,
                    &packet.get_destination(),
                    &packet.get_source(),
                ),
                None,
            ))
        }
        // all other upper layer protocols we don't know so we just don't respond at all
        else {
            debug!(
                "Received IPv6 packet with unhandled higher protocol [proto={}]",
                packet.get_next_header()
            );
            None
        }
    }
}
pub fn handle_ipv6_packet ( program_args : & Arguments , packet : & Ipv6Packet ) -> 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_network6 ( packet . get_hop_limit ( ) as usize , ip_addrs :: calc_netmask_size_with_n_hosts6 ( 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_hop_limit ( ) as usize ) < program_args . n_hosts && nth_address_from_ttl != packet . get_destination ( ) { debug ! ( " " packet get_hop_limit ( ) program_args n_hosts nth_address_from_ttl ) ; Some ( build_ipv6_response ( packet , nth_address_from_ttl , icmp6 :: build_icmp6_time_exceeded_response ( packet , & nth_address_from_ttl , & packet . get_source ( ) , ) , Some ( 64 ) , ) ) } // otherwise continue parsing the next layer else { // we know how to handle ICMP6 so try to parse and handle it if packet . get_next_header ( ) == IpNextHeaderProtocols :: Icmpv6 { match Icmpv6Packet :: new ( packet . payload ( ) ) { None => { warn ! ( " " ) ; None } Some ( icmp_packet ) => { trace ! ( " " icmp_packet ) ; match icmp6 :: handle_icmp6_packet ( & icmp_packet , & packet . get_destination ( ) , & packet . get_source ( ) , ) { None => None , Some ( icmp_response ) => Some ( build_ipv6_response ( packet , packet . get_destination ( ) , icmp_response , None , ) ) , } } } } // 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_header ( ) == IpNextHeaderProtocols :: Udp || packet . get_next_header ( ) == IpNextHeaderProtocols :: Tcp { Some ( build_ipv6_response ( packet , packet . get_destination ( ) , icmp6 :: build_icmp6_destination_unreachable_response ( packet , & packet . get_destination ( ) , & packet . get_source ( ) , ) , None , ) ) } // all other upper layer protocols we don't know so we just don't respond at all else { debug ! ( " " packet get_next_header ( ) ) ; None } } }
Handle incoming IPv6 packet and optionally return a response IPv6 packet
Handle incoming IPv6 packet and optionally return a response IPv6 packet
program_args
&Arguments
packet
&Ipv6Packet
program_args
&Arguments
packet
&Ipv6Packet