00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ns3/log.h"
00022 #include "ns3/assert.h"
00023 #include "ns3/packet.h"
00024 #include "ns3/node.h"
00025 #include "ns3/boolean.h"
00026
00027 #include "udp-l4-protocol.h"
00028 #include "udp-header.h"
00029 #include "ipv4-end-point-demux.h"
00030 #include "ipv4-end-point.h"
00031 #include "ipv4-l3-protocol.h"
00032 #include "udp-socket-impl.h"
00033
00034 NS_LOG_COMPONENT_DEFINE ("UdpL4Protocol");
00035
00036 namespace ns3 {
00037
00038 NS_OBJECT_ENSURE_REGISTERED (UdpL4Protocol);
00039
00040
00041 const uint8_t UdpL4Protocol::PROT_NUMBER = 17;
00042
00043 TypeId
00044 UdpL4Protocol::GetTypeId (void)
00045 {
00046 static TypeId tid = TypeId ("ns3::UdpL4Protocol")
00047 .SetParent<Ipv4L4Protocol> ()
00048 .AddConstructor<UdpL4Protocol> ()
00049 .AddAttribute ("CalcChecksum", "If true, we calculate the checksum of outgoing packets"
00050 " and verify the checksum of incoming packets.",
00051 BooleanValue (false),
00052 MakeBooleanAccessor (&UdpL4Protocol::m_calcChecksum),
00053 MakeBooleanChecker ())
00054 ;
00055 return tid;
00056 }
00057
00058 UdpL4Protocol::UdpL4Protocol ()
00059 : m_endPoints (new Ipv4EndPointDemux ())
00060 {
00061 NS_LOG_FUNCTION_NOARGS ();
00062 }
00063
00064 UdpL4Protocol::~UdpL4Protocol ()
00065 {
00066 NS_LOG_FUNCTION_NOARGS ();
00067 }
00068
00069 void
00070 UdpL4Protocol::SetNode (Ptr<Node> node)
00071 {
00072 m_node = node;
00073 }
00074
00075 int
00076 UdpL4Protocol::GetProtocolNumber (void) const
00077 {
00078 return PROT_NUMBER;
00079 }
00080
00081
00082 void
00083 UdpL4Protocol::DoDispose (void)
00084 {
00085 NS_LOG_FUNCTION_NOARGS ();
00086 if (m_endPoints != 0)
00087 {
00088 delete m_endPoints;
00089 m_endPoints = 0;
00090 }
00091 m_node = 0;
00092 Ipv4L4Protocol::DoDispose ();
00093 }
00094
00095 Ptr<Socket>
00096 UdpL4Protocol::CreateSocket (void)
00097 {
00098 NS_LOG_FUNCTION_NOARGS ();
00099 Ptr<UdpSocketImpl> socket = CreateObject<UdpSocketImpl> ();
00100 socket->SetNode (m_node);
00101 socket->SetUdp (this);
00102 return socket;
00103 }
00104
00105 Ipv4EndPoint *
00106 UdpL4Protocol::Allocate (void)
00107 {
00108 NS_LOG_FUNCTION_NOARGS ();
00109 return m_endPoints->Allocate ();
00110 }
00111
00112 Ipv4EndPoint *
00113 UdpL4Protocol::Allocate (Ipv4Address address)
00114 {
00115 NS_LOG_FUNCTION (this << address);
00116 return m_endPoints->Allocate (address);
00117 }
00118
00119 Ipv4EndPoint *
00120 UdpL4Protocol::Allocate (uint16_t port)
00121 {
00122 NS_LOG_FUNCTION (this << port);
00123 return m_endPoints->Allocate (port);
00124 }
00125
00126 Ipv4EndPoint *
00127 UdpL4Protocol::Allocate (Ipv4Address address, uint16_t port)
00128 {
00129 NS_LOG_FUNCTION (this << address << port);
00130 return m_endPoints->Allocate (address, port);
00131 }
00132 Ipv4EndPoint *
00133 UdpL4Protocol::Allocate (Ipv4Address localAddress, uint16_t localPort,
00134 Ipv4Address peerAddress, uint16_t peerPort)
00135 {
00136 NS_LOG_FUNCTION (this << localAddress << localPort << peerAddress << peerPort);
00137 return m_endPoints->Allocate (localAddress, localPort,
00138 peerAddress, peerPort);
00139 }
00140
00141 void
00142 UdpL4Protocol::DeAllocate (Ipv4EndPoint *endPoint)
00143 {
00144 NS_LOG_FUNCTION (this << endPoint);
00145 m_endPoints->DeAllocate (endPoint);
00146 }
00147
00148 void
00149 UdpL4Protocol::ReceiveIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
00150 uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo,
00151 Ipv4Address payloadSource,Ipv4Address payloadDestination,
00152 const uint8_t payload[8])
00153 {
00154 NS_LOG_FUNCTION (this << icmpSource << icmpTtl << icmpType << icmpCode << icmpInfo
00155 << payloadSource << payloadDestination);
00156 uint16_t src, dst;
00157 src = payload[0] << 8;
00158 src |= payload[1];
00159 dst = payload[2] << 8;
00160 dst |= payload[3];
00161
00162 Ipv4EndPoint *endPoint = m_endPoints->SimpleLookup (payloadSource, src, payloadDestination, dst);
00163 if (endPoint != 0)
00164 {
00165 endPoint->ForwardIcmp (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
00166 }
00167 else
00168 {
00169 NS_LOG_DEBUG ("no endpoint found source=" << payloadSource <<
00170 ", destination="<<payloadDestination<<
00171 ", src=" << src << ", dst=" << dst);
00172 }
00173 }
00174
00175 enum Ipv4L4Protocol::RxStatus
00176 UdpL4Protocol::Receive(Ptr<Packet> packet,
00177 Ipv4Address const &source,
00178 Ipv4Address const &destination,
00179 Ptr<Ipv4Interface> interface)
00180 {
00181 NS_LOG_FUNCTION (this << packet << source << destination);
00182 UdpHeader udpHeader;
00183 if(m_calcChecksum)
00184 {
00185 udpHeader.EnableChecksums();
00186 }
00187
00188 udpHeader.InitializeChecksum (source, destination, PROT_NUMBER);
00189
00190 packet->RemoveHeader (udpHeader);
00191
00192 if(!udpHeader.IsChecksumOk ())
00193 {
00194 NS_LOG_INFO("Bad checksum : dropping packet!");
00195 return Ipv4L4Protocol::RX_CSUM_FAILED;
00196 }
00197
00198 Ipv4EndPointDemux::EndPoints endPoints =
00199 m_endPoints->Lookup (destination, udpHeader.GetDestinationPort (),
00200 source, udpHeader.GetSourcePort (), interface);
00201 if (endPoints.empty ())
00202 {
00203 return Ipv4L4Protocol::RX_ENDPOINT_UNREACH;
00204 }
00205 for (Ipv4EndPointDemux::EndPointsI endPoint = endPoints.begin ();
00206 endPoint != endPoints.end (); endPoint++)
00207 {
00208 (*endPoint)->ForwardUp (packet->Copy (), source, udpHeader.GetSourcePort ());
00209 }
00210 return Ipv4L4Protocol::RX_OK;
00211 }
00212
00213 void
00214 UdpL4Protocol::Send (Ptr<Packet> packet,
00215 Ipv4Address saddr, Ipv4Address daddr,
00216 uint16_t sport, uint16_t dport)
00217 {
00218 NS_LOG_FUNCTION (this << packet << saddr << daddr << sport << dport);
00219
00220 UdpHeader udpHeader;
00221 if(m_calcChecksum)
00222 {
00223 udpHeader.EnableChecksums();
00224 udpHeader.InitializeChecksum (saddr,
00225 daddr,
00226 PROT_NUMBER);
00227 }
00228 udpHeader.SetDestinationPort (dport);
00229 udpHeader.SetSourcePort (sport);
00230
00231 packet->AddHeader (udpHeader);
00232
00233 Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
00234 if (ipv4 != 0)
00235 {
00236 NS_LOG_LOGIC ("Sending to IP");
00237 ipv4->Send (packet, saddr, daddr, PROT_NUMBER);
00238 }
00239 }
00240
00241
00242 };
00243