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
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
65WvIPRawStream::~WvIPRawStream()
66{
67}
68
69
71{
72 return &remaddr;
73}
74
75
76const WvAddr *WvIPRawStream::local() const
77{
78 return &localaddr;
79}
80
81
82size_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
98size_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
121void 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}
Base class for different address types, each of which will have the ability to convert itself to/from...
void setfd(int fd)
Sets the file descriptor for both reading and writing.
int getfd() const
Returns the Unix file descriptor for reading and writing.
virtual bool isok() const
return true if the stream is actually usable right now
void set_nonblock(bool nonblock)
Make the fds on this stream blocking or non-blocking.
Definition wvfdstream.cc:97
void set_close_on_exec(bool close_on_exec)
Make the fds on this stream close-on-exec or not.
An IP address is made up of a "dotted quad" – four decimal numbers in the form www....
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
WvIPRawStream(const WvIPAddr &_local, const WvIPAddr &_rem, int ip_protocol=IPPROTO_RAW)
connect a new socket
Definition wvipraw.cc:16
virtual const WvAddr * src() const
return the remote address (source of incoming packets, target of outgoing packets).
Definition wvipraw.cc:70
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
virtual void seterr(int _errnum)
Override seterr() from WvError so that it auto-closes the stream.
Definition wvstream.cc:451