modules/up/src/util/net.cc
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- init_ipAddr
- setAddress
- setAddress
- Socket
- setsockopt
1 /*
2 // $Id: net.cc,v 1.2 2001/09/07 11:44:06 shane Exp $
3 //
4 // Copyright (c) 1994 by the University of Southern California
5 // All rights reserved.
6 //
7 // Permission to use, copy, modify, and distribute this software and its
8 // documentation in source and binary forms for lawful non-commercial
9 // purposes and without fee is hereby granted, provided that the above
10 // copyright notice appear in all copies and that both the copyright
11 // notice and this permission notice appear in supporting documentation,
12 // and that any documentation, advertising materials, and other materials
13 // related to such distribution and use acknowledge that the software was
14 // developed by the University of Southern California, Information
15 // Sciences Institute. The name of the USC may not be used to endorse or
16 // promote products derived from this software without specific prior
17 // written permission.
18 //
19 // THE UNIVERSITY OF SOUTHERN CALIFORNIA DOES NOT MAKE ANY
20 // REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR ANY
21 // PURPOSE. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
22 // IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
23 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
24 // TITLE, AND NON-INFRINGEMENT.
25 //
26 // IN NO EVENT SHALL USC, OR ANY OTHER CONTRIBUTOR BE LIABLE FOR ANY
27 // SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, WHETHER IN CONTRACT, TORT,
28 // OR OTHER FORM OF ACTION, ARISING OUT OF OR IN CONNECTION WITH, THE USE
29 // OR PERFORMANCE OF THIS SOFTWARE.
30 //
31 // Questions concerning this software should be directed to
32 // ratoolset@isi.edu.
33 //
34 // Author(s): eddy@isi.edu
35 */
36
37 #include "net.hh"
38
39 //
40 // setName sets either the hexaddr or the hostname, then calls
41 // _getHostent() to fill in the hostent and copy the official
42 // values into the redundant vars in the ipAddr class
43 //
44 void
45 ipAddr::init_ipAddr () {
/* [<][>][^][v][top][bottom][index][help] */
46 bzero ((char *) &hostname, MAXHOSTNAMELEN);
47 bzero ((char *) &dottedaddr, sizeof (dottedaddr));
48 bzero ((char *) &maskedaddr, sizeof (maskedaddr));
49 bzero ((char *) &asname, sizeof (asname));
50 hp = (struct hostent *) NULL;
51 mask = 32; // default to a host, unless changed
52 hexaddr = 0;
53 }
54
55 int
56 ipAddr::setAddress (const char *addr)
/* [<][>][^][v][top][bottom][index][help] */
57 {
58 hp = (struct hostent *) NULL;
59 hexaddr = (u_long) inet_addr (addr);
60 if (hexaddr != INADDR_NONE) {
61 hp = gethostbyaddr ((char *) &hexaddr, sizeof (hexaddr), AF_INET);
62 } else {
63 hp = gethostbyname ((char *) addr);
64 }
65 if (hp) {
66 bcopy (hp->h_addr, (caddr_t) &hexaddr, (size_t) hp->h_length);
67 strcpy (hostname, hp->h_name);
68 }
69 if (hp == NULL && hexaddr == INADDR_NONE)
70 error.fatal ("Could not resolve %s\0", addr);
71 return (error());
72 }
73
74 int
75 ipAddr::setAddress (u_long hex)
/* [<][>][^][v][top][bottom][index][help] */
76 {
77 hp = (struct hostent *) NULL;
78 hexaddr = hex;
79 hp = gethostbyaddr ((char *) &hexaddr, sizeof (hexaddr), AF_INET);
80 if (hp) {
81 bcopy (hp->h_addr, (caddr_t) &hexaddr, (size_t) hp->h_length);
82 strcpy (hostname, hp->h_name);
83 }
84 // we should do a range check on hexaddr and throw an exception
85 if (!hp)
86 error.fatal ("Could not set ipaddr for 0x%x", hex);
87 return (error());
88 }
89
90 ////////////////////////////////////////////////////////////////////////
91 Socket::Socket (u_int f, u_int t, u_int p)
/* [<][>][^][v][top][bottom][index][help] */
92 {
93 bzero ((char *) &sockdst, sizeof (sockdst));
94 bzero ((char *) &socksrc, sizeof (socksrc));
95 send_flags = 0;
96 sockdst.sin_family = family = f;
97 sockdst.sin_port = proto = p;
98 socksrc.sin_family = family = f;
99 socksrc.sin_port = proto = p;
100 in = out = NULL;
101 type = t;
102 sock = socket (family, type, proto);
103 if (sock < 0)
104 error.fatal ("socket");
105 }
106
107 int
108 Socket::setsockopt (int level, int optname, char *data, int dlen)
/* [<][>][^][v][top][bottom][index][help] */
109 {
110 int on = 1;
111 switch (level) {
112 case SOL_SOCKET :
113 if (optname & SO_DEBUG) {
114 (void) ::setsockopt (sock, level, SO_DEBUG,
115 (char *) &on, sizeof (on));
116 }
117 if (optname & SO_DONTROUTE) {
118 (void) ::setsockopt (sock, level, SO_DONTROUTE,
119 (char *) &on, sizeof (on));
120 }
121 if (optname & SO_SNDBUF) {
122 error = ::setsockopt(sock, level, SO_SNDBUF,
123 (char *)&data, dlen);
124 if (error())
125 return error.fatal ("setsocketopt: SO_SNDBUF");
126 }
127 break; // SOL_SOCKET
128 case IPPROTO_IP:
129 switch (optname) {
130 #ifdef IP_HDRINCL
131 case IP_HDRINCL:
132 error = ::setsockopt (sock, level, optname, (char *)&on, sizeof(on));
133 if (error())
134 error("setsockopt: IP_HDRINCL");
135 return error();
136 break; // IP_HDRINCL
137 #endif // IP_HDRINCL
138 }
139 #ifdef IP_OPTIONS
140 default:
141 int err = ::setsockopt (sock, level, optname, (char *) data, dlen);
142 if (err)
143 error.fatal ("setsockopt: level: %d, optname: %d\n", level, optname);
144 return error();
145 break;
146 #endif // IP_OPTIONS
147 }
148 }
149
150
151 int
152 Socket::write (char *buf, int len)
153 {
154 char *b = (char *) buf;
155 int l = len;
156 while (l > 0) {
157 int c = ::write (sock, b, l);
158 if (c < 0) {
159 // Added by wlee@isi.edu
160 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
161 errno = 0;
162 continue;
163 }
164 return error.fatal ("write");
165 }
166 l -= c;
167 b += c;
168 }
169 return (len - l);
170 }
171
172 int
173 Socket::read (char *buf, int len)
174 {
175 int c = -1;
176 while (c < 0) {
177 c = ::read (sock, buf, len);
178 if (c < 0) {
179 // Modified by wlee@isi.edu
180 if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
181 errno = 0;
182 continue;
183 }
184 return error.fatal ("Socket::read");
185 }
186 }
187 return c;
188 }
189
190 int
191 Socket::wait_for_reply (char *buffer, int size = MAXPACKETLEN, int seconds = 0)
192 {
193 fd_set fds;
194 FD_ZERO (&fds);
195 FD_SET (sock, &fds);
196 Timer timeout(seconds);
197 int c = select (sock+1, &fds, (fd_set *) NULL, (fd_set *) NULL, timeout.tval());
198 if (c > 0) {
199 c = recvfrom ((char *)buffer, 1024);
200 }
201 if (c < 0)
202 error.fatal ("Socket.wait_for_reply");
203 return c; // < 0 = count; 0 = timeout; > 0 = system err
204 }
205
206
207 ////////////////////////////////////////////////////////////////////////
208 //
209 // open up a connection to listen on
210 //
211 ////////////////////////////////////////////////////////////////////////
212 TCP::TCP (int p) :
213 Socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)
214 {
215 init_server (p);
216 }
217
218 int TCP::init_server (int p) {
219 setLocalPort (p);
220 bind();
221 listen();
222 if (error())
223 error.fatal ("TCP socket");
224 return 0;
225 }
226
227 TCP::TCP (char *hostname, int p) : Socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)
228 {
229 service = (struct servent *) NULL;
230 init_tcp (hostname, p);
231 }
232
233 TCP::TCP (char *hostname, char *s) : Socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)
234 {
235 service = getservbyname (s, "tcp");
236 if (service == NULL) {
237 error.fatal ("tcp: unknown service: %s\n", s);
238 return;
239 }
240 init_tcp (hostname, service->s_port);
241 }
242
243 int
244 TCP::init_tcp (char *hostname, int p)
245 {
246 ipaddr->setAddress (hostname);
247 set_dstInaddr (ipaddr->getInaddr());
248 setPort (p);
249 port = p;
250 connect ();
251 return error();
252 }
253
254
255
256 ////////////////////////////////////////////////////////////////////////
257 UDP::UDP (char *hostname, int p) : Socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)
258 {
259 init_udp (hostname, p);
260 }
261
262 UDP::UDP (char *hostname, char *s) : Socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)
263 {
264 service = getservbyname (s, "udp");
265 if (service == NULL) {
266 error.fatal ("udp: unknown service: %s\n", s);
267 return;
268 }
269 init_udp (hostname, service->s_port);
270 }