comparing with http://code.nsnam.org/ns-3-dev searching for changes changeset: 4245:fec2f830d015 tag: tip user: Craig Dowell date: Sat Feb 28 16:25:24 2009 -0800 summary: trace consistency changes diff -r 7c98934dcccd -r fec2f830d015 examples/wifi-wired-bridging.cc --- 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 @@ int main (int argc, char *argv[]) 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); diff -r 7c98934dcccd -r fec2f830d015 src/devices/csma/csma-net-device.cc --- 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 @@ CsmaNetDevice::GetTypeId (void) PointerValue (), MakePointerAccessor (&CsmaNetDevice::m_receiveErrorModel), MakePointerChecker ()) + + // + // 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 ()) - .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 @@ CsmaNetDevice::CsmaNetDevice () 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 @@ CsmaNetDevice::AddHeader (Ptr p, 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 @@ CsmaNetDevice::ProcessHeader (PtrGetUid ()); + 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 @@ CsmaNetDevice::TransmitStart () } else { + m_phyTxBackoffTrace (m_currentPkt); + m_backoff.IncrNumRetries (); Time backoffTime = m_backoff.GetBackoffTime (); @@ -464,28 +528,29 @@ CsmaNetDevice::TransmitStart () // // 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) @@ -493,19 +558,17 @@ 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 @@ CsmaNetDevice::TransmitAbort (void) { 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 @@ CsmaNetDevice::TransmitCompleteEvent (vo 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 @@ CsmaNetDevice::TransmitReadyEvent (void) 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 @@ CsmaNetDevice::TransmitReadyEvent (void) { 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 @@ CsmaNetDevice::Receive (Ptr pack 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 @@ CsmaNetDevice::Receive (Ptr pack 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 @@ CsmaNetDevice::Receive (Ptr pack 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 @@ CsmaNetDevice::Receive (Ptr pack 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 pac CsmaNetDevice::SendFrom (Ptr 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 @@ CsmaNetDevice::SendFrom (Ptr pac // if (IsSendEnabled () == false) { + m_macTxDropTrace (packet); return false; } @@ -910,11 +996,15 @@ CsmaNetDevice::SendFrom (Ptr pac 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 @@ CsmaNetDevice::SendFrom (Ptr pac // 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 (); } } diff -r 7c98934dcccd -r fec2f830d015 src/devices/csma/csma-net-device.h --- 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 @@ private: Ptr 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 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 > m_rxTrace; + TracedCallback > m_macTxTrace; /** - * The trace source for the packet drop events that the device can - * fire. + * 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 > m_dropTrace; + TracedCallback > 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 > m_macRxTrace; + + /** + * The trace source fired when a packet starts the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxStartTrace; + + /** + * The trace source fired when a packet ends the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxTrace; + + /** + * The trace source fired when the phy layer drops a packet as it tries + * to transmit it. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxDropTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxStartTrace; + + /** + * The trace source fired when the phy layer drops a packet it has received. + * + * \see class CallBackTraceSource + */ + TracedCallback > 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 > 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 > 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 > m_promiscSnifferTrace; /** * The Node to which this device is attached. @@ -671,6 +778,7 @@ private: * 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. */ diff -r 7c98934dcccd -r fec2f830d015 src/devices/emu/emu-net-device.cc --- 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 #include @@ -82,14 +83,72 @@ EmuNetDevice::GetTypeId (void) 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 ()) - .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 @@ EmuNetDevice::ForwardUp (uint8_t *buf, u { 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 @@ EmuNetDevice::ForwardUp (uint8_t *buf, u Ptr 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 @@ EmuNetDevice::ForwardUp (uint8_t *buf, u 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 pack EmuNetDevice::SendFrom (Ptr 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 @@ EmuNetDevice::SendFrom (Ptr pack 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 @@ EmuNetDevice::SendFrom (Ptr pack 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 @@ EmuNetDevice::SendFrom (Ptr pack NS_LOG_LOGIC ("calling sendto"); + m_phyTxStartTrace (packet); + int32_t rc; rc = sendto (m_sock, packet->PeekData (), packet->GetSize (), 0, reinterpret_cast (&ll), sizeof (ll)); + NS_LOG_LOGIC ("sendto returns " << rc); - NS_LOG_LOGIC ("sendto returns " << rc); + m_phyTxTrace (packet); return rc == -1 ? false : true; } diff -r 7c98934dcccd -r fec2f830d015 src/devices/emu/emu-net-device.h --- 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 @@ private: Ptr 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 + * \see class CallBackTraceSource */ - TracedCallback > m_rxTrace; + TracedCallback > m_macTxTrace; /** - * The trace source for the packet drop events that the device can - * fire. + * 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 + * \see class CallBackTraceSource */ - TracedCallback > m_dropTrace; + TracedCallback > 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 > m_macRxTrace; + + /** + * The trace source fired when a packet starts the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxStartTrace; + + /** + * The trace source fired when a packet ends the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxTrace; + + /** + * The trace source fired when the phy layer drops a packet as it tries + * to transmit it. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxDropTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxTrace; + + /** + * The trace source fired when a packet starts the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxStartTrace; + + /** + * The trace source fired when the phy layer drops a packet it has received. + * + * \see class CallBackTraceSource + */ + TracedCallback > 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 > 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 > m_promiscSnifferTrace; /** * Time to start spinning up the device diff -r 7c98934dcccd -r fec2f830d015 src/devices/point-to-point/point-to-point-channel.h --- 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 @@ public: void Attach (Ptr 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 p, Ptr src, - Time txTime); + bool TransmitStart (Ptr p, Ptr src, Time txTime); /** * \brief Get number of devices on this channel diff -r 7c98934dcccd -r fec2f830d015 src/devices/point-to-point/point-to-point-net-device.cc --- 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 @@ PointToPointNetDevice::GetTypeId (void) PointerValue (), MakePointerAccessor (&PointToPointNetDevice::m_receiveErrorModel), MakePointerChecker ()) - .AddAttribute ("TxQueue", - "A queue to use as the transmit queue in the device.", - PointerValue (), - MakePointerAccessor (&PointToPointNetDevice::m_queue), - MakePointerChecker ()) .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 ()) + + // + // 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 @@ PointToPointNetDevice::PointToPointNetDe 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 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 @@ PointToPointNetDevice::DoDispose() m_node = 0; m_channel = 0; m_receiveErrorModel = 0; + m_currentPkt = 0; NetDevice::DoDispose (); } @@ -157,48 +202,63 @@ PointToPointNetDevice::TransmitStart (Pt { 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 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 @@ PointToPointNetDevice::Attach (PtrAttach(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 @@ PointToPointNetDevice::Receive (PtrIsCorrupt (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 pktCopy = packet->Copy (); + m_promiscCallback (this, pktCopy, protocol, GetRemote (), GetAddress (), NetDevice::PACKET_HOST); } + + m_rxCallback (this, packet, protocol, GetRemote ()); } } @@ -406,33 +478,37 @@ PointToPointNetDevice::Send( 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 diff -r 7c98934dcccd -r fec2f830d015 src/devices/point-to-point/point-to-point-net-device.h --- 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,25 +388,126 @@ private: Ptr m_queue; /** - * The trace source for the packet reception events that the device can - * fire. - * - * @see class CallBackTraceSource - */ - TracedCallback > m_rxTrace; - - /** - * The trace source for the packet drop events that the device can - * fire. - * - * @see class CallBackTraceSource - */ - TracedCallback > m_dropTrace; - - /** * Error model for receive packet events */ Ptr 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 > 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 > 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 > m_macRxTrace; + + /** + * The trace source fired when a packet starts the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > 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 > m_phyTxTrace; + + /** + * The trace source fired when the phy layer drops a packet before it tries + * to transmit it. + * + * \see class CallBackTraceSource + */ + TracedCallback > 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 > m_phyRxStartTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > 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 > 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 > 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 > m_promiscSnifferTrace; Ptr m_node; Mac48Address m_address; @@ -435,6 +536,8 @@ private: * Ethernet. */ uint32_t m_mtu; + + Ptr m_currentPkt; }; } // namespace ns3 diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/adhoc-wifi-mac.cc --- 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 @@ AdhocWifiMac::Enqueue (Ptr destination->RecordDisassociated (); } + m_macTxTrace (packet); m_dca->Queue (packet, hdr); } bool @@ -246,6 +248,7 @@ AdhocWifiMac::ForwardUp (Ptr pac AdhocWifiMac::ForwardUp (Ptr packet, WifiMacHeader const *hdr) { NS_LOG_DEBUG ("received size="<GetSize ()<<", from="<GetAddr2 ()); + m_macRxTrace (packet); m_upCallback (packet, hdr->GetAddr2 (), hdr->GetAddr1 ()); } Ptr diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/mac-low.cc --- 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 @@ MacLow::ForwardDown (Ptr p */ 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 diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/nqap-wifi-mac.cc --- 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 pack NqapWifiMac::ForwardUp (Ptr packet, Mac48Address from, Mac48Address to) { NS_LOG_FUNCTION (this << packet << from); + m_macRxTrace (packet); m_upCallback (packet, from, to); } + void NqapWifiMac::ForwardDown (Ptr packet, Mac48Address from, Mac48Address to) { @@ -298,6 +301,8 @@ NqapWifiMac::ForwardDown (PtrQueue (packet, hdr); } void @@ -472,11 +477,13 @@ NqapWifiMac::Receive (Ptr packet { // 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 ()) diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/nqsta-wifi-mac.cc --- 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 pac NqstaWifiMac::ForwardUp (Ptr 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 void NqstaWifiMac::Enqueue (Ptr 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 packet, Mac48Address to) { NS_LOG_FUNCTION (this << packet << to); if (!IsAssociated ()) { + m_macTxDropTrace (packet); TryToEnsureAssociated (); return; } @@ -476,12 +480,19 @@ NqstaWifiMac::Enqueue (Ptr 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 @@ NqstaWifiMac::Receive (Ptr packe !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 @@ NqstaWifiMac::Receive (Ptr packe /* this is a frame aimed at an AP. * so we can safely ignore it. */ + m_macRxDropTrace (packet); } else if (hdr->IsBeacon ()) { diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/wifi-mac.cc --- 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 @@ WifiMac::GetTypeId (void) 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 @@ WifiMac::GetMaxMsduSize (void) const return m_maxMsduSize; } +void +WifiMac::SnifferTrace (Ptr packet) +{ + m_snifferTrace (packet); +} + } // namespace ns3 diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/wifi-mac.h --- 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 @@ public: * \param linkDown the callback to invoke when the link becomes down. */ virtual void SetLinkDownCallback (Callback linkDown) = 0; + + /* + * 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 packet); + private: - - - static Time GetDefaultMaxPropagationDelay (void); static Time GetDefaultSlot (void); static Time GetDefaultSifs (void); @@ -189,6 +193,61 @@ private: 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 > 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 > 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 > 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 > 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 > m_snifferTrace; }; } // namespace ns3 diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/wifi-net-device.cc --- 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 @@ WifiNetDevice::GetTypeId (void) MakePointerAccessor (&WifiNetDevice::SetRemoteStationManager, &WifiNetDevice::GetRemoteStationManager), MakePointerChecker ()) - .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 @@ WifiNetDevice::IsBridge (void) const return false; } bool -WifiNetDevice::Send(Ptr packet, const Address& dest, uint16_t protocolNumber) +WifiNetDevice::Send (Ptr 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 @@ WifiNetDevice::ForwardUp (Ptr pa { 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 @@ WifiNetDevice::SendFrom (Ptr pac 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 @@ WifiNetDevice::SupportsSendFrom (void) c return m_mac->SupportsSendFrom (); } +void +WifiNetDevice::SniffPacket (Ptr packet, Mac48Address to, Mac48Address from, uint16_t type) +{ + Ptr 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 diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/wifi-net-device.h --- 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 @@ private: Ptr m_stationManager; NetDevice::ReceiveCallback m_forwardUp; NetDevice::PromiscReceiveCallback m_promiscRx; + TracedCallback, Mac48Address> m_rxLogger; TracedCallback, 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 packet, Mac48Address to, Mac48Address from, uint16_t type); + uint32_t m_ifIndex; std::string m_name; bool m_linkUp; diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/wifi-phy.cc --- 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 @@ WifiPhy::GetTypeId (void) { static TypeId tid = TypeId ("ns3::WifiPhy") .SetParent () + .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; } diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/wifi-phy.h --- 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 @@ public: * unless they have received a cca busy report. */ virtual void NotifyTxStart (Time duration) = 0; + /** * \param duration the expected busy duration. * @@ -171,6 +173,13 @@ public: * transmission power is calculated as txPowerMin + txPowerLevel * (txPowerMax - txPowerMin) / nTxLevels */ virtual void SendPacket (Ptr 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 packet) = 0; /** * \param listener the new listener @@ -250,6 +259,74 @@ public: 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 > m_phyTxStartTrace; + + /** + * The trace source fired when a packet ends the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxTrace; + + /** + * The trace source fired when the phy layer drops a packet as it tries + * to transmit it. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxDropTrace; + + /** + * The trace source fired when a packet starts the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxStartTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxTrace; + + /** + * The trace source fired when the phy layer drops a packet it has received. + * + * \see class CallBackTraceSource + */ + TracedCallback > 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 > m_promiscSnifferTrace; }; } // namespace ns3 diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/yans-wifi-phy.cc --- 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 NS_LOG_COMPONENT_DEFINE ("YansWifiPhy"); @@ -322,6 +323,7 @@ YansWifiPhy::StartReceivePacket (Ptr Simulator::Now () + m_state->GetDelayUntilIdle ()) { // that packet will be noise _after_ the reception of the @@ -332,6 +334,7 @@ YansWifiPhy::StartReceivePacket (Ptr Simulator::Now () + m_state->GetDelayUntilIdle ()) { // that packet will be noise _after_ the transmission of the @@ -347,6 +350,7 @@ YansWifiPhy::StartReceivePacket (PtrSwitchToSync (rxDuration); NS_ASSERT (m_endSyncEvent.IsExpired ()); + m_phyRxStartTrace (packet); m_endSyncEvent = Simulator::Schedule (rxDuration, &YansWifiPhy::EndSync, this, packet, event); @@ -355,6 +359,7 @@ YansWifiPhy::StartReceivePacket (PtrSwitchMaybeToCcaBusy (delayUntilCcaEnd); } } + void YansWifiPhy::SendPacket (Ptr packet, WifiMode txMode, WifiPreamble preamble, uint8_t txPower) { @@ -391,8 +397,16 @@ YansWifiPhy::SendPacket (PtrSwitchToTx (txDuration, packet, txMode, preamble, txPower); m_channel->Send (this, packet, GetPowerDbm (txPower) + m_txGainDb, txMode, preamble); +} + +void +YansWifiPhy::SendDone (Ptr packet) +{ + m_phyTxTrace (packet); } uint32_t @@ -550,11 +564,14 @@ YansWifiPhy::EndSync (Ptr packet 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); } } diff -r 7c98934dcccd -r fec2f830d015 src/devices/wifi/yans-wifi-phy.h --- 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 @@ public: virtual void SetReceiveOkCallback (WifiPhy::SyncOkCallback callback); virtual void SetReceiveErrorCallback (WifiPhy::SyncErrorCallback callback); virtual void SendPacket (Ptr packet, WifiMode mode, enum WifiPreamble preamble, uint8_t txPowerLevel); + virtual void SendDone (Ptr packet); virtual void RegisterListener (WifiPhyListener *listener); virtual bool IsStateCcaBusy (void); virtual bool IsStateIdle (void); @@ -134,6 +135,54 @@ private: void EndSync (Ptr packet, Ptr event); private: + /** + * The trace source fired when a packet starts the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxStartTrace; + + /** + * The trace source fired when a packet ends the transmission process on + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxTrace; + + /** + * The trace source fired when the phy layer drops a packet as it tries + * to transmit it. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyTxDropTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxTrace; + + /** + * The trace source fired when a packet ends the reception process from + * the medium. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxStartTrace; + + /** + * The trace source fired when the phy layer drops a packet it has received. + * + * \see class CallBackTraceSource + */ + TracedCallback > m_phyRxDropTrace; + +private: double m_edThresholdW; double m_ccaMode1ThresholdW; double m_txGainDb; @@ -151,6 +200,7 @@ private: WifiPhyStandard m_standard; Ptr m_state; InterferenceHelper m_interference; + }; } // namespace ns3 diff -r 7c98934dcccd -r fec2f830d015 src/helper/csma-helper.cc --- 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 @@ CsmaHelper::SetDeviceParameter (std::str { SetDeviceAttribute (n1, v1); } + void CsmaHelper::SetChannelParameter (std::string n1, const AttributeValue &v1) { @@ -91,12 +92,10 @@ CsmaHelper::EnablePcap (std::string file 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 @@ CsmaHelper::EnableAscii (std::ostream &o { 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 @@ CsmaHelper::InstallStar (std::string hub } void -CsmaHelper::EnqueueEvent (Ptr writer, Ptr packet) +CsmaHelper::SniffEvent (Ptr writer, Ptr packet) { writer->WritePacket (packet); } -void -CsmaHelper::RxEvent (Ptr writer, Ptr packet) -{ - writer->WritePacket (packet); -} + void CsmaHelper::AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr packet) { diff -r 7c98934dcccd -r fec2f830d015 src/helper/csma-helper.h --- 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: private: Ptr InstallPriv (Ptr node, Ptr channel) const; - static void RxEvent (Ptr writer, Ptr packet); - static void EnqueueEvent (Ptr writer, Ptr packet); + static void SniffEvent (Ptr writer, Ptr packet); + + static void AsciiRxEvent (std::ostream *os, std::string path, Ptr packet); static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr packet); static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr packet); static void AsciiDropEvent (std::ostream *os, std::string path, Ptr packet); - static void AsciiRxEvent (std::ostream *os, std::string path, Ptr packet); + ObjectFactory m_queueFactory; ObjectFactory m_deviceFactory; ObjectFactory m_channelFactory; diff -r 7c98934dcccd -r fec2f830d015 src/helper/emu-helper.cc --- 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 @@ EmuHelper::EnablePcap ( 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 @@ EmuHelper::EnableAscii (std::ostream &os 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 @@ EmuHelper::InstallPriv (Ptr node) } void -EmuHelper::EnqueueEvent (Ptr writer, Ptr packet) -{ - NS_LOG_FUNCTION (writer << packet); - writer->WritePacket (packet); -} - - void -EmuHelper::RxEvent (Ptr writer, Ptr packet) +EmuHelper::SniffEvent (Ptr writer, Ptr packet) { NS_LOG_FUNCTION (writer << packet); writer->WritePacket (packet); diff -r 7c98934dcccd -r fec2f830d015 src/helper/emu-helper.h --- 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 @@ public: private: Ptr InstallPriv (Ptr node) const; - static void RxEvent (Ptr writer, Ptr packet); - static void EnqueueEvent (Ptr writer, Ptr packet); - static void AsciiEnqueueEvent (std::ostream *os, std::string path, - Ptr packet); - static void AsciiDequeueEvent (std::ostream *os, std::string path, - Ptr packet); - static void AsciiDropEvent (std::ostream *os, std::string path, - Ptr packet); - static void AsciiRxEvent (std::ostream *os, std::string path, - Ptr packet); + static void SniffEvent (Ptr writer, Ptr packet); + + static void AsciiRxEvent (std::ostream *os, std::string path, Ptr packet); + static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr packet); + static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr packet); + static void AsciiDropEvent (std::ostream *os, std::string path, Ptr packet); ObjectFactory m_queueFactory; ObjectFactory m_deviceFactory; diff -r 7c98934dcccd -r fec2f830d015 src/helper/point-to-point-helper.cc --- 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 @@ PointToPointHelper::EnablePcap (std::str 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 @@ PointToPointHelper::EnableAscii (std::os { 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 @@ PointToPointHelper::InstallStar (std::st } void -PointToPointHelper::EnqueueEvent (Ptr writer, Ptr packet) -{ - writer->WritePacket (packet); -} -void -PointToPointHelper::RxEvent (Ptr writer, Ptr packet) +PointToPointHelper::SniffEvent (Ptr writer, Ptr packet) { writer->WritePacket (packet); } diff -r 7c98934dcccd -r fec2f830d015 src/helper/point-to-point-helper.h --- 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 @@ public: private: void EnablePcap (Ptr node, Ptr device, Ptr queue); + static void SniffEvent (Ptr writer, Ptr packet); + void EnableAscii (Ptr node, Ptr device); - static void RxEvent (Ptr writer, Ptr packet); - static void EnqueueEvent (Ptr writer, Ptr packet); + static void AsciiRxEvent (std::ostream *os, std::string path, Ptr packet); static void AsciiEnqueueEvent (std::ostream *os, std::string path, Ptr packet); static void AsciiDequeueEvent (std::ostream *os, std::string path, Ptr packet); static void AsciiDropEvent (std::ostream *os, std::string path, Ptr packet); - static void AsciiRxEvent (std::ostream *os, std::string path, Ptr packet); + ObjectFactory m_queueFactory; ObjectFactory m_channelFactory; ObjectFactory m_deviceFactory; diff -r 7c98934dcccd -r fec2f830d015 src/helper/wifi-helper.cc --- 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 @@ -36,6 +36,61 @@ NS_LOG_COMPONENT_DEFINE ("WifiHelper"); NS_LOG_COMPONENT_DEFINE ("WifiHelper"); namespace ns3 { + +static void PcapSnifferEvent (Ptr writer, Ptr 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 pcap = Create (); + 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 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 = *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 () {} diff -r 7c98934dcccd -r fec2f830d015 src/helper/wifi-helper.h --- 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 @@ public: * \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; diff -r 7c98934dcccd -r fec2f830d015 src/helper/yans-wifi-helper.cc --- 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 writer, Ptr packet, - WifiMode mode, WifiPreamble preamble, - uint8_t txLevel) -{ - writer->WritePacket (packet); -} - -static void PcapPhyRxEvent (Ptr writer, - Ptr packet, double snr, WifiMode mode, - enum WifiPreamble preamble) +static void PcapSnifferEvent (Ptr writer, Ptr packet) { writer->WritePacket (packet); } @@ -229,11 +220,8 @@ YansWifiPhyHelper::EnablePcap (std::stri 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)