diff --git a/src/internet-stack/icmpv4-l4-protocol.cc b/src/internet-stack/icmpv4-l4-protocol.cc index df06c6ae7..fe38ee1b4 100644 --- a/src/internet-stack/icmpv4-l4-protocol.cc +++ b/src/internet-stack/icmpv4-l4-protocol.cc @@ -219,23 +219,22 @@ Icmpv4L4Protocol::HandleTimeExceeded (Ptr p, enum Ipv4L4Protocol::RxStatus Icmpv4L4Protocol::Receive(Ptr p, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr incomingInterface) { - NS_LOG_FUNCTION (this << p << source << destination << incomingInterface); + NS_LOG_FUNCTION (this << p << header << incomingInterface); Icmpv4Header icmp; p->RemoveHeader (icmp); switch (icmp.GetType ()) { case Icmpv4Header::ECHO: - HandleEcho (p, icmp, source, destination); + HandleEcho (p, icmp, header.GetSource (), header.GetDestination ()); break; case Icmpv4Header::DEST_UNREACH: - HandleDestUnreach (p, icmp, source, destination); + HandleDestUnreach (p, icmp, header.GetSource (), header.GetDestination ()); break; case Icmpv4Header::TIME_EXCEEDED: - HandleTimeExceeded (p, icmp, source, destination); + HandleTimeExceeded (p, icmp, header.GetSource (), header.GetDestination ()); break; default: NS_LOG_DEBUG (icmp << " " << *p); diff --git a/src/internet-stack/icmpv4-l4-protocol.h b/src/internet-stack/icmpv4-l4-protocol.h index e13981145..3a93d3811 100644 --- a/src/internet-stack/icmpv4-l4-protocol.h +++ b/src/internet-stack/icmpv4-l4-protocol.h @@ -25,8 +25,7 @@ public: static uint16_t GetStaticProtocolNumber (void); virtual int GetProtocolNumber (void) const; virtual enum Ipv4L4Protocol::RxStatus Receive(Ptr p, - const Ipv4Address &source, - const Ipv4Address &destination, + Ipv4Header const &header, Ptr incomingInterface); void SendDestUnreachFragNeeded (Ipv4Header header, Ptr orgData, uint16_t nextHopMtu); diff --git a/src/internet-stack/ipv4-end-point.cc b/src/internet-stack/ipv4-end-point.cc index 3b3db1221..267ae7ee3 100644 --- a/src/internet-stack/ipv4-end-point.cc +++ b/src/internet-stack/ipv4-end-point.cc @@ -89,7 +89,7 @@ Ipv4EndPoint::GetBoundNetDevice (void) } void -Ipv4EndPoint::SetRxCallback (Callback, Ipv4Address, Ipv4Address, uint16_t> callback) +Ipv4EndPoint::SetRxCallback (Callback, Ipv4Header, uint16_t, Ptr > callback) { m_rxCallback = callback; } @@ -106,17 +106,20 @@ Ipv4EndPoint::SetDestroyCallback (Callback callback) } void -Ipv4EndPoint::ForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport) +Ipv4EndPoint::ForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport, + Ptr incomingInterface) { if (!m_rxCallback.IsNull ()) { - Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, saddr, daddr, sport); + Simulator::ScheduleNow (&Ipv4EndPoint::DoForwardUp, this, p, header, sport, + incomingInterface); } } void -Ipv4EndPoint::DoForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport) +Ipv4EndPoint::DoForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport, + Ptr incomingInterface) { - m_rxCallback (p, saddr, daddr, sport); + m_rxCallback (p, header, sport, incomingInterface); } void diff --git a/src/internet-stack/ipv4-end-point.h b/src/internet-stack/ipv4-end-point.h index 8754de203..4d134320c 100644 --- a/src/internet-stack/ipv4-end-point.h +++ b/src/internet-stack/ipv4-end-point.h @@ -25,6 +25,8 @@ #include "ns3/ipv4-address.h" #include "ns3/callback.h" #include "ns3/net-device.h" +#include "ns3/ipv4-header.h" +#include "ns3/ipv4-interface.h" namespace ns3 { @@ -59,13 +61,14 @@ public: Ptr GetBoundNetDevice (void); // Called from socket implementations to get notified about important events. - void SetRxCallback (Callback, Ipv4Address, Ipv4Address, uint16_t> callback); + void SetRxCallback (Callback, Ipv4Header, uint16_t, Ptr > callback); void SetIcmpCallback (Callback callback); void SetDestroyCallback (Callback callback); // Called from an L4Protocol implementation to notify an endpoint of a // packet reception. - void ForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport); + void ForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport, + Ptr incomingInterface); // Called from an L4Protocol implementation to notify an endpoint of // an icmp message reception. void ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, @@ -73,7 +76,8 @@ public: uint32_t icmpInfo); private: - void DoForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t sport); + void DoForwardUp (Ptr p, const Ipv4Header& header, uint16_t sport, + Ptr incomingInterface); void DoForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo); @@ -82,7 +86,7 @@ private: Ipv4Address m_peerAddr; uint16_t m_peerPort; Ptr m_boundnetdevice; - Callback, Ipv4Address, Ipv4Address, uint16_t> m_rxCallback; + Callback, Ipv4Header, uint16_t, Ptr > m_rxCallback; Callback m_icmpCallback; Callback m_destroyCallback; }; diff --git a/src/internet-stack/ipv4-l3-protocol.cc b/src/internet-stack/ipv4-l3-protocol.cc index 9141432eb..04271ba2d 100644 --- a/src/internet-stack/ipv4-l3-protocol.cc +++ b/src/internet-stack/ipv4-l3-protocol.cc @@ -480,7 +480,7 @@ Ipv4L3Protocol::Receive( Ptr device, Ptr p, uint16_t pr { NS_LOG_LOGIC ("Forwarding to raw socket"); Ptr socket = *i; - socket->ForwardUp (packet, ipHeader, device); + socket->ForwardUp (packet, ipHeader, ipv4Interface); } NS_ASSERT_MSG (m_routingProtocol != 0, "Need a routing protocol object to process packets"); @@ -818,7 +818,7 @@ Ipv4L3Protocol::LocalDeliver (Ptr packet, Ipv4Header const&ip, uin // RX_ENDPOINT_UNREACH codepath Ptr copy = p->Copy (); enum Ipv4L4Protocol::RxStatus status = - protocol->Receive (p, ip.GetSource (), ip.GetDestination (), GetInterface (iif)); + protocol->Receive (p, ip, GetInterface (iif)); switch (status) { case Ipv4L4Protocol::RX_OK: // fall through diff --git a/src/internet-stack/ipv4-l4-protocol.h b/src/internet-stack/ipv4-l4-protocol.h index 810c5d2af..d144de669 100644 --- a/src/internet-stack/ipv4-l4-protocol.h +++ b/src/internet-stack/ipv4-l4-protocol.h @@ -62,14 +62,14 @@ public: * \param p packet to forward up * \param source source address of packet received * \param destination address of packet received + * \param header IPv4 Header information * \param incomingInterface the Ipv4Interface on which the packet arrived * * Called from lower-level layers to send the packet up * in the stack. */ virtual enum RxStatus Receive(Ptr p, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr incomingInterface) = 0; /** diff --git a/src/internet-stack/ipv4-raw-socket-impl.cc b/src/internet-stack/ipv4-raw-socket-impl.cc index 09a2dd750..c88416b1a 100644 --- a/src/internet-stack/ipv4-raw-socket-impl.cc +++ b/src/internet-stack/ipv4-raw-socket-impl.cc @@ -3,6 +3,7 @@ #include "ipv4-raw-socket-impl.h" #include "ipv4-l3-protocol.h" #include "icmpv4.h" +#include "ns3/ipv4-packet-info-tag.h" #include "ns3/inet-socket-address.h" #include "ns3/node.h" #include "ns3/packet.h" @@ -289,9 +290,9 @@ Ipv4RawSocketImpl::SetProtocol (uint16_t protocol) } bool -Ipv4RawSocketImpl::ForwardUp (Ptr p, Ipv4Header ipHeader, Ptr device) +Ipv4RawSocketImpl::ForwardUp (Ptr p, Ipv4Header ipHeader, Ptr incomingInterface) { - NS_LOG_FUNCTION (this << *p << ipHeader << device); + NS_LOG_FUNCTION (this << *p << ipHeader << incomingInterface); if (m_shutdownRecv) { return false; @@ -302,6 +303,14 @@ Ipv4RawSocketImpl::ForwardUp (Ptr p, Ipv4Header ipHeader, Ptr copy = p->Copy (); + // Should check via getsockopt ().. + if (this->m_recvpktinfo) + { + Ipv4PacketInfoTag tag; + copy->RemovePacketTag (tag); + tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ()); + copy->AddPacketTag (tag); + } if (m_protocol == 1) { Icmpv4Header icmpHeader; diff --git a/src/internet-stack/ipv4-raw-socket-impl.h b/src/internet-stack/ipv4-raw-socket-impl.h index 4baa8171d..654349b7c 100644 --- a/src/internet-stack/ipv4-raw-socket-impl.h +++ b/src/internet-stack/ipv4-raw-socket-impl.h @@ -5,6 +5,7 @@ #include "ns3/socket.h" #include "ns3/ipv4-header.h" #include "ns3/ipv4-route.h" +#include "ns3/ipv4-interface.h" #include namespace ns3 { @@ -41,7 +42,7 @@ public: Address &fromAddress); void SetProtocol (uint16_t protocol); - bool ForwardUp (Ptr p, Ipv4Header ipHeader, Ptr device); + bool ForwardUp (Ptr p, Ipv4Header ipHeader, Ptr incomingInterface); virtual void SetAllowBroadcast (bool allowBroadcast); virtual bool GetAllowBroadcast () const; diff --git a/src/internet-stack/ipv4-raw-test.cc b/src/internet-stack/ipv4-raw-test.cc index 07b8e6615..bf347e02c 100644 --- a/src/internet-stack/ipv4-raw-test.cc +++ b/src/internet-stack/ipv4-raw-test.cc @@ -1,6 +1,6 @@ /* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* - * Copyright (c) 2010 Keio University + * Copyright (c) 2010 Hajime Tazaki * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/src/internet-stack/ipv6-raw-socket-impl.cc b/src/internet-stack/ipv6-raw-socket-impl.cc index 7e684cb5a..ccb93aafb 100644 --- a/src/internet-stack/ipv6-raw-socket-impl.cc +++ b/src/internet-stack/ipv6-raw-socket-impl.cc @@ -26,6 +26,7 @@ #include "ns3/log.h" #include "ns3/ipv6-route.h" #include "ns3/ipv6-routing-protocol.h" +#include "ns3/ipv6-packet-info-tag.h" #include "ipv6-l3-protocol.h" #include "ipv6-raw-socket-impl.h" @@ -325,6 +326,15 @@ bool Ipv6RawSocketImpl::ForwardUp (Ptr p, Ipv6Header hdr, Ptrm_recvpktinfo) + { + Ipv6PacketInfoTag tag; + copy->RemovePacketTag (tag); + tag.SetRecvIf (device->GetIfIndex ()); + copy->AddPacketTag (tag); + } + copy->AddHeader (hdr); struct Data data; data.packet = copy; diff --git a/src/internet-stack/nsc-tcp-l4-protocol.cc b/src/internet-stack/nsc-tcp-l4-protocol.cc index 621262286..1cbd647a3 100644 --- a/src/internet-stack/nsc-tcp-l4-protocol.cc +++ b/src/internet-stack/nsc-tcp-l4-protocol.cc @@ -302,11 +302,10 @@ NscTcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint) Ipv4L4Protocol::RxStatus NscTcpL4Protocol::Receive (Ptr packet, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr incomingInterface) { - NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface); + NS_LOG_FUNCTION (this << packet << header << incomingInterface); Ipv4Header ipHeader; uint32_t packetSize = packet->GetSize(); @@ -315,8 +314,8 @@ NscTcpL4Protocol::Receive (Ptr packet, // a complete IP packet, so we add the IP header back. // Since the original header is already gone, we create a new one // based on the information we have. - ipHeader.SetSource (source); - ipHeader.SetDestination (destination); + ipHeader.SetSource (header.GetSource ()); + ipHeader.SetDestination (header.GetDestination ()); ipHeader.SetProtocol (PROT_NUMBER); ipHeader.SetPayloadSize (packetSize); ipHeader.SetTtl (1); @@ -382,7 +381,7 @@ void NscTcpL4Protocol::wakeup() for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin (); endPoint != endPoints.end (); endPoint++) { // NSC HACK: (ab)use TcpSocket::ForwardUp for signalling - (*endPoint)->ForwardUp (NULL, Ipv4Address(), Ipv4Address(), 0); + (*endPoint)->ForwardUp (NULL, Ipv4Header(), 0, 0); } } diff --git a/src/internet-stack/nsc-tcp-l4-protocol.h b/src/internet-stack/nsc-tcp-l4-protocol.h index 31d0db963..aebec0fde 100644 --- a/src/internet-stack/nsc-tcp-l4-protocol.h +++ b/src/internet-stack/nsc-tcp-l4-protocol.h @@ -82,8 +82,7 @@ public: * \param incomingInterface The Ipv4Interface it was received on */ virtual Ipv4L4Protocol::RxStatus Receive (Ptr p, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr incomingInterface); protected: diff --git a/src/internet-stack/nsc-tcp-socket-impl.cc b/src/internet-stack/nsc-tcp-socket-impl.cc index b41b3ba5a..6245689ee 100644 --- a/src/internet-stack/nsc-tcp-socket-impl.cc +++ b/src/internet-stack/nsc-tcp-socket-impl.cc @@ -466,7 +466,8 @@ NscTcpSocketImpl::GetRxAvailable (void) const } void -NscTcpSocketImpl::ForwardUp (Ptr packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port) +NscTcpSocketImpl::ForwardUp (Ptr packet, Ipv4Header header, uint16_t port, + Ptr incomingInterface) { NSCWakeup(); } diff --git a/src/internet-stack/nsc-tcp-socket-impl.h b/src/internet-stack/nsc-tcp-socket-impl.h index 78fdfa247..1e0e93c73 100644 --- a/src/internet-stack/nsc-tcp-socket-impl.h +++ b/src/internet-stack/nsc-tcp-socket-impl.h @@ -90,7 +90,8 @@ private: friend class Tcp; // invoked by Tcp class int FinishBind (void); - void ForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port); + void ForwardUp (Ptr p, Ipv4Header header, uint16_t port, + Ptr incomingInterface); void Destroy (void); //methods for state bool SendPendingData(void); diff --git a/src/internet-stack/tcp-l4-protocol.cc b/src/internet-stack/tcp-l4-protocol.cc index 3d56c4b24..2138d1307 100644 --- a/src/internet-stack/tcp-l4-protocol.cc +++ b/src/internet-stack/tcp-l4-protocol.cc @@ -478,17 +478,16 @@ TcpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint) enum Ipv4L4Protocol::RxStatus TcpL4Protocol::Receive (Ptr packet, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &ipHeader, Ptr incomingInterface) { - NS_LOG_FUNCTION (this << packet << source << destination << incomingInterface); + NS_LOG_FUNCTION (this << packet << ipHeader << incomingInterface); TcpHeader tcpHeader; if(Node::ChecksumEnabled ()) { tcpHeader.EnableChecksums(); - tcpHeader.InitializeChecksum (source, destination, PROT_NUMBER); + tcpHeader.InitializeChecksum (ipHeader.GetSource (), ipHeader.GetDestination (), PROT_NUMBER); } packet->PeekHeader (tcpHeader); @@ -507,16 +506,16 @@ TcpL4Protocol::Receive (Ptr packet, NS_LOG_LOGIC ("TcpL4Protocol "<Lookup (destination, tcpHeader.GetDestinationPort (), - source, tcpHeader.GetSourcePort (),incomingInterface); + m_endPoints->Lookup (ipHeader.GetDestination (), tcpHeader.GetDestinationPort (), + ipHeader.GetSource (), tcpHeader.GetSourcePort (),incomingInterface); if (endPoints.empty ()) { NS_LOG_LOGIC (" No endpoints matched on TcpL4Protocol "< packet, } header.SetSourcePort (tcpHeader.GetDestinationPort ()); header.SetDestinationPort (tcpHeader.GetSourcePort ()); - SendPacket (rstPacket, header, destination, source); + SendPacket (rstPacket, header, ipHeader.GetDestination (), ipHeader.GetSource ()); return Ipv4L4Protocol::RX_ENDPOINT_CLOSED; } else @@ -549,7 +548,8 @@ TcpL4Protocol::Receive (Ptr packet, } NS_ASSERT_MSG (endPoints.size() == 1 , "Demux returned more than one endpoint"); NS_LOG_LOGIC ("TcpL4Protocol "<ForwardUp (packet, source, destination, tcpHeader.GetSourcePort ()); + (*endPoints.begin ())->ForwardUp (packet, ipHeader, tcpHeader.GetSourcePort (), + incomingInterface); return Ipv4L4Protocol::RX_OK; } diff --git a/src/internet-stack/tcp-l4-protocol.h b/src/internet-stack/tcp-l4-protocol.h index f43b4d8e4..07e728aea 100644 --- a/src/internet-stack/tcp-l4-protocol.h +++ b/src/internet-stack/tcp-l4-protocol.h @@ -100,11 +100,11 @@ public: * \param p The Packet to dump the contents into * \param source The source's Ipv4Address * \param destination The destinations Ipv4Address + * \param header IPv4 Header information * \param incomingInterface The Ipv4Interface it was received on */ virtual enum Ipv4L4Protocol::RxStatus Receive (Ptr p, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr incomingInterface); protected: diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index fa2734dcc..5e6ff25f0 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -664,7 +664,8 @@ TcpSocketImpl::BindToNetDevice (Ptr netdevice) } void -TcpSocketImpl::ForwardUp (Ptr packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port) +TcpSocketImpl::ForwardUp (Ptr packet, Ipv4Header header, uint16_t port, + Ptr incomingInterface) { NS_LOG_DEBUG("Socket " << this << " got forward up" << " dport " << m_endPoint->GetLocalPort() << @@ -672,10 +673,10 @@ TcpSocketImpl::ForwardUp (Ptr packet, Ipv4Address saddr, Ipv4Address dad " sport " << m_endPoint->GetPeerPort() << " saddr " << m_endPoint->GetPeerAddress()); - NS_LOG_FUNCTION (this << packet << saddr << daddr << port); + NS_LOG_FUNCTION (this << packet << header << port); - Address fromAddress = InetSocketAddress (saddr, port); - Address toAddress = InetSocketAddress (daddr, m_endPoint->GetLocalPort()); + Address fromAddress = InetSocketAddress (header.GetSource (), port); + Address toAddress = InetSocketAddress (header.GetDestination (), m_endPoint->GetLocalPort()); TcpHeader tcpHeader; packet->RemoveHeader (tcpHeader); diff --git a/src/internet-stack/tcp-socket-impl.h b/src/internet-stack/tcp-socket-impl.h index 568e0f7b1..8cf41ac43 100644 --- a/src/internet-stack/tcp-socket-impl.h +++ b/src/internet-stack/tcp-socket-impl.h @@ -28,6 +28,8 @@ #include "ns3/ptr.h" #include "ns3/ipv4-address.h" #include "ns3/event-id.h" +#include "ns3/ipv4-header.h" +#include "ipv4-interface.h" #include "tcp-typedefs.h" #include "pending-data.h" #include "ns3/sequence-number.h" @@ -103,7 +105,8 @@ private: friend class Tcp; // invoked by Tcp class int FinishBind (void); - void ForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port); + void ForwardUp (Ptr p, Ipv4Header header, uint16_t port, + Ptr incomingInterface); void Destroy (void); int DoSendTo (Ptr p, const Address &daddr); int DoSendTo (Ptr p, Ipv4Address daddr, uint16_t dport); diff --git a/src/internet-stack/udp-l4-protocol.cc b/src/internet-stack/udp-l4-protocol.cc index f9185cf1c..ec373a38f 100644 --- a/src/internet-stack/udp-l4-protocol.cc +++ b/src/internet-stack/udp-l4-protocol.cc @@ -198,18 +198,17 @@ UdpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl, enum Ipv4L4Protocol::RxStatus UdpL4Protocol::Receive(Ptr packet, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr interface) { - NS_LOG_FUNCTION (this << packet << source << destination); + NS_LOG_FUNCTION (this << packet << header); UdpHeader udpHeader; if(Node::ChecksumEnabled ()) { udpHeader.EnableChecksums(); } - udpHeader.InitializeChecksum (source, destination, PROT_NUMBER); + udpHeader.InitializeChecksum (header.GetSource (), header.GetDestination (), PROT_NUMBER); packet->RemoveHeader (udpHeader); @@ -220,8 +219,8 @@ UdpL4Protocol::Receive(Ptr packet, } Ipv4EndPointDemux::EndPoints endPoints = - m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (), - source, udpHeader.GetSourcePort (), interface); + m_endPoints->Lookup (header.GetDestination (), udpHeader.GetDestinationPort (), + header.GetSource (), udpHeader.GetSourcePort (), interface); if (endPoints.empty ()) { NS_LOG_LOGIC ("RX_ENDPOINT_UNREACH"); @@ -230,7 +229,8 @@ UdpL4Protocol::Receive(Ptr packet, for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin (); endPoint != endPoints.end (); endPoint++) { - (*endPoint)->ForwardUp (packet->Copy (), source, destination, udpHeader.GetSourcePort ()); + (*endPoint)->ForwardUp (packet->Copy (), header, udpHeader.GetSourcePort (), + interface); } return Ipv4L4Protocol::RX_OK; } diff --git a/src/internet-stack/udp-l4-protocol.h b/src/internet-stack/udp-l4-protocol.h index 631be23d3..2c74de258 100644 --- a/src/internet-stack/udp-l4-protocol.h +++ b/src/internet-stack/udp-l4-protocol.h @@ -86,12 +86,12 @@ public: * \param p The Packet to dump the contents into * \param source The source's Ipv4Address * \param destination The destinations Ipv4Address + * \param header IPv4 Header information * \param interface the interface from which the packet is coming. */ // inherited from Ipv4L4Protocol virtual enum Ipv4L4Protocol::RxStatus Receive(Ptr p, - Ipv4Address const &source, - Ipv4Address const &destination, + Ipv4Header const &header, Ptr interface); /** diff --git a/src/internet-stack/udp-socket-impl.cc b/src/internet-stack/udp-socket-impl.cc index 25e528e9a..3b516f49f 100644 --- a/src/internet-stack/udp-socket-impl.cc +++ b/src/internet-stack/udp-socket-impl.cc @@ -27,6 +27,7 @@ #include "ns3/ipv4-routing-protocol.h" #include "ns3/udp-socket-factory.h" #include "ns3/trace-source-accessor.h" +#include "ns3/ipv4-packet-info-tag.h" #include "udp-socket-impl.h" #include "udp-l4-protocol.h" #include "ipv4-end-point.h" @@ -609,17 +610,28 @@ UdpSocketImpl::BindToNetDevice (Ptr netdevice) } void -UdpSocketImpl::ForwardUp (Ptr packet, Ipv4Address saddr, Ipv4Address daddr, uint16_t port) +UdpSocketImpl::ForwardUp (Ptr packet, Ipv4Header header, uint16_t port, + Ptr incomingInterface) { - NS_LOG_FUNCTION (this << packet << saddr << daddr << port); + NS_LOG_FUNCTION (this << packet << header << port); if (m_shutdownRecv) { return; } + + // Should check via getsockopt ().. + if (this->m_recvpktinfo) + { + Ipv4PacketInfoTag tag; + packet->RemovePacketTag (tag); + tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ()); + packet->AddPacketTag (tag); + } + if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize) { - Address address = InetSocketAddress (saddr, port); + Address address = InetSocketAddress (header.GetSource (), port); SocketAddressTag tag; tag.SetAddress (address); packet->AddPacketTag (tag); diff --git a/src/internet-stack/udp-socket-impl.h b/src/internet-stack/udp-socket-impl.h index da757a244..4e129b17b 100644 --- a/src/internet-stack/udp-socket-impl.h +++ b/src/internet-stack/udp-socket-impl.h @@ -28,6 +28,7 @@ #include "ns3/ptr.h" #include "ns3/ipv4-address.h" #include "ns3/udp-socket.h" +#include "ns3/ipv4-interface.h" #include "icmpv4.h" namespace ns3 { @@ -100,7 +101,8 @@ private: friend class UdpSocketFactory; // invoked by Udp class int FinishBind (void); - void ForwardUp (Ptr p, Ipv4Address saddr, Ipv4Address daddr, uint16_t port); + void ForwardUp (Ptr p, Ipv4Header header, uint16_t port, + Ptr incomingInterface); void Destroy (void); int DoSend (Ptr p); int DoSendTo (Ptr p, const Address &daddr); diff --git a/src/node/ipv4-packet-info-tag.cc b/src/node/ipv4-packet-info-tag.cc new file mode 100644 index 000000000..af83c7f99 --- /dev/null +++ b/src/node/ipv4-packet-info-tag.cc @@ -0,0 +1,284 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2010 Hajime Tazaki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Hajime Tazaki + */ + + +#include +#include "ns3/ipv4-address.h" +#include "ns3/test.h" +#include "ipv4-packet-info-tag.h" + +namespace ns3 { + +Ipv4PacketInfoTag::Ipv4PacketInfoTag () + : m_addr (Ipv4Address ()), + m_spec_dst (Ipv4Address ()), + m_ifindex (0), + m_ttl (0) +{ +} + +void +Ipv4PacketInfoTag::SetAddress (Ipv4Address addr) +{ + m_addr = addr; +} + +Ipv4Address +Ipv4PacketInfoTag::GetAddress (void) const +{ + return m_addr; +} + +void +Ipv4PacketInfoTag::SetLocalAddress (Ipv4Address addr) +{ + m_spec_dst = addr; +} + +Ipv4Address +Ipv4PacketInfoTag::GetLocalAddress (void) const +{ + return m_spec_dst; +} + +void +Ipv4PacketInfoTag::SetRecvIf (uint32_t ifindex) +{ + m_ifindex = ifindex; +} + +uint32_t +Ipv4PacketInfoTag::GetRecvIf (void) const +{ + return m_ifindex; +} + +void +Ipv4PacketInfoTag::SetTtl (uint8_t ttl) +{ + m_ttl = ttl; +} + +uint8_t +Ipv4PacketInfoTag::GetTtl (void) const +{ + return m_ttl; +} + + + +TypeId +Ipv4PacketInfoTag::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::Ipv4PacketInfoTag") + .SetParent () + .AddConstructor () + ; + return tid; +} +TypeId +Ipv4PacketInfoTag::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +Ipv4PacketInfoTag::GetSerializedSize (void) const +{ + return 4 + 4 + + sizeof (uint32_t) + + sizeof (uint8_t); +} +void +Ipv4PacketInfoTag::Serialize (TagBuffer i) const +{ + uint8_t buf[4]; + m_addr.Serialize (buf); + i.Write (buf, 4); + m_spec_dst.Serialize (buf); + i.Write (buf, 4); + i.WriteU32 (m_ifindex); + i.WriteU8 (m_ttl); +} +void +Ipv4PacketInfoTag::Deserialize (TagBuffer i) +{ + uint8_t buf[4]; + i.Read (buf, 4); + m_addr.Deserialize (buf); + i.Read (buf, 4); + m_spec_dst.Deserialize (buf); + m_ifindex = i.ReadU32 (); + m_ttl = i.ReadU8 (); +} +void +Ipv4PacketInfoTag::Print (std::ostream &os) const +{ + os << "Ipv4 PKTINFO [DestAddr: " << m_addr; + os << ", Local Address:" << m_spec_dst; + os << ", RecvIf:" << (uint32_t) m_ifindex; + os << ", TTL:" << (uint32_t) m_ttl; + os << "] "; +} +}//namespace ns3 + +//----------------------------------------------------------------------------- +// Unit tests +//----------------------------------------------------------------------------- + +#include "ns3/log.h" +#include "ns3/abort.h" +#include "ns3/attribute.h" +#include "ns3/object-factory.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/ipv4-address-helper.h" +#include "ns3/csma-helper.h" +#include "ns3/node-container.h" +#include "ns3/object-factory.h" +#include "ns3/socket-factory.h" +#include "ns3/udp-socket-factory.h" +#include "ns3/udp-socket.h" +#include "ns3/ipv4-raw-socket-factory.h" +#include "ns3/inet-socket-address.h" +#include "ns3/simulator.h" + +namespace ns3 { + +class Ipv4PacketInfoTagTest: public TestCase +{ +public: + Ipv4PacketInfoTagTest (); +private: + virtual bool DoRun (void); + void RxCb (Ptr socket); + void DoSendData (Ptr socket, std::string to); +}; + +Ipv4PacketInfoTagTest::Ipv4PacketInfoTagTest () + : TestCase ("Ipv4PacketInfoTagTest") +{} + +void +Ipv4PacketInfoTagTest::RxCb (Ptr socket) +{ + uint32_t availableData; + Ptr m_receivedPacket; + + availableData = socket->GetRxAvailable (); + m_receivedPacket = socket->Recv (std::numeric_limits::max(), 0); + NS_ASSERT (availableData == m_receivedPacket->GetSize ()); + + Ipv4PacketInfoTag tag; + bool found; + found = m_receivedPacket->RemovePacketTag (tag); + NS_ASSERT (found); + tag.Print (std::cout); +} + +void +Ipv4PacketInfoTagTest::DoSendData (Ptr socket, std::string to) +{ + Address realTo = InetSocketAddress (Ipv4Address (to.c_str()), 200); + if (DynamicCast (socket) != 0) + { + NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create (123), 0, realTo), + 123, "XXX"); + } + // Should only Ipv4RawSock + else + { + socket->SendTo (Create (123), 0, realTo); + } +} + +bool +Ipv4PacketInfoTagTest::DoRun (void) +{ + NodeContainer n; + n.Create (2); + + InternetStackHelper internet; + internet.Install (n); + + CsmaHelper csma; + NetDeviceContainer d = csma.Install (n); + + Ipv4AddressHelper ipv4; + ipv4.SetBase ("10.1.1.0", "255.255.255.0"); + Ipv4InterfaceContainer i = ipv4.Assign (d); + + // IPv4 test + Ptr factory = n.Get (0)->GetObject (UdpSocketFactory::GetTypeId ()); + Ptr socket = factory->CreateSocket (); + InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 200); + socket->Bind (local); + socket->SetRecvPktInfo (true); + socket->SetRecvCallback (MakeCallback (&ns3::Ipv4PacketInfoTagTest::RxCb, this)); + + // receive on loopback + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv4PacketInfoTagTest::DoSendData, this, socket, "127.0.0.1"); + Simulator::Run (); + + // send from node1 and recved via csma + Ptr factory2 = n.Get (1)->GetObject (UdpSocketFactory::GetTypeId ()); + Ptr socket2 = factory2->CreateSocket (); + Simulator::ScheduleWithContext (socket2->GetNode ()->GetId (), Seconds (0), + &Ipv4PacketInfoTagTest::DoSendData, this, socket, "10.1.1.1"); + Simulator::Run (); + + // ipv4 w rawsocket + factory = n.Get (0)->GetObject (Ipv4RawSocketFactory::GetTypeId ()); + socket = factory->CreateSocket (); + local = InetSocketAddress (Ipv4Address::GetAny (), 0); + socket->Bind (local); + socket->SetRecvPktInfo (true); + socket->SetRecvCallback (MakeCallback (&ns3::Ipv4PacketInfoTagTest::RxCb, this)); + + // receive on loopback + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv4PacketInfoTagTest::DoSendData, this, socket, "127.0.0.1"); + Simulator::Run (); + + // send from node1 and recved via csma + factory2 = n.Get (1)->GetObject (Ipv4RawSocketFactory::GetTypeId ()); + socket2 = factory2->CreateSocket (); + Simulator::ScheduleWithContext (socket2->GetNode ()->GetId (), Seconds (0), + &Ipv4PacketInfoTagTest::DoSendData, this, socket, "10.1.1.1"); + Simulator::Run (); + + return 0; +} + +static class Ipv4PacketInfoTagTestSuite : public TestSuite +{ +public: + Ipv4PacketInfoTagTestSuite (); +private: +} g_packetinfotagTests; + +Ipv4PacketInfoTagTestSuite::Ipv4PacketInfoTagTestSuite () + : TestSuite ("ipv4-packet-info-tag", UNIT) +{ + AddTestCase (new Ipv4PacketInfoTagTest ()); +} + + +} diff --git a/src/node/ipv4-packet-info-tag.h b/src/node/ipv4-packet-info-tag.h new file mode 100644 index 000000000..2fcf69044 --- /dev/null +++ b/src/node/ipv4-packet-info-tag.h @@ -0,0 +1,89 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2010 Hajime Tazaki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Hajime Tazaki + */ + +#ifndef __IPV4_PACKET_INFO_TAG_H__ +#define __IPV4_PACKET_INFO_TAG_H__ + +#include "ns3/tag.h" + +namespace ns3 { + + +class Node; +class Packet; + +/** + * \brief This class implements Linux struct pktinfo + * in order to deliver ancillary information to the socket interface. + * This is used with socket option such as IP_PKTINFO, IP_RECVTTL, + * IP_RECVTOS. See linux manpage ip(7). + * + * This tag in the send direction is presently not enabled but we + * would accept a patch along those lines in the future. + */ +class Ipv4PacketInfoTag : public Tag +{ +public: + Ipv4PacketInfoTag (); + // Implemented, but not used in the stack yet + void SetAddress (Ipv4Address addr); + // Implemented, but not used in the stack yet + Ipv4Address GetAddress (void) const; + // This corresponds to "ipi_spec_dst" in struct in_pktinfo. + // Implemented, but not used in the stack yet + void SetLocalAddress (Ipv4Address addr); + // This corresponds to "ipi_spec_dst" in struct in_pktinfo. + // Implemented, but not used in the stack yet + Ipv4Address GetLocalAddress (void) const; + void SetRecvIf (uint32_t ifindex); + uint32_t GetRecvIf (void) const; + // Implemented, but not used in the stack yet + void SetTtl (uint8_t ttl); + // Implemented, but not used in the stack yet + uint8_t GetTtl (void) const; + + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (TagBuffer i) const; + virtual void Deserialize (TagBuffer i); + virtual void Print (std::ostream &os) const; + +private: + // Linux IP_PKTINFO ip(7) implementation + // + // struct in_pktinfo { + // unsigned int ipi_ifindex; /* Interface index */ + // struct in_addr ipi_spec_dst; /* Local address */ + // struct in_addr ipi_addr; /* Header Destination + // address */ + // }; + + Ipv4Address m_addr; + Ipv4Address m_spec_dst; + uint32_t m_ifindex; + + // Uset for IP_RECVTTL, though not implemented yet. + uint8_t m_ttl; +}; +} //namespace ns3 + +#endif /* __IPV4_PACKET_INFO_TAG_H__ */ + diff --git a/src/node/ipv6-packet-info-tag.cc b/src/node/ipv6-packet-info-tag.cc new file mode 100644 index 000000000..43d979023 --- /dev/null +++ b/src/node/ipv6-packet-info-tag.cc @@ -0,0 +1,294 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2010 Hajime Tazaki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Hajime Tazaki + */ + + +#include +#include "ns3/ipv6-address.h" +#include "ns3/test.h" +#include "ipv6-packet-info-tag.h" + +namespace ns3 { + +Ipv6PacketInfoTag::Ipv6PacketInfoTag () + : m_addr (Ipv6Address ()), + m_ifindex (0), + m_hoplimit (0), + m_tclass (0) +{ +} + +void +Ipv6PacketInfoTag::SetAddress (Ipv6Address addr) +{ + m_addr = addr; +} + +Ipv6Address +Ipv6PacketInfoTag::GetAddress (void) const +{ + return m_addr; +} + +void +Ipv6PacketInfoTag::SetRecvIf (uint32_t ifindex) +{ + m_ifindex = ifindex; +} + +uint32_t +Ipv6PacketInfoTag::GetRecvIf (void) const +{ + return m_ifindex; +} + +void +Ipv6PacketInfoTag::SetHoplimit (uint8_t ttl) +{ + m_hoplimit = ttl; +} + +uint8_t +Ipv6PacketInfoTag::GetHoplimit (void) const +{ + return m_hoplimit; +} + +void +Ipv6PacketInfoTag::SetTrafficClass (uint8_t tclass) +{ + m_tclass = tclass; +} + +uint8_t +Ipv6PacketInfoTag::GetTrafficClass (void) const +{ + return m_tclass; +} + + +TypeId +Ipv6PacketInfoTag::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::Ipv6PacketInfoTag") + .SetParent () + .AddConstructor () + ; + return tid; +} +TypeId +Ipv6PacketInfoTag::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + +uint32_t +Ipv6PacketInfoTag::GetSerializedSize (void) const +{ + return 16 + + sizeof (uint8_t) + + sizeof (uint8_t) + + sizeof (uint8_t); +} +void +Ipv6PacketInfoTag::Serialize (TagBuffer i) const +{ + uint8_t buf[16]; + m_addr.Serialize (buf); + i.Write (buf, 16); + i.WriteU8 (m_ifindex); + i.WriteU8 (m_hoplimit); + i.WriteU8 (m_tclass); +} +void +Ipv6PacketInfoTag::Deserialize (TagBuffer i) +{ + uint8_t buf[16]; + i.Read (buf, 16); + m_addr.Deserialize (buf); + m_ifindex = i.ReadU8 (); + m_hoplimit = i.ReadU8 (); + m_tclass = i.ReadU8 (); +} +void +Ipv6PacketInfoTag::Print (std::ostream &os) const +{ + os << "Ipv6 PKTINFO [DestAddr: " << m_addr; + os << ", RecvIf:" << (uint32_t) m_ifindex; + os << ", TTL:" << (uint32_t) m_hoplimit; + os << ", TClass:" << (uint32_t) m_tclass; + os << "] "; +} +}//namespace ns3 + +//----------------------------------------------------------------------------- +// Unit tests +//----------------------------------------------------------------------------- + +#include "ns3/log.h" +#include "ns3/abort.h" +#include "ns3/attribute.h" +#include "ns3/object-factory.h" +#include "ns3/internet-stack-helper.h" +#include "ns3/ipv6-address-helper.h" +#include "ns3/csma-helper.h" +#include "ns3/node-container.h" +#include "ns3/object-factory.h" +#include "ns3/socket-factory.h" +#include "ns3/udp-socket-factory.h" +#include "ns3/udp-socket.h" +#include "ns3/ipv6-raw-socket-factory.h" +#include "ns3/inet6-socket-address.h" +#include "ns3/simulator.h" +#include "ns3/uinteger.h" + +namespace ns3 { + +class Ipv6PacketInfoTagTest: public TestCase +{ +public: + Ipv6PacketInfoTagTest (); +private: + virtual bool DoRun (void); + void RxCb (Ptr socket); + void DoSendData (Ptr socket, std::string to); +}; + +Ipv6PacketInfoTagTest::Ipv6PacketInfoTagTest () + : TestCase ("Ipv6PacketInfoTagTest") +{} + +void +Ipv6PacketInfoTagTest::RxCb (Ptr socket) +{ + uint32_t availableData; + Ptr m_receivedPacket; + + availableData = socket->GetRxAvailable (); + m_receivedPacket = socket->Recv (std::numeric_limits::max(), 0); + NS_ASSERT (availableData == m_receivedPacket->GetSize ()); + + Ipv6PacketInfoTag tag; + bool found; + found = m_receivedPacket->RemovePacketTag (tag); + NS_ASSERT (found); + tag.Print (std::cout); + std::cout << std::endl; +} + +void +Ipv6PacketInfoTagTest::DoSendData (Ptr socket, std::string to) +{ + Address realTo = Inet6SocketAddress (Ipv6Address (to.c_str()), 200); + if (DynamicCast (socket) != 0) + { + NS_TEST_EXPECT_MSG_EQ (socket->SendTo (Create (123), 0, realTo), + 123, "XXX"); + } + // Should only Ipv6RawSock + else + { + socket->SendTo (Create (123), 0, realTo); + } +} + +bool +Ipv6PacketInfoTagTest::DoRun (void) +{ + NodeContainer n; + n.Create (2); + + InternetStackHelper internet; + internet.Install (n); + + CsmaHelper csma; + NetDeviceContainer d = csma.Install (n); + + Ipv6AddressHelper ipv6; + ipv6.NewNetwork(Ipv6Address("2000:1000:0:2000::"), Ipv6Prefix(64)); + Ipv6InterfaceContainer i = ipv6.Assign (d); + + + // ipv6 w rawsocket + Ptr factory = n.Get (0)->GetObject (Ipv6RawSocketFactory::GetTypeId ()); + Ptr socket = factory->CreateSocket (); + Inet6SocketAddress local = Inet6SocketAddress (Ipv6Address::GetAny (), 0); + socket->SetAttribute ("Protocol", UintegerValue (Ipv6Header::IPV6_ICMPV6)); + socket->Bind (local); + socket->SetRecvPktInfo (true); + socket->SetRecvCallback (MakeCallback (&ns3::Ipv6PacketInfoTagTest::RxCb, this)); + + // receive on loopback + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv6PacketInfoTagTest::DoSendData, this, socket, "::1"); + Simulator::Run (); + + // send from node1 and recved via csma + Ptr factory2 = n.Get (1)->GetObject (Ipv6RawSocketFactory::GetTypeId ()); + Ptr socket2 = factory2->CreateSocket (); + std::stringstream dst; + dst << i.GetAddress (0, 0); + Simulator::ScheduleWithContext (socket2->GetNode ()->GetId (), Seconds (0), + &Ipv6PacketInfoTagTest::DoSendData, this, socket, + dst.str ()); + Simulator::Run (); + +#ifdef UDP6_SUPPORTED + // IPv6 test + factory = n.Get (0)->GetObject (UdpSocketFactory::GetTypeId ()); + socket = factory->CreateSocket (); + local = Inet6SocketAddress (Ipv6Address::GetAny (), 200); + socket->Bind (local); + socket->SetRecvPktInfo (true); + socket->SetRecvCallback (MakeCallback (&ns3::Ipv6PacketInfoTagTest::RxCb, this)); + + // receive on loopback + Simulator::ScheduleWithContext (socket->GetNode ()->GetId (), Seconds (0), + &Ipv6PacketInfoTagTest::DoSendData, this, socket, "::1"); + Simulator::Run (); + + // send from node1 and recved via csma + factory2 = n.Get (1)->GetObject (UdpSocketFactory::GetTypeId ()); + socket2 = factory2->CreateSocket (); + Simulator::ScheduleWithContext (socket2->GetNode ()->GetId (), Seconds (0), + &Ipv6PacketInfoTagTest::DoSendData, this, socket, "10.1.1.1"); + Simulator::Run (); + +#endif // UDP6_SUPPORTED + + // IPv6 test + return 0; +} + +static class Ipv6PacketInfoTagTestSuite : public TestSuite +{ +public: + Ipv6PacketInfoTagTestSuite (); +private: +} g_packetinfotagTests; + +Ipv6PacketInfoTagTestSuite::Ipv6PacketInfoTagTestSuite () + : TestSuite ("ipv6-packet-info-tag", UNIT) +{ + AddTestCase (new Ipv6PacketInfoTagTest ()); +} + + +} + diff --git a/src/node/ipv6-packet-info-tag.h b/src/node/ipv6-packet-info-tag.h new file mode 100644 index 000000000..4931a9741 --- /dev/null +++ b/src/node/ipv6-packet-info-tag.h @@ -0,0 +1,94 @@ +/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ +/* + * Copyright (c) 2010 Hajime Tazaki + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation; + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Hajime Tazaki + */ + +#ifndef __IPV6_PACKET_INFO_TAG_H__ +#define __IPV6_PACKET_INFO_TAG_H__ + +#include "ns3/tag.h" + +namespace ns3 { + + +class Node; +class Packet; + +/** + * \brief This class implements a tag that carries socket ancillary + * data to the socket interface. This is used like + * socket option of IP_PKTINFO/IPV6_PKTINFO in RFC 3542 + * See: http://tools.ietf.org/html/rfc3542 + * + * This tag in the send direction is presently not enabled but we + * would accept a patch along those lines in the future. To include + * the nexthop in the send direction would increase the size of the + * tag beyond 20 bytes, so in that case, we recommend that an + * additional tag be used to carry the IPv6 next hop address. + */ +class Ipv6PacketInfoTag : public Tag +{ +public: + Ipv6PacketInfoTag (); + // Implemented, but not used in the stack yet + void SetAddress (Ipv6Address addr); + // Implemented, but not used in the stack yet + Ipv6Address GetAddress (void) const; + void SetRecvIf (uint32_t ifindex); + uint32_t GetRecvIf (void) const; + // Implemented, but not used in the stack yet + void SetHoplimit (uint8_t ttl); + // Implemented, but not used in the stack yet + uint8_t GetHoplimit (void) const; + // Implemented, but not used in the stack yet + void SetTrafficClass (uint8_t tclass); + // Implemented, but not used in the stack yet + uint8_t GetTrafficClass (void) const; + + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + virtual uint32_t GetSerializedSize (void) const; + virtual void Serialize (TagBuffer i) const; + virtual void Deserialize (TagBuffer i); + virtual void Print (std::ostream &os) const; + +private: + /* + * RFC 3542 includes + * for outgoing packet, + * 1. the source IPv6 address, + * 2. the outgoing interface index, + * 3. the outgoing hop limit, + * 4. the next hop address, and + * 5. the outgoing traffic class value. + * + * for incoming packet, + * 1. the destination IPv6 address, + * 2. the arriving interface index, + * 3. the arriving hop limit, and + * 4. the arriving traffic class value. + */ + Ipv6Address m_addr; + uint8_t m_ifindex; + uint8_t m_hoplimit; + uint8_t m_tclass; +}; +} //namespace ns3 + +#endif /* __IPV6_PACKET_INFO_TAG_H__ */ + diff --git a/src/node/socket.cc b/src/node/socket.cc index f5884ec7c..c32cb37cb 100644 --- a/src/node/socket.cc +++ b/src/node/socket.cc @@ -34,6 +34,7 @@ namespace ns3 { Socket::Socket (void) { m_boundnetdevice = 0; + m_recvpktinfo = false; NS_LOG_FUNCTION_NOARGS (); } @@ -324,6 +325,13 @@ Socket::GetBoundNetDevice () return m_boundnetdevice; } +void +Socket::SetRecvPktInfo (bool flag) +{ + NS_LOG_FUNCTION_NOARGS (); + m_recvpktinfo = flag; +} + /*************************************************************** * Socket Tags ***************************************************************/ diff --git a/src/node/socket.h b/src/node/socket.h index e61399884..14a77316b 100644 --- a/src/node/socket.h +++ b/src/node/socket.h @@ -570,6 +570,16 @@ public: */ virtual bool GetAllowBroadcast () const = 0; + /** + * \brief Enable/Disable receive packet information to socket. + * + * For IP_PKTINFO/IP6_PKTINFO. This method is only usable for + * Raw socket and Datagram Socket. Not supported for Stream socket. + * + * \param Enable/Disable receive information + * \returns nothing + */ + void SetRecvPktInfo (bool flag); protected: void NotifyConnectionSucceeded (void); @@ -583,6 +593,7 @@ protected: void NotifyDataRecv (void); virtual void DoDispose (void); Ptr m_boundnetdevice; + bool m_recvpktinfo; private: Callback > m_connectionSucceeded; Callback > m_connectionFailed; diff --git a/src/node/wscript b/src/node/wscript index 20f7ea6e3..8c9764d85 100644 --- a/src/node/wscript +++ b/src/node/wscript @@ -51,6 +51,8 @@ def build(bld): 'radiotap-header.cc', 'spectrum-phy.cc', 'spectrum-channel.cc', + 'ipv4-packet-info-tag.cc', + 'ipv6-packet-info-tag.cc', ] headers = bld.new_task_gen('ns3header') @@ -103,4 +105,6 @@ def build(bld): 'spectrum-phy.h', 'spectrum-channel.h', 'phy-mac.h', + 'ipv4-packet-info-tag.h', + 'ipv6-packet-info-tag.h', ]