ns-3 Direct Code Execution
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
unix-socket-fd.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2006,2007 INRIA
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: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 #include "unix-socket-fd.h"
21 #include "process.h"
22 #include "dce-manager.h"
23 #include "utils.h"
24 #include "cmsg.h"
25 #include "sys/dce-socket.h"
26 #include "ns3/log.h"
27 #include "ns3/socket.h"
28 #include "ns3/packet.h"
29 #include "ns3/inet-socket-address.h"
30 #include "ns3/packet-socket-address.h"
31 #include "ns3/packet-socket.h"
32 #include "ns3/uinteger.h"
33 #include "ns3/boolean.h"
34 #include "ns3/simulator.h"
35 #include "ns3/netlink-socket-address.h"
36 #include "ns3/inet6-socket-address.h"
37 #include <fcntl.h>
38 #include <errno.h>
39 #include <linux/icmp.h> // need ICMP_FILTER
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <sys/mman.h>
43 #include <net/ethernet.h>
44 #include <linux/if_arp.h>
45 #include <linux/netlink.h>
46 #include <poll.h>
47 #include <linux/netlink.h>
48 #include <sys/ioctl.h>
49 
50 NS_LOG_COMPONENT_DEFINE ("UnixSocketFd");
51 
52 namespace ns3 {
53 
54 UnixSocketFd::UnixSocketFd (Ptr<Socket> socket)
55  : m_socket (socket),
56  m_sendTimeout (Seconds (0.0)),
57  m_recvTimeout (Seconds (0.0)),
58  m_peekedData (0)
59 {
60  m_socket->SetAttributeFailSafe ("SndBufSize", UintegerValue (126976));
61  m_socket->SetAttributeFailSafe ("RcvBufSize", UintegerValue (126976));
62  m_socket->SetRecvCallback (MakeCallback (&UnixSocketFd::RecvSocketData, this));
63  m_socket->SetSendCallback (MakeCallback (&UnixSocketFd::SendSocketData, this));
64 }
66 {
67  NS_LOG_FUNCTION (this);
68  ClearSocket ();
69 }
70 void *
71 UnixSocketFd::Mmap (void *start, size_t length, int prot, int flags, off64_t offset)
72 {
73  Thread *current = Current ();
74  NS_LOG_FUNCTION (this << current << start << length << prot << flags << offset);
75  NS_ASSERT (current != 0);
76  current->err = ENODEV;
77  return MAP_FAILED;
78 }
79 int
80 UnixSocketFd::Fxstat (int ver, struct stat *buf)
81 {
82  NS_LOG_FUNCTION (this << Current () << buf);
83  NS_ASSERT (Current () != 0);
84  buf->st_mode = S_IFSOCK;
85  buf->st_dev = -1;
86  buf->st_blksize = 0;
87  return 0;
88 }
89 int
90 UnixSocketFd::Fxstat64 (int ver, struct stat64 *buf)
91 {
92  NS_LOG_FUNCTION (this << Current () << buf);
93  NS_ASSERT (Current () != 0);
94  buf->st_mode = S_IFSOCK;
95  buf->st_dev = -1;
96  buf->st_blksize = 0;
97  return 0;
98 }
99 int
101 {
102  switch (m_socket->GetErrno ())
103  {
104  case Socket::ERROR_ISCONN:
105  return EISCONN;
106  case Socket::ERROR_NOTCONN:
107  return ENOTCONN;
108  case Socket::ERROR_MSGSIZE:
109  return EMSGSIZE;
110  case Socket::ERROR_AGAIN:
111  return EAGAIN;
112  case Socket::ERROR_SHUTDOWN:
113  return EPIPE;
114  case Socket::ERROR_OPNOTSUPP:
115  return EOPNOTSUPP;
116  case Socket::ERROR_AFNOSUPPORT:
117  return EAFNOSUPPORT;
118  case Socket::ERROR_INVAL:
119  return EINVAL;
120  case Socket::ERROR_BADF:
121  return EBADF;
122  case Socket::ERROR_NOROUTETOHOST:
123  return EHOSTUNREACH;
124  case Socket::SOCKET_ERRNO_LAST:
125  case Socket::ERROR_NOTERROR:
126  return EAGAIN;
127  case Socket::ERROR_ADDRINUSE:
128  return EADDRINUSE;
129  default:
130  NS_LOG_ERROR ("Unknown Errno:" << m_socket->GetErrno ());
131  NS_ASSERT (false);
132  return 0; // quiet compiler
133  break;
134  }
135 }
136 void
137 UnixSocketFd::RecvSocketData (Ptr<Socket> socket)
138 {
139  NS_LOG_FUNCTION (this << m_socket << socket);
140 
141  int pi = POLLIN;
142  WakeWaiters (&pi);
143 }
144 void
145 UnixSocketFd::SendSocketData (Ptr<Socket> socket, uint32_t available)
146 {
147  NS_LOG_FUNCTION (this << m_socket << socket);
148 
149  int pi = POLLOUT;
150  WakeWaiters (&pi);
151 }
152 void
154 {
155  *res = m_socket->Close ();
156 }
157 int
159 {
160  Thread *current = Current ();
161  NS_LOG_FUNCTION (this << current);
162  NS_ASSERT (current != 0);
163 
164  Callback<void, Ptr<Socket> > nil = MakeNullCallback<void, Ptr<Socket> > ();
165  m_socket->SetCloseCallbacks (nil, nil);
166  TaskManager *manager = TaskManager::Current ();
167  int result = -1;
168  manager->ExecOnMain (MakeEvent (&UnixSocketFd::MainClose, this, &result));
169 
170  if (result == -1)
171  {
172  current->err = ErrnoToSimuErrno ();
173  }
174  ClearSocket ();
183  int pi = POLLHUP;
184  WakeWaiters (&pi);
185  return result;
186 }
187 ssize_t
188 UnixSocketFd::Write (const void *buf, size_t count)
189 {
190  NS_LOG_FUNCTION (this << buf << count);
191  struct msghdr msg;
192  struct iovec iov;
193  msg.msg_control = 0;
194  msg.msg_controllen = 0;
195  msg.msg_iovlen = 1;
196  msg.msg_iov = &iov;
197  iov.iov_len = count;
198  iov.iov_base = (void*)buf;
199  msg.msg_name = 0;
200  msg.msg_namelen = 0;
201  ssize_t retval = Sendmsg (&msg, 0);
202  return retval;
203 }
204 ssize_t
205 UnixSocketFd::Read (void *buf, size_t count)
206 {
207  NS_LOG_FUNCTION (this << buf << count);
208  struct msghdr msg;
209  struct iovec iov;
210  msg.msg_control = 0;
211  msg.msg_controllen = 0;
212  msg.msg_iovlen = 1;
213  msg.msg_iov = &iov;
214  iov.iov_len = count;
215  iov.iov_base = buf;
216  msg.msg_name = 0;
217  msg.msg_namelen = 0;
218  ssize_t retval = Recvmsg (&msg, 0);
219  return retval;
220 }
221 ssize_t
222 UnixSocketFd::Recvmsg (struct msghdr *msg, int flags)
223 {
224  bool nonBlocking = (m_statusFlags & O_NONBLOCK) == O_NONBLOCK;
225  flags |= nonBlocking ? MSG_DONTWAIT : 0;
226  return DoRecvmsg (msg, flags);
227 }
228 ssize_t
229 UnixSocketFd::Sendmsg (const struct msghdr *msg, int flags)
230 {
231  bool nonBlocking = (m_statusFlags & O_NONBLOCK) == O_NONBLOCK;
232  flags |= nonBlocking ? MSG_DONTWAIT : 0;
233  return DoSendmsg (msg, flags);
234 }
235 
236 bool
238 {
239  return false;
240 }
241 
242 int
243 UnixSocketFd::Setsockopt (int level, int optname,
244  const void *optval, socklen_t optlen)
245 {
246  Thread *current = Current ();
247  NS_LOG_FUNCTION (this << current << level << optname << optval << optlen);
248  NS_ASSERT (current != 0);
249 
250  switch (level)
251  {
252  case SOL_RAW:
253  switch (optname)
254  {
255  case ICMP_FILTER:
256  {
257  if (optlen != 4)
258  {
259  current->err = EINVAL;
260  return -1;
261  }
262  uint32_t *data = (uint32_t *)optval;
263  if (!m_socket->SetAttributeFailSafe ("IcmpFilter", UintegerValue (*data)))
264  {
265  current->err = ENOPROTOOPT;
266  return -1;
267  }
268  } break;
269  default:
270  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_RAW, optname: " << optname);
271  break;
272  }
273  break;
274  case SOL_SOCKET:
275  switch (optname)
276  {
277  case SO_RCVTIMEO:
278  {
279  if (optlen != sizeof (struct timeval))
280  {
281  current->err = EINVAL;
282  return -1;
283  }
284  struct timeval *tv = (struct timeval *)optval;
286  } break;
287  case SO_SNDTIMEO:
288  {
289  if (optlen != sizeof (struct timeval))
290  {
291  current->err = EINVAL;
292  return -1;
293  }
294  struct timeval *tv = (struct timeval *)optval;
296  } break;
297  case SO_SNDBUF:
298  {
299  if (optlen != sizeof (int))
300  {
301  current->err = EINVAL;
302  return -1;
303  }
304  int *val = (int*)optval;
305  if (!m_socket->SetAttributeFailSafe ("SndBufSize", UintegerValue (*val)))
306  {
307  current->err = EINVAL;
308  return -1;
309  }
310  } break;
311  case SO_RCVBUF:
312  {
313  if (optlen != sizeof (int))
314  {
315  current->err = EINVAL;
316  return -1;
317  }
318  int *val = (int*)optval;
319  if (!m_socket->SetAttributeFailSafe ("RcvBufSize", UintegerValue (*val)))
320  {
321  current->err = EINVAL;
322  return -1;
323  }
324  } break;
325  default:
326  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_SOCKET, optname: " << optname);
327  break;
328  }
329  break;
330  case SOL_IP:
331  switch (optname)
332  {
333  case IP_RECVERR:
334  {
335  if (optlen != sizeof (int))
336  {
337  current->err = EINVAL;
338  return -1;
339  }
340  int *v = (int*)optval;
341  m_recverr = *v;
342  } break;
343  case IP_RECVTTL:
344  {
345  if (optlen != sizeof (int))
346  {
347  current->err = EINVAL;
348  return -1;
349  }
350  int *v = (int*)optval;
351  m_recvttl = *v;
352  } break;
353  case IP_TTL:
354  {
355  if (optlen != sizeof (int))
356  {
357  current->err = EINVAL;
358  return -1;
359  }
360  int *v = (int*)optval;
361  if (!m_socket->SetAttributeFailSafe ("IpTtl", UintegerValue (*v)))
362  {
363  current->err = ENOPROTOOPT;
364  return -1;
365  }
366  } break;
367  case IP_HDRINCL:
368  {
369  if (optlen != sizeof (int))
370  {
371  current->err = EINVAL;
372  return -1;
373  }
374  int *v = (int*)optval;
375  if (!m_socket->SetAttributeFailSafe ("IpHeaderInclude",
376  BooleanValue (*v ? true : false)))
377  {
378  current->err = ENOPROTOOPT;
379  return -1;
380  }
381  } break;
382  case IP_PKTINFO:
383  {
384  if (optlen != sizeof (int))
385  {
386  current->err = EINVAL;
387  return -1;
388  }
389  int *v = (int*)optval;
390  m_socket->SetRecvPktInfo (*v ? true : false);
391  } break;
392  default:
393  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_IP, optname: " << optname);
394  break;
395  }
396  break;
397  case SOL_IPV6:
398  switch (optname)
399  {
400  case IPV6_PKTINFO:
401  {
402  if (optlen != sizeof (int))
403  {
404  current->err = EINVAL;
405  return -1;
406  }
407  int *v = (int*)optval;
408  m_socket->SetRecvPktInfo (*v ? true : false);
409  } break;
410  // case IPV6_RECVPKTINFO: {
411  // if (optlen != sizeof (int))
412  // {
413  // current->err = EINVAL;
414  // return -1;
415  // }
416  // int *v = (int*)optval;
417  // m_recvpktinfo6 = *v;
418  // } break;
419  // case IPV6_CHECKSUM: {
420  // if (optlen != sizeof (int))
421  // {
422  // current->err = EINVAL;
423  // return -1;
424  // }
425  // int *v = (int*)optval;
426  // m_sockchecksum = *v;
427  // } break;
428  // case IPV6_MULTICAST_LOOP: {
429  // if (optlen != sizeof (int))
430  // {
431  // current->err = EINVAL;
432  // return -1;
433  // }
434  // int *v = (int*)optval;
435  // m_multicastloop = *v;
436  // } break;
437  // case IPV6_UNICAST_HOPS: {
438  // if (optlen != sizeof (int))
439  // {
440  // current->err = EINVAL;
441  // return -1;
442  // }
443  // int *v = (int*)optval;
444  // m_unicasthops = *v;
445  // } break;
446  // case IPV6_MULTICAST_HOPS: {
447  // if (optlen != sizeof (int))
448  // {
449  // current->err = EINVAL;
450  // return -1;
451  // }
452  // int *v = (int*)optval;
453  // m_multicasthops = *v;
454  // } break;
455  // case IPV6_RECVHOPLIMIT: {
456  // if (optlen != sizeof (int))
457  // {
458  // current->err = EINVAL;
459  // return -1;
460  // }
461  // int *v = (int*)optval;
462  // m_recvhoplimit = *v;
463  // } break;
464  default:
465  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_IPV6, optname: " << optname);
466  break;
467  }
468  break;
469  default:
470  {
471  NS_LOG_WARN ("Unsupported sockopt: level = " << level);
472  current->err = ENOPROTOOPT;
473  return -1;
474  } break;
475  }
476  return 0;
477 }
478 int
479 UnixSocketFd::Getsockopt (int level, int optname,
480  void *optval, socklen_t *optlen)
481 {
482  Thread *current = Current ();
483  NS_LOG_FUNCTION (this << current << level << optname << optval << optlen);
484  NS_ASSERT (current != 0);
485 
486  switch (level)
487  {
488  case SOL_RAW:
489  switch (optname)
490  {
491  case ICMP_FILTER:
492  {
493  if (*optlen < 4)
494  {
495  current->err = EINVAL;
496  return -1;
497  }
498  UintegerValue data;
499  if (!m_socket->GetAttributeFailSafe ("IcmpFilter", data))
500  {
501  current->err = ENOPROTOOPT;
502  return -1;
503  }
504  uint32_t v = data.Get ();
505  memcpy (optval, (void*)&v, 4);
506  *optlen = 4;
507  } break;
508  default:
509  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_RAW, optname: " << optname);
510  break;
511  }
512  break;
513  case SOL_SOCKET:
514  switch (optname)
515  {
516  case SO_RCVTIMEO:
517  {
518  if (*optlen < sizeof (struct timeval))
519  {
520  current->err = EINVAL;
521  return -1;
522  }
523  struct timeval *tv = (struct timeval *)optval;
525  *optlen = sizeof (struct timeval);
526  } break;
527  case SO_SNDTIMEO:
528  {
529  if (*optlen < sizeof (struct timeval))
530  {
531  current->err = EINVAL;
532  return -1;
533  }
534  struct timeval *tv = (struct timeval *)optval;
536  *optlen = sizeof (struct timeval);
537  } break;
538  case SO_SNDBUF:
539  {
540  if (*optlen < sizeof (int))
541  {
542  current->err = EINVAL;
543  return -1;
544  }
545  int *val = (int*)optval;
546  UintegerValue attrValue;
547  if (!m_socket->GetAttributeFailSafe ("SndBufSize", attrValue))
548  {
549  current->err = EINVAL;
550  return -1;
551  }
552  *val = attrValue.Get ();
553  *optlen = sizeof (int);
554  } break;
555 
556  case SO_RCVBUF:
557  {
558  if (*optlen < sizeof (int))
559  {
560  current->err = EINVAL;
561  return -1;
562  }
563  int *val = (int*)optval;
564  UintegerValue attrValue;
565  if (!m_socket->GetAttributeFailSafe ("RcvBufSize", attrValue))
566  {
567  current->err = EINVAL;
568  return -1;
569  }
570  *val = attrValue.Get ();
571  *optlen = sizeof (int);
572  } break;
573 
574  default:
575  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_SOCKET, optname: " << optname);
576  break;
577  }
578  break;
579  case SOL_IP:
580  switch (optname)
581  {
582  case IP_RECVERR:
583  {
584  if (*optlen < sizeof (int))
585  {
586  current->err = EINVAL;
587  return -1;
588  }
589  int *v = (int*)optval;
590  *v = m_recverr;
591  *optlen = sizeof (int);
592  } break;
593  case IP_RECVTTL:
594  {
595  if (*optlen < sizeof (int))
596  {
597  current->err = EINVAL;
598  return -1;
599  }
600  int *v = (int*)optval;
601  *v = m_recvttl;
602  *optlen = sizeof (int);
603  } break;
604  case IP_TTL:
605  {
606  if (*optlen < sizeof (int))
607  {
608  current->err = EINVAL;
609  return -1;
610  }
611  int *v = (int*)optval;
612  UintegerValue val;
613  if (!m_socket->GetAttributeFailSafe ("IpTtl", val))
614  {
615  current->err = ENOPROTOOPT;
616  return -1;
617  }
618  *v = val.Get ();
619  *optlen = sizeof (int);
620  } break;
621  case IP_HDRINCL:
622  {
623  if (*optlen != sizeof (int))
624  {
625  current->err = EINVAL;
626  return -1;
627  }
628  int *v = (int*)optval;
629  BooleanValue val;
630  if (!m_socket->GetAttributeFailSafe ("IpHeaderInclude", val))
631  {
632  current->err = ENOPROTOOPT;
633  return -1;
634  }
635  *v = val.Get () ? 1 : 0;
636  *optlen = sizeof (int);
637  } break;
638  default:
639  NS_LOG_WARN ("Unsupported setsockopt requested. level: SOL_IP, optname: " << optname);
640  break;
641  }
642  break;
643  }
644  return 0;
645 }
646 int
647 UnixSocketFd::Getsockname (struct sockaddr *name, socklen_t *namelen)
648 {
649  Thread *current = Current ();
650  NS_LOG_FUNCTION (this << current << name << *namelen);
651  NS_ASSERT (current != 0);
652  Address ad;
653  int status = m_socket->GetSockName (ad);
654  if (status == -1)
655  {
656  current->err = ErrnoToSimuErrno ();
657  return -1;
658  }
659  if (Ns3AddressToPosixAddress (ad, name, namelen) == -1)
660  {
661  current->err = EINVAL;
662  return -1;
663  }
664  return 0;
665 }
666 int
667 UnixSocketFd::Getpeername (struct sockaddr *name, socklen_t *namelen)
668 {
669  //XXX
670  return -1;
671 }
672 int
673 UnixSocketFd::Ioctl (int request, char *argp)
674 {
675  Thread *current = Current ();
676  NS_LOG_FUNCTION (this << current);
677  NS_ASSERT (current != 0);
678 
679  if (FIONBIO == request)
680  {
681  const int *arg = (const int *) argp;
682  if (*arg)
683  {
684  m_statusFlags = m_statusFlags | O_NONBLOCK;
685  }
686  else
687  {
688  m_statusFlags = m_statusFlags & ~O_NONBLOCK;
689  }
690  return 0;
691  }
692  else
693  {
694  current->err = EINVAL;
695 
696  return -1;
697  }
698 }
699 Address
700 UnixSocketFd::PosixAddressToNs3Address (const struct sockaddr *my_addr, socklen_t addrlen) const
701 {
702  if (my_addr->sa_family == AF_INET)
703  {
704  const struct sockaddr_in *addr = (const struct sockaddr_in *)my_addr;
705  Ipv4Address ipv4;
706  ipv4.Set (ntohl (addr->sin_addr.s_addr));
707  uint16_t port = ntohs (addr->sin_port);
708  InetSocketAddress inet = InetSocketAddress (ipv4, port);
709  return inet;
710  }
711  else if (my_addr->sa_family == AF_INET6)
712  {
713  const struct sockaddr_in6 *addr = (const struct sockaddr_in6 *)my_addr;
714  Ipv6Address ipv6;
715  ipv6.Set ((uint8_t *)addr->sin6_addr.s6_addr);
716  uint16_t port = ntohs (addr->sin6_port);
717  Inet6SocketAddress inet = Inet6SocketAddress (ipv6, port);
718  return inet;
719  }
720  else if (my_addr->sa_family == AF_NETLINK)
721  {
722  const struct sockaddr_nl *addr = (const struct sockaddr_nl *)my_addr;
723  //user space netlink socket has a nozero process id
724  //uint32_t pid = addr->nl_pid ? addr->nl_pid : getpid ();
725 
726  //pretend that it is kernel-level netlink socket. is required by unmodified version of quagga
727  uint32_t pid = addr->nl_pid;
728 
729  NetlinkSocketAddress nladdress = NetlinkSocketAddress (pid, addr->nl_groups);
730  return nladdress;
731  }
732  NS_ASSERT (false);
733  return Address ();
734 }
735 int
737  struct sockaddr *addr, socklen_t *addrlen) const
738 {
739  if (addr == 0 || addrlen == 0)
740  {
741  return 0;
742  }
743  if (InetSocketAddress::IsMatchingType (nsaddr))
744  {
745  InetSocketAddress ns_inetaddr = InetSocketAddress::ConvertFrom (nsaddr);
746  if (*addrlen < sizeof (struct sockaddr_in))
747  {
748  return -1;
749  }
750  struct sockaddr_in *inet_addr = (struct sockaddr_in *)addr;
751  memset (inet_addr, 0, sizeof (struct sockaddr_in));
752  inet_addr->sin_family = AF_INET;
753  inet_addr->sin_port = htons (ns_inetaddr.GetPort ());
754  inet_addr->sin_addr.s_addr = htonl (ns_inetaddr.GetIpv4 ().Get ());
755  *addrlen = sizeof(struct sockaddr_in);
756  }
757  else if (Inet6SocketAddress::IsMatchingType (nsaddr))
758  {
759  Inet6SocketAddress ns_inetaddr = Inet6SocketAddress::ConvertFrom (nsaddr);
760  if (*addrlen < sizeof (struct sockaddr_in6))
761  {
762  return -1;
763  }
764  struct sockaddr_in6 *inet_addr = (struct sockaddr_in6 *)addr;
765  inet_addr->sin6_family = AF_INET6;
766  inet_addr->sin6_port = htons (ns_inetaddr.GetPort ());
767  ns_inetaddr.GetIpv6 ().GetBytes (inet_addr->sin6_addr.s6_addr);
768  *addrlen = sizeof(struct sockaddr_in6);
769  }
770  else if (NetlinkSocketAddress::IsMatchingType (nsaddr))
771  {
772  NetlinkSocketAddress ns_nladdr = NetlinkSocketAddress::ConvertFrom (nsaddr);
773  NS_ASSERT (*addrlen >= sizeof (struct sockaddr_nl));
774  struct sockaddr_nl *nl_addr = (struct sockaddr_nl *)addr;
775  nl_addr->nl_family = AF_NETLINK;
776  nl_addr->nl_pid = ns_nladdr.GetProcessID ();
777  nl_addr->nl_groups = ns_nladdr.GetGroupsMask ();
778  *addrlen = sizeof (struct sockaddr_nl);
779  return 0;
780  }
781  else
782  {
783  NS_ASSERT (false);
784  }
785  return 0;
786 }
787 int
788 UnixSocketFd::Bind (const struct sockaddr *my_addr, socklen_t addrlen)
789 {
790  Thread *current = Current ();
791  NS_LOG_FUNCTION (this << current);
792  NS_ASSERT (current != 0);
793 
794  Address ad = PosixAddressToNs3Address (my_addr, addrlen);
795  int result = m_socket->Bind (ad);
796  if (result == -1)
797  {
798  current->err = ErrnoToSimuErrno ();
799  }
800  return result;
801 }
802 void
803 UnixSocketFd::MainConnect (int *r, Address adr)
804 {
805  *r = m_socket->Connect (adr);
806 }
807 int
808 UnixSocketFd::Connect (const struct sockaddr *my_addr, socklen_t addrlen)
809 {
810  Thread *current = Current ();
811  NS_LOG_FUNCTION (this << current);
812  NS_ASSERT (current != 0);
813 
814  Address ad = PosixAddressToNs3Address (my_addr, addrlen);
815  TaskManager *manager = TaskManager::Current ();
816 
817  int result = -1;
818  manager->ExecOnMain (MakeEvent (&UnixSocketFd::MainConnect, this, &result, ad));
819 
820  if (result == -1)
821  {
822  current->err = ErrnoToSimuErrno ();
823  }
824  return result;
825 }
826 bool
828 {
829  return m_recverr == 1;
830 }
831 bool
833 {
834  return m_recvttl == 1;
835 }
836 // bool
837 // UnixSocketFd::IsRecvPktInfo (void) const
838 // {
839 // return m_recvpktinfo == 1;
840 // }
841 // bool
842 // UnixSocketFd::IsRecvPktInfo6 (void) const
843 // {
844 // return m_recvpktinfo6 == 1;
845 // }
846 // bool
847 // UnixSocketFd::IsIpHdrIncl (void) const
848 // {
849 // return m_iphdrincl == 1;
850 // }
851 off64_t
852 UnixSocketFd::Lseek (off64_t offset, int whence)
853 {
854  Thread *current = Current ();
855  NS_LOG_FUNCTION (this << current << offset << whence);
856  NS_ASSERT (current != 0);
857  current->err = ESPIPE;
858  return -1;
859 }
860 bool
862 {
863  Thread *current = Current ();
864  NS_LOG_FUNCTION (this << current << dontwait);
865  if (dontwait && !CanRecv ())
866  {
867  current->err = EAGAIN;
868  return false;
869  }
870  if (!CanRecv ())
871  {
872  bool ok = false;
873  WaitQueueEntryTimeout *wq = new WaitQueueEntryTimeout (POLLIN | POLLHUP, m_recvTimeout);
874  AddWaitQueue (wq, true);
875  NS_LOG_DEBUG ("WaitRecvDoSignal: waiting ...");
876  PollTable::Result res = wq->Wait ();
877  NS_LOG_DEBUG ("WaitRecvDoSignal: wait result:" << res);
878  RemoveWaitQueue (wq, true);
879  NS_LOG_FUNCTION (this << "DELETING: " << wq);
880  delete wq;
881  wq = 0;
882 
883  if (res == PollTable::INTERRUPTED)
884  {
885  UtilsDoSignal ();
886  current->err = EINTR;
887  return false;
888  }
889  else
890  {
891  ok = (res == PollTable::OK);
892  if (!ok)
893  {
894  current->err = EAGAIN;
895  }
896  }
897 
898  return ok;
899  }
900  NS_ASSERT (CanRecv ());
901  return true;
902 }
903 Time
905 {
906  return m_recvTimeout;
907 }
908 Time
910 {
911  return m_sendTimeout;
912 }
913 
914 int
916  const struct itimerspec *new_value,
917  struct itimerspec *old_value)
918 {
919  NS_LOG_FUNCTION (this << Current () << flags << new_value << old_value);
920  NS_ASSERT (Current () != 0);
921  Thread *current = Current ();
922  current->err = EINVAL;
923  return -1;
924 }
925 int
926 UnixSocketFd::Gettime (struct itimerspec *cur_value) const
927 {
928  NS_LOG_FUNCTION (this << Current () << cur_value);
929  NS_ASSERT (Current () != 0);
930  Thread *current = Current ();
931  current->err = EINVAL;
932  return -1;
933 }
934 
935 void
937 {
938  if (m_socket)
939  {
940  Callback<void, Ptr<Socket> > nil = MakeNullCallback<void, Ptr<Socket> > ();
941 
942  Callback<void, Ptr<Socket>, const Address &> nil2 = MakeNullCallback<void, Ptr<Socket>, const Address &> ();
943  Callback<bool, Ptr<Socket>, const Address &> nil3 = MakeNullCallback<bool, Ptr<Socket>, const Address &> ();
944 
945  m_socket->SetAcceptCallback (nil3, nil2);
946 
947  m_socket->SetConnectCallback (nil, nil);
948  m_socket->SetCloseCallbacks (nil, nil);
949 
950  m_socket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
951  m_socket->SetSendCallback (MakeNullCallback<void,Ptr<Socket>,uint32_t> ());
952  }
953 
954  m_socket = 0;
955 }
956 void
957 UnixSocketFd::ChangeSocket (Ptr<Socket> socket)
958 {
959  ClearSocket ();
960  m_socket = socket;
961  m_socket->SetAttributeFailSafe ("SndBufSize", UintegerValue (4096));
962  m_socket->SetAttributeFailSafe ("RcvBufSize", UintegerValue (4096));
963  m_socket->SetRecvCallback (MakeCallback (&UnixSocketFd::RecvSocketData, this));
964  m_socket->SetSendCallback (MakeCallback (&UnixSocketFd::SendSocketData, this));
965 }
966 int
967 UnixSocketFd::Ns3AddressToDeviceIndependantPhysicalLayerAddress (const Address& nsaddr, const Packet& pac,
968  struct sockaddr_ll *addr, socklen_t *addrlen) const
969 {
970  if (PacketSocketAddress::IsMatchingType (nsaddr))
971  {
972  PacketSocketAddress ll_addr = PacketSocketAddress::ConvertFrom (nsaddr);
973  if (*addrlen < sizeof (struct sockaddr_ll))
974  {
975  return -1;
976  }
977  memset (addr, 0, sizeof (struct sockaddr_ll));
978  addr->sll_family = AF_PACKET;
979  addr->sll_protocol = htons (ll_addr.GetProtocol ());
980  addr->sll_ifindex = ll_addr.GetSingleDevice () + 1;
981  addr->sll_hatype = 0;
982  ll_addr.GetPhysicalAddress ().CopyAllTo (&(addr->sll_pkttype), 8);
983  *addrlen = sizeof(struct sockaddr_ll);
984 
985  PacketSocketTag pst;
986  DeviceNameTag dnt;
987  bool found;
988 
989  found = pac.PeekPacketTag (dnt);
990  if (found)
991  {
992  if (dnt.GetDeviceName () == "NetDevice")
993  {
994  addr->sll_hatype = ARPHRD_PPP;
995  }
996  else if (dnt.GetDeviceName () == "LoopbackNetDevice")
997  {
998  addr->sll_hatype = ARPHRD_LOOPBACK;
999  }
1000  else if (dnt.GetDeviceName () == "CsmaNetDevice")
1001  {
1002  addr->sll_hatype = ARPHRD_ETHER;
1003  }
1004  else if (dnt.GetDeviceName () == "PointToPointNetDevice")
1005  {
1006  addr->sll_hatype = ARPHRD_PPP;
1007  }
1008  else if (dnt.GetDeviceName () == "WifiNetDevice")
1009  {
1010  addr->sll_hatype = ARPHRD_IEEE80211;
1011  }
1012  }
1013  found = pac.PeekPacketTag (pst);
1014  if (found)
1015  {
1016  addr->sll_pkttype = pst.GetPacketType ();
1017  }
1018  }
1019  else
1020  {
1021  NS_ASSERT (false);
1022  }
1023  return 0;
1024 }
1025 int
1027 {
1028  Thread *current = Current ();
1029  NS_ASSERT (current != 0);
1030  NS_LOG_FUNCTION (this << current << length);
1031 
1032  current->err = EINVAL;
1033  return -1;
1034 }
1035 
1036 void
1037 UnixSocketFd::AddPeekedData (const uint8_t *buf, uint32_t count, Address from)
1038 {
1039  Ptr<Packet> p = Create<Packet> (buf, count);
1040  m_peekedAddress = from;
1041  if (!m_peekedData)
1042  {
1043  m_peekedData = p;
1044  }
1045  else
1046  {
1047  m_peekedData->AddAtEnd (p);
1048  }
1049 }
1050 
1051 void
1053 {
1054  if (!m_peekedData)
1055  {
1056  m_peekedData = p;
1057  }
1058  else
1059  {
1060  m_peekedData->AddAtEnd (p);
1061  }
1062 }
1063 bool
1065 {
1066  return ((0 != m_peekedData) && (m_peekedData->GetSize () > 0));
1067 }
1068 Address
1070 {
1071  return m_peekedAddress;
1072 }
1073 
1074 } // namespace ns3