WvStreams
wvipraw.cc
1 /*
2  * Worldvisions Weaver Software:
3  * Copyright (C) 1997-2002 Net Integration Technologies, Inc.
4  *
5  * WvIPRawStream can send and receive packets on a connectionless IP socket.
6  * See wvipraw.h for details.
7  */
8 #include "wvipraw.h"
9 #include <sys/socket.h>
10 #include <fcntl.h>
11 
12 #ifdef ISDARWIN
13 # define socklen_t int
14 #endif
15 
17  const WvIPAddr &_rem,
18  int ip_protocol) :
19  localaddr(_local), remaddr(_rem)
20 {
21  int x = 1;
22  setfd(socket(PF_INET, SOCK_RAW, ip_protocol));
23  if (getfd() < 0
24  || setsockopt(getfd(), SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)) < 0)
25  {
26  seterr(errno);
27  return;
28  }
29 
30  set_close_on_exec(true);
31  set_nonblock(true);
32 
33  struct sockaddr *sa = _local.sockaddr();
34  if (bind(getfd(), sa, _local.sockaddr_len()))
35  {
36  delete sa;
37  seterr(errno);
38  return;
39  }
40  delete sa;
41 
42  struct sockaddr_in nsa;
43  socklen_t nsalen = sizeof(nsa);
44  if (getsockname(getfd(), (sockaddr *)&nsa, &nsalen) < 0)
45  {
46  seterr(errno);
47  return;
48  }
49  localaddr = WvIPAddr((sockaddr*)&nsa);
50 
51  if (WvIPAddr(_rem) != WvIPAddr())
52  {
53  struct sockaddr *sa = _rem.sockaddr();
54  if (connect(getfd(), sa, _rem.sockaddr_len()))
55  {
56  delete sa;
57  seterr(errno);
58  return;
59  }
60  delete sa;
61  }
62 }
63 
64 
65 WvIPRawStream::~WvIPRawStream()
66 {
67 }
68 
69 
70 const WvAddr *WvIPRawStream::src() const
71 {
72  return &remaddr;
73 }
74 
75 
76 const WvAddr *WvIPRawStream::local() const
77 {
78  return &localaddr;
79 }
80 
81 
82 size_t WvIPRawStream::uread(void *buf, size_t count)
83 {
84  if (!isok() || !buf || !count) return 0;
85 
86  struct sockaddr_in from;
87  socklen_t fromlen = sizeof(from);
88  int in = recvfrom(getfd(), buf, count, 0, (sockaddr *)&from, &fromlen);
89 
90  if (in >= 0)
91  remaddr = WvIPAddr((sockaddr *)&from);
92 
93  // errors in IP are ignored
94  return in < 0 ? 0 : in;
95 }
96 
97 
98 size_t WvIPRawStream::uwrite(const void *buf, size_t count)
99 {
100  if (!isok() || !buf || !count) return 0;
101 
102  struct sockaddr *to = remaddr.sockaddr();
103  size_t tolen = remaddr.sockaddr_len();
104  int out;
105 
106  out = sendto(getfd(), buf, count, 0, to, tolen);
107 
108  if (out < 0 && errno == EACCES) // permission denied
109  seterr(EACCES);
110 
111  free(to);
112 
113  // errors in UDP are ignored
114  // pretend that the write always succeeds even if the kernel
115  // complains since we don't want datagrams backing up in the
116  // buffer and forming merged datagrams as a result
117  return out < 0 ? 0 : out;
118 }
119 
120 
121 void WvIPRawStream::enable_broadcasts()
122 {
123  int value = 1;
124 
125  if (!isok()) return;
126 
127  setsockopt(getfd(), SOL_SOCKET, SO_BROADCAST, &value, sizeof(value));
128 }
WvIPRawStream::src
virtual const WvAddr * src() const
return the remote address (source of incoming packets, target of outgoing packets).
Definition: wvipraw.cc:70
WvFdStream::isok
virtual bool isok() const
return true if the stream is actually usable right now
Definition: wvfdstream.cc:134
WvIPRawStream::WvIPRawStream
WvIPRawStream(const WvIPAddr &_local, const WvIPAddr &_rem, int ip_protocol=IPPROTO_RAW)
connect a new socket
Definition: wvipraw.cc:16
WvStream::seterr
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
Definition: wvstream.cc:451
WvFdStream::setfd
void setfd(int fd)
Sets the file descriptor for both reading and writing.
Definition: wvfdstream.h:36
WvAddr
Base class for different address types, each of which will have the ability to convert itself to/from...
Definition: wvaddr.h:118
WvFdStream::getfd
int getfd() const
Returns the Unix file descriptor for reading and writing.
Definition: wvfdstream.h:81
WvFdStream::set_close_on_exec
void set_close_on_exec(bool close_on_exec)
Make the fds on this stream close-on-exec or not.
Definition: wvfdstream.cc:107
WvIPRawStream::uread
virtual size_t uread(void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by read().
Definition: wvipraw.cc:82
WvIPAddr
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
Definition: wvaddr.h:249
WvIPRawStream::uwrite
virtual size_t uwrite(const void *buf, size_t count)
unbuffered I/O functions; these ignore the buffer, which is handled by write().
Definition: wvipraw.cc:98
WvFdStream::set_nonblock
void set_nonblock(bool nonblock)
Make the fds on this stream blocking or non-blocking.
Definition: wvfdstream.cc:97