OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [gnu/] [java/] [net/] [natPlainDatagramSocketImplWin32.cc] - Blame information for rev 756

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 756 jeremybenn
/* Copyright (C) 2003, 2006 Free Software Foundation
2
 
3
   This file is part of libgcj.
4
 
5
This software is copyrighted work licensed under the terms of the
6
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
7
details.  */
8
 
9
#include <config.h>
10
#include <platform.h>
11
#include <string.h>
12
 
13
#if HAVE_BSTRING_H
14
// Needed for bzero, implicitly used by FD_ZERO on IRIX 5.2
15
#include <bstring.h>
16
#endif
17
 
18
#include <gnu/java/net/PlainDatagramSocketImpl.h>
19
#include <java/io/IOException.h>
20
#include <java/net/BindException.h>
21
#include <java/net/SocketException.h>
22
#include <java/net/InetAddress.h>
23
#include <java/net/NetworkInterface.h>
24
#include <java/net/DatagramPacket.h>
25
#include <java/net/PortUnreachableException.h>
26
#include <java/net/SocketTimeoutException.h>
27
#include <java/lang/InternalError.h>
28
#include <java/lang/Object.h>
29
#include <java/lang/Boolean.h>
30
#include <java/lang/Integer.h>
31
 
32
union SockAddr
33
{
34
  struct sockaddr_in address;
35
#ifdef HAVE_INET6
36
  struct sockaddr_in6 address6;
37
#endif
38
};
39
 
40
union McastReq
41
{
42
#if HAVE_STRUCT_IP_MREQ
43
  struct ip_mreq mreq;
44
#endif
45
#if HAVE_STRUCT_IPV6_MREQ
46
  struct ipv6_mreq mreq6;
47
#endif
48
};
49
 
50
union InAddr
51
{
52
  struct in_addr addr;
53
#ifdef HAVE_INET6
54
  struct in6_addr addr6;
55
#endif
56
};
57
 
58
// FIXME: routines here and/or in natPlainSocketImpl.cc could throw
59
// NoRouteToHostException; also consider UnknownHostException, ConnectException.
60
 
61
void
62
gnu::java::net::PlainDatagramSocketImpl::create ()
63
{
64
  SOCKET sock = ::socket (AF_INET, SOCK_DGRAM, 0);
65
 
66
  if (sock == INVALID_SOCKET)
67
    {
68
      _Jv_ThrowSocketException ();
69
    }
70
 
71
  // Cast this to a HANDLE so we can make
72
  // it non-inheritable via _Jv_platform_close_on_exec.
73
  HANDLE hSocket = (HANDLE) sock;
74
  _Jv_platform_close_on_exec (hSocket);
75
 
76
  // We use native_fd in place of fd here.  From leaving fd null we avoid
77
  // the double close problem in FileDescriptor.finalize.
78
  native_fd = (jint) hSocket;
79
}
80
 
81
void
82
gnu::java::net::PlainDatagramSocketImpl::bind (jint lport,
83
                                          ::java::net::InetAddress *host)
84
{
85
  union SockAddr u;
86
  struct sockaddr *ptr = (struct sockaddr *) &u.address;
87
  // FIXME: Use getaddrinfo() to get actual protocol instead of assuming ipv4.
88
  jbyteArray haddress = host->addr;
89
  jbyte *bytes = elements (haddress);
90
  int len = haddress->length;
91
 
92
  if (len == 4)
93
    {
94
      u.address.sin_family = AF_INET;
95
 
96
      if (host != NULL)
97
        memcpy (&u.address.sin_addr, bytes, len);
98
      else
99
        u.address.sin_addr.s_addr = htonl (INADDR_ANY);
100
 
101
      len = sizeof (struct sockaddr_in);
102
      u.address.sin_port = htons (lport);
103
    }
104
#ifdef HAVE_INET6
105
  else if (len == 16)
106
    {
107
      u.address6.sin6_family = AF_INET6;
108
      memcpy (&u.address6.sin6_addr, bytes, len);
109
      len = sizeof (struct sockaddr_in6);
110
      u.address6.sin6_port = htons (lport);
111
    }
112
#endif
113
  else
114
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
115
 
116
  if (::bind (native_fd, ptr, len) == 0)
117
    {
118
      socklen_t addrlen = sizeof(u);
119
 
120
      if (lport != 0)
121
        localPort = lport;
122
      else if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) == 0)
123
        localPort = ntohs (u.address.sin_port);
124
      else
125
        goto error;
126
 
127
      /* Allow broadcast by default. */
128
      int broadcast = 1;
129
      if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &broadcast,
130
                        sizeof (broadcast)) != 0)
131
        goto error;
132
 
133
      return;
134
    }
135
 
136
error:
137
  DWORD dwErrorCode = WSAGetLastError ();
138
  throw new ::java::net::BindException (_Jv_WinStrError (dwErrorCode));
139
}
140
 
141
void
142
gnu::java::net::PlainDatagramSocketImpl::connect (::java::net::InetAddress *, jint)
143
{
144
  throw new ::java::lang::InternalError (JvNewStringLatin1 (
145
      "PlainDatagramSocketImpl::connect: not implemented yet"));
146
}
147
 
148
void
149
gnu::java::net::PlainDatagramSocketImpl::disconnect ()
150
{
151
  throw new ::java::lang::InternalError (JvNewStringLatin1 (
152
      "PlainDatagramSocketImpl::disconnect: not implemented yet"));
153
}
154
 
155
jint
156
gnu::java::net::PlainDatagramSocketImpl::peek (::java::net::InetAddress *i)
157
{
158
  // FIXME: Deal with Multicast and if the socket is connected.
159
  union SockAddr u;
160
  socklen_t addrlen = sizeof(u);
161
  ssize_t retlen =
162
    ::recvfrom (native_fd, (char *) NULL, 0, MSG_PEEK, (sockaddr*) &u,
163
      &addrlen);
164
  if (retlen < 0)
165
    goto error;
166
  // FIXME: Deal with Multicast addressing and if the socket is connected.
167
  jbyteArray raddr;
168
  jint rport;
169
  if (u.address.sin_family == AF_INET)
170
    {
171
      raddr = JvNewByteArray (4);
172
      memcpy (elements (raddr), &u.address.sin_addr, 4);
173
      rport = ntohs (u.address.sin_port);
174
    }
175
#ifdef HAVE_INET6
176
  else if (u.address.sin_family == AF_INET6)
177
    {
178
      raddr = JvNewByteArray (16);
179
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
180
      rport = ntohs (u.address6.sin6_port);
181
    }
182
#endif
183
  else
184
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
185
 
186
  i->addr = raddr;
187
  return rport;
188
error:
189
  DWORD dwErrorCode = WSAGetLastError ();
190
  if (dwErrorCode == WSAECONNRESET)
191
    throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
192
 
193
  _Jv_ThrowIOException ();
194
  return -1;
195
    // we should never get here
196
}
197
 
198
jint
199
gnu::java::net::PlainDatagramSocketImpl::peekData(::java::net::DatagramPacket *p)
200
{
201
  // FIXME: Deal with Multicast and if the socket is connected.
202
  union SockAddr u;
203
  socklen_t addrlen = sizeof(u);
204
  jbyte *dbytes = elements (p->getData()) + p->getOffset();
205
  jint maxlen = p->maxlen - p->getOffset();
206
  ssize_t retlen = 0;
207
 
208
  if (timeout > 0)
209
    {
210
      int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO,
211
        (char*)&timeout, sizeof(timeout));
212
      if (nRet != NO_ERROR)
213
        goto error;
214
    }
215
 
216
  retlen =
217
    ::recvfrom (native_fd, (char *) dbytes, maxlen, MSG_PEEK, (sockaddr*) &u,
218
      &addrlen);
219
  if (retlen == SOCKET_ERROR)
220
    goto error;
221
  // FIXME: Deal with Multicast addressing and if the socket is connected.
222
  jbyteArray raddr;
223
  jint rport;
224
  if (u.address.sin_family == AF_INET)
225
    {
226
      raddr = JvNewByteArray (4);
227
      memcpy (elements (raddr), &u.address.sin_addr, 4);
228
      rport = ntohs (u.address.sin_port);
229
    }
230
#ifdef HAVE_INET6
231
  else if (u.address.sin_family == AF_INET6)
232
    {
233
      raddr = JvNewByteArray (16);
234
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
235
      rport = ntohs (u.address6.sin6_port);
236
    }
237
#endif
238
  else
239
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
240
 
241
  p->setAddress (::java::net::InetAddress::getByAddress (raddr));
242
  p->setPort (rport);
243
  p->length = (jint) retlen;
244
  return rport;
245
 
246
error:
247
  DWORD dwErrorCode = WSAGetLastError ();
248
  if (dwErrorCode == WSAECONNRESET)
249
    throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
250
  else if (dwErrorCode == WSAETIMEDOUT)
251
    throw new ::java::net::SocketTimeoutException (_Jv_WinStrError (dwErrorCode));
252
  else
253
    _Jv_ThrowIOException ();
254
 
255
  return -1;
256
    // we should never get here
257
}
258
 
259
// Close(shutdown) the socket.
260
void
261
gnu::java::net::PlainDatagramSocketImpl::close ()
262
{
263
  // Avoid races from asynchronous finalization.
264
  JvSynchronize sync (this);
265
 
266
  // The method isn't declared to throw anything, so we disregard
267
  // the return value.
268
  ::closesocket (native_fd);
269
  native_fd = -1;
270
  timeout = 0;
271
}
272
 
273
void
274
gnu::java::net::PlainDatagramSocketImpl::send (::java::net::DatagramPacket *p)
275
{
276
  JvSynchronize lock (SEND_LOCK);
277
 
278
  // FIXME: Deal with Multicast and if the socket is connected.
279
  jint rport = p->getPort();
280
  union SockAddr u;
281
  jbyteArray haddress = p->getAddress()->addr;
282
  jbyte *bytes = elements (haddress);
283
  int len = haddress->length;
284
  struct sockaddr *ptr = (struct sockaddr *) &u.address;
285
  jbyte *dbytes = elements (p->getData()) + p->getOffset();
286
  if (len == 4)
287
    {
288
      u.address.sin_family = AF_INET;
289
      memcpy (&u.address.sin_addr, bytes, len);
290
      len = sizeof (struct sockaddr_in);
291
      u.address.sin_port = htons (rport);
292
    }
293
#ifdef HAVE_INET6
294
  else if (len == 16)
295
    {
296
      u.address6.sin6_family = AF_INET6;
297
      memcpy (&u.address6.sin6_addr, bytes, len);
298
      len = sizeof (struct sockaddr_in6);
299
      u.address6.sin6_port = htons (rport);
300
    }
301
#endif
302
  else
303
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
304
 
305
  if (::sendto (native_fd, (char *) dbytes, p->getLength(), 0, ptr, len) >= 0)
306
    return;
307
 
308
  DWORD dwErrorCode = WSAGetLastError ();
309
  if (dwErrorCode == WSAECONNRESET)
310
    throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
311
 
312
  _Jv_ThrowIOException ();
313
}
314
 
315
void
316
gnu::java::net::PlainDatagramSocketImpl::receive (::java::net::DatagramPacket *p)
317
{
318
  JvSynchronize lock (RECEIVE_LOCK);
319
 
320
  // FIXME: Deal with Multicast and if the socket is connected.
321
  union SockAddr u;
322
  socklen_t addrlen = sizeof(u);
323
  jbyte *dbytes = elements (p->getData()) + p->getOffset();
324
  jint maxlen = p->maxlen - p->getOffset();
325
  ssize_t retlen = 0;
326
 
327
  if (timeout > 0)
328
    {
329
      // This implementation doesn't allow specifying an infinite
330
      // timeout after specifying a finite one, but Sun's JDK 1.4.1
331
      // didn't seem to allow this either....
332
      int nRet= ::setsockopt(native_fd, SOL_SOCKET, SO_RCVTIMEO,
333
        (char*)&timeout, sizeof(timeout));
334
      if (nRet != NO_ERROR)
335
        goto error;
336
    }
337
 
338
  retlen =
339
    ::recvfrom (native_fd, (char *) dbytes, maxlen, 0, (sockaddr*) &u,
340
      &addrlen);
341
  if (retlen < 0)
342
    goto error;
343
  // FIXME: Deal with Multicast addressing and if the socket is connected.
344
  jbyteArray raddr;
345
  jint rport;
346
  if (u.address.sin_family == AF_INET)
347
    {
348
      raddr = JvNewByteArray (4);
349
      memcpy (elements (raddr), &u.address.sin_addr, 4);
350
      rport = ntohs (u.address.sin_port);
351
    }
352
#ifdef HAVE_INET6
353
  else if (u.address.sin_family == AF_INET6)
354
    {
355
      raddr = JvNewByteArray (16);
356
      memcpy (elements (raddr), &u.address6.sin6_addr, 16);
357
      rport = ntohs (u.address6.sin6_port);
358
    }
359
#endif
360
  else
361
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid family"));
362
 
363
  p->setAddress (::java::net::InetAddress::getByAddress (raddr));
364
  p->setPort (rport);
365
  p->length = (jint) retlen;
366
  return;
367
 
368
 error:
369
  DWORD dwErrorCode = WSAGetLastError();
370
  if (dwErrorCode == WSAECONNRESET)
371
    throw new ::java::net::PortUnreachableException (_Jv_WinStrError (dwErrorCode));
372
  else if (dwErrorCode == WSAETIMEDOUT)
373
    throw new ::java::net::SocketTimeoutException (_Jv_WinStrError (dwErrorCode));
374
  else
375
    throw new ::java::io::IOException (_Jv_WinStrError (dwErrorCode));
376
}
377
 
378
void
379
gnu::java::net::PlainDatagramSocketImpl::setTimeToLive (jint ttl)
380
{
381
  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
382
  char val = (char) ttl;
383
  socklen_t val_len = sizeof(val);
384
 
385
  if (::setsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, val_len) == 0)
386
    return;
387
 
388
  _Jv_ThrowIOException ();
389
}
390
 
391
jint
392
gnu::java::net::PlainDatagramSocketImpl::getTimeToLive ()
393
{
394
  // Assumes IPPROTO_IP rather than IPPROTO_IPV6 since socket created is IPv4.
395
  char val;
396
  socklen_t val_len = sizeof(val);
397
 
398
  if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_TTL, &val, &val_len) == 0)
399
    return ((int) val) & 0xFF;
400
 
401
  _Jv_ThrowIOException ();
402
 
403
  return -1;
404
    // we should never get here
405
}
406
 
407
void
408
gnu::java::net::PlainDatagramSocketImpl::mcastGrp (::java::net::InetAddress *inetaddr,
409
                                              ::java::net::NetworkInterface *,
410
                                              jboolean join)
411
{
412
  // FIXME: implement use of NetworkInterface
413
  jbyteArray haddress = inetaddr->addr;
414
  int len = haddress->length;
415
  int level, opname;
416
  const char *ptr;
417
  if (0)
418
    ;
419
#if HAVE_STRUCT_IP_MREQ
420
  else if (len == 4)
421
    {
422
      level = IPPROTO_IP;
423
      opname = join ? IP_ADD_MEMBERSHIP : IP_DROP_MEMBERSHIP;
424
      memcpy (&u.mreq.imr_multiaddr, bytes, len);
425
      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
426
      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
427
      u.mreq.imr_interface.s_addr = htonl (INADDR_ANY);
428
      len = sizeof (struct ip_mreq);
429
      ptr = (const char *) &u.mreq;
430
    }
431
#endif
432
#if HAVE_STRUCT_IPV6_MREQ
433
  else if (len == 16)
434
    {
435
      level = IPPROTO_IPV6;
436
 
437
      /* Prefer new RFC 2553 names.  */
438
#ifndef IPV6_JOIN_GROUP
439
#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
440
#endif
441
#ifndef IPV6_LEAVE_GROUP
442
#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
443
#endif
444
 
445
      opname = join ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP;
446
      memcpy (&u.mreq6.ipv6mr_multiaddr, bytes, len);
447
      // FIXME:  If a non-default interface is set, use it; see Stevens p. 501.
448
      // Maybe not, see note in last paragraph at bottom of Stevens p. 497.
449
      u.mreq6.ipv6mr_interface = 0;
450
      len = sizeof (struct ipv6_mreq);
451
      ptr = (const char *) &u.mreq6;
452
    }
453
#endif
454
  else
455
    throw new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
456
 
457
  if (::setsockopt (native_fd, level, opname, ptr, len) == 0)
458
    return;
459
 
460
  _Jv_ThrowIOException ();
461
}
462
 
463
void
464
gnu::java::net::PlainDatagramSocketImpl::setOption (jint optID,
465
                                               ::java::lang::Object *value)
466
{
467
  int val;
468
  socklen_t val_len = sizeof (val);
469
 
470
  if (native_fd < 0)
471
    throw new ::java::net::SocketException (JvNewStringUTF ("Socket closed"));
472
 
473
  if (_Jv_IsInstanceOf (value, &::java::lang::Boolean::class$))
474
    {
475
      ::java::lang::Boolean *boolobj =
476
        static_cast< ::java::lang::Boolean *> (value);
477
      val = boolobj->booleanValue() ? 1 : 0;
478
    }
479
  else if (_Jv_IsInstanceOf (value, &::java::lang::Integer::class$))
480
    {
481
      ::java::lang::Integer *intobj =
482
        static_cast< ::java::lang::Integer *> (value);
483
      val = (int) intobj->intValue();
484
    }
485
  // Else assume value to be an InetAddress for use with IP_MULTICAST_IF.
486
 
487
  switch (optID)
488
    {
489
      case _Jv_TCP_NODELAY_ :
490
        throw new ::java::net::SocketException (
491
          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
492
        return;
493
      case _Jv_SO_LINGER_ :
494
        throw new ::java::net::SocketException (
495
          JvNewStringUTF ("SO_LINGER not valid for UDP"));
496
        return;
497
      case _Jv_SO_KEEPALIVE_ :
498
        throw new ::java::net::SocketException (
499
          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
500
        return;
501
 
502
      case _Jv_SO_BROADCAST_ :
503
        if (::setsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
504
                          val_len) != 0)
505
          goto error;
506
  break;
507
 
508
      case _Jv_SO_OOBINLINE_ :
509
        throw new ::java::net::SocketException (
510
          JvNewStringUTF ("SO_OOBINLINE: not valid for UDP"));
511
        break;
512
 
513
      case _Jv_SO_SNDBUF_ :
514
      case _Jv_SO_RCVBUF_ :
515
        int opt;
516
        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
517
        if (::setsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, val_len) != 0)
518
    goto error;
519
        return;
520
      case _Jv_SO_REUSEADDR_ :
521
  if (::setsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
522
      val_len) != 0)
523
    goto error;
524
  return;
525
      case _Jv_SO_BINDADDR_ :
526
        throw new ::java::net::SocketException (
527
          JvNewStringUTF ("SO_BINDADDR: read only option"));
528
        return;
529
      case _Jv_IP_MULTICAST_IF_ :
530
  union InAddr u;
531
        jbyteArray haddress;
532
  jbyte *bytes;
533
  int len;
534
  int level, opname;
535
  const char *ptr;
536
 
537
  haddress = ((::java::net::InetAddress *) value)->addr;
538
  bytes = elements (haddress);
539
  len = haddress->length;
540
  if (len == 4)
541
    {
542
      level = IPPROTO_IP;
543
      opname = IP_MULTICAST_IF;
544
      memcpy (&u.addr, bytes, len);
545
      len = sizeof (struct in_addr);
546
      ptr = (const char *) &u.addr;
547
    }
548
// Tru64 UNIX V5.0 has struct sockaddr_in6, but no IPV6_MULTICAST_IF
549
#if defined (HAVE_INET6) && defined (IPV6_MULTICAST_IF)
550
  else if (len == 16)
551
    {
552
      level = IPPROTO_IPV6;
553
      opname = IPV6_MULTICAST_IF;
554
      memcpy (&u.addr6, bytes, len);
555
      len = sizeof (struct in6_addr);
556
      ptr = (const char *) &u.addr6;
557
    }
558
#endif
559
  else
560
    throw
561
      new ::java::net::SocketException (JvNewStringUTF ("invalid length"));
562
 
563
  if (::setsockopt (native_fd, level, opname, ptr, len) != 0)
564
    goto error;
565
        return;
566
 
567
      case _Jv_IP_MULTICAST_IF2_ :
568
        throw new ::java::net::SocketException (
569
          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
570
        break;
571
 
572
      case _Jv_IP_MULTICAST_LOOP_ :
573
        throw new ::java::net::SocketException (
574
          JvNewStringUTF ("IP_MULTICAST_LOOP: not yet implemented"));
575
        break;
576
 
577
      case _Jv_IP_TOS_ :
578
        if (::setsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
579
     val_len) != 0)
580
    goto error;
581
  return;
582
 
583
      case _Jv_SO_TIMEOUT_ :
584
  timeout = val;
585
        return;
586
      default :
587
        WSASetLastError (WSAENOPROTOOPT);
588
    }
589
 
590
 error:
591
  _Jv_ThrowSocketException ();
592
}
593
 
594
::java::lang::Object *
595
gnu::java::net::PlainDatagramSocketImpl::getOption (jint optID)
596
{
597
  int val;
598
  socklen_t val_len = sizeof(val);
599
  union SockAddr u;
600
  socklen_t addrlen = sizeof(u);
601
 
602
  switch (optID)
603
    {
604
      case _Jv_TCP_NODELAY_ :
605
        throw new ::java::net::SocketException (
606
          JvNewStringUTF ("TCP_NODELAY not valid for UDP"));
607
        break;
608
      case _Jv_SO_LINGER_ :
609
        throw new ::java::net::SocketException (
610
          JvNewStringUTF ("SO_LINGER not valid for UDP"));
611
        break;
612
      case _Jv_SO_KEEPALIVE_ :
613
        throw new ::java::net::SocketException (
614
          JvNewStringUTF ("SO_KEEPALIVE not valid for UDP"));
615
        break;
616
 
617
      case _Jv_SO_BROADCAST_ :
618
  if (::getsockopt (native_fd, SOL_SOCKET, SO_BROADCAST, (char *) &val,
619
      &val_len) != 0)
620
    goto error;
621
  return new ::java::lang::Boolean (val != 0);
622
 
623
      case _Jv_SO_OOBINLINE_ :
624
        throw new ::java::net::SocketException (
625
          JvNewStringUTF ("SO_OOBINLINE not valid for UDP"));
626
        break;
627
 
628
      case _Jv_SO_RCVBUF_ :
629
      case _Jv_SO_SNDBUF_ :
630
        int opt;
631
        optID == _Jv_SO_SNDBUF_ ? opt = SO_SNDBUF : opt = SO_RCVBUF;
632
        if (::getsockopt (native_fd, SOL_SOCKET, opt, (char *) &val, &val_len) != 0)
633
    goto error;
634
        else
635
    return new ::java::lang::Integer (val);
636
  break;
637
      case _Jv_SO_BINDADDR_:
638
  // cache the local address
639
  if (localAddress == NULL)
640
    {
641
      jbyteArray laddr;
642
      if (::getsockname (native_fd, (sockaddr*) &u, &addrlen) != 0)
643
        goto error;
644
      if (u.address.sin_family == AF_INET)
645
        {
646
    laddr = JvNewByteArray (4);
647
    memcpy (elements (laddr), &u.address.sin_addr, 4);
648
        }
649
#ifdef HAVE_INET6
650
            else if (u.address.sin_family == AF_INET6)
651
        {
652
    laddr = JvNewByteArray (16);
653
    memcpy (elements (laddr), &u.address6.sin6_addr, 16);
654
        }
655
#endif
656
      else
657
        throw new ::java::net::SocketException (
658
            JvNewStringUTF ("invalid family"));
659
      localAddress = ::java::net::InetAddress::getByAddress (laddr);
660
    }
661
  return localAddress;
662
  break;
663
      case _Jv_SO_REUSEADDR_ :
664
  if (::getsockopt (native_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &val,
665
      &val_len) != 0)
666
    goto error;
667
  return new ::java::lang::Boolean (val != 0);
668
  break;
669
      case _Jv_IP_MULTICAST_IF_ :
670
  struct in_addr inaddr;
671
    socklen_t inaddr_len;
672
  char *bytes;
673
 
674
    inaddr_len = sizeof(inaddr);
675
  if (::getsockopt (native_fd, IPPROTO_IP, IP_MULTICAST_IF, (char *) &inaddr,
676
      &inaddr_len) != 0)
677
    goto error;
678
 
679
  bytes = inet_ntoa (inaddr);
680
 
681
  return ::java::net::InetAddress::getByName (JvNewStringLatin1 (bytes));
682
  break;
683
      case _Jv_SO_TIMEOUT_ :
684
        return new ::java::lang::Integer (timeout);
685
        break;
686
 
687
      case _Jv_IP_MULTICAST_IF2_ :
688
        throw new ::java::net::SocketException (
689
          JvNewStringUTF ("IP_MULTICAST_IF2: not yet implemented"));
690
        break;
691
 
692
      case _Jv_IP_MULTICAST_LOOP_ :
693
  if (::getsockopt (native_fd, SOL_SOCKET, IP_MULTICAST_LOOP, (char *) &val,
694
      &val_len) != 0)
695
    goto error;
696
  return new ::java::lang::Boolean (val != 0);
697
 
698
      case _Jv_IP_TOS_ :
699
        if (::getsockopt (native_fd, SOL_SOCKET, IP_TOS, (char *) &val,
700
           &val_len) != 0)
701
          goto error;
702
        return new ::java::lang::Integer (val);
703
 
704
      default :
705
        WSASetLastError (WSAENOPROTOOPT);
706
    }
707
 
708
error:
709
  _Jv_ThrowSocketException ();
710
  return 0;
711
    // we should never get here
712
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.