diff --git a/src/devices/csma-cd/csma-cd-net-device.cc b/src/devices/csma-cd/csma-cd-net-device.cc index ea4855f05..3d2670fa4 100644 --- a/src/devices/csma-cd/csma-cd-net-device.cc +++ b/src/devices/csma-cd/csma-cd-net-device.cc @@ -457,26 +457,62 @@ CsmaCdNetDevice::AddQueue (Ptr q) } void -CsmaCdNetDevice::Receive (Packet& p) +CsmaCdNetDevice::Receive (const Packet& packet) { + EthernetHeader header (false); + EthernetTrailer trailer; + Eui48Address broadcast; + Eui48Address destination; + Packet p = packet; + NS_DEBUG ("CsmaCdNetDevice::Receive UID is (" << p.GetUid() << ")"); // Only receive if send side of net device is enabled if (!IsReceiveEnabled()) - return; - - uint16_t param = 0; - Packet packet = p; - - if (ProcessHeader(packet, param)) { - m_rxTrace (packet); - ForwardUp (packet, param); - } - else - { - m_dropTrace (packet); + goto drop; } + + if (m_encapMode == RAW) + { + ForwardUp (packet, 0, GetBroadcast ()); + goto drop; + } + p.RemoveTrailer(trailer); + trailer.CheckFcs(p); + p.RemoveHeader(header); + + broadcast = Eui48Address::ConvertFrom (GetBroadcast ()); + destination = Eui48Address::ConvertFrom (GetAddress ()); + if ((header.GetDestination() != broadcast) && + (header.GetDestination() != destination)) + { + // not for us. + goto drop; + } + + uint16_t protocol; + switch (m_encapMode) + { + case ETHERNET_V1: + case IP_ARP: + protocol = header.GetLengthType(); + break; + case LLC: { + LlcSnapHeader llc; + p.RemoveHeader (llc); + protocol = llc.GetType (); + } break; + case RAW: + NS_ASSERT (false); + break; + } + + m_rxTrace (p); + ForwardUp (p, protocol, header.GetSource ().ConvertTo ()); + return; + drop: + m_dropTrace (p); } Ptr diff --git a/src/devices/csma-cd/csma-cd-net-device.h b/src/devices/csma-cd/csma-cd-net-device.h index eb116f3e3..6b1341b89 100644 --- a/src/devices/csma-cd/csma-cd-net-device.h +++ b/src/devices/csma-cd/csma-cd-net-device.h @@ -173,7 +173,7 @@ enum CsmaCdEncapsulationMode { * @see CsmaCdChannel * \param p a reference to the received packet */ - void Receive (Packet& p); + void Receive (const Packet& p); bool IsSendEnabled (void); bool IsReceiveEnabled (void); diff --git a/src/devices/point-to-point/point-to-point-net-device.cc b/src/devices/point-to-point/point-to-point-net-device.cc index 4b4157b26..b450421f5 100644 --- a/src/devices/point-to-point/point-to-point-net-device.cc +++ b/src/devices/point-to-point/point-to-point-net-device.cc @@ -220,12 +220,12 @@ void PointToPointNetDevice::AddQueue (Ptr q) void PointToPointNetDevice::Receive (Packet& p) { NS_DEBUG ("PointToPointNetDevice::Receive (" << &p << ")"); - uint16_t param = 0; + uint16_t protocol = 0; Packet packet = p; - ProcessHeader(packet, param); + ProcessHeader(packet, protocol); m_rxTrace (packet); - ForwardUp (packet, param); + ForwardUp (packet, protocol, GetBroadcast ()); } Ptr PointToPointNetDevice::GetQueue(void) const diff --git a/src/internet-node/arp-l3-protocol.cc b/src/internet-node/arp-l3-protocol.cc index a18b2ab5d..100f1df88 100644 --- a/src/internet-node/arp-l3-protocol.cc +++ b/src/internet-node/arp-l3-protocol.cc @@ -84,7 +84,7 @@ ArpL3Protocol::FindCache (Ptr device) } void -ArpL3Protocol::Receive(const Packet& p, uint16_t protocol, Ptr device) +ArpL3Protocol::Receive(Ptr device, const Packet& p, uint16_t protocol, const Address &from) { ArpCache *cache = FindCache (device); ArpHeader arp; diff --git a/src/internet-node/arp-l3-protocol.h b/src/internet-node/arp-l3-protocol.h index d3ae7441d..a2ea8227e 100644 --- a/src/internet-node/arp-l3-protocol.h +++ b/src/internet-node/arp-l3-protocol.h @@ -53,7 +53,7 @@ public: /** * \brief Recieve a packet */ - void Receive(const Packet& p, uint16_t protocol, Ptr device); + void Receive(Ptr device, const Packet& p, uint16_t protocol, const Address &from); /** * \brief Perform an ARP lookup * \param p diff --git a/src/internet-node/ipv4-l3-protocol.cc b/src/internet-node/ipv4-l3-protocol.cc index eaf2734a3..31c3935f5 100644 --- a/src/internet-node/ipv4-l3-protocol.cc +++ b/src/internet-node/ipv4-l3-protocol.cc @@ -241,7 +241,7 @@ Ipv4L3Protocol::FindInterfaceForDevice (Ptr device) } void -Ipv4L3Protocol::Receive(const Packet& p, uint16_t protocol, Ptr device) +Ipv4L3Protocol::Receive( Ptr device, const Packet& p, uint16_t protocol, const Address &from) { uint32_t index = 0; for (Ipv4InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++) diff --git a/src/internet-node/ipv4-l3-protocol.h b/src/internet-node/ipv4-l3-protocol.h index 200a001d4..d9abe535a 100644 --- a/src/internet-node/ipv4-l3-protocol.h +++ b/src/internet-node/ipv4-l3-protocol.h @@ -95,7 +95,7 @@ public: * - implement a per-NetDevice ARP cache * - send back arp replies on the right device */ - void Receive(const Packet& p, uint16_t protocol, Ptr device); + void Receive( Ptr device, const Packet& p, uint16_t protocol, const Address &from); /** * \param packet packet to send diff --git a/src/internet-node/ipv4-loopback-interface.cc b/src/internet-node/ipv4-loopback-interface.cc index 320a32ce4..47ddc9ee2 100644 --- a/src/internet-node/ipv4-loopback-interface.cc +++ b/src/internet-node/ipv4-loopback-interface.cc @@ -44,7 +44,7 @@ void Ipv4LoopbackInterface::SendTo (Packet packet, Ipv4Address dest) { Ptr ipv4 = m_node->QueryInterface (Ipv4L3Protocol::iid); - ipv4->Receive (packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()); + ipv4->Receive (GetDevice (), packet, Ipv4L3Protocol::PROT_NUMBER, GetDevice ()->GetAddress ()); } }//namespace ns3 diff --git a/src/internet-node/udp-socket.cc b/src/internet-node/udp-socket.cc index bdbc08887..61d32499e 100644 --- a/src/internet-node/udp-socket.cc +++ b/src/internet-node/udp-socket.cc @@ -136,20 +136,21 @@ UdpSocket::ShutdownRecv (void) return 0; } -void -UdpSocket::DoClose(ns3::Callback > closeCompleted) +int +UdpSocket::DoClose(Callback > closeCompleted) { // XXX: we should set the close state and check it in all API methods. if (!closeCompleted.IsNull ()) { closeCompleted (this); } + return 0; } -void +int UdpSocket::DoConnect(const Address & address, - ns3::Callback > connectionSucceeded, - ns3::Callback > connectionFailed, - ns3::Callback > halfClose) + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose) { InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); m_defaultAddress = transport.GetIpv4 (); @@ -159,11 +160,12 @@ UdpSocket::DoConnect(const Address & address, connectionSucceeded (this); } m_connected = true; + return 0; } int -UdpSocket::DoAccept(ns3::Callback, const Address&> connectionRequest, - ns3::Callback, const Address&> newConnectionCreated, - ns3::Callback > closeRequested) +UdpSocket::DoAccept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, + Callback > closeRequested) { // calling accept on a udp socket is a programming error. m_errno = ERROR_OPNOTSUPP; @@ -172,7 +174,7 @@ UdpSocket::DoAccept(ns3::Callback, const Address&> connectionR int UdpSocket::DoSend (const uint8_t* buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent) + Callback, uint32_t> dataSent) { if (!m_connected) { @@ -192,7 +194,7 @@ UdpSocket::DoSend (const uint8_t* buffer, } int UdpSocket::DoSendPacketTo (const Packet &p, const Address &address, - ns3::Callback, uint32_t> dataSent) + Callback, uint32_t> dataSent) { InetSocketAddress transport = InetSocketAddress::ConvertFrom (address); Ipv4Address ipv4 = transport.GetIpv4 (); @@ -201,7 +203,7 @@ UdpSocket::DoSendPacketTo (const Packet &p, const Address &address, } int UdpSocket::DoSendPacketTo (const Packet &p, Ipv4Address ipv4, uint16_t port, - ns3::Callback, uint32_t> dataSent) + Callback, uint32_t> dataSent) { if (m_endPoint == 0) { @@ -229,7 +231,7 @@ int UdpSocket::DoSendTo(const Address &address, const uint8_t *buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent) + Callback, uint32_t> dataSent) { if (m_connected) { @@ -251,12 +253,12 @@ UdpSocket::DoSendTo(const Address &address, return DoSendPacketTo (p, ipv4, port, dataSent); } void -UdpSocket::DoRecv(ns3::Callback, const uint8_t*, uint32_t,const Address&> callback) +UdpSocket::DoRecv(Callback, const uint8_t*, uint32_t,const Address&> callback) { m_rxCallback = callback; } void -UdpSocket::DoRecvDummy(ns3::Callback, uint32_t,const Address&> callback) +UdpSocket::DoRecvDummy(Callback, uint32_t,const Address&> callback) { m_dummyRxCallback = callback; } diff --git a/src/internet-node/udp-socket.h b/src/internet-node/udp-socket.h index 82d3cd6a3..8778aff84 100644 --- a/src/internet-node/udp-socket.h +++ b/src/internet-node/udp-socket.h @@ -51,23 +51,23 @@ public: virtual int ShutdownRecv (void); private: - virtual void DoClose(ns3::Callback > closeCompleted); - virtual void DoConnect(const Address & address, - ns3::Callback > connectionSucceeded, - ns3::Callback > connectionFailed, - ns3::Callback > halfClose); - virtual int DoAccept(ns3::Callback, const Address&> connectionRequest, - ns3::Callback, const Address&> newConnectionCreated, - ns3::Callback > closeRequested); + virtual int DoClose(Callback > closeCompleted); + virtual int DoConnect(const Address & address, + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose); + virtual int DoAccept(Callback, const Address&> connectionRequest, + Callback, const Address&> newConnectionCreated, + Callback > closeRequested); virtual int DoSend (const uint8_t* buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent); + Callback, uint32_t> dataSent); virtual int DoSendTo(const Address &address, const uint8_t *buffer, uint32_t size, - ns3::Callback, uint32_t> dataSent); - virtual void DoRecv(ns3::Callback, const uint8_t*, uint32_t,const Address&>); - virtual void DoRecvDummy(ns3::Callback, uint32_t,const Address&>); + Callback, uint32_t> dataSent); + virtual void DoRecv(Callback, const uint8_t*, uint32_t,const Address&>); + virtual void DoRecvDummy(Callback, uint32_t,const Address&>); private: friend class Udp; @@ -76,9 +76,9 @@ private: void ForwardUp (const Packet &p, Ipv4Address ipv4, uint16_t port); void Destroy (void); int DoSendPacketTo (const Packet &p, const Address &daddr, - ns3::Callback, uint32_t> dataSent); + Callback, uint32_t> dataSent); int DoSendPacketTo (const Packet &p, Ipv4Address daddr, uint16_t dport, - ns3::Callback, uint32_t> dataSent); + Callback, uint32_t> dataSent); Ipv4EndPoint *m_endPoint; Ptr m_node; diff --git a/src/node/net-device.cc b/src/node/net-device.cc index a7ef06c7a..4fa2e8d51 100644 --- a/src/node/net-device.cc +++ b/src/node/net-device.cc @@ -197,18 +197,19 @@ NetDevice::GetChannel (void) const // Receive packets from below bool -NetDevice::ForwardUp(Packet& p, uint32_t param) +NetDevice::ForwardUp(const Packet& p, uint32_t param, const Address &from) { bool retval = false; - Packet packet = p; - NS_DEBUG ("NetDevice::ForwardUp: UID is " << packet.GetUid() + NS_DEBUG ("NetDevice::ForwardUp: UID is " << p.GetUid() << " device is: " << GetName()); if (!m_receiveCallback.IsNull ()) { - retval = m_receiveCallback (this, packet, param); - } else { + retval = m_receiveCallback (this, p, param, from); + } + else + { NS_DEBUG ("NetDevice::Receive call back is NULL"); } @@ -248,7 +249,7 @@ NetDevice::NeedsArp (void) const } void -NetDevice::SetReceiveCallback (Callback,const Packet &,uint16_t> cb) +NetDevice::SetReceiveCallback (ReceiveCallback cb) { m_receiveCallback = cb; } diff --git a/src/node/net-device.h b/src/node/net-device.h index 88109a894..dd590f39c 100644 --- a/src/node/net-device.h +++ b/src/node/net-device.h @@ -177,11 +177,24 @@ public: */ bool NeedsArp (void) const; + /** + * \param device a pointer to the net device which is calling this callback + * \param packet the packet received + * \param protocol the 16 bit protocol number associated with this packet. + * This protocol number is expected to be the same protocol number + * given to the Send method by the user on the sender side. + * \param address the address of the sender + * \returns true if the callback could handle the packet successfully, false + * otherwise. + */ + typedef Callback,const Packet &,uint16_t,const Address &> ReceiveCallback; + /** * \param cb callback to invoke whenever a packet has been received and must * be forwarded to the higher layers. + * */ - void SetReceiveCallback (Callback,const Packet &,uint16_t> cb); + void SetReceiveCallback (ReceiveCallback cb); protected: /** @@ -230,6 +243,7 @@ public: * \param p packet sent from below up to Network Device * \param param Extra parameter extracted from header and needed by * some protocols + * \param address the address of the sender of this packet. * \returns true if the packet was forwarded successfully, * false otherwise. * @@ -237,7 +251,7 @@ public: * forwards it to the higher layers by calling this method * which is responsible for passing it up to the Rx callback. */ - bool ForwardUp (Packet& p, uint32_t param); + bool ForwardUp (const Packet& p, uint32_t param, const Address &address); /** @@ -248,8 +262,6 @@ public: */ virtual void DoDispose (void); - Callback,const Packet &,uint16_t> m_receiveCallback; - private: /** * \param p packet to send @@ -297,6 +309,7 @@ public: bool m_isMulticast; bool m_isPointToPoint; Callback m_linkChangeCallback; + ReceiveCallback m_receiveCallback; }; }; // namespace ns3 diff --git a/src/node/node.cc b/src/node/node.cc index 5c3d7c6f3..7aaa0216a 100644 --- a/src/node/node.cc +++ b/src/node/node.cc @@ -22,6 +22,7 @@ #include "node-list.h" #include "net-device.h" #include "application.h" +#include "packet-socket-factory.h" #include "ns3/simulator.h" #include "ns3/empty-trace-resolver.h" @@ -33,16 +34,23 @@ Node::Node() : m_id(0), m_sid(0) { - SetInterfaceId (Node::iid); - m_id = NodeList::Add (this); + Construct (); } Node::Node(uint32_t sid) : m_id(0), m_sid(sid) { + Construct (); +} + +void +Node::Construct (void) +{ SetInterfaceId (Node::iid); m_id = NodeList::Add (this); + Ptr socketFactory = Create (); + AddInterface (socketFactory); } Node::~Node () @@ -69,8 +77,8 @@ Node::GetSystemId (void) const uint32_t Node::AddDevice (Ptr device) { - uint32_t index = m_devices.size (); m_devices.push_back (device); + uint32_t index = m_devices.size (); device->SetIfIndex(index); device->SetReceiveCallback (MakeCallback (&Node::ReceiveFromDevice, this)); NotifyDeviceAdded (device); @@ -79,7 +87,14 @@ Node::AddDevice (Ptr device) Ptr Node::GetDevice (uint32_t index) const { - return m_devices[index]; + if (index == 0) + { + return 0; + } + else + { + return m_devices[index - 1]; + } } uint32_t Node::GetNDevices (void) const @@ -143,24 +158,11 @@ Node::RegisterProtocolHandler (ProtocolHandler handler, { struct Node::ProtocolHandlerEntry entry; entry.handler = handler; - entry.isSpecificProtocol = true; entry.protocol = protocolType; entry.device = device; m_handlers.push_back (entry); } -void -Node::RegisterProtocolHandler (ProtocolHandler handler, - Ptr device) -{ - struct Node::ProtocolHandlerEntry entry; - entry.handler = handler; - entry.isSpecificProtocol = false; - entry.protocol = 0; - entry.device = device; - m_handlers.push_back (entry); -} - void Node::UnregisterProtocolHandler (ProtocolHandler handler) { @@ -176,7 +178,8 @@ Node::UnregisterProtocolHandler (ProtocolHandler handler) } bool -Node::ReceiveFromDevice (Ptr device, const Packet &packet, uint16_t protocol) +Node::ReceiveFromDevice (Ptr device, const Packet &packet, + uint16_t protocol, const Address &from) { bool found = false; for (ProtocolHandlerList::iterator i = m_handlers.begin (); @@ -185,10 +188,10 @@ Node::ReceiveFromDevice (Ptr device, const Packet &packet, uint16_t p if (i->device == 0 || (i->device != 0 && i->device == device)) { - if (!i->isSpecificProtocol || - (i->isSpecificProtocol && i->protocol == protocol)) + if (i->protocol == 0 || + i->protocol == protocol) { - i->handler (packet, protocol, device); + i->handler (device, packet, protocol, from); found = true; } } diff --git a/src/node/node.h b/src/node/node.h index 2e3953458..eea8089a5 100644 --- a/src/node/node.h +++ b/src/node/node.h @@ -33,6 +33,7 @@ class TraceResolver; class NetDevice; class Application; class Packet; +class Address; /** * \brief A network Node. @@ -56,6 +57,17 @@ class Node : public Object public: static const InterfaceId iid; + /** + * Must be invoked by subclasses only. + */ + Node(); + /** + * \param systemId a unique integer used for parallel simulations. + * + * Must be invoked by subclasses only. + */ + Node(uint32_t systemId); + virtual ~Node(); /** @@ -91,11 +103,15 @@ public: * Associate this device to this node. * This method is called automatically from NetDevice::NetDevice * so the user has little reason to call this method himself. + * The index returned is always non-zero. */ uint32_t AddDevice (Ptr device); /** * \param index the index of the requested NetDevice * \returns the requested NetDevice associated to this Node. + * + * The indexes used by the GetDevice method start at one and + * end at GetNDevices () */ Ptr GetDevice (uint32_t index) const; /** @@ -128,11 +144,15 @@ public: /** * A protocol handler */ - typedef Callback > ProtocolHandler; + typedef Callback, const Packet &,uint16_t,const Address &> ProtocolHandler; /** * \param handler the handler to register * \param protocolType the type of protocol this handler is - * interested in. + * interested in. This protocol type is a so-called + * EtherType, as registered here: + * http://standards.ieee.org/regauth/ethertype/eth.txt + * the value zero is interpreted as matching all + * protocols. * \param device the device attached to this handler. If the * value is zero, the handler is attached to all * devices on this node. @@ -140,18 +160,6 @@ public: void RegisterProtocolHandler (ProtocolHandler handler, uint16_t protocolType, Ptr device); - /** - * \param handler the handler to register - * \param device the device attached to this handler. If the - * value is zero, the handler is attached to all - * devices on this node. - * - * Register a handler to receive all packets for all - * protocols. - */ - void RegisterProtocolHandler (ProtocolHandler handler, - Ptr device); - /** * \param handler the handler to unregister * @@ -161,16 +169,6 @@ public: void UnregisterProtocolHandler (ProtocolHandler handler); protected: - /** - * Must be invoked by subclasses only. - */ - Node(); - /** - * \param systemId a unique integer used for parallel simulations. - * - * Must be invoked by subclasses only. - */ - Node(uint32_t systemId); /** * The dispose method. Subclasses must override this method * and must chain up to it by calling Node::DoDispose at the @@ -195,11 +193,12 @@ private: */ virtual void NotifyDeviceAdded (Ptr device); - bool ReceiveFromDevice (Ptr device, const Packet &packet, uint16_t protocol); + bool ReceiveFromDevice (Ptr device, const Packet &packet, + uint16_t protocol, const Address &from); + void Construct (void); struct ProtocolHandlerEntry { ProtocolHandler handler; - bool isSpecificProtocol; uint16_t protocol; Ptr device; }; diff --git a/src/node/socket.cc b/src/node/socket.cc index b8995cfea..e3e573ab6 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -5,19 +5,19 @@ namespace ns3 { Socket::~Socket () {} -void +int Socket::Close(Callback > closeCompleted) { - DoClose (closeCompleted); + return DoClose (closeCompleted); } -void +int Socket::Connect(const Address & address, Callback > connectionSucceeded, Callback > connectionFailed, Callback > halfClose) { - DoConnect (address, connectionSucceeded, connectionFailed, halfClose); + return DoConnect (address, connectionSucceeded, connectionFailed, halfClose); } int Socket::Accept(Callback, const Address&> connectionRequest, diff --git a/src/node/socket.h b/src/node/socket.h index 547ed4320..991fb01b1 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -52,7 +52,9 @@ public: ERROR_AGAIN, ERROR_SHUTDOWN, ERROR_OPNOTSUPP, + ERROR_AFNOSUPPORT, ERROR_INVAL, + ERROR_BADF, SOCKET_ERRNO_LAST }; @@ -92,7 +94,7 @@ public: * After the Close call, the socket is no longer valid, and cannot * safely be used for subsequent operations. */ - void Close(Callback > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket)); + int Close(Callback > closeCompleted = MakeCallback (&Socket::DummyCallbackVoidSocket)); /** * \returns zero on success, -1 on failure. @@ -122,10 +124,10 @@ public: * \param halfClose XXX When exactly is this callback invoked ? If it invoked when the * other side closes the connection ? Or when I call Close ? */ - void Connect(const Address &address, - Callback > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket), - Callback > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket), - Callback > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket)); + int Connect(const Address &address, + Callback > connectionSucceeded = MakeCallback(&Socket::DummyCallbackVoidSocket), + Callback > connectionFailed = MakeCallback(&Socket::DummyCallbackVoidSocket), + Callback > halfClose = MakeCallback(&Socket::DummyCallbackVoidSocket)); /** * \brief Accept connection requests from remote hosts @@ -201,11 +203,11 @@ public: MakeCallback (&Socket::DummyCallbackVoidSocketUi32Address)); private: - virtual void DoClose(Callback > closeCompleted) = 0; - virtual void DoConnect(const Address & address, - Callback > connectionSucceeded, - Callback > connectionFailed, - Callback > halfClose) = 0; + virtual int DoClose(Callback > closeCompleted) = 0; + virtual int DoConnect(const Address & address, + Callback > connectionSucceeded, + Callback > connectionFailed, + Callback > halfClose) = 0; virtual int DoAccept(Callback, const Address&> connectionRequest, Callback, const Address&> newConnectionCreated, Callback > closeRequested) = 0;