00001 #include "ipv4-raw-socket-impl.h"
00002 #include "ipv4-l3-protocol.h"
00003 #include "icmpv4.h"
00004 #include "ns3/inet-socket-address.h"
00005 #include "ns3/node.h"
00006 #include "ns3/packet.h"
00007 #include "ns3/uinteger.h"
00008 #include "ns3/log.h"
00009
00010 NS_LOG_COMPONENT_DEFINE ("Ipv4RawSocketImpl");
00011
00012 namespace ns3 {
00013
00014 NS_OBJECT_ENSURE_REGISTERED (Ipv4RawSocketImpl);
00015
00016 TypeId
00017 Ipv4RawSocketImpl::GetTypeId (void)
00018 {
00019 static TypeId tid = TypeId ("ns3::Ipv4RawSocketImpl")
00020 .SetParent<Socket> ()
00021 .AddAttribute ("Protocol", "Protocol number to match.",
00022 UintegerValue (0),
00023 MakeUintegerAccessor (&Ipv4RawSocketImpl::m_protocol),
00024 MakeUintegerChecker<uint16_t> ())
00025 .AddAttribute ("IcmpFilter",
00026 "Any icmp header whose type field matches a bit in this filter is dropped.",
00027 UintegerValue (0),
00028 MakeUintegerAccessor (&Ipv4RawSocketImpl::m_icmpFilter),
00029 MakeUintegerChecker<uint32_t> ())
00030 ;
00031 return tid;
00032 }
00033
00034 Ipv4RawSocketImpl::Ipv4RawSocketImpl ()
00035 {
00036 NS_LOG_FUNCTION (this);
00037 m_err = Socket::ERROR_NOTERROR;
00038 m_node = 0;
00039 m_src = Ipv4Address::GetAny ();
00040 m_dst = Ipv4Address::GetAny ();
00041 m_protocol = 0;
00042 m_shutdownSend = false;
00043 m_shutdownRecv = false;
00044 }
00045
00046 void
00047 Ipv4RawSocketImpl::SetNode (Ptr<Node> node)
00048 {
00049 m_node = node;
00050 }
00051
00052 void
00053 Ipv4RawSocketImpl::DoDispose (void)
00054 {
00055 NS_LOG_FUNCTION (this);
00056 m_node = 0;
00057 Socket::DoDispose ();
00058 }
00059
00060 enum Socket::SocketErrno
00061 Ipv4RawSocketImpl::GetErrno (void) const
00062 {
00063 NS_LOG_FUNCTION (this);
00064 return m_err;
00065 }
00066 Ptr<Node>
00067 Ipv4RawSocketImpl::GetNode (void) const
00068 {
00069 NS_LOG_FUNCTION (this);
00070 return m_node;
00071 }
00072 int
00073 Ipv4RawSocketImpl::Bind (const Address &address)
00074 {
00075 NS_LOG_FUNCTION (this << address);
00076 if (!InetSocketAddress::IsMatchingType (address))
00077 {
00078 m_err = Socket::ERROR_INVAL;
00079 return -1;
00080 }
00081 InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
00082 m_src = ad.GetIpv4 ();
00083 return 0;
00084 }
00085 int
00086 Ipv4RawSocketImpl::Bind (void)
00087 {
00088 NS_LOG_FUNCTION (this);
00089 m_src = Ipv4Address::GetAny ();
00090 return 0;
00091 }
00092 int
00093 Ipv4RawSocketImpl::GetSockName (Address &address) const
00094 {
00095 address = InetSocketAddress (m_src, 0);
00096 return 0;
00097 }
00098 int
00099 Ipv4RawSocketImpl::Close (void)
00100 {
00101 NS_LOG_FUNCTION (this);
00102 Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
00103 if (ipv4 != 0)
00104 {
00105 ipv4->DeleteRawSocket (this);
00106 }
00107 return 0;
00108 }
00109 int
00110 Ipv4RawSocketImpl::ShutdownSend (void)
00111 {
00112 NS_LOG_FUNCTION (this);
00113 m_shutdownSend = true;
00114 return 0;
00115 }
00116 int
00117 Ipv4RawSocketImpl::ShutdownRecv (void)
00118 {
00119 NS_LOG_FUNCTION (this);
00120 m_shutdownRecv = true;
00121 return 0;
00122 }
00123 int
00124 Ipv4RawSocketImpl::Connect (const Address &address)
00125 {
00126 NS_LOG_FUNCTION (this << address);
00127 if (!InetSocketAddress::IsMatchingType (address))
00128 {
00129 m_err = Socket::ERROR_INVAL;
00130 return -1;
00131 }
00132 InetSocketAddress ad = InetSocketAddress::ConvertFrom (address);
00133 m_dst = ad.GetIpv4 ();
00134 return 0;
00135 }
00136 int
00137 Ipv4RawSocketImpl::Listen (void)
00138 {
00139 NS_LOG_FUNCTION (this);
00140 m_err = Socket::ERROR_OPNOTSUPP;
00141 return -1;
00142 }
00143 uint32_t
00144 Ipv4RawSocketImpl::GetTxAvailable (void) const
00145 {
00146 NS_LOG_FUNCTION (this);
00147 return 0xffffffff;
00148 }
00149 int
00150 Ipv4RawSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
00151 {
00152 NS_LOG_FUNCTION (this << p << flags);
00153 InetSocketAddress to = InetSocketAddress (m_dst, m_protocol);
00154 return SendTo (p, flags, to);
00155 }
00156 int
00157 Ipv4RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags,
00158 const Address &toAddress)
00159 {
00160 NS_LOG_FUNCTION (this << p << flags << toAddress);
00161 if (!InetSocketAddress::IsMatchingType (toAddress))
00162 {
00163 m_err = Socket::ERROR_INVAL;
00164 return -1;
00165 }
00166 if (m_shutdownSend)
00167 {
00168 return 0;
00169 }
00170 InetSocketAddress ad = InetSocketAddress::ConvertFrom (toAddress);
00171 Ptr<Ipv4L3Protocol> ipv4 = m_node->GetObject<Ipv4L3Protocol> ();
00172 Ipv4Address dst = ad.GetIpv4 ();
00173 uint32_t localIfIndex;
00174 if (ipv4->GetIfIndexForDestination(dst, localIfIndex))
00175 {
00176 ipv4->Send (p, ipv4->GetAddress (localIfIndex), dst, m_protocol);
00177 }
00178 else
00179 {
00180 NS_LOG_DEBUG ("dropped because no outgoing route.");
00181 }
00182 return 0;
00183 }
00184 uint32_t
00185 Ipv4RawSocketImpl::GetRxAvailable (void) const
00186 {
00187 NS_LOG_FUNCTION (this);
00188 uint32_t rx = 0;
00189 for (std::list<Data>::const_iterator i = m_recv.begin (); i != m_recv.end (); ++i)
00190 {
00191 rx += (i->packet)->GetSize ();
00192 }
00193 return rx;
00194 }
00195 Ptr<Packet>
00196 Ipv4RawSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
00197 {
00198 NS_LOG_FUNCTION (this << maxSize << flags);
00199 Address tmp;
00200 return RecvFrom (maxSize, flags, tmp);
00201 }
00202 Ptr<Packet>
00203 Ipv4RawSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
00204 Address &fromAddress)
00205 {
00206 NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
00207 if (m_recv.empty ())
00208 {
00209 return 0;
00210 }
00211 struct Data data = m_recv.front ();
00212 m_recv.pop_front ();
00213 if (data.packet->GetSize () > maxSize)
00214 {
00215 Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
00216 data.packet->RemoveAtStart (maxSize);
00217 m_recv.push_front (data);
00218 return first;
00219 }
00220 InetSocketAddress inet = InetSocketAddress (data.fromIp, data.fromProtocol);
00221 fromAddress = inet;
00222 return data.packet;
00223 }
00224
00225 void
00226 Ipv4RawSocketImpl::SetProtocol (uint16_t protocol)
00227 {
00228 NS_LOG_FUNCTION (this << protocol);
00229 m_protocol = protocol;
00230 }
00231
00232 bool
00233 Ipv4RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv4Header ipHeader, Ptr<NetDevice> device)
00234 {
00235 NS_LOG_FUNCTION (this << *p << ipHeader << device);
00236 if (m_shutdownRecv)
00237 {
00238 return false;
00239 }
00240 if ((m_src == Ipv4Address::GetAny () || ipHeader.GetDestination () == m_src) &&
00241 (m_dst == Ipv4Address::GetAny () || ipHeader.GetSource () == m_dst) &&
00242 ipHeader.GetProtocol () == m_protocol)
00243 {
00244 Ptr<Packet> copy = p->Copy ();
00245 if (m_protocol == 1)
00246 {
00247 Icmpv4Header icmpHeader;
00248 copy->PeekHeader (icmpHeader);
00249 uint8_t type = icmpHeader.GetType ();
00250 if (type < 32 &&
00251 ((1 << type) & m_icmpFilter))
00252 {
00253
00254 return false;
00255 }
00256 }
00257 copy->AddHeader (ipHeader);
00258 struct Data data;
00259 data.packet = copy;
00260 data.fromIp = ipHeader.GetSource ();
00261 data.fromProtocol = ipHeader.GetProtocol ();
00262 m_recv.push_back (data);
00263 NotifyDataRecv ();
00264 return true;
00265 }
00266 return false;
00267 }
00268
00269 }