ns-3-click support for promisc mode
This commit is contained in:
@@ -17,17 +17,23 @@
|
||||
// Adaptation of examples/udp/udp-client-server.cc for
|
||||
// Click based nodes running wifi.
|
||||
//
|
||||
// Network topology
|
||||
// Network topology:
|
||||
//
|
||||
// (1.4)
|
||||
// (( n4 ))
|
||||
//
|
||||
// 172.16.1.0/24
|
||||
//
|
||||
// (1.1) (1.2) (1.3)
|
||||
// n0 )) (( n1 )) (( n2
|
||||
// WLAN
|
||||
//
|
||||
// - UDP flows from n0 to n1
|
||||
// - UDP flows from n0 to n1 and n2 to n1.
|
||||
// - All nodes are Click based.
|
||||
// - The single ethernet interface that each node
|
||||
// uses is named 'eth0' in the Click file.
|
||||
// - Node 4 is running in promiscuous mode and can listen in on
|
||||
// the packets being exchanged between n0-n1 and n2-n1.
|
||||
//
|
||||
|
||||
#include <fstream>
|
||||
@@ -59,16 +65,6 @@ WriteArp (Ptr<Ipv4ClickRouting> clickRouter)
|
||||
// Access the handler
|
||||
NS_LOG_INFO (clickRouter->WriteHandler ("wifi/arpquerier", "insert", "172.16.1.2 00:00:00:00:00:02"));
|
||||
}
|
||||
|
||||
void SetPromisc (Ptr<Ipv4ClickRouting> clickRouter)
|
||||
{
|
||||
// 4th node can listen to traffic in promisc mode
|
||||
// Note: Promiscuous mode support for Click has
|
||||
// been added ahead of the official Wifi support
|
||||
// for promiscuous mode. Thus, the below line will
|
||||
// not work until then.
|
||||
clickRouter->SetPromiscuous ("eth0");
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
@@ -142,7 +138,14 @@ main (int argc, char *argv[])
|
||||
// Install Click on the nodes
|
||||
//
|
||||
ClickInternetStackHelper clickinternet;
|
||||
clickinternet.SetClickFile (n, "src/click/examples/nsclick-wifi-single-interface.click");
|
||||
clickinternet.SetClickFile (n.Get (0), "src/click/examples/nsclick-wifi-single-interface.click");
|
||||
clickinternet.SetClickFile (n.Get (1), "src/click/examples/nsclick-wifi-single-interface.click");
|
||||
clickinternet.SetClickFile (n.Get (2), "src/click/examples/nsclick-wifi-single-interface.click");
|
||||
|
||||
// Node 4 is to run in promiscuous mode. This can be verified
|
||||
// from the pcap trace Node4_in_eth0.pcap generated after running
|
||||
// this script.
|
||||
clickinternet.SetClickFile (n.Get (3), "src/click/examples/nsclick-wifi-single-interface-promisc.click");
|
||||
clickinternet.SetRoutingTableElement (n, "rt");
|
||||
clickinternet.Install (n);
|
||||
Ipv4AddressHelper ipv4;
|
||||
@@ -180,9 +183,6 @@ main (int argc, char *argv[])
|
||||
|
||||
wifiPhy.EnablePcap ("nsclick-udp-client-server-wifi", d);
|
||||
|
||||
// Call SetPromiscuous mode on Click Router for node 4
|
||||
Simulator::Schedule (Seconds (0.1), &SetPromisc, n.Get (3)->GetObject<Ipv4ClickRouting> ());
|
||||
|
||||
// Force the MAC address of the second node: The current ARP
|
||||
// implementation of Click sends only one ARP request per incoming
|
||||
// packet for an unknown destination and does not retransmit if no
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
// nsclick-wifi-single-interface.click
|
||||
//
|
||||
// Copyright (c) 2011, Deutsche Telekom Laboratories
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License version
|
||||
// 2 as published by the Free Software Foundation;
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// Author: Ruben Merz <ruben@net.t-labs.tu-berlin.de>
|
||||
//
|
||||
// This is a single host Click configuration for wifi.
|
||||
// Sets the interface in promiscuous mode
|
||||
// The node broadcasts ARP requests if it wants to find a destination
|
||||
// address, and it responds to ARP requests made for it.
|
||||
|
||||
elementclass WiFiSimHost {
|
||||
$ipaddr, $hwaddr |
|
||||
|
||||
cl::Classifier(12/0806 20/0001,12/0806 20/0002, -);
|
||||
forhost::IPClassifier(dst host $ipaddr,-);
|
||||
arpquerier::ARPQuerier(eth0);
|
||||
arpresponder::ARPResponder(eth0);
|
||||
|
||||
ethout::Queue
|
||||
-> ToDump(out_eth0.pcap,PER_NODE 1)
|
||||
-> ToSimDevice(eth0);
|
||||
|
||||
// All packets received on eth0 are silently
|
||||
// dropped if they are destined for another location
|
||||
FromSimDevice(eth0,4096, PROMISC true)
|
||||
-> ToDump(in_eth0.pcap,PER_NODE 1,ENCAP ETHER)
|
||||
-> cl;
|
||||
|
||||
// ARP queries from other nodes go to the ARP responder element
|
||||
cl[0] -> arpresponder;
|
||||
|
||||
// ARP responses go to our ARP query element
|
||||
cl[1] -> [1]arpquerier;
|
||||
|
||||
// All other packets get checked whether they are meant for us
|
||||
cl[2]
|
||||
-> Strip (14)
|
||||
-> CheckIPHeader2
|
||||
-> MarkIPHeader
|
||||
-> GetIPAddress(16) // Sets destination IP address annotation from packet data
|
||||
-> forhost;
|
||||
|
||||
// Packets for us are pushed outside
|
||||
forhost[0]
|
||||
->[0]output;
|
||||
|
||||
// Packets for other folks or broadcast packets get sent to output 1
|
||||
forhost[1]
|
||||
-> ToDump(discard.pcap,2000,PER_NODE 1,ENCAP IP)
|
||||
-> [1]output;
|
||||
|
||||
// Incoming packets get pushed into the ARP query module
|
||||
input[0]
|
||||
-> arpquerier;
|
||||
|
||||
// Both the ARP query and response modules send data out to
|
||||
// the simulated network device, eth0.
|
||||
arpquerier
|
||||
-> ToDump(out_arpquery.pcap,PER_NODE 1)
|
||||
-> ethout;
|
||||
|
||||
arpresponder
|
||||
-> ToDump(out_arprespond.pcap,PER_NODE 1)
|
||||
-> ethout;
|
||||
|
||||
}
|
||||
|
||||
elementclass TapSimHost {
|
||||
$dev |
|
||||
|
||||
// Packets go to "tap0" which sends them to the kernel
|
||||
input[0]
|
||||
-> ToDump(tokernel.pcap,2000,IP,PER_NODE 1)
|
||||
-> ToSimDevice($dev,IP);
|
||||
|
||||
// Packets sent out by the "kernel" get pushed outside
|
||||
FromSimDevice($dev,4096)
|
||||
-> CheckIPHeader2
|
||||
-> ToDump(fromkernel.pcap,2000,IP,PER_NODE 1)
|
||||
-> GetIPAddress(16)
|
||||
-> [0]output;
|
||||
}
|
||||
|
||||
// Instantiate elements
|
||||
wifi::WiFiSimHost(eth0:ip,eth0:eth);
|
||||
kernel::TapSimHost(tap0);
|
||||
|
||||
// Users can do some processing between the two elements
|
||||
wifi[0] -> kernel;
|
||||
kernel -> wifi;
|
||||
// Packets not for us are discarded
|
||||
wifi[1] -> Discard;
|
||||
|
||||
// It is mandatory to use an IPRouteTable element with ns-3-click
|
||||
// (but we do not use it in this example)
|
||||
rt :: LinearIPLookup (172.16.1.0/24 0.0.0.0 1);
|
||||
// We are actually not using the routing table
|
||||
Idle () -> rt;
|
||||
rt[0] -> Discard;
|
||||
rt[1] -> Discard;
|
||||
@@ -388,14 +388,11 @@ Ipv4ClickRouting::WriteHandler (std::string elementName, std::string handlerName
|
||||
}
|
||||
|
||||
void
|
||||
Ipv4ClickRouting::SetPromiscuous (std::string ifName)
|
||||
Ipv4ClickRouting::SetPromisc (int ifid)
|
||||
{
|
||||
Ptr<Ipv4L3ClickProtocol> ipv4l3 = DynamicCast<Ipv4L3ClickProtocol> (m_ipv4);
|
||||
NS_ASSERT (ipv4l3);
|
||||
// Interface ethN gets index 1+N, but netdevice will start at 0
|
||||
// To ensure this, install a Click stack on a node only after
|
||||
// all NetDevices have been installed.
|
||||
ipv4l3->SetPromisc (GetInterfaceId (ifName.c_str ()) - 1);
|
||||
NS_ASSERT(ipv4l3);
|
||||
ipv4l3->SetPromisc (ifid);
|
||||
}
|
||||
|
||||
Ptr<Ipv4Route>
|
||||
@@ -628,6 +625,16 @@ int simclick_sim_command (simclick_node_t *simnode, int cmd, ...)
|
||||
break;
|
||||
}
|
||||
|
||||
case SIMCLICK_IF_PROMISC:
|
||||
{
|
||||
int ifid = va_arg(val, int);
|
||||
clickInstance->SetPromisc (ifid);
|
||||
|
||||
retval = 0;
|
||||
NS_LOG_DEBUG (clickInstance->GetNodeName () << " SIMCLICK_IF_PROMISC: " << ifid << " " << ns3::Simulator::Now ());
|
||||
break;
|
||||
}
|
||||
|
||||
case SIMCLICK_IF_READY:
|
||||
{
|
||||
int ifid = va_arg (val, int); // Commented out so that optimized build works
|
||||
|
||||
@@ -108,7 +108,8 @@ public:
|
||||
*
|
||||
* \brief Sets an interface to run on promiscuous mode.
|
||||
*/
|
||||
void SetPromiscuous (std::string ifName);
|
||||
void SetPromisc (int ifid);
|
||||
|
||||
|
||||
private:
|
||||
simclick_node_t *m_simNode;
|
||||
|
||||
@@ -574,35 +574,22 @@ Ipv4L3ClickProtocol::SetForwarding (uint32_t i, bool val)
|
||||
void
|
||||
Ipv4L3ClickProtocol::SetPromisc (uint32_t i)
|
||||
{
|
||||
NS_ASSERT (i <= m_node->GetNDevices ());
|
||||
if (i > m_promiscDeviceList.size ())
|
||||
{
|
||||
m_promiscDeviceList.resize (i);
|
||||
}
|
||||
std::vector<bool>::iterator it = m_promiscDeviceList.begin ();
|
||||
std::advance (it, i);
|
||||
m_promiscDeviceList.insert (it, true);
|
||||
NS_ASSERT(i <= m_node->GetNDevices ());
|
||||
Ptr<NetDevice> netdev = GetNetDevice (i);
|
||||
NS_ASSERT (netdev);
|
||||
Ptr<Node> node = GetObject<Node> ();
|
||||
NS_ASSERT (node);
|
||||
node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
|
||||
0, netdev,true);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Ipv4L3ClickProtocol::AddInterface (Ptr<NetDevice> device)
|
||||
{
|
||||
NS_LOG_FUNCTION (this << &device);
|
||||
|
||||
Ptr<Node> node = GetObject<Node> ();
|
||||
NS_LOG_DEBUG ("Size:" << m_promiscDeviceList.size () << " Interface index" << device->GetIfIndex ());
|
||||
if (m_promiscDeviceList.size () > 0
|
||||
&& (m_promiscDeviceList.size () >= device->GetIfIndex ())
|
||||
&& (m_promiscDeviceList[device->GetIfIndex ()]))
|
||||
{
|
||||
node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
|
||||
0, device,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
|
||||
Ipv4L3ClickProtocol::PROT_NUMBER, device);
|
||||
}
|
||||
node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
|
||||
Ipv4L3ClickProtocol::PROT_NUMBER, device);
|
||||
node->RegisterProtocolHandler (MakeCallback (&Ipv4L3ClickProtocol::Receive, this),
|
||||
ArpL3Protocol::PROT_NUMBER, device);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user