bool
IpcsClassifierRecord::CheckMatchSrcAddr (Ipv4Address srcAddress) const
{
  for (std::vector<struct ipv4Addr>::const_iterator iter = m_srcAddr.begin (); iter != m_srcAddr.end (); ++iter)
    {
      NS_LOG_INFO ("src addr check match: pkt=" << srcAddress << " cls=" << (*iter).Address << "/" << (*iter).Mask);
      if (srcAddress.CombineMask ((*iter).Mask) == (*iter).Address)
        {
          return true;
        }
    }
  NS_LOG_INFO ("NOT OK!");
  return false;
}
/*
 * If we have an exact match, we return it.
 * Otherwise, if we find a generic match, we return it.
 * Otherwise, we return 0.
 */
Ipv4EndPointDemux::EndPoints
Ipv4EndPointDemux::Lookup (Ipv4Address daddr, uint16_t dport, 
                           Ipv4Address saddr, uint16_t sport,
                           Ptr<Ipv4Interface> incomingInterface)
{
  NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);
  
  EndPoints retval1; // Matches exact on local port, wildcards on others
  EndPoints retval2; // Matches exact on local port/adder, wildcards on others
  EndPoints retval3; // Matches all but local address
  EndPoints retval4; // Exact match on all 4

  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++) 
    {
      Ipv4EndPoint* endP = *i;
      NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
                                                 << " daddr=" << endP->GetLocalAddress ()
                                                 << " sport=" << endP->GetPeerPort ()
                                                 << " saddr=" << endP->GetPeerAddress ());
      if (endP->GetLocalPort () != dport) 
        {
          NS_LOG_LOGIC ("Skipping endpoint " << &endP
                                             << " because endpoint dport "
                                             << endP->GetLocalPort ()
                                             << " does not match packet dport " << dport);
          continue;
        }
      if (endP->GetBoundNetDevice ())
        {
          if (endP->GetBoundNetDevice () != incomingInterface->GetDevice ())
            {
              NS_LOG_LOGIC ("Skipping endpoint " << &endP
                                                 << " because endpoint is bound to specific device and"
                                                 << endP->GetBoundNetDevice ()
                                                 << " does not match packet device " << incomingInterface->GetDevice ());
              continue;
            }
        }
      bool subnetDirected = false;
      Ipv4Address incomingInterfaceAddr = daddr;  // may be a broadcast
      for (uint32_t i = 0; i < incomingInterface->GetNAddresses (); i++)
        {
          Ipv4InterfaceAddress addr = incomingInterface->GetAddress (i);
          if (addr.GetLocal ().CombineMask (addr.GetMask ()) == daddr.CombineMask (addr.GetMask ()) &&
              daddr.IsSubnetDirectedBroadcast (addr.GetMask ()))
            {
              subnetDirected = true;
              incomingInterfaceAddr = addr.GetLocal ();
            }
        }
      bool isBroadcast = (daddr.IsBroadcast () || subnetDirected == true);
      NS_LOG_DEBUG ("dest addr " << daddr << " broadcast? " << isBroadcast);
      bool localAddressMatchesWildCard = 
        endP->GetLocalAddress () == Ipv4Address::GetAny ();
      bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;

      if (isBroadcast)
        {
          NS_LOG_DEBUG ("Found bcast, localaddr " << endP->GetLocalAddress ());
        }

      if (isBroadcast && (endP->GetLocalAddress () != Ipv4Address::GetAny ()))
        {
          localAddressMatchesExact = (endP->GetLocalAddress () ==
                                      incomingInterfaceAddr);
        }
      // if no match here, keep looking
      if (!(localAddressMatchesExact || localAddressMatchesWildCard))
        continue; 
      bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
      bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
      bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
      bool remoteAddressMatchesWildCard = endP->GetPeerAddress () ==
        Ipv4Address::GetAny ();
      // If remote does not match either with exact or wildcard,
      // skip this one
      if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
        continue;
      if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
        continue;

      // Now figure out which return list to add this one to
      if (localAddressMatchesWildCard &&
          remotePeerMatchesWildCard &&
          remoteAddressMatchesWildCard)
        { // Only local port matches exactly
          retval1.push_back (endP);
        }
      if ((localAddressMatchesExact || (isBroadcast && localAddressMatchesWildCard))&&
          remotePeerMatchesWildCard &&
          remoteAddressMatchesWildCard)
        { // Only local port and local address matches exactly
          retval2.push_back (endP);
        }
      if (localAddressMatchesWildCard &&
          remotePeerMatchesExact &&
          remoteAddressMatchesExact)
        { // All but local address
          retval3.push_back (endP);
        }
      if (localAddressMatchesExact &&
          remotePeerMatchesExact &&
          remoteAddressMatchesExact)
        { // All 4 match
          retval4.push_back (endP);
        }
    }

  // Here we find the most exact match
  if (!retval4.empty ()) return retval4;
  if (!retval3.empty ()) return retval3;
  if (!retval2.empty ()) return retval2;
  return retval1;  // might be empty if no matches
}