--- a/examples/wifi-wired-bridging.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/examples/wifi-wired-bridging.cc Sat Feb 28 16:25:24 2009 -0800
@@ -183,8 +183,11 @@
apps.Start (Seconds (0.5));
apps.Stop (Seconds (3.0));
- YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", staNodes[1].Get (1));
- YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging", staNodes[0].Get (0));
+ WifiHelper::EnablePcap ("wifi-wired-bridging", staNodes[1].Get (1));
+ WifiHelper::EnablePcap ("wifi-wired-bridging", staNodes[0].Get (0));
+
+ YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging-promisc", staNodes[1].Get (1));
+ YansWifiPhyHelper::EnablePcap ("wifi-wired-bridging-promisc", staNodes[0].Get (0));
std::ofstream os;
os.open ("wifi-wired-bridging.mob");
MobilityHelper::EnableAsciiAll (os);
--- a/src/devices/csma/csma-net-device.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/csma/csma-net-device.cc Sat Feb 28 16:25:24 2009 -0800
@@ -77,17 +77,65 @@
PointerValue (),
MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel),
MakePointerChecker<ErrorModel> ())
+
+ //
+ // Transmit queueing discipline for the device which includes its own set
+ // of trace hooks.
+ //
.AddAttribute ("TxQueue",
"A queue to use as the transmit queue in the device.",
PointerValue (),
MakePointerAccessor (&CsmaNetDevice::m_queue),
MakePointerChecker<Queue> ())
- .AddTraceSource ("Rx",
- "Trace source indicating reception of packet destined for broadcast, multicast or local address.",
- MakeTraceSourceAccessor (&CsmaNetDevice::m_rxTrace))
- .AddTraceSource ("Drop",
- "Trace source indicating packet discarded due to receiver disabled or error model decision.",
- MakeTraceSourceAccessor (&CsmaNetDevice::m_dropTrace))
+
+ //
+ // Trace sources at the "top" of the net device, where packets transition
+ // to/from higher layers.
+ //
+ .AddTraceSource ("MacTx",
+ "Trace source indicating a packet has arrived for transmission by this device",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_macTxTrace))
+ .AddTraceSource ("MacTxDrop",
+ "Trace source indicating a packet has been dropped by the device before transmission",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_macTxDropTrace))
+ .AddTraceSource ("MacRx",
+ "Trace source indicating a packet has been received by this device and is being forwarded up the stack",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_macRxTrace))
+ //
+ // Trace souces at the "bottom" of the net device, where packets transition
+ // to/from the channel.
+ //
+ .AddTraceSource ("PhyTxStart",
+ "Trace source indicating a packet has begun transmitting over the channel",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxStartTrace))
+ .AddTraceSource ("PhyTx",
+ "Trace source indicating a packet has been completely transmitted over the channel",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxTrace))
+ .AddTraceSource ("PhyTxDrop",
+ "Trace source indicating a packet has been dropped by the device during transmission",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxDropTrace))
+ .AddTraceSource ("PhyRxStart",
+ "Trace source indicating a packet has begun being received by the device",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyRxStartTrace))
+ .AddTraceSource ("PhyRx",
+ "Trace source indicating a packet has been completely received by the device",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyRxTrace))
+ .AddTraceSource ("PhyRxDrop",
+ "Trace source indicating a packet has been dropped by the device during reception",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyRxDropTrace))
+ .AddTraceSource ("PhyTxBackoff",
+ "Trace source indicating a packet has been delayed by the CSMA backoff process",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_phyTxBackoffTrace))
+
+ //
+ // Trace sources designed to simulate a packet sniffer facility (tcpdump).
+ //
+ .AddTraceSource ("Sniffer",
+ "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_snifferTrace))
+ .AddTraceSource ("PromiscSniffer",
+ "Trace source simulating a promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&CsmaNetDevice::m_promiscSnifferTrace))
;
return tid;
}
@@ -102,11 +150,15 @@
m_channel = 0;
//
- // We would like to let the attribute system take care of initializing the packet encapsulation stuff, but we also don't want to
- // get caught up in initialization order changes. So we'll get the three problem variables into a consistent state here before the
- // attribute calls, and then depend on the semantics of the setters to preserve a consistent state. This really doesn't have to be
- // the same set of values as the initial values set by the attributes, but it does have to be a consistent set. That is, you can
- // just change the ddfault encapsulation mode above without having to change it here. We keep it the same for GP.
+ // We would like to let the attribute system take care of initializing the
+ // packet encapsulation stuff, but we also don't want to get caught up in
+ // initialization order changes. So we'll get the three problem variables
+ // into a consistent state here before the attribute calls, and then depend
+ // on the semantics of the setters to preserve a consistent state. This
+ // really doesn't have to be the same set of values as the initial values
+ // set by the attributes, but it does have to be a consistent set. That is,
+ // you can just change the default encapsulation mode above without having
+ // to change it here.
//
m_encapMode = DIX;
m_frameSize = DEFAULT_FRAME_SIZE;
@@ -332,7 +384,8 @@
case DIX:
NS_LOG_LOGIC ("Encapsulating packet as DIX (type interpretation)");
//
- // This corresponds to the type interpretation of the lengthType field as in the old Ethernet Blue Book.
+ // This corresponds to the type interpretation of the lengthType field as
+ // in the old Ethernet Blue Book.
//
lengthType = protocolNumber;
break;
@@ -407,38 +460,47 @@
}
void
-CsmaNetDevice::TransmitStart ()
+CsmaNetDevice::TransmitStart (void)
{
NS_LOG_FUNCTION_NOARGS ();
//
// This function is called to start the process of transmitting a packet. We
- // expect that a Ptr to the packet to be transmitted has been placed in
- // m_currentPkt.
+ // expect that the packet to transmit will be found in m_currentPkt.
+ //
+ NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitStart(): m_currentPkt not set");
- NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
- NS_LOG_LOGIC ("UID is " << m_currentPkt->GetUid ());
+ NS_LOG_LOGIC ("m_currentPkt = " << m_currentPkt);
+ NS_LOG_LOGIC ("UID = " << m_currentPkt->GetUid ());
//
- // We need to tell the channel that we've started wiggling the wire and
- // schedule an event that will be executed when it's time to tell the
- // channel that we're done wiggling the wire.
+ // Only transmit if the send side of net device is enabled
+ //
+ if (IsSendEnabled () == false)
+ {
+ m_phyTxDropTrace (m_currentPkt);
+ m_currentPkt = 0;
+ return;
+ }
+
+ //
+ // Somebody has called here telling us to start transmitting a packet. They
+ // can only do this if the state machine is in the READY or BACKOFF state.
+ // Specifically, if we are ready to start transmitting, we cannot already
+ // be transmitting (i.e., BUSY)
//
NS_ASSERT_MSG ((m_txMachineState == READY) || (m_txMachineState == BACKOFF),
"Must be READY to transmit. Tx state is: " << m_txMachineState);
//
- // Only transmit if send side of net device is enabled
+ // Now we have to sense the state of the medium and either start transmitting
+ // if it is idle, or backoff our transmission if someone else is on the wire.
//
- if (IsSendEnabled () == false)
- {
- return;
- }
-
if (m_channel->GetState () != IDLE)
{
//
- // The channel is busy -- backoff and rechedule TransmitStart ()
+ // The channel is busy -- backoff and rechedule TransmitStart() unless
+ // we have exhausted all of our retries.
//
m_txMachineState = BACKOFF;
@@ -451,6 +513,8 @@
}
else
{
+ m_phyTxBackoffTrace (m_currentPkt);
+
m_backoff.IncrNumRetries ();
Time backoffTime = m_backoff.GetBackoffTime ();
@@ -464,48 +528,47 @@
//
// The channel is free, transmit the packet
//
- m_txMachineState = BUSY;
- Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ()));
-
- NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
-
- Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, this);
-
if (m_channel->TransmitStart (m_currentPkt, m_deviceId) == false)
{
- NS_LOG_WARN ("Channel transmit start did not work at " << tEvent.GetSeconds () << "sec");
+ NS_LOG_WARN ("Channel TransmitStart returns an error");
+ m_phyTxDropTrace (m_currentPkt);
+ m_currentPkt = 0;
m_txMachineState = READY;
}
else
{
//
- // Transmission succeeded, reset the backoff time parameters.
+ // Transmission succeeded, reset the backoff time parameters and
+ // schedule a transmit complete event.
//
m_backoff.ResetBackoffTime ();
+ m_txMachineState = BUSY;
+ m_phyTxStartTrace (m_currentPkt);
+
+ Time tEvent = Seconds (m_bps.CalculateTxTime (m_currentPkt->GetSize ()));
+ NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << tEvent.GetSeconds () << "sec");
+ Simulator::Schedule (tEvent, &CsmaNetDevice::TransmitCompleteEvent, this);
}
}
}
-
void
CsmaNetDevice::TransmitAbort (void)
{
NS_LOG_FUNCTION_NOARGS ();
//
- // When we started transmitting the current packet, it was placed in
- // m_currentPkt. So we had better find one there.
+ // When we started the process of transmitting the current packet, it was
+ // placed in m_currentPkt. So we had better find one there.
//
NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): m_currentPkt zero");
NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
- //
- // Hit the drop trace source.
- //
- // XXX Should there be a separate transmit drop trace?
- //
- m_dropTrace (m_currentPkt);
+ m_phyTxDropTrace (m_currentPkt);
+ m_currentPkt = 0;
+
+ NS_ASSERT_MSG (m_txMachineState == BACKOFF, "Must be in BACKOFF state to abort. Tx state is: " << m_txMachineState);
//
// We're done with that one, so reset the backoff algorithm and ready the
@@ -527,6 +590,8 @@
{
m_currentPkt = m_queue->Dequeue ();
NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitAbort(): IsEmpty false but no Packet on queue?");
+ m_snifferTrace (m_currentPkt);
+ m_promiscSnifferTrace (m_currentPkt);
TransmitStart ();
}
}
@@ -555,6 +620,8 @@
NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
m_channel->TransmitEnd ();
+ m_phyTxTrace (m_currentPkt);
+ m_currentPkt = 0;
NS_LOG_LOGIC ("Schedule TransmitReadyEvent in " << m_tInterframeGap.GetSeconds () << "sec");
@@ -575,12 +642,10 @@
m_txMachineState = READY;
//
- // When we started transmitting the current packet, it was placed in
- // m_currentPkt. So we had better find one there.
+ // We expect that the packet we had been transmitting was cleared when the
+ // TransmitCompleteEvent() was executed.
//
- NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitCompleteEvent(): m_currentPkt zero");
- NS_LOG_LOGIC ("m_currentPkt=" << m_currentPkt);
- NS_LOG_LOGIC ("Pkt UID is " << m_currentPkt->GetUid () << ")");
+ NS_ASSERT_MSG (m_currentPkt == 0, "CsmaNetDevice::TransmitReadyEvent(): m_currentPkt nonzero");
//
// Get the next packet from the queue for transmitting
@@ -593,6 +658,8 @@
{
m_currentPkt = m_queue->Dequeue ();
NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::TransmitReadyEvent(): IsEmpty false but no Packet on queue?");
+ m_snifferTrace (m_currentPkt);
+ m_promiscSnifferTrace (m_currentPkt);
TransmitStart ();
}
}
@@ -658,21 +725,26 @@
multicast6Node.CopyFrom(mac);
//
- // We never forward up packets that we sent. Real devices don't do this since
- // their receivers are disabled during send, so we don't. Drop the packet
- // silently (no tracing) since it would really never get here in a real device.
+ // We never forward up packets that we sent. Real devices don't do this since
+ // their receivers are disabled during send, so we don't.
//
if (senderDevice == this)
{
return;
}
+ //
+ // Hit the trace hook. This trace will fire on all packets received from the
+ // channel except those originated by this device.
+ //
+ m_phyRxTrace (packet);
+
//
// Only receive if the send side of net device is enabled
//
if (IsReceiveEnabled () == false)
{
- m_dropTrace (packet);
+ m_phyRxDropTrace (packet);
return;
}
@@ -695,7 +767,7 @@
if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
{
NS_LOG_LOGIC ("Dropping pkt due to error model ");
- m_dropTrace (packet);
+ m_phyRxDropTrace (packet);
}
else
{
@@ -717,12 +789,14 @@
protocol = header.GetLengthType ();
}
+ //
+ // Classify the packet based on its destination.
+ //
PacketType packetType;
if (header.GetDestination ().IsBroadcast ())
{
packetType = PACKET_BROADCAST;
- m_rxTrace (originalPacket);
}
else if (header.GetDestination ().IsMulticast () ||
header.GetDestination() == multicast6Node ||
@@ -731,25 +805,36 @@
header.GetDestination() == multicast6AllHosts)
{
packetType = PACKET_MULTICAST;
- m_rxTrace (originalPacket);
}
else if (header.GetDestination () == m_address)
{
packetType = PACKET_HOST;
- m_rxTrace (originalPacket);
}
else
{
packetType = PACKET_OTHERHOST;
}
-
+
+ //
+ // For all kinds of packetType we receive, we hit the promiscuous sniffer
+ // hook and pass a copy up to the promiscuous callback. Pass a copy to
+ // make sure that nobody messes with our packet.
+ //
+ m_promiscSnifferTrace (originalPacket);
if (!m_promiscRxCallback.IsNull ())
{
- m_promiscRxCallback (this, packet, protocol, header.GetSource (), header.GetDestination (), packetType);
+ m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), packetType);
}
+ //
+ // If this packet is not destined for some other host, it must be for us
+ // as either a broadcast, multicast or unicast. We need to hit the mac
+ // packet received trace hook and forward the packet up the stack.
+ //
if (packetType != PACKET_OTHERHOST)
{
+ m_snifferTrace (originalPacket);
+ m_macRxTrace (originalPacket);
m_rxCallback (this, packet, protocol, header.GetSource ());
}
}
@@ -893,7 +978,7 @@
CsmaNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address& dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
- NS_LOG_LOGIC ("p=" << packet);
+ NS_LOG_LOGIC ("packet =" << packet);
NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
NS_ASSERT (IsLinkUp ());
@@ -903,6 +988,7 @@
//
if (IsSendEnabled () == false)
{
+ m_macTxDropTrace (packet);
return false;
}
@@ -910,11 +996,15 @@
Mac48Address source = Mac48Address::ConvertFrom (src);
AddHeader (packet, source, destination, protocolNumber);
+ m_macTxTrace (packet);
+
//
- // Place the packet to be sent on the send queue
+ // Place the packet to be sent on the send queue. Note that the
+ // queue may fire a drop trace, but we will too.
//
if (m_queue->Enqueue(packet) == false)
{
+ m_macTxDropTrace (packet);
return false;
}
@@ -925,12 +1015,12 @@
//
if (m_txMachineState == READY)
{
- //
- // The next packet to be transmitted goes in m_currentPkt
- //
- m_currentPkt = m_queue->Dequeue ();
- if (m_currentPkt != 0)
+ if (m_queue->IsEmpty () == false)
{
+ m_currentPkt = m_queue->Dequeue ();
+ NS_ASSERT_MSG (m_currentPkt != 0, "CsmaNetDevice::SendFrom(): IsEmpty false but no Packet on queue?");
+ m_promiscSnifferTrace (packet);
+ m_snifferTrace (packet);
TransmitStart ();
}
}
--- a/src/devices/csma/csma-net-device.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/csma/csma-net-device.h Sat Feb 28 16:25:24 2009 -0800
@@ -637,25 +637,132 @@
Ptr<Queue> m_queue;
/**
- * Error model for receive packet events
+ * Error model for receive packet events. When active this model will be
+ * used to model transmission errors by marking some of the packets
+ * received as corrupt.
*/
Ptr<ErrorModel> m_receiveErrorModel;
/**
- * The trace source for the packet reception events that the device can
- * fire.
+ * The trace source fired when packets come into the "top" of the device
+ * at the L3/L2 transition, before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+ /**
+ * The trace source fired when packets coming into the "top" of the device
+ * at the L3/L2 transition are dropped before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+ /**
+ * The trace source fired for packets successfully received by the device
+ * immediately before being forwarded up to higher layers (at the L2/L3
+ * transition).
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+ /**
+ * The trace source fired when a packet starts the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet as it tries
+ * to transmit it.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
+
+ /**
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
*
* \see class CallBackTraceSource
*/
- TracedCallback<Ptr<const Packet> > m_rxTrace;
+ TracedCallback<Ptr<const Packet> > m_phyRxTrace;
+
+ /**
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxStartTrace;
/**
- * The trace source for the packet drop events that the device can
- * fire.
+ * The trace source fired when the phy layer drops a packet it has received.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+ /**
+ * The trace source fired when the phy layer is forced to begin the backoff
+ * process for a packet. This can happen a number of times as the backoff
+ * sequence is repeated with increasing delays.
*
* \see class CallBackTraceSource
*/
- TracedCallback<Ptr<const Packet> > m_dropTrace;
+ TracedCallback<Ptr<const Packet> > m_phyTxBackoffTrace;
+
+ /**
+ * A trace source that emulates a non-promiscuous protocol sniffer connected
+ * to the device. Unlike your average everyday sniffer, this trace source
+ * will not fire on PACKET_OTHERHOST events.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_snifferTrace;
+
+ /**
+ * A trace source that emulates a promiscuous mode protocol sniffer connected
+ * to the device. This trace source fire on packets destined for any host
+ * just like your average everyday packet sniffer.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
/**
* The Node to which this device is attached.
@@ -671,6 +778,7 @@
* The callback used to notify higher layers that a packet has been received.
*/
NetDevice::ReceiveCallback m_rxCallback;
+
/**
* The callback used to notify higher layers that a packet has been received in promiscuous mode.
*/
--- a/src/devices/emu/emu-net-device.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/emu/emu-net-device.cc Sat Feb 28 16:25:24 2009 -0800
@@ -22,17 +22,18 @@
#include "ns3/log.h"
#include "ns3/queue.h"
#include "ns3/simulator.h"
-#include "ns3/realtime-simulator-impl.h"
-#include "ns3/mac48-address.h"
#include "ns3/ethernet-header.h"
#include "ns3/ethernet-trailer.h"
#include "ns3/llc-snap-header.h"
+#include "ns3/boolean.h"
+#include "ns3/uinteger.h"
+#include "ns3/pointer.h"
+#include "ns3/string.h"
#include "ns3/trace-source-accessor.h"
-#include "ns3/pointer.h"
#include "ns3/channel.h"
#include "ns3/system-thread.h"
-#include "ns3/string.h"
-#include "ns3/boolean.h"
+#include "ns3/realtime-simulator-impl.h"
+#include "ns3/mac48-address.h"
#include <sys/wait.h>
#include <sys/stat.h>
@@ -82,14 +83,72 @@
TimeValue (Seconds (0.)),
MakeTimeAccessor (&EmuNetDevice::m_tStop),
MakeTimeChecker ())
+
+ //
+ // Transmit queueing discipline for the device which includes its own set
+ // of trace hooks. Note that this is really going to run "on top of" the
+ // queueing discipline that will most likely be present in the devices of
+ // the underlying operating system.
+ //
.AddAttribute ("TxQueue",
"A queue to use as the transmit queue in the device.",
PointerValue (),
MakePointerAccessor (&EmuNetDevice::m_queue),
MakePointerChecker<Queue> ())
- .AddTraceSource ("Rx",
- "Trace source indicating recvfrom of packet destined for broadcast, multicast or local address.",
- MakeTraceSourceAccessor (&EmuNetDevice::m_rxTrace))
+
+ //
+ // Trace sources at the "top" of the net device, where packets transition
+ // to/from higher layers. These points do not really correspond to the
+ // MAC layer of the underlying operating system, but exist to provide
+ // a consitent tracing environment. These trace hooks should really be
+ // interpreted as the points at which a packet leaves the ns-3 environment
+ // destined for the underlying operating system or vice-versa.
+ //
+ .AddTraceSource ("MacTx",
+ "Trace source indicating a packet has arrived for transmission by this device",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_macTxTrace))
+ .AddTraceSource ("MacTxDrop",
+ "Trace source indicating a packet has been dropped by the device before transmission",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_macTxDropTrace))
+ .AddTraceSource ("MacRx",
+ "Trace source indicating a packet has been received by this device and is being forwarded up the stack",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_macRxTrace))
+ //
+ // In normal ns-3 net devices, these trace souces correspond to the "bottom"
+ // of the net device, where packets transition to/from the channel. In
+ // the case of the emu device, there is no physical layer access and so
+ // these are duplicates of the MAC-level hooks. Intepret these points
+ // also as the points at which a packet leaves the ns-3 environment
+ // destined for the underlying operating system or vice-versa.
+ //
+ .AddTraceSource ("PhyTxStart",
+ "Trace source indicating a packet has begun transmitting over the channel",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_phyTxStartTrace))
+ .AddTraceSource ("PhyTx",
+ "Trace source indicating a packet has been completely transmitted over the channel",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_phyTxTrace))
+ .AddTraceSource ("PhyTxDrop",
+ "Trace source indicating a packet has been dropped by the device during transmission",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_phyTxDropTrace))
+ .AddTraceSource ("PhyRxStart",
+ "Trace source indicating a packet has begun being received by the device",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_phyRxStartTrace))
+ .AddTraceSource ("PhyRx",
+ "Trace source indicating a packet has been completely received by the device",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_phyRxTrace))
+ .AddTraceSource ("PhyRxDrop",
+ "Trace source indicating a packet has been dropped by the device during reception",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_phyRxDropTrace))
+
+ //
+ // Trace sources designed to simulate a packet sniffer facility (tcpdump).
+ //
+ .AddTraceSource ("Sniffer",
+ "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_snifferTrace))
+ .AddTraceSource ("PromiscSniffer",
+ "Trace source simulating a promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&EmuNetDevice::m_promiscSnifferTrace))
;
return tid;
}
@@ -490,6 +549,19 @@
{
NS_LOG_FUNCTION (buf << len);
+ /* IPv6 support*/
+ uint8_t mac[6];
+ Mac48Address multicast6AllNodes("33:33:00:00:00:01");
+ Mac48Address multicast6AllRouters("33:33:00:00:00:02");
+ Mac48Address multicast6AllHosts("33:33:00:00:00:03");
+ Mac48Address multicast6Node; /* multicast address addressed to our MAC address */
+
+ /* generate IPv6 multicast ethernet destination that nodes will accept */
+ GetAddress().CopyTo(mac);
+ mac[0]=0x33;
+ mac[1]=0x33;
+ multicast6Node.CopyFrom(mac);
+
//
// Create a packet out of the buffer we received and free that buffer.
//
@@ -504,6 +576,13 @@
Ptr<Packet> originalPacket = packet->Copy ();
//
+ // Hit the trace hook. This trace will fire on all packets received from the
+ // OS (promiscuous). Packets are received instantaneously.
+ //
+ m_phyRxStartTrace (packet);
+ m_phyRxTrace (packet);
+
+ //
// Checksum the packet
//
EthernetTrailer trailer;
@@ -516,43 +595,68 @@
NS_LOG_LOGIC ("Pkt source is " << header.GetSource ());
NS_LOG_LOGIC ("Pkt destination is " << header.GetDestination ());
- LlcSnapHeader llc;
- packet->RemoveHeader (llc);
- uint16_t protocol = llc.GetType ();
+ uint16_t protocol;
+
+ //
+ // If the length/type is less than 1500, it corresponds to a length
+ // interpretation packet. In this case, it is an 802.3 packet and
+ // will also have an 802.2 LLC header. If greater than 1500, we
+ // find the protocol number (Ethernet type) directly.
+ //
+ if (header.GetLengthType () <= 1500)
+ {
+ LlcSnapHeader llc;
+ packet->RemoveHeader (llc);
+ protocol = llc.GetType ();
+ }
+ else
+ {
+ protocol = header.GetLengthType ();
+ }
PacketType packetType;
if (header.GetDestination ().IsBroadcast ())
{
- NS_LOG_LOGIC ("Pkt destination is PACKET_BROADCAST");
packetType = NS3_PACKET_BROADCAST;
}
- else if (header.GetDestination ().IsMulticast ())
+ else if (header.GetDestination ().IsMulticast () ||
+ header.GetDestination() == multicast6Node ||
+ header.GetDestination() == multicast6AllNodes ||
+ header.GetDestination() == multicast6AllRouters ||
+ header.GetDestination() == multicast6AllHosts)
{
- NS_LOG_LOGIC ("Pkt destination is PACKET_MULTICAST");
- packetType = NS3_PACKET_MULTICAST;
+ packetType = NS3_PACKET_MULTICAST;
}
else if (header.GetDestination () == m_address)
{
- NS_LOG_LOGIC ("Pkt destination is PACKET_HOST");
packetType = NS3_PACKET_HOST;
}
else
{
- NS_LOG_LOGIC ("Pkt destination is PACKET_OTHERHOST");
packetType = NS3_PACKET_OTHERHOST;
}
+ //
+ // For all kinds of packetType we receive, we hit the promiscuous sniffer
+ // hook and pass a copy up to the promiscuous callback. Pass a copy to
+ // make sure that nobody messes with our packet.
+ //
+ m_promiscSnifferTrace (originalPacket);
if (!m_promiscRxCallback.IsNull ())
{
- NS_LOG_LOGIC ("calling m_promiscRxCallback");
m_promiscRxCallback (this, packet->Copy (), protocol, header.GetSource (), header.GetDestination (), packetType);
}
+ //
+ // If this packet is not destined for some other host, it must be for us
+ // as either a broadcast, multicast or unicast. We need to hit the mac
+ // packet received trace hook and forward the packet up the stack.
+ //
if (packetType != NS3_PACKET_OTHERHOST)
{
- m_rxTrace (originalPacket);
- NS_LOG_LOGIC ("calling m_rxCallback");
+ m_snifferTrace (originalPacket);
+ m_macRxTrace (originalPacket);
m_rxCallback (this, packet, protocol, header.GetSource ());
}
}
@@ -632,10 +736,12 @@
EmuNetDevice::SendFrom (Ptr<Packet> packet, const Address &src, const Address &dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION (packet << src << dest << protocolNumber);
+ NS_LOG_LOGIC ("packet =" << packet);
+ NS_LOG_LOGIC ("UID is " << packet->GetUid () << ")");
if (IsLinkUp () == false)
{
- NS_LOG_LOGIC ("Link is down, returning");
+ m_macTxDropTrace (packet);
return false;
}
@@ -646,34 +752,11 @@
NS_LOG_LOGIC ("Transmit packet from " << source);
NS_LOG_LOGIC ("Transmit packet to " << destination);
-#if 0
- {
- struct ifreq ifr;
- bzero (&ifr, sizeof(ifr));
- strncpy ((char *)ifr.ifr_name, m_deviceName.c_str (), IFNAMSIZ);
-
- NS_LOG_LOGIC ("Getting MAC address");
- int32_t rc = ioctl (m_sock, SIOCGIFHWADDR, &ifr);
- if (rc == -1)
- {
- NS_FATAL_ERROR ("EmuNetDevice::SendFrom(): Can't get MAC address");
- }
-
- std::ostringstream oss;
- oss << std::hex <<
- (ifr.ifr_hwaddr.sa_data[0] & 0xff) << ":" <<
- (ifr.ifr_hwaddr.sa_data[1] & 0xff) << ":" <<
- (ifr.ifr_hwaddr.sa_data[2] & 0xff) << ":" <<
- (ifr.ifr_hwaddr.sa_data[3] & 0xff) << ":" <<
- (ifr.ifr_hwaddr.sa_data[4] & 0xff) << ":" <<
- (ifr.ifr_hwaddr.sa_data[5] & 0xff) << std::dec;
-
- NS_LOG_LOGIC ("Fixup source to HW MAC " << oss.str ());
- source = Mac48Address (oss.str ().c_str ());
- NS_LOG_LOGIC ("source now " << source);
- }
-#endif
-
+ //
+ // We've got to pick either DIX (Ethernet) or LLC/SNAP (IEEE 802.3) as a
+ // packet format. IEEE 802.3 is slightly more formally correct, so we
+ // go that route.
+ //
LlcSnapHeader llc;
llc.SetType (protocolNumber);
packet->AddHeader (llc);
@@ -688,11 +771,23 @@
trailer.CalcFcs (packet);
packet->AddTrailer (trailer);
+ //
+ // there's not much meaning associated with the different layers in this
+ // device, so don't be surprised when they're all stacked together in
+ // essentially one place. We do this for trace consistency across devices.
+ //
+ m_macTxTrace (packet);
+
//
- // Enqueue and dequeue the packet to hit the tracing hooks.
+ // Enqueue and dequeue the packet to hit the queue tracing hooks.
//
m_queue->Enqueue (packet);
packet = m_queue->Dequeue ();
+ NS_ASSERT_MSG (packet, "EmuNetDevice::SendFrom(): packet zero from queue");
+
+ m_promiscSnifferTrace (packet);
+ m_snifferTrace (packet);
+
struct sockaddr_ll ll;
bzero (&ll, sizeof (ll));
@@ -703,10 +798,13 @@
NS_LOG_LOGIC ("calling sendto");
+ m_phyTxStartTrace (packet);
+
int32_t rc;
rc = sendto (m_sock, packet->PeekData (), packet->GetSize (), 0, reinterpret_cast<struct sockaddr *> (&ll), sizeof (ll));
+ NS_LOG_LOGIC ("sendto returns " << rc);
- NS_LOG_LOGIC ("sendto returns " << rc);
+ m_phyTxTrace (packet);
return rc == -1 ? false : true;
}
--- a/src/devices/emu/emu-net-device.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/emu/emu-net-device.h Sat Feb 28 16:25:24 2009 -0800
@@ -264,20 +264,116 @@
Ptr<Queue> m_queue;
/**
- * The trace source for the packet reception events that the device can
- * fire.
+ * The trace source fired when packets come into the "top" of the device
+ * at the L3/L2 transition, before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+ /**
+ * The trace source fired when packets coming into the "top" of the device
+ * at the L3/L2 transition are dropped before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+ /**
+ * The trace source fired for packets successfully received by the device
+ * immediately before being forwarded up to higher layers (at the L2/L3
+ * transition).
*
- * @see class CallBackTraceSource
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+ /**
+ * The trace source fired when a packet starts the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
*/
- TracedCallback<Ptr<const Packet> > m_rxTrace;
+ TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet as it tries
+ * to transmit it.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
/**
- * The trace source for the packet drop events that the device can
- * fire.
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxTrace;
+
+ /**
+ * The trace source fired when a packet starts the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxStartTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet it has received.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+ /**
+ * A trace source that emulates a non-promiscuous protocol sniffer connected
+ * to the device. Unlike your average everyday sniffer, this trace source
+ * will not fire on PACKET_OTHERHOST events.
*
- * @see class CallBackTraceSource
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
*/
- TracedCallback<Ptr<const Packet> > m_dropTrace;
+ TracedCallback<Ptr<const Packet> > m_snifferTrace;
+
+ /**
+ * A trace source that emulates a promiscuous mode protocol sniffer connected
+ * to the device. This trace source fire on packets destined for any host
+ * just like your average everyday packet sniffer.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
/**
* Time to start spinning up the device
--- a/src/devices/point-to-point/point-to-point-channel.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/point-to-point/point-to-point-channel.h Sat Feb 28 16:25:24 2009 -0800
@@ -62,13 +62,13 @@
void Attach (Ptr<PointToPointNetDevice> device);
/**
- * \brief Attach a given netdevice to this channel
+ * \brief Transmit a packet over this channel
* \param p Packet to transmit
* \param src Source PointToPointNetDevice
* \param txTime Transmit time to apply
+ * \returns true if successful (currently always true)
*/
- bool TransmitStart (Ptr<Packet> p, Ptr<PointToPointNetDevice> src,
- Time txTime);
+ bool TransmitStart (Ptr<Packet> p, Ptr<PointToPointNetDevice> src, Time txTime);
/**
* \brief Get number of devices on this channel
--- a/src/devices/point-to-point/point-to-point-net-device.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/point-to-point/point-to-point-net-device.cc Sat Feb 28 16:25:24 2009 -0800
@@ -62,23 +62,67 @@
PointerValue (),
MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel),
MakePointerChecker<ErrorModel> ())
- .AddAttribute ("TxQueue",
- "A queue to use as the transmit queue in the device.",
- PointerValue (),
- MakePointerAccessor (&PointToPointNetDevice::m_queue),
- MakePointerChecker<Queue> ())
.AddAttribute ("InterframeGap",
"The time to wait between packet (frame) transmissions",
TimeValue (Seconds (0.0)),
MakeTimeAccessor (&PointToPointNetDevice::m_tInterframeGap),
MakeTimeChecker ())
- .AddTraceSource ("Rx",
- "Trace source indicating reception of packet from the PointToPointChannel.",
- MakeTraceSourceAccessor (&PointToPointNetDevice::m_rxTrace))
- .AddTraceSource ("Drop",
- "Trace source indicating a packet was discarded due to a ReceiveErrorModel decision.",
- MakeTraceSourceAccessor (&PointToPointNetDevice::m_dropTrace))
+
+ //
+ // Transmit queueing discipline for the device which includes its own set
+ // of trace hooks.
+ //
+ .AddAttribute ("TxQueue",
+ "A queue to use as the transmit queue in the device.",
+ PointerValue (),
+ MakePointerAccessor (&PointToPointNetDevice::m_queue),
+ MakePointerChecker<Queue> ())
+ //
+ // Trace sources at the "top" of the net device, where packets transition
+ // to/from higher layers.
+ //
+ .AddTraceSource ("MacTx",
+ "Trace source indicating a packet has arrived for transmission by this device",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_macTxTrace))
+ .AddTraceSource ("MacTxDrop",
+ "Trace source indicating a packet has been dropped by the device before transmission",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_macTxDropTrace))
+ .AddTraceSource ("MacRx",
+ "Trace source indicating a packet has been received by this device and is being forwarded up the stack",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_macRxTrace))
+ //
+ // Trace souces at the "bottom" of the net device, where packets transition
+ // to/from the channel.
+ //
+ .AddTraceSource ("PhyTxStart",
+ "Trace source indicating a packet has begun transmitting over the channel",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyTxStartTrace))
+ .AddTraceSource ("PhyTx",
+ "Trace source indicating a packet has been completely transmitted over the channel",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyTxTrace))
+ .AddTraceSource ("PhyTxDrop",
+ "Trace source indicating a packet has been dropped by the device during transmission",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyTxDropTrace))
+ .AddTraceSource ("PhyRxStart",
+ "Trace source indicating a packet has begun being received by the device",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyRxStartTrace))
+ .AddTraceSource ("PhyRx",
+ "Trace source indicating a packet has been completely received by the device",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyRxTrace))
+ .AddTraceSource ("PhyRxDrop",
+ "Trace source indicating a packet has been dropped by the device during reception",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_phyRxDropTrace))
+
+ //
+ // Trace sources designed to simulate a packet sniffer facility (tcpdump).
+ //
+ .AddTraceSource ("Sniffer",
+ "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_snifferTrace))
+ .AddTraceSource ("PromiscSniffer",
+ "Trace source simulating a promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&PointToPointNetDevice::m_promiscSnifferTrace))
;
return tid;
}
@@ -89,7 +133,8 @@
m_txMachineState (READY),
m_channel (0),
m_name (""),
- m_linkUp (false)
+ m_linkUp (false),
+ m_currentPkt (0)
{
NS_LOG_FUNCTION (this);
@@ -112,8 +157,7 @@
PointToPointNetDevice::AddHeader(Ptr<Packet> p, uint16_t protocolNumber)
{
NS_LOG_FUNCTION_NOARGS ();
- NS_ASSERT_MSG (protocolNumber == 0x800,
- "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
+ NS_ASSERT_MSG (protocolNumber == 0x800, "PointToPointNetDevice::AddHeader(): protocolNumber must be 0x800");
PppHeader ppp;
p->AddHeader (ppp);
}
@@ -135,6 +179,7 @@
m_node = 0;
m_channel = 0;
m_receiveErrorModel = 0;
+ m_currentPkt = 0;
NetDevice::DoDispose ();
}
@@ -157,48 +202,63 @@
{
NS_LOG_FUNCTION (this << p);
NS_LOG_LOGIC ("UID is " << p->GetUid () << ")");
-//
-// This function is called to start the process of transmitting a packet.
-// We need to tell the channel that we've started wiggling the wire and
-// schedule an event that will be executed when the transmission is complete.
-//
+
+ //
+ // This function is called to start the process of transmitting a packet.
+ // We need to tell the channel that we've started wiggling the wire and
+ // schedule an event that will be executed when the transmission is complete.
+ //
NS_ASSERT_MSG(m_txMachineState == READY, "Must be READY to transmit");
m_txMachineState = BUSY;
+ m_phyTxTrace (m_currentPkt);
+ m_currentPkt = p;
+
Time txTime = Seconds (m_bps.CalculateTxTime(p->GetSize()));
Time txCompleteTime = txTime + m_tInterframeGap;
- NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " <<
- txCompleteTime.GetSeconds () << "sec");
+ NS_LOG_LOGIC ("Schedule TransmitCompleteEvent in " << txCompleteTime.GetSeconds () << "sec");
+ Simulator::Schedule (txCompleteTime, &PointToPointNetDevice::TransmitComplete, this);
- Simulator::Schedule (txCompleteTime,
- &PointToPointNetDevice::TransmitComplete, this);
-
- return m_channel->TransmitStart(p, this, txTime);
+ bool result = m_channel->TransmitStart(p, this, txTime);
+ if (result == false)
+ {
+ m_phyTxDropTrace (p);
+ }
+ return result;
}
void
PointToPointNetDevice::TransmitComplete (void)
{
NS_LOG_FUNCTION_NOARGS ();
-//
-// This function is called to when we're all done transmitting a packet.
-// We try and pull another packet off of the transmit queue. If the queue
-// is empty, we are done, otherwise we need to start transmitting the
-// next packet.
-//
+
+ //
+ // This function is called to when we're all done transmitting a packet.
+ // We try and pull another packet off of the transmit queue. If the queue
+ // is empty, we are done, otherwise we need to start transmitting the
+ // next packet.
+ //
NS_ASSERT_MSG(m_txMachineState == BUSY, "Must be BUSY if transmitting");
m_txMachineState = READY;
+
+ NS_ASSERT_MSG (m_currentPkt != 0, "PointToPointNetDevice::TransmitComplete(): m_currentPkt zero");
+
+ m_phyTxTrace (m_currentPkt);
+ m_currentPkt = 0;
+
Ptr<Packet> p = m_queue->Dequeue ();
if (p == 0)
{
-//
-// No packet was on the queue, so we just exit.
-//
+ //
+ // No packet was on the queue, so we just exit.
+ //
return;
}
-//
-// Got another packet off of the queue, so start the transmit process agin.
-//
+
+ //
+ // Got another packet off of the queue, so start the transmit process agin.
+ //
+ m_snifferTrace (p);
TransmitStart(p);
}
@@ -211,11 +271,11 @@
m_channel->Attach(this);
-//
-// This device is up whenever it is attached to a channel. A better plan
-// would be to have the link come up when both devices are attached, but this
-// is not done for now.
-//
+ //
+ // This device is up whenever it is attached to a channel. A better plan
+ // would be to have the link come up when both devices are attached, but this
+ // is not done for now.
+ //
NotifyLinkUp ();
return true;
}
@@ -242,25 +302,37 @@
if (m_receiveErrorModel && m_receiveErrorModel->IsCorrupt (packet) )
{
-//
-// If we have an error model and it indicates that it is time to lose a
-// corrupted packet, don't forward this packet up, let it go.
-//
- m_dropTrace (packet);
+ //
+ // If we have an error model and it indicates that it is time to lose a
+ // corrupted packet, don't forward this packet up, let it go.
+ //
+ m_phyRxDropTrace (packet);
}
else
{
-//
-// Hit the receive trace hook, strip off the point-to-point protocol header
-// and forward this packet up the protocol stack.
-//
- m_rxTrace (packet);
+ //
+ // Hit the trace hooks. All of these hooks are in the same place in this
+ // device becuase it is so simple, but this is not usually the case.
+ //
+ m_snifferTrace (packet);
+ m_phyRxTrace (packet);
+ m_macRxTrace (packet);
+
+ //
+ // Strip off the point-to-point protocol header and forward this packet
+ // up the protocol stack. Since this is a simple point-to-point link,
+ // there is no difference in what the promisc callback sees and what the
+ // normal receive callback sees.
+ //
ProcessHeader(packet, protocol);
- m_rxCallback (this, packet, protocol, GetRemote ());
+
if (!m_promiscCallback.IsNull ())
{
- m_promiscCallback (this, packet, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST);
+ Ptr<Packet> pktCopy = packet->Copy ();
+ m_promiscCallback (this, pktCopy, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST);
}
+
+ m_rxCallback (this, packet, protocol, GetRemote ());
}
}
@@ -406,33 +478,37 @@
NS_LOG_LOGIC ("p=" << packet << ", dest=" << &dest);
NS_LOG_LOGIC ("UID is " << packet->GetUid ());
-//
-// If IsLinkUp() is false it means there is no channel to send any packet
-// over so we just return an error.
-//
+ //
+ // If IsLinkUp() is false it means there is no channel to send any packet
+ // over so we just hit the drop trace on the packet and return an error.
+ //
if (IsLinkUp () == false)
{
+ m_macTxDropTrace (packet);
return false;
}
-//
-// Stick a point to point protocol header on the packet in preparation for
-// shoving it out the door.
-//
+ //
+ // Stick a point to point protocol header on the packet in preparation for
+ // shoving it out the door.
+ //
AddHeader(packet, protocolNumber);
-//
-// If there's a transmission in progress, we enque the packet for later
-// transmission; otherwise we send it now.
-//
+ m_macTxTrace (packet);
+
+ //
+ // If there's a transmission in progress, we enque the packet for later
+ // transmission; otherwise we send it now.
+ //
if (m_txMachineState == READY)
{
-//
-// Even if the transmitter is immediately available, we still enqueue and
-// dequeue the packet to hit the tracing hooks.
-//
+ //
+ // Even if the transmitter is immediately available, we still enqueue and
+ // dequeue the packet to hit the tracing hooks.
+ //
m_queue->Enqueue (packet);
packet = m_queue->Dequeue ();
+ m_snifferTrace (packet);
return TransmitStart (packet);
}
else
--- a/src/devices/point-to-point/point-to-point-net-device.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/point-to-point/point-to-point-net-device.h Sat Feb 28 16:25:24 2009 -0800
@@ -388,26 +388,127 @@
Ptr<Queue> m_queue;
/**
- * The trace source for the packet reception events that the device can
- * fire.
- *
- * @see class CallBackTraceSource
- */
- TracedCallback<Ptr<const Packet> > m_rxTrace;
-
- /**
- * The trace source for the packet drop events that the device can
- * fire.
- *
- * @see class CallBackTraceSource
- */
- TracedCallback<Ptr<const Packet> > m_dropTrace;
-
- /**
* Error model for receive packet events
*/
Ptr<ErrorModel> m_receiveErrorModel;
+ /**
+ * The trace source fired when packets come into the "top" of the device
+ * at the L3/L2 transition, before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+ /**
+ * The trace source fired when packets coming into the "top" of the device
+ * at the L3/L2 transition are dropped before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+ /**
+ * The trace source fired for packets successfully received by the device
+ * immediately before being forwarded up to higher layers (at the L2/L3
+ * transition).
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+ /**
+ * The trace source fired when a packet starts the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the transmission process on
+ * the medium. This happens immediately after the device has completed
+ * packet transmission and has stopped "wiggling" the wire. N.B. This
+ * is not the same time that the packet will be received on a remote device
+ * as that time includes a speed-of-light delay.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet before it tries
+ * to transmit it.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
+
+ /**
+ * The trace source fired when a packet starts the reception process from
+ * the medium -- when the simulated first bit(s) arrive.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet it has received.
+ * This happens if the receiver is not enabled or the error model is active
+ * and indicates that the packet is corrupt.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+ /**
+ * A trace source that emulates a non-promiscuous protocol sniffer connected
+ * to the device. Unlike your average everyday sniffer, this trace source
+ * will not fire on PACKET_OTHERHOST events.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_snifferTrace;
+
+ /**
+ * A trace source that emulates a promiscuous mode protocol sniffer connected
+ * to the device. This trace source fire on packets destined for any host
+ * just like your average everyday packet sniffer.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
+
Ptr<Node> m_node;
Mac48Address m_address;
NetDevice::ReceiveCallback m_rxCallback;
@@ -435,6 +536,8 @@
* Ethernet.
*/
uint32_t m_mtu;
+
+ Ptr<Packet> m_currentPkt;
};
} // namespace ns3
--- a/src/devices/wifi/adhoc-wifi-mac.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/adhoc-wifi-mac.cc Sat Feb 28 16:25:24 2009 -0800
@@ -24,6 +24,7 @@
#include "mac-rx-middle.h"
#include "wifi-phy.h"
#include "dcf-manager.h"
+#include "wifi-mac-trailer.h"
#include "ns3/pointer.h"
#include "ns3/packet.h"
#include "ns3/log.h"
@@ -234,6 +235,7 @@
destination->RecordDisassociated ();
}
+ m_macTxTrace (packet);
m_dca->Queue (packet, hdr);
}
bool
@@ -246,6 +248,7 @@
AdhocWifiMac::ForwardUp (Ptr<Packet> packet, WifiMacHeader const *hdr)
{
NS_LOG_DEBUG ("received size="<<packet->GetSize ()<<", from="<<hdr->GetAddr2 ());
+ m_macRxTrace (packet);
m_upCallback (packet, hdr->GetAddr2 (), hdr->GetAddr1 ());
}
Ptr<DcaTxop>
--- a/src/devices/wifi/mac-low.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/mac-low.cc Sat Feb 28 16:25:24 2009 -0800
@@ -840,6 +840,10 @@
*/
Time txDuration = m_phy->CalculateTxDuration (packet->GetSize (), txMode, WIFI_PREAMBLE_LONG);
Simulator::Schedule (txDuration, &MacLow::NotifyNav, this, *hdr, txMode, WIFI_PREAMBLE_LONG);
+ /*
+ * Tell the phy when we expect the packet has completely been sent -- for tracing
+ */
+ Simulator::Schedule (txDuration, &WifiPhy::SendDone, m_phy, packet);
}
void
--- a/src/devices/wifi/nqap-wifi-mac.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/nqap-wifi-mac.cc Sat Feb 28 16:25:24 2009 -0800
@@ -30,6 +30,7 @@
#include "dcf-manager.h"
#include "mac-rx-middle.h"
#include "mac-low.h"
+#include "wifi-mac-trailer.h"
#include "ns3/pointer.h"
NS_LOG_COMPONENT_DEFINE ("NqapWifiMac");
@@ -285,8 +286,10 @@
NqapWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
{
NS_LOG_FUNCTION (this << packet << from);
+ m_macRxTrace (packet);
m_upCallback (packet, from, to);
}
+
void
NqapWifiMac::ForwardDown (Ptr<const Packet> packet, Mac48Address from, Mac48Address to)
{
@@ -298,6 +301,8 @@
hdr.SetAddr3 (from);
hdr.SetDsFrom ();
hdr.SetDsNotTo ();
+
+ m_macTxTrace (packet);
m_dca->Queue (packet, hdr);
}
void
@@ -472,11 +477,13 @@
{
// this is an AP-to-AP frame
// we ignore for now.
+ m_macRxDropTrace (packet);
}
else
{
// we can ignore these frames since
// they are not targeted at the AP
+ m_macRxDropTrace (packet);
}
}
else if (hdr->IsMgt ())
--- a/src/devices/wifi/nqsta-wifi-mac.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/nqsta-wifi-mac.cc Sat Feb 28 16:25:24 2009 -0800
@@ -34,6 +34,7 @@
#include "mac-low.h"
#include "dcf-manager.h"
#include "mac-rx-middle.h"
+#include "wifi-mac-trailer.h"
#include "ns3/trace-source-accessor.h"
#include "ns3/pointer.h"
@@ -321,6 +322,7 @@
NqstaWifiMac::ForwardUp (Ptr<Packet> packet, Mac48Address from, Mac48Address to)
{
NS_LOG_FUNCTION (this << packet << from << to);
+ m_macRxTrace (packet);
m_forwardUp (packet, from, to);
}
void
@@ -457,14 +459,16 @@
void
NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to, Mac48Address from)
{
- NS_FATAL_ERROR ("Qsta does not support enqueue");
+ NS_FATAL_ERROR ("Qsta does not support SendTo");
}
+
void
NqstaWifiMac::Enqueue (Ptr<const Packet> packet, Mac48Address to)
{
NS_LOG_FUNCTION (this << packet << to);
if (!IsAssociated ())
{
+ m_macTxDropTrace (packet);
TryToEnsureAssociated ();
return;
}
@@ -476,12 +480,19 @@
hdr.SetAddr3 (to);
hdr.SetDsNotFrom ();
hdr.SetDsTo ();
+
+ m_macTxTrace (packet);
m_dca->Queue (packet, hdr);
}
+
bool
NqstaWifiMac::SupportsSendFrom (void) const
{
- return true;
+ //
+ // The 802.11 MAC protocol has no way to support bridging outside of
+ // infrastructure mode
+ //
+ return false;
}
@@ -498,24 +509,29 @@
!hdr->GetAddr1 ().IsGroup ())
{
NS_LOG_LOGIC ("packet is not for us");
+ m_macRxDropTrace (packet);
}
else if (hdr->IsData ())
{
if (!IsAssociated ())
{
NS_LOG_LOGIC ("Received data frame while not associated: ignore");
+ m_macRxDropTrace (packet);
return;
}
if (!(hdr->IsFromDs () && !hdr->IsToDs ()))
{
NS_LOG_LOGIC ("Received data frame not from the DS: ignore");
+ m_macRxDropTrace (packet);
return;
}
if (hdr->GetAddr2 () != GetBssid ())
{
NS_LOG_LOGIC ("Received data frame not from the the BSS we are associated with: ignore");
+ m_macRxDropTrace (packet);
return;
}
+
ForwardUp (packet, hdr->GetAddr3 (), hdr->GetAddr1 ());
}
else if (hdr->IsProbeReq () ||
@@ -524,6 +540,7 @@
/* this is a frame aimed at an AP.
* so we can safely ignore it.
*/
+ m_macRxDropTrace (packet);
}
else if (hdr->IsBeacon ())
{
--- a/src/devices/wifi/wifi-mac.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-mac.cc Sat Feb 28 16:25:24 2009 -0800
@@ -19,6 +19,7 @@
*/
#include "wifi-mac.h"
#include "ns3/uinteger.h"
+#include "ns3/trace-source-accessor.h"
namespace ns3 {
@@ -117,7 +118,26 @@
MakeSsidAccessor (&WifiMac::GetSsid,
&WifiMac::SetSsid),
MakeSsidChecker ())
+ .AddTraceSource ("MacTx",
+ "A packet has been received from higher layers and is being processed in preparation for "
+ "queueing for transmission.",
+ MakeTraceSourceAccessor (&WifiMac::m_macTxTrace))
+ .AddTraceSource ("MacTxDrop",
+ "A packet has been dropped in the MAC layer before being queued for transmission.",
+ MakeTraceSourceAccessor (&WifiMac::m_macTxDropTrace))
+ .AddTraceSource ("MacRx",
+ "A packet has been received by this device, has been passed up from the physical layer "
+ "and is being forwarded up the local protocol stack.",
+ MakeTraceSourceAccessor (&WifiMac::m_macRxTrace))
+ .AddTraceSource ("MacRxDrop",
+ "A packet has been dropped in the MAC layer after it has been passed up from the physical "
+ "layer.",
+ MakeTraceSourceAccessor (&WifiMac::m_macRxDropTrace))
+ .AddTraceSource ("Sniffer",
+ "Trace source simulating a non-promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&WifiMac::m_snifferTrace))
;
+
return tid;
}
@@ -144,5 +164,11 @@
return m_maxMsduSize;
}
+void
+WifiMac::SnifferTrace (Ptr<const Packet> packet)
+{
+ m_snifferTrace (packet);
+}
+
} // namespace ns3
--- a/src/devices/wifi/wifi-mac.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-mac.h Sat Feb 28 16:25:24 2009 -0800
@@ -176,10 +176,14 @@
* \param linkDown the callback to invoke when the link becomes down.
*/
virtual void SetLinkDownCallback (Callback<void> linkDown) = 0;
-private:
+ /*
+ * Let the net device hit a trace hook. This is done to group the high-level
+ * trace sources all in one place for ease of use.
+ */
+ void SnifferTrace (Ptr<const Packet> packet);
-
+private:
static Time GetDefaultMaxPropagationDelay (void);
static Time GetDefaultSlot (void);
static Time GetDefaultSifs (void);
@@ -189,6 +193,61 @@
Time m_maxPropagationDelay;
uint32_t m_maxMsduSize;
+
+protected:
+
+ /**
+ * The trace source fired when packets come into the "top" of the device
+ * at the L3/L2 transition, before being queued for transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxTrace;
+
+ /**
+ * The trace source fired when packets coming into the "top" of the device
+ * are dropped at the MAC layer during transmission.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macTxDropTrace;
+
+ /**
+ * The trace source fired for packets successfully received by the device
+ * immediately before being forwarded up to higher layers (at the L2/L3
+ * transition).
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macRxTrace;
+
+ /**
+ * The trace source fired when packets coming into the "top" of the device
+ * are dropped at the MAC layer during reception.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_macRxDropTrace;
+
+ /**
+ * A trace source that emulates a non-promiscuous protocol sniffer connected
+ * to the device. Unlike your average everyday sniffer, this trace source
+ * will not fire on PACKET_OTHERHOST events.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_snifferTrace;
};
} // namespace ns3
--- a/src/devices/wifi/wifi-net-device.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-net-device.cc Sat Feb 28 16:25:24 2009 -0800
@@ -23,6 +23,8 @@
#include "wifi-remote-station-manager.h"
#include "wifi-channel.h"
#include "ns3/llc-snap-header.h"
+#include "ns3/ethernet-header.h"
+#include "ns3/ethernet-trailer.h"
#include "ns3/packet.h"
#include "ns3/uinteger.h"
#include "ns3/pointer.h"
@@ -57,10 +59,6 @@
MakePointerAccessor (&WifiNetDevice::SetRemoteStationManager,
&WifiNetDevice::GetRemoteStationManager),
MakePointerChecker<WifiRemoteStationManager> ())
- .AddTraceSource ("Rx", "Received payload from the MAC layer.",
- MakeTraceSourceAccessor (&WifiNetDevice::m_rxLogger))
- .AddTraceSource ("Tx", "Send payload to the MAC layer.",
- MakeTraceSourceAccessor (&WifiNetDevice::m_txLogger))
;
return tid;
}
@@ -243,11 +241,14 @@
return false;
}
bool
-WifiNetDevice::Send(Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
+WifiNetDevice::Send (Ptr<Packet> packet, const Address& dest, uint16_t protocolNumber)
{
NS_ASSERT (Mac48Address::IsMatchingType (dest));
Mac48Address realTo = Mac48Address::ConvertFrom (dest);
+ Mac48Address realFrom = Mac48Address::ConvertFrom (GetAddress ());
+
+ SniffPacket (packet, realTo, realFrom, protocolNumber);
LlcSnapHeader llc;
llc.SetType (protocolNumber);
@@ -303,13 +304,16 @@
{
type = NetDevice::PACKET_OTHERHOST;
}
+
if (type != NetDevice::PACKET_OTHERHOST)
{
+ SniffPacket (packet, to, from, llc.GetType ());
m_forwardUp (this, packet, llc.GetType (), from);
}
+
if (!m_promiscRx.IsNull ())
{
- m_promiscRx (this, packet, llc.GetType (), from, to, type);
+ m_promiscRx (this, packet->Copy (), llc.GetType (), from, to, type);
}
}
@@ -341,6 +345,8 @@
Mac48Address realTo = Mac48Address::ConvertFrom (dest);
Mac48Address realFrom = Mac48Address::ConvertFrom (source);
+ SniffPacket (packet, realTo, realFrom, protocolNumber);
+
LlcSnapHeader llc;
llc.SetType (protocolNumber);
packet->AddHeader (llc);
@@ -364,5 +370,26 @@
return m_mac->SupportsSendFrom ();
}
+void
+WifiNetDevice::SniffPacket (Ptr<const Packet> packet, Mac48Address to, Mac48Address from, uint16_t type)
+{
+ Ptr<Packet> copy = packet->Copy ();
+ EthernetHeader header (false);
+ header.SetSource (from);
+ header.SetDestination (to);
+
+ LlcSnapHeader llc;
+ llc.SetType (type);
+ copy->AddHeader (llc);
+
+ header.SetLengthType (copy->GetSize ());
+ copy->AddHeader (header);
+
+ EthernetTrailer trailer;
+ trailer.CalcFcs (copy);
+ copy->AddTrailer (trailer);
+ m_mac->SnifferTrace (copy);
+}
+
} // namespace ns3
--- a/src/devices/wifi/wifi-net-device.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-net-device.h Sat Feb 28 16:25:24 2009 -0800
@@ -118,8 +118,18 @@
Ptr<WifiRemoteStationManager> m_stationManager;
NetDevice::ReceiveCallback m_forwardUp;
NetDevice::PromiscReceiveCallback m_promiscRx;
+
TracedCallback<Ptr<const Packet>, Mac48Address> m_rxLogger;
TracedCallback<Ptr<const Packet>, Mac48Address> m_txLogger;
+
+ /**
+ * At the top of the MAC level, we do what many folks do and make the wifi
+ * packets look like Ethernet packets coming in and out of the "driver." If
+ * you are interested in seeing all of the wifi details, you should use the
+ * much lower level PHY promiscuous sniffer trace.
+ */
+ void SniffPacket (Ptr<const Packet> packet, Mac48Address to, Mac48Address from, uint16_t type);
+
uint32_t m_ifIndex;
std::string m_name;
bool m_linkUp;
--- a/src/devices/wifi/wifi-phy.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-phy.cc Sat Feb 28 16:25:24 2009 -0800
@@ -55,6 +55,27 @@
{
static TypeId tid = TypeId ("ns3::WifiPhy")
.SetParent<Object> ()
+ .AddTraceSource ("PhyTxStart",
+ "Trace source indicating a packet has begun transmitting over the channel medium",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyTxStartTrace))
+ .AddTraceSource ("PhyTx",
+ "Trace source indicating a packet has been completely transmitted over the channel",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyTxTrace))
+ .AddTraceSource ("PhyTxDrop",
+ "Trace source indicating a packet has been dropped by the device during transmission",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyTxDropTrace))
+ .AddTraceSource ("PhyRxStart",
+ "Trace source indicating a packet has begun being received from the channel medium by the device",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyRxStartTrace))
+ .AddTraceSource ("PhyRx",
+ "Trace source indicating a packet has been completely received from the channel medium by the device",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyRxTrace))
+ .AddTraceSource ("PhyRxDrop",
+ "Trace source indicating a packet has been dropped by the device during reception",
+ MakeTraceSourceAccessor (&WifiPhy::m_phyRxDropTrace))
+ .AddTraceSource ("PromiscSniffer",
+ "Trace source simulating a promiscuous packet sniffer attached to the device",
+ MakeTraceSourceAccessor (&WifiPhy::m_promiscSnifferTrace))
;
return tid;
}
--- a/src/devices/wifi/wifi-phy.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/wifi-phy.h Sat Feb 28 16:25:24 2009 -0800
@@ -30,6 +30,7 @@
#include "wifi-mode.h"
#include "wifi-preamble.h"
#include "wifi-phy-standard.h"
+#include "ns3/traced-callback.h"
namespace ns3 {
@@ -79,6 +80,7 @@
* unless they have received a cca busy report.
*/
virtual void NotifyTxStart (Time duration) = 0;
+
/**
* \param duration the expected busy duration.
*
@@ -173,6 +175,13 @@
virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel) = 0;
/**
+ * \param packet the packet that was sent
+ *
+ * Tell the PHY-level that MAC low believes it should have just completed the send.
+ */
+ virtual void SendDone (Ptr<const Packet> packet) = 0;
+
+ /**
* \param listener the new listener
*
* Add the input listener to the list of objects to be notified of
@@ -250,6 +259,74 @@
static WifiMode Get36mba (void);
static WifiMode Get48mba (void);
static WifiMode Get54mba (void);
+
+protected:
+ /**
+ * The trace source fired when a packet starts the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet as it tries
+ * to transmit it.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
+
+ /**
+ * The trace source fired when a packet starts the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet it has received.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+ /**
+ * A trace source that emulates a promiscuous mode protocol sniffer connected
+ * to the device. This trace source fire on packets destined for any host
+ * just like your average everyday packet sniffer.
+ *
+ * On the transmit size, this trace hook will fire after a packet is dequeued
+ * from the device queue for transmission. In Linux, for example, this would
+ * correspond to the point just before a device hard_start_xmit where
+ * dev_queue_xmit_nit is called to dispatch the packet to the PF_PACKET
+ * ETH_P_ALL handlers.
+ *
+ * On the receive side, this trace hook will fire when a packet is received,
+ * just before the receive callback is executed. In Linux, for example,
+ * this would correspond to the point at which the packet is dispatched to
+ * packet sniffers in netif_receive_skb.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_promiscSnifferTrace;
};
} // namespace ns3
--- a/src/devices/wifi/yans-wifi-phy.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/yans-wifi-phy.cc Sat Feb 28 16:25:24 2009 -0800
@@ -34,6 +34,7 @@
#include "ns3/enum.h"
#include "ns3/pointer.h"
#include "ns3/net-device.h"
+#include "ns3/trace-source-accessor.h"
#include <math.h>
NS_LOG_COMPONENT_DEFINE ("YansWifiPhy");
@@ -322,6 +323,7 @@
case YansWifiPhy::SYNC:
NS_LOG_DEBUG ("drop packet because already in Sync (power="<<
rxPowerW<<"W)");
+ m_phyRxDropTrace (packet);
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
{
// that packet will be noise _after_ the reception of the
@@ -332,6 +334,7 @@
case YansWifiPhy::TX:
NS_LOG_DEBUG ("drop packet because already in Tx (power="<<
rxPowerW<<"W)");
+ m_phyRxDropTrace (packet);
if (endRx > Simulator::Now () + m_state->GetDelayUntilIdle ())
{
// that packet will be noise _after_ the transmission of the
@@ -347,6 +350,7 @@
// sync to signal
m_state->SwitchToSync (rxDuration);
NS_ASSERT (m_endSyncEvent.IsExpired ());
+ m_phyRxStartTrace (packet);
m_endSyncEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndSync, this,
packet,
event);
@@ -355,6 +359,7 @@
{
NS_LOG_DEBUG ("drop packet because signal power too Small ("<<
rxPowerW<<"<"<<m_edThresholdW<<")");
+ m_phyRxDropTrace (packet);
goto maybeCcaBusy;
}
break;
@@ -374,6 +379,7 @@
m_state->SwitchMaybeToCcaBusy (delayUntilCcaEnd);
}
}
+
void
YansWifiPhy::SendPacket (Ptr<const Packet> packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower)
{
@@ -391,10 +397,18 @@
{
m_endSyncEvent.Cancel ();
}
+ m_phyTxStartTrace (packet);
+ m_promiscSnifferTrace (packet);
m_state->SwitchToTx (txDuration, packet, txMode, preamble, txPower);
m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble);
}
+void
+YansWifiPhy::SendDone (Ptr<const Packet> packet)
+{
+ m_phyTxTrace (packet);
+}
+
uint32_t
YansWifiPhy::GetNModes (void) const
{
@@ -550,11 +564,14 @@
if (m_random.GetValue () > snrPer.per)
{
+ m_phyRxTrace (packet);
+ m_promiscSnifferTrace (packet);
m_state->SwitchFromSyncEndOk (packet, snrPer.snr, event->GetPayloadMode (), event->GetPreambleType ());
}
else
{
/* failure. */
+ m_phyRxDropTrace (packet);
m_state->SwitchFromSyncEndError (packet, snrPer.snr);
}
}
--- a/src/devices/wifi/yans-wifi-phy.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/devices/wifi/yans-wifi-phy.h Sat Feb 28 16:25:24 2009 -0800
@@ -102,6 +102,7 @@
virtual void SetReceiveOkCallback (WifiPhy::SyncOkCallback callback);
virtual void SetReceiveErrorCallback (WifiPhy::SyncErrorCallback callback);
virtual void SendPacket (Ptr<const Packet> packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel);
+ virtual void SendDone (Ptr<const Packet> packet);
virtual void RegisterListener (WifiPhyListener *listener);
virtual bool IsStateCcaBusy (void);
virtual bool IsStateIdle (void);
@@ -134,6 +135,54 @@
void EndSync (Ptr<Packet> packet, Ptr<InterferenceHelper::Event> event);
private:
+ /**
+ * The trace source fired when a packet starts the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxStartTrace;
+
+ /**
+ * The trace source fired when a packet ends the transmission process on
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet as it tries
+ * to transmit it.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyTxDropTrace;
+
+ /**
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxTrace;
+
+ /**
+ * The trace source fired when a packet ends the reception process from
+ * the medium.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxStartTrace;
+
+ /**
+ * The trace source fired when the phy layer drops a packet it has received.
+ *
+ * \see class CallBackTraceSource
+ */
+ TracedCallback<Ptr<const Packet> > m_phyRxDropTrace;
+
+private:
double m_edThresholdW;
double m_ccaMode1ThresholdW;
double m_txGainDb;
@@ -151,6 +200,7 @@
WifiPhyStandard m_standard;
Ptr<WifiPhyStateHelper> m_state;
InterferenceHelper m_interference;
+
};
} // namespace ns3
--- a/src/helper/csma-helper.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/csma-helper.cc Sat Feb 28 16:25:24 2009 -0800
@@ -69,6 +69,7 @@
{
SetDeviceAttribute (n1, v1);
}
+
void
CsmaHelper::SetChannelParameter (std::string n1, const AttributeValue &v1)
{
@@ -91,12 +92,10 @@
pcap->Open (oss.str ());
pcap->WriteEthernetHeader ();
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/Rx";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::RxEvent, pcap));
- oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::EnqueueEvent, pcap));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/Sniffer";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&CsmaHelper::SniffEvent, pcap));
}
+
void
CsmaHelper::EnablePcap (std::string filename, NetDeviceContainer d)
{
@@ -132,7 +131,7 @@
{
Packet::EnablePrinting ();
std::ostringstream oss;
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/Rx";
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/MacRx";
Config::Connect (oss.str (), MakeBoundCallback (&CsmaHelper::AsciiRxEvent, &os));
oss.str ("");
oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::CsmaNetDevice/TxQueue/Enqueue";
@@ -279,15 +278,11 @@
}
void
-CsmaHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+CsmaHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
{
writer->WritePacket (packet);
}
-void
-CsmaHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
- writer->WritePacket (packet);
-}
+
void
CsmaHelper::AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet)
{
--- a/src/helper/csma-helper.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/csma-helper.h Sat Feb 28 16:25:24 2009 -0800
@@ -331,12 +331,13 @@
private:
Ptr<NetDevice> InstallPriv (Ptr<Node> node, Ptr<CsmaChannel> channel) const;
- static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
- static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+ static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+
+ static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
static void AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
- static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+
ObjectFactory m_queueFactory;
ObjectFactory m_deviceFactory;
ObjectFactory m_channelFactory;
--- a/src/helper/emu-helper.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/emu-helper.cc Sat Feb 28 16:25:24 2009 -0800
@@ -78,16 +78,8 @@
pcap->WriteEthernetHeader ();
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid <<
- "/$ns3::EmuNetDevice/Rx";
- Config::ConnectWithoutContext (oss.str (),
- MakeBoundCallback (&EmuHelper::RxEvent, pcap));
-
- oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid <<
- "/$ns3::EmuNetDevice/TxQueue/Enqueue";
- Config::ConnectWithoutContext (oss.str (),
- MakeBoundCallback (&EmuHelper::EnqueueEvent, pcap));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/Sniffer";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&EmuHelper::SniffEvent, pcap));
}
void
@@ -131,28 +123,20 @@
Packet::EnablePrinting ();
std::ostringstream oss;
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid <<
- "/$ns3::EmuNetDevice/Rx";
- Config::Connect (oss.str (),
- MakeBoundCallback (&EmuHelper::AsciiRxEvent, &os));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/MacRx";
+ Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiRxEvent, &os));
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid <<
- "/$ns3::EmuNetDevice/TxQueue/Enqueue";
- Config::Connect (oss.str (),
- MakeBoundCallback (&EmuHelper::AsciiEnqueueEvent, &os));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Enqueue";
+ Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiEnqueueEvent, &os));
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid <<
- "/$ns3::EmuNetDevice/TxQueue/Dequeue";
- Config::Connect (oss.str (),
- MakeBoundCallback (&EmuHelper::AsciiDequeueEvent, &os));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Dequeue";
+ Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiDequeueEvent, &os));
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid <<
- "/$ns3::EmuNetDevice/TxQueue/Drop";
- Config::Connect (oss.str (),
- MakeBoundCallback (&EmuHelper::AsciiDropEvent, &os));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::EmuNetDevice/TxQueue/Drop";
+ Config::Connect (oss.str (), MakeBoundCallback (&EmuHelper::AsciiDropEvent, &os));
}
void
@@ -228,14 +212,7 @@
}
void
-EmuHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
- NS_LOG_FUNCTION (writer << packet);
- writer->WritePacket (packet);
-}
-
- void
-EmuHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+EmuHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
{
NS_LOG_FUNCTION (writer << packet);
writer->WritePacket (packet);
--- a/src/helper/emu-helper.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/emu-helper.h Sat Feb 28 16:25:24 2009 -0800
@@ -184,16 +184,12 @@
private:
Ptr<NetDevice> InstallPriv (Ptr<Node> node) const;
- static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
- static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
- static void AsciiEnqueueEvent (std::ostream *os, std::string path,
- Ptr<const Packet> packet);
- static void AsciiDequeueEvent (std::ostream *os, std::string path,
- Ptr<const Packet> packet);
- static void AsciiDropEvent (std::ostream *os, std::string path,
- Ptr<const Packet> packet);
- static void AsciiRxEvent (std::ostream *os, std::string path,
- Ptr<const Packet> packet);
+ static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+
+ static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+ static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+ static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+ static void AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
ObjectFactory m_queueFactory;
ObjectFactory m_deviceFactory;
--- a/src/helper/point-to-point-helper.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/point-to-point-helper.cc Sat Feb 28 16:25:24 2009 -0800
@@ -90,11 +90,8 @@
pcap->Open (oss.str ());
pcap->WritePppHeader ();
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/Rx";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::RxEvent, pcap));
- oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::EnqueueEvent, pcap));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/Sniffer";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PointToPointHelper::SniffEvent, pcap));
}
void
PointToPointHelper::EnablePcap (std::string filename, NetDeviceContainer d)
@@ -131,7 +128,7 @@
{
Packet::EnablePrinting ();
std::ostringstream oss;
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/Rx";
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/MacRx";
Config::Connect (oss.str (), MakeBoundCallback (&PointToPointHelper::AsciiRxEvent, &os));
oss.str ("");
oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::PointToPointNetDevice/TxQueue/Enqueue";
@@ -247,12 +244,7 @@
}
void
-PointToPointHelper::EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
-{
- writer->WritePacket (packet);
-}
-void
-PointToPointHelper::RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+PointToPointHelper::SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
{
writer->WritePacket (packet);
}
--- a/src/helper/point-to-point-helper.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/point-to-point-helper.h Sat Feb 28 16:25:24 2009 -0800
@@ -261,13 +261,14 @@
private:
void EnablePcap (Ptr<Node> node, Ptr<NetDevice> device, Ptr<Queue> queue);
+ static void SniffEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+
void EnableAscii (Ptr<Node> node, Ptr<NetDevice> device);
- static void RxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
- static void EnqueueEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet);
+ static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
static void AsciiDropEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
- static void AsciiRxEvent (std::ostream *os, std::string path, Ptr<const Packet> packet);
+
ObjectFactory m_queueFactory;
ObjectFactory m_channelFactory;
ObjectFactory m_deviceFactory;
--- a/src/helper/wifi-helper.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/wifi-helper.cc Sat Feb 28 16:25:24 2009 -0800
@@ -37,6 +37,61 @@
namespace ns3 {
+static void PcapSnifferEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
+{
+ writer->WritePacket (packet);
+}
+
+void
+WifiHelper::EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid)
+{
+ std::ostringstream oss;
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Mac/";
+ Config::MatchContainer matches = Config::LookupMatches (oss.str ());
+ if (matches.GetN () == 0)
+ {
+ return;
+ }
+ oss.str ("");
+ oss << filename << "-" << nodeid << "-" << deviceid << ".pcap";
+ Ptr<PcapWriter> pcap = Create<PcapWriter> ();
+ pcap->Open (oss.str ());
+ pcap->WriteEthernetHeader ();
+ oss.str ("");
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Mac/Sniffer";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSnifferEvent, pcap));
+}
+
+void
+WifiHelper::EnablePcap (std::string filename, NetDeviceContainer d)
+{
+ for (NetDeviceContainer::Iterator i = d.Begin (); i != d.End (); ++i)
+ {
+ Ptr<NetDevice> dev = *i;
+ EnablePcap (filename, dev->GetNode ()->GetId (), dev->GetIfIndex ());
+ }
+}
+void
+WifiHelper::EnablePcap (std::string filename, NodeContainer n)
+{
+ NetDeviceContainer devs;
+ for (NodeContainer::Iterator i = n.Begin (); i != n.End (); ++i)
+ {
+ Ptr<Node> node = *i;
+ for (uint32_t j = 0; j < node->GetNDevices (); ++j)
+ {
+ devs.Add (node->GetDevice (j));
+ }
+ }
+ EnablePcap (filename, devs);
+}
+
+void
+WifiHelper::EnablePcapAll (std::string filename)
+{
+ EnablePcap (filename, NodeContainer::GetGlobal ());
+}
+
WifiPhyHelper::~WifiPhyHelper ()
{}
--- a/src/helper/wifi-helper.h Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/wifi-helper.h Sat Feb 28 16:25:24 2009 -0800
@@ -159,6 +159,43 @@
* \returns a device container which contains all the devices created by this method.
*/
NetDeviceContainer Install (const WifiPhyHelper &phy, std::string nodeName) const;
+ /**
+ * \param filename filename prefix to use for pcap files.
+ * \param nodeid the id of the node to generate pcap output for.
+ * \param deviceid the id of the device to generate pcap output for.
+ *
+ * Generate a pcap file which contains the link-level data observed
+ * by the specified deviceid within the specified nodeid. The pcap
+ * data is stored in the file prefix-nodeid-deviceid.pcap.
+ *
+ * This method should be invoked after the network topology has
+ * been fully constructed.
+ */
+ static void EnablePcap (std::string filename, uint32_t nodeid, uint32_t deviceid);
+ /**
+ * \param filename filename prefix to use for pcap files.
+ * \param d container of devices of type ns3::WifiNetDevice
+ *
+ * Enable pcap output on each input device which is of the
+ * ns3::WifiNetDevice type.
+ */
+ static void EnablePcap (std::string filename, NetDeviceContainer d);
+ /**
+ * \param filename filename prefix to use for pcap files.
+ * \param n container of nodes.
+ *
+ * Enable pcap output on each device which is of the
+ * ns3::WifiNetDevice type and which is located in one of the
+ * input nodes.
+ */
+ static void EnablePcap (std::string filename, NodeContainer n);
+ /**
+ * \param filename filename prefix to use for pcap files.
+ *
+ * Enable pcap output on each device which is of the
+ * ns3::WifiNetDevice type
+ */
+ static void EnablePcapAll (std::string filename);
private:
ObjectFactory m_stationManager;
--- a/src/helper/yans-wifi-helper.cc Wed Feb 25 12:27:00 2009 -0500
+++ b/src/helper/yans-wifi-helper.cc Sat Feb 28 16:25:24 2009 -0800
@@ -31,16 +31,7 @@
namespace ns3 {
-static void PcapPhyTxEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet,
- WifiMode mode, WifiPreamble preamble,
- uint8_t txLevel)
-{
- writer->WritePacket (packet);
-}
-
-static void PcapPhyRxEvent (Ptr<PcapWriter> writer,
- Ptr<const Packet> packet, double snr, WifiMode mode,
- enum WifiPreamble preamble)
+static void PcapSnifferEvent (Ptr<PcapWriter> writer, Ptr<const Packet> packet)
{
writer->WritePacket (packet);
}
@@ -229,11 +220,8 @@
pcap->Open (oss.str ());
pcap->WriteWifiHeader ();
oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/Tx";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyTxEvent, pcap));
- oss.str ("");
- oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/State/RxOk";
- Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapPhyRxEvent, pcap));
+ oss << "/NodeList/" << nodeid << "/DeviceList/" << deviceid << "/$ns3::WifiNetDevice/Phy/PromiscSniffer";
+ Config::ConnectWithoutContext (oss.str (), MakeBoundCallback (&PcapSnifferEvent, pcap));
}
void
YansWifiPhyHelper::EnablePcap (std::string filename, NetDeviceContainer d)