# HG changeset patch # User Max Schettler # Date 1462661286 -10800 # Sun May 08 01:48:06 2016 +0300 # Node ID 052698351327504edbdf4a4312575a6250713c48 # Parent 8044a6a0db2202aa5587fca8c7487c0d58098cfc Add check to Ipv6L3Protocol for a valid address before sending. This changeset provides checks for tentative or invalid addresses before actually sending a packet. If the address does not support sending the packet in question, it is dropped and a log message is generated. This partly fixes #1704. diff -r 8044a6a0db22 -r 052698351327 src/internet/model/ipv6-l3-protocol.cc --- a/src/internet/model/ipv6-l3-protocol.cc Wed Apr 27 15:31:39 2016 +0200 +++ b/src/internet/model/ipv6-l3-protocol.cc Sun May 08 01:48:06 2016 +0300 @@ -1166,11 +1166,36 @@ ipv6Fragment->GetFragments (packet, ipHeader, targetMtu, fragments); } - if (!route->GetGateway ().IsEqual (Ipv6Address::GetAny ())) + Ipv6Address nextHop = (route->GetGateway ().IsEqual (Ipv6Address::GetAny ())) ? ipHeader.GetDestinationAddress () : route->GetGateway(); + Ipv6InterfaceAddress src = outInterface->GetAddressMatchingDestination (nextHop); + bool tentative_ns = false; + if (src.GetState() == Ipv6InterfaceAddress::TENTATIVE) + { + if (ipHeader.GetNextHeader() == Ipv6Header::IPV6_ICMPV6) + { + Icmpv6Header icmpv6Header; + packet->PeekHeader (icmpv6Header); + if (icmpv6Header.GetType () == Icmpv6Header::ICMPV6_ND_NEIGHBOR_SOLICITATION) + { + Icmpv6NS ns; + packet->PeekHeader (ns); + if (ns.GetIpv6Target() == src.GetAddress()) + { + tentative_ns = true; + } + } + } + } + if ((src.GetState() == Ipv6InterfaceAddress::TENTATIVE && !tentative_ns) || src.GetState() == Ipv6InterfaceAddress::INVALID) + { + NS_LOG_LOGIC ("Dropping-- interface address state is invalid or tentative"); + m_dropTrace (ipHeader, packet, DROP_INVALID_ADDRESS, m_node->GetObject (), interface); + } + else { if (outInterface->IsUp ()) { - NS_LOG_LOGIC ("Send to gateway " << route->GetGateway ()); + NS_LOG_LOGIC ("Send to " << nextHop); if (fragments.size () != 0) { @@ -1179,46 +1204,18 @@ for (std::list::const_iterator it = fragments.begin (); it != fragments.end (); it++) { CallTxTrace (it->second, it->first, m_node->GetObject (), interface); - outInterface->Send (it->first, it->second, route->GetGateway ()); + outInterface->Send (it->first, it->second, nextHop); } } else { CallTxTrace (ipHeader, packet, m_node->GetObject (), interface); - outInterface->Send (packet, ipHeader, route->GetGateway ()); + outInterface->Send (packet, ipHeader, nextHop); } } else { - NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << route->GetGateway ()); - m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject (), interface); - } - } - else - { - if (outInterface->IsUp ()) - { - NS_LOG_LOGIC ("Send to destination " << ipHeader.GetDestinationAddress ()); - - if (fragments.size () != 0) - { - std::ostringstream oss; - - for (std::list::const_iterator it = fragments.begin (); it != fragments.end (); it++) - { - CallTxTrace (it->second, it->first, m_node->GetObject (), interface); - outInterface->Send (it->first, it->second, ipHeader.GetDestinationAddress ()); - } - } - else - { - CallTxTrace (ipHeader, packet, m_node->GetObject (), interface); - outInterface->Send (packet, ipHeader, ipHeader.GetDestinationAddress ()); - } - } - else - { - NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << ipHeader.GetDestinationAddress ()); + NS_LOG_LOGIC ("Dropping-- outgoing interface is down: " << nextHop); m_dropTrace (ipHeader, packet, DROP_INTERFACE_DOWN, m_node->GetObject (), interface); } } diff -r 8044a6a0db22 -r 052698351327 src/internet/model/ipv6-l3-protocol.h --- a/src/internet/model/ipv6-l3-protocol.h Wed Apr 27 15:31:39 2016 +0200 +++ b/src/internet/model/ipv6-l3-protocol.h Sun May 08 01:48:06 2016 +0300 @@ -86,6 +86,7 @@ DROP_UNKNOWN_OPTION, /**< Unknown option */ DROP_MALFORMED_HEADER, /**< Malformed header */ DROP_FRAGMENT_TIMEOUT, /**< Fragment timeout */ + DROP_INVALID_ADDRESS, /**< Invalid address (state is either tentative or invalid) */ }; /**