PageRenderTime 56ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/src/internet/model/ipv6-raw-socket-impl.cc

https://github.com/scarletttu/ns-3-codel-dev
C++ | 414 lines | 324 code | 64 blank | 26 comment | 34 complexity | 6d053c153c6bc4063344359eb89ed7d2 MD5 | raw file
Possible License(s): GPL-2.0
  1. /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
  2. /*
  3. * Copyright (c) 2007-2009 Strasbourg University
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation;
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. *
  18. * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
  19. */
  20. #include <netinet/in.h>
  21. #include <sys/socket.h>
  22. #include <sys/types.h>
  23. #include "ns3/inet6-socket-address.h"
  24. #include "ns3/node.h"
  25. #include "ns3/packet.h"
  26. #include "ns3/uinteger.h"
  27. #include "ns3/log.h"
  28. #include "ns3/ipv6-route.h"
  29. #include "ns3/ipv6-routing-protocol.h"
  30. #include "ns3/ipv6-packet-info-tag.h"
  31. #include "ipv6-l3-protocol.h"
  32. #include "ipv6-raw-socket-impl.h"
  33. #include "icmpv6-header.h"
  34. #include "icmpv6-l4-protocol.h"
  35. namespace ns3
  36. {
  37. NS_LOG_COMPONENT_DEFINE ("Ipv6RawSocketImpl");
  38. NS_OBJECT_ENSURE_REGISTERED (Ipv6RawSocketImpl);
  39. TypeId Ipv6RawSocketImpl::GetTypeId ()
  40. {
  41. static TypeId tid = TypeId ("ns3::Ipv6RawSocketImpl")
  42. .SetParent<Socket> ()
  43. .AddAttribute ("Protocol", "Protocol number to match.",
  44. UintegerValue (0),
  45. MakeUintegerAccessor (&Ipv6RawSocketImpl::m_protocol),
  46. MakeUintegerChecker<uint16_t> ())
  47. ;
  48. return tid;
  49. }
  50. Ipv6RawSocketImpl::Ipv6RawSocketImpl ()
  51. {
  52. NS_LOG_FUNCTION_NOARGS ();
  53. m_err = Socket::ERROR_NOTERROR;
  54. m_node = 0;
  55. m_src = Ipv6Address::GetAny ();
  56. m_dst = Ipv6Address::GetAny ();
  57. m_protocol = 0;
  58. m_shutdownSend = false;
  59. m_shutdownRecv = false;
  60. Icmpv6FilterSetPassAll();
  61. }
  62. Ipv6RawSocketImpl::~Ipv6RawSocketImpl ()
  63. {
  64. }
  65. void Ipv6RawSocketImpl::DoDispose ()
  66. {
  67. NS_LOG_FUNCTION_NOARGS ();
  68. m_node = 0;
  69. Socket::DoDispose ();
  70. }
  71. void Ipv6RawSocketImpl::SetNode (Ptr<Node> node)
  72. {
  73. NS_LOG_FUNCTION (this << node);
  74. m_node = node;
  75. }
  76. Ptr<Node> Ipv6RawSocketImpl::GetNode () const
  77. {
  78. return m_node;
  79. }
  80. enum Socket::SocketErrno Ipv6RawSocketImpl::GetErrno () const
  81. {
  82. NS_LOG_FUNCTION_NOARGS ();
  83. return m_err;
  84. }
  85. enum Socket::SocketType Ipv6RawSocketImpl::GetSocketType () const
  86. {
  87. return NS3_SOCK_RAW;
  88. }
  89. int Ipv6RawSocketImpl::Bind (const Address& address)
  90. {
  91. NS_LOG_FUNCTION (this << address);
  92. if (!Inet6SocketAddress::IsMatchingType (address))
  93. {
  94. m_err = Socket::ERROR_INVAL;
  95. return -1;
  96. }
  97. Inet6SocketAddress ad = Inet6SocketAddress::ConvertFrom (address);
  98. m_src = ad.GetIpv6 ();
  99. return 0;
  100. }
  101. int Ipv6RawSocketImpl::Bind ()
  102. {
  103. NS_LOG_FUNCTION_NOARGS ();
  104. m_src = Ipv6Address::GetAny ();
  105. return 0;
  106. }
  107. int Ipv6RawSocketImpl::Bind6 ()
  108. {
  109. return(Bind());
  110. }
  111. int Ipv6RawSocketImpl::GetSockName (Address& address) const
  112. {
  113. NS_LOG_FUNCTION_NOARGS ();
  114. address = Inet6SocketAddress (m_src, 0);
  115. return 0;
  116. }
  117. int Ipv6RawSocketImpl::Close ()
  118. {
  119. NS_LOG_FUNCTION_NOARGS ();
  120. Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
  121. if (ipv6)
  122. {
  123. ipv6->DeleteRawSocket (this);
  124. }
  125. return 0;
  126. }
  127. int Ipv6RawSocketImpl::ShutdownSend ()
  128. {
  129. NS_LOG_FUNCTION_NOARGS ();
  130. m_shutdownSend = true;
  131. return 0;
  132. }
  133. int Ipv6RawSocketImpl::ShutdownRecv ()
  134. {
  135. NS_LOG_FUNCTION_NOARGS ();
  136. m_shutdownRecv = true;
  137. return 0;
  138. }
  139. int Ipv6RawSocketImpl::Connect (const Address& address)
  140. {
  141. NS_LOG_FUNCTION (this << address);
  142. if (!Inet6SocketAddress::IsMatchingType (address))
  143. {
  144. m_err = Socket::ERROR_INVAL;
  145. return -1;
  146. }
  147. Inet6SocketAddress ad = Inet6SocketAddress::ConvertFrom (address);
  148. m_dst = ad.GetIpv6 ();
  149. return 0;
  150. }
  151. int Ipv6RawSocketImpl::Listen ()
  152. {
  153. NS_LOG_FUNCTION_NOARGS ();
  154. m_err = Socket::ERROR_OPNOTSUPP;
  155. return -1;
  156. }
  157. int Ipv6RawSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
  158. {
  159. NS_LOG_FUNCTION (this << p << flags);
  160. Inet6SocketAddress to = Inet6SocketAddress (m_dst, m_protocol);
  161. return SendTo (p, flags, to);
  162. }
  163. int Ipv6RawSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address& toAddress)
  164. {
  165. NS_LOG_FUNCTION (this << p << flags << toAddress);
  166. if (!Inet6SocketAddress::IsMatchingType (toAddress))
  167. {
  168. m_err = Socket::ERROR_INVAL;
  169. return -1;
  170. }
  171. if (m_shutdownSend)
  172. {
  173. return 0;
  174. }
  175. Inet6SocketAddress ad = Inet6SocketAddress::ConvertFrom (toAddress);
  176. Ptr<Ipv6L3Protocol> ipv6 = m_node->GetObject<Ipv6L3Protocol> ();
  177. Ipv6Address dst = ad.GetIpv6 ();
  178. if (ipv6->GetRoutingProtocol ())
  179. {
  180. Ipv6Header hdr;
  181. hdr.SetDestinationAddress (dst);
  182. SocketErrno err = ERROR_NOTERROR;
  183. Ptr<Ipv6Route> route = 0;
  184. Ptr<NetDevice> oif (0); /*specify non-zero if bound to a source address */
  185. if (!m_src.IsAny ())
  186. {
  187. int32_t index = ipv6->GetInterfaceForAddress (m_src);
  188. NS_ASSERT (index >= 0);
  189. oif = ipv6->GetNetDevice (index);
  190. }
  191. route = ipv6->GetRoutingProtocol ()->RouteOutput (p, hdr, oif, err);
  192. if (route)
  193. {
  194. NS_LOG_LOGIC ("Route exists");
  195. if (m_protocol == Icmpv6L4Protocol::GetStaticProtocolNumber ())
  196. {
  197. /* calculate checksum here for ICMPv6 echo request (sent by ping6)
  198. * as we cannot determine source IPv6 address at application level
  199. */
  200. uint8_t type;
  201. p->CopyData (&type, sizeof(type));
  202. if (type == Icmpv6Header::ICMPV6_ECHO_REQUEST)
  203. {
  204. Icmpv6Echo hdr (1);
  205. p->RemoveHeader (hdr);
  206. hdr.CalculatePseudoHeaderChecksum (route->GetSource (), dst, p->GetSize () + hdr.GetSerializedSize (), Icmpv6L4Protocol::GetStaticProtocolNumber ());
  207. p->AddHeader (hdr);
  208. }
  209. }
  210. ipv6->Send (p, route->GetSource (), dst, m_protocol, route);
  211. }
  212. else
  213. {
  214. NS_LOG_DEBUG ("No route, dropped!");
  215. }
  216. }
  217. return 0;
  218. }
  219. Ptr<Packet> Ipv6RawSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
  220. {
  221. NS_LOG_FUNCTION (this << maxSize << flags);
  222. Address tmp;
  223. return RecvFrom (maxSize, flags, tmp);
  224. }
  225. Ptr<Packet> Ipv6RawSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags, Address& fromAddress)
  226. {
  227. NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
  228. if (m_data.empty ())
  229. {
  230. return 0;
  231. }
  232. /* get packet */
  233. struct Data data = m_data.front ();
  234. m_data.pop_front ();
  235. if (data.packet->GetSize () > maxSize)
  236. {
  237. Ptr<Packet> first = data.packet->CreateFragment (0, maxSize);
  238. if (!(flags & MSG_PEEK))
  239. {
  240. data.packet->RemoveAtStart (maxSize);
  241. }
  242. m_data.push_front (data);
  243. return first;
  244. }
  245. fromAddress = Inet6SocketAddress (data.fromIp, data.fromProtocol);
  246. return data.packet;
  247. }
  248. uint32_t Ipv6RawSocketImpl::GetTxAvailable () const
  249. {
  250. NS_LOG_FUNCTION_NOARGS ();
  251. return 0xffffffff;
  252. }
  253. uint32_t Ipv6RawSocketImpl::GetRxAvailable () const
  254. {
  255. NS_LOG_FUNCTION_NOARGS ();
  256. uint32_t rx = 0;
  257. for (std::list<Data>::const_iterator it = m_data.begin (); it != m_data.end (); ++it)
  258. {
  259. rx+= (it->packet)->GetSize ();
  260. }
  261. return rx;
  262. }
  263. bool Ipv6RawSocketImpl::ForwardUp (Ptr<const Packet> p, Ipv6Header hdr, Ptr<NetDevice> device)
  264. {
  265. NS_LOG_FUNCTION (this << *p << hdr << device);
  266. if (m_shutdownRecv)
  267. {
  268. return false;
  269. }
  270. if ((m_src == Ipv6Address::GetAny () || hdr.GetDestinationAddress () == m_src) &&
  271. (m_dst == Ipv6Address::GetAny () || hdr.GetSourceAddress () == m_dst) &&
  272. hdr.GetNextHeader () == m_protocol)
  273. {
  274. Ptr<Packet> copy = p->Copy ();
  275. if (m_protocol == Icmpv6L4Protocol::GetStaticProtocolNumber ())
  276. {
  277. /* filter */
  278. Icmpv6Header icmpHeader;
  279. copy->PeekHeader (icmpHeader);
  280. uint8_t type = icmpHeader.GetType ();
  281. if (Icmpv6FilterWillBlock(type))
  282. {
  283. /* packet filtered */
  284. return false;
  285. }
  286. }
  287. // Should check via getsockopt ()..
  288. if (IsRecvPktInfo ())
  289. {
  290. Ipv6PacketInfoTag tag;
  291. copy->RemovePacketTag (tag);
  292. tag.SetRecvIf (device->GetIfIndex ());
  293. copy->AddPacketTag (tag);
  294. }
  295. copy->AddHeader (hdr);
  296. struct Data data;
  297. data.packet = copy;
  298. data.fromIp = hdr.GetSourceAddress ();
  299. data.fromProtocol = hdr.GetNextHeader ();
  300. m_data.push_back (data);
  301. NotifyDataRecv ();
  302. return true;
  303. }
  304. return false;
  305. }
  306. bool
  307. Ipv6RawSocketImpl::SetAllowBroadcast (bool allowBroadcast)
  308. {
  309. if (!allowBroadcast)
  310. {
  311. return false;
  312. }
  313. return true;
  314. }
  315. bool
  316. Ipv6RawSocketImpl::GetAllowBroadcast () const
  317. {
  318. return true;
  319. }
  320. void
  321. Ipv6RawSocketImpl::Icmpv6FilterSetPassAll()
  322. {
  323. memset(&m_icmpFilter, 0xff, sizeof(icmpv6Filter));
  324. }
  325. void
  326. Ipv6RawSocketImpl::Icmpv6FilterSetBlockAll()
  327. {
  328. memset(&m_icmpFilter, 0x00, sizeof(icmpv6Filter));
  329. }
  330. void
  331. Ipv6RawSocketImpl::Icmpv6FilterSetPass(uint8_t type)
  332. {
  333. (m_icmpFilter.icmpv6Filt[(type) >> 5]) |= (uint32_t(1) << ((type) & 31));
  334. }
  335. void
  336. Ipv6RawSocketImpl::Icmpv6FilterSetBlock(uint8_t type)
  337. {
  338. (m_icmpFilter.icmpv6Filt[(type) >> 5]) &= ~(uint32_t(1) << ((type) & 31));
  339. }
  340. bool
  341. Ipv6RawSocketImpl::Icmpv6FilterWillPass(uint8_t type)
  342. {
  343. return (((m_icmpFilter.icmpv6Filt[(type) >> 5]) & (uint32_t(1) << ((type) & 31))) != 0);
  344. }
  345. bool
  346. Ipv6RawSocketImpl::Icmpv6FilterWillBlock(uint8_t type)
  347. {
  348. return (((m_icmpFilter.icmpv6Filt[(type) >> 5]) & (uint32_t(1) << ((type) & 31))) == 0);
  349. }
  350. } /* namespace ns3 */