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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [native/] [jni/] [native-lib/] [cpnet.c] - Blame information for rev 774

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 774 jeremybenn
/* cpnet.c -
2
   Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
#include "config.h"
39
#include <jni.h>
40
#include <assert.h>
41
#include <sys/socket.h>
42
#include <sys/types.h>
43
#include <unistd.h>
44
#include <errno.h>
45
#include <fcntl.h>
46
#include <netinet/in.h>
47
#include <netinet/tcp.h>
48
#include <netdb.h>
49
#include <sys/time.h>
50
#include <unistd.h>
51
#include <arpa/inet.h>
52
 
53
#if defined(HAVE_SYS_IOCTL_H)
54
#define BSD_COMP /* Get FIONREAD on Solaris2 */
55
#include <sys/ioctl.h>
56
#endif
57
#if defined(HAVE_SYS_FILIO_H) /* Get FIONREAD on Solaris 2.5 */
58
#include <sys/filio.h>
59
#endif
60
 
61
#include "cpnet.h"
62
 
63
#define SOCKET_DEFAULT_TIMEOUT -1 /* milliseconds */
64
 
65
static int socketTimeouts[FD_SETSIZE];
66
 
67
static jint waitForWritable(jint fd)
68
{
69
  struct timeval tv;
70
  fd_set writeset;
71
  int ret;
72
 
73
 
74
  FD_ZERO(&writeset);
75
  FD_SET(fd, &writeset);
76
  if (socketTimeouts[fd] > 0)
77
    {
78
      tv.tv_sec = socketTimeouts[fd] / 1000;
79
      tv.tv_usec = (socketTimeouts[fd] % 1000) * 1000;
80
      ret = select(fd+1, NULL, &writeset, NULL, &tv);
81
    }
82
  else
83
    ret = select(fd+1, NULL, &writeset, NULL, NULL);
84
 
85
  return (ret <= 0) ? -1 : 0;
86
}
87
 
88
static jint waitForReadable(jint fd)
89
{
90
  struct timeval tv;
91
  fd_set readset;
92
  int ret;
93
 
94
 
95
  FD_ZERO(&readset);
96
  FD_SET(fd, &readset);
97
  if (socketTimeouts[fd] > 0)
98
    {
99
      tv.tv_sec = socketTimeouts[fd] / 1000;
100
      tv.tv_usec = (socketTimeouts[fd] % 1000) * 1000;
101
      ret = select(fd+1, &readset, NULL, NULL, &tv);
102
    }
103
  else
104
    ret = select(fd+1, &readset, NULL, NULL, NULL);
105
 
106
  return (ret <= 0) ? -1 : 0;
107
}
108
 
109
jint cpnet_openSocketStream(JNIEnv *env UNUSED, jint *fd, jint family)
110
{
111
  *fd = socket(family, SOCK_STREAM, 0);
112
  if (*fd == -1)
113
    return errno;
114
 
115
  fcntl(*fd, F_SETFD, FD_CLOEXEC);
116
  assert(*fd < FD_SETSIZE);
117
  socketTimeouts[*fd] = SOCKET_DEFAULT_TIMEOUT;
118
  return 0;
119
}
120
 
121
jint cpnet_openSocketDatagram(JNIEnv *env UNUSED, jint *fd, jint family)
122
{
123
  *fd = socket(family, SOCK_DGRAM, 0);
124
  if (*fd == -1)
125
    return errno;
126
 
127
  fcntl(*fd, F_SETFD, FD_CLOEXEC);
128
  assert(*fd < FD_SETSIZE);
129
  socketTimeouts[*fd] = SOCKET_DEFAULT_TIMEOUT;
130
  return 0;
131
}
132
 
133
jint cpnet_shutdown (JNIEnv *env UNUSED, jint fd, jbyte flag)
134
{
135
  int ret;
136
  int shut_flag = 0;
137
 
138
  if (flag == CPNET_SHUTDOWN_READ)
139
    shut_flag = SHUT_RD;
140
  else if (flag == CPNET_SHUTDOWN_WRITE)
141
    shut_flag = SHUT_WR;
142
 
143
  ret = shutdown (fd, shut_flag);
144
  if (ret != 0)
145
    return errno;
146
  return 0;
147
}
148
 
149
jint cpnet_close(JNIEnv *env UNUSED, jint fd)
150
{
151
  if (close (fd) != 0)
152
    return errno;
153
  return 0;
154
}
155
 
156
jint cpnet_listen(JNIEnv *env UNUSED, jint fd, jint queuelen)
157
{
158
  if (listen (fd, queuelen) != 0)
159
    return errno;
160
  return 0;
161
}
162
 
163
jint cpnet_accept(JNIEnv *env UNUSED, jint fd, jint *newfd)
164
{
165
  if (waitForReadable (fd) < 0)
166
    return ETIMEDOUT;
167
 
168
  *newfd = accept(fd, NULL, 0);
169
  if (*newfd != 0)
170
    return errno;
171
 
172
  return 0;
173
}
174
 
175
jint cpnet_bind(JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
176
{
177
  int ret;
178
 
179
  ret = bind(fd, (struct sockaddr *)addr->data, addr->len);
180
  if (ret != 0)
181
    return errno;
182
 
183
  return 0;
184
}
185
 
186
jint cpnet_connect(JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
187
{
188
  int ret;
189
 
190
  /* TODO: implement socket time out */
191
  ret = connect(fd, (struct sockaddr *)addr->data, addr->len);
192
  if (ret != 0)
193
    return errno;
194
 
195
  return 0;
196
}
197
 
198
jint cpnet_getLocalAddr(JNIEnv *env, jint fd, cpnet_address **addr)
199
{
200
  socklen_t slen = 1024;
201
  int ret;
202
 
203
  *addr = JCL_malloc(env, slen);
204
 
205
  slen -= sizeof(jint);
206
  ret = getsockname(fd, (struct sockaddr *)(*addr)->data, &slen );
207
  if (ret != 0)
208
    {
209
      int err = errno;
210
      JCL_free(env, *addr);
211
      return err;
212
    }
213
 
214
  (*addr)->len = slen;
215
 
216
  return 0;
217
}
218
 
219
jint cpnet_getRemoteAddr(JNIEnv *env, jint fd, cpnet_address **addr)
220
{
221
  socklen_t slen = 1024;
222
  int ret;
223
 
224
  *addr = JCL_malloc(env, slen);
225
 
226
  slen -= sizeof(jint);
227
  ret = getpeername(fd, (struct sockaddr *)(*addr)->data, &slen );
228
  if (ret != 0)
229
    {
230
      int err = errno;
231
      JCL_free(env, *addr);
232
      return err;
233
    }
234
 
235
  (*addr)->len = slen;
236
 
237
  return 0;
238
}
239
 
240
jint cpnet_setBroadcast(JNIEnv *env UNUSED, jint fd, jint flag)
241
{
242
  int ret;
243
 
244
  ret = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &flag, sizeof(flag));
245
  if (ret != 0)
246
    return errno;
247
 
248
  return 0;
249
}
250
 
251
#if defined (HAVE_MSG_NOSIGNAL)
252
#elif defined (HAVE_SO_NOSIGPIPE)
253
static int setsockopt_NOSIGPIPE (int fd)
254
{
255
  int setToTrue = 1;
256
  return setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, &setToTrue, sizeof(setToTrue));
257
}
258
#endif
259
 
260
jint cpnet_send (JNIEnv *env UNUSED, jint fd, jbyte *data, jint len, jint *bytes_sent)
261
{
262
  ssize_t ret;
263
 
264
  if (waitForWritable(fd) < 0)
265
    return ETIMEDOUT;
266
 
267
#if defined (HAVE_MSG_NOSIGNAL)
268
  ret = send(fd, data, len, MSG_NOSIGNAL);
269
#elif defined (HAVE_SO_NOSIGPIPE)
270
  ret = setsockopt_NOSIGPIPE(fd);
271
  if (ret == 0) ret = send(fd, data, len, 0);
272
#else
273
  /* We want SIGPIPE to be omitted. But this configuration does not have an
274
   * option for that.
275
   */
276
  ret = send(fd, data, len, 0);
277
#endif
278
  if (ret < 0)
279
    return errno;
280
 
281
  *bytes_sent = ret;
282
 
283
  return 0;
284
}
285
 
286
jint cpnet_sendTo (JNIEnv *env UNUSED, jint fd, jbyte *data, jint len, cpnet_address *addr, jint *bytes_sent)
287
{
288
  ssize_t ret;
289
 
290
  if (waitForWritable(fd) < 0)
291
    return ETIMEDOUT;
292
 
293
#if defined (HAVE_MSG_NOSIGNAL)
294
  ret = sendto(fd, data, len, MSG_NOSIGNAL, (struct sockaddr *)addr->data,
295
               addr->len);
296
#elif defined (HAVE_SO_NOSIGPIPE)
297
  ret = setsockopt_NOSIGPIPE(fd);
298
  if (ret == 0)
299
  {
300
    ret = sendto(fd, data, len, 0, (struct sockaddr *)addr->data,
301
               addr->len);
302
  }
303
#else
304
  /* We want SIGPIPE to be omitted. But this configuration does not have an
305
   * option for that.
306
   */
307
  ret = sendto(fd, data, len, 0, (struct sockaddr *)addr->data,
308
               addr->len);
309
#endif
310
 
311
  if (ret < 0)
312
    return errno;
313
 
314
  *bytes_sent = ret;
315
  return 0;
316
}
317
 
318
jint cpnet_recv (JNIEnv *env UNUSED, jint fd, jbyte *data, jint len, jint *bytes_recv)
319
{
320
  ssize_t ret;
321
 
322
  if (waitForReadable(fd) < 0)
323
    return ETIMEDOUT;
324
 
325
  ret = recv(fd, data, len, 0);
326
  if (ret < 0)
327
    return errno;
328
 
329
  *bytes_recv = ret;
330
 
331
  return 0;
332
}
333
 
334
jint cpnet_recvFrom (JNIEnv *env, jint fd, jbyte *data, jint len, cpnet_address **addr, jint *bytes_recv)
335
{
336
  socklen_t slen = 1024;
337
  ssize_t ret;
338
 
339
  if (waitForReadable(fd) < 0)
340
    return ETIMEDOUT;
341
 
342
  *addr = JCL_malloc(env, slen);
343
 
344
  slen -= sizeof(jint);
345
  ret = recvfrom(fd, data, len, 0, (struct sockaddr *) (*addr)->data, &slen);
346
  if (ret < 0)
347
    {
348
      int err = errno;
349
      JCL_free(env, *addr);
350
      return err;
351
    }
352
 
353
  (*addr)->len = slen;
354
  *bytes_recv = ret;
355
 
356
  return 0;
357
}
358
 
359
jint cpnet_setSocketTCPNoDelay (JNIEnv *env UNUSED, jint fd, jint nodelay)
360
{
361
  socklen_t len = sizeof(jint);
362
  int ret;
363
 
364
  ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, len);
365
  if (ret < 0)
366
    return errno;
367
 
368
  return 0;
369
}
370
 
371
jint cpnet_getSocketTCPNoDelay (JNIEnv *env UNUSED, jint fd, jint *nodelay)
372
{
373
  socklen_t len = sizeof(jint);
374
  int ret;
375
 
376
  ret = getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, nodelay, &len);
377
  if (ret < 0)
378
    return errno;
379
 
380
  return 0;
381
}
382
 
383
jint cpnet_setLinger (JNIEnv *env UNUSED, jint fd, jint flag, jint value)
384
{
385
  socklen_t len = sizeof(struct linger);
386
  int ret;
387
  struct linger __linger;
388
 
389
  if (flag)
390
    {
391
      __linger.l_onoff = 0;
392
    }
393
  else
394
    {
395
      __linger.l_linger = value;
396
      __linger.l_onoff = 1;
397
    }
398
 
399
  ret = setsockopt(fd, SOL_SOCKET, SO_LINGER, &__linger, len);
400
  if (ret < 0)
401
    return errno;
402
 
403
  return 0;
404
}
405
 
406
jint cpnet_getLinger (JNIEnv *env UNUSED, jint fd, jint *flag, jint *value)
407
{
408
  socklen_t slen = sizeof(struct linger);
409
  struct linger __linger;
410
  int ret;
411
 
412
  ret = getsockopt(fd, SOL_SOCKET, SO_LINGER, &__linger, &slen);
413
  if (ret != 0)
414
    return errno;
415
 
416
  *flag = __linger.l_onoff;
417
  *value = __linger.l_linger;
418
 
419
  return ret;
420
}
421
 
422
jint cpnet_setSocketTimeout (JNIEnv *env UNUSED, jint fd, jint value)
423
{
424
  socketTimeouts[fd] = value;
425
  return 0;
426
}
427
 
428
jint cpnet_getSocketTimeout (JNIEnv *env UNUSED, jint fd, jint *value)
429
{
430
  *value = socketTimeouts[fd];
431
  return 0;
432
}
433
 
434
jint cpnet_setSendBuf (JNIEnv *env UNUSED, jint fd, jint value)
435
{
436
  int ret;
437
 
438
  ret = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value));
439
  if (ret != 0)
440
    return errno;
441
 
442
  return 0;
443
}
444
 
445
jint cpnet_getSendBuf (JNIEnv *env UNUSED, jint fd, jint *value)
446
{
447
  int ret;
448
  socklen_t slen = sizeof(*value);
449
 
450
  ret = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, value, &slen);
451
  if (ret != 0)
452
    return errno;
453
 
454
  return 0;
455
}
456
 
457
jint cpnet_setRecvBuf (JNIEnv *env UNUSED, jint fd, jint value)
458
{
459
  int ret;
460
 
461
  ret = setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value));
462
  if (ret != 0)
463
    return errno;
464
 
465
  return 0;
466
}
467
 
468
jint cpnet_getRecvBuf (JNIEnv *env UNUSED, jint fd, jint *value)
469
{
470
  int ret;
471
  socklen_t slen = sizeof(*value);
472
 
473
  ret = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, value, &slen);
474
  if (ret != 0)
475
    return errno;
476
 
477
  return 0;
478
}
479
 
480
jint cpnet_setTTL (JNIEnv *env UNUSED, jint fd, jint value)
481
{
482
  int ret;
483
 
484
  ret = setsockopt(fd, IPPROTO_IP, IP_TTL, &value, sizeof(value));
485
  if (ret != 0)
486
    return errno;
487
 
488
  return 0;
489
}
490
 
491
jint cpnet_getTTL (JNIEnv *env UNUSED, jint fd, jint *value)
492
{
493
  int ret;
494
  socklen_t slen = sizeof(*value);
495
 
496
  ret = getsockopt(fd, IPPROTO_IP, IP_TTL, value, &slen);
497
  if (ret != 0)
498
    return errno;
499
 
500
  return 0;
501
}
502
 
503
jint cpnet_setMulticastIF (JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
504
{
505
  int ret;
506
 
507
  ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr *)addr->data, addr->len);
508
  if (ret != 0)
509
    return errno;
510
 
511
  return 0;
512
}
513
 
514
jint cpnet_getMulticastIF (JNIEnv *env, jint fd, cpnet_address **addr)
515
{
516
  socklen_t slen = 1024;
517
  int ret;
518
 
519
  *addr = JCL_malloc(env, slen);
520
 
521
  slen -= sizeof(jint);
522
  ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr *)(*addr)->data, &slen);
523
  (*addr)->len = slen;
524
 
525
  if (ret != 0)
526
    return errno;
527
 
528
  return 0;
529
}
530
 
531
jint cpnet_setReuseAddress (JNIEnv *env UNUSED, jint fd, jint reuse)
532
{
533
  int ret;
534
 
535
  ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
536
  if (ret != 0)
537
    return errno;
538
 
539
  return 0;
540
}
541
 
542
jint cpnet_getReuseAddress (JNIEnv *env UNUSED, jint fd, jint *reuse)
543
{
544
  int ret;
545
  socklen_t slen = sizeof(*reuse);
546
 
547
  ret = getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, reuse, &slen);
548
  if (ret != 0)
549
    return errno;
550
 
551
  return 0;
552
}
553
 
554
jint cpnet_setKeepAlive (JNIEnv *env UNUSED, jint fd, jint keep)
555
{
556
  int ret;
557
 
558
  ret = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keep, sizeof(keep));
559
  if (ret != 0)
560
    return errno;
561
 
562
  return 0;
563
}
564
 
565
jint cpnet_getKeepAlive (JNIEnv *env UNUSED, jint fd, jint *keep)
566
{
567
  int ret;
568
  socklen_t slen = sizeof(*keep);
569
 
570
  ret = getsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, keep, &slen);
571
  if (ret != 0)
572
    return errno;
573
 
574
  return 0;
575
}
576
 
577
jint cpnet_addMembership (JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
578
{
579
  struct ip_mreq req;
580
  int ret;
581
  struct sockaddr_in *sockaddr = (struct sockaddr_in *)addr->data;
582
 
583
  memset(&req, 0, sizeof(req));
584
  req.imr_multiaddr = sockaddr->sin_addr;
585
  req.imr_interface.s_addr = INADDR_ANY;
586
  ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req));
587
  if (ret != 0)
588
    return errno;
589
 
590
  return 0;
591
}
592
 
593
jint cpnet_dropMembership (JNIEnv *env UNUSED, jint fd, cpnet_address *addr)
594
{
595
  struct ip_mreq req;
596
  int ret;
597
  struct sockaddr_in *sockaddr = (struct sockaddr_in *)addr->data;
598
 
599
  memset(&req, 0, sizeof(req));
600
  req.imr_multiaddr = sockaddr->sin_addr;
601
  req.imr_interface.s_addr = INADDR_ANY;
602
  ret = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &req, sizeof(req));
603
  if (ret != 0)
604
    return errno;
605
 
606
  return 0;
607
}
608
 
609
jint cpnet_getAvailableBytes (JNIEnv *env UNUSED, jint fd, jint *availableBytes)
610
{
611
  int ret;
612
 
613
  ret = ioctl(fd, FIONREAD, availableBytes);
614
  if (ret != 0)
615
    return errno;
616
 
617
  return 0;
618
}
619
 
620
jint cpnet_getHostname (JNIEnv *env UNUSED, char *hostname, jint hostname_len)
621
{
622
  int ret;
623
 
624
  ret = gethostname(hostname, hostname_len);
625
  if (ret != 0)
626
    return errno;
627
 
628
  hostname[hostname_len-1] = 0;
629
  return 0;
630
}
631
 
632
jint cpnet_getHostByName (JNIEnv *env, const char *hostname, cpnet_address ***addresses, jint *addresses_count)
633
{
634
  struct hostent hret;
635
  struct hostent *result;
636
  jint buflen = 1024;
637
  int herr = 0;
638
  int ret = 0;
639
  int counter = 0;
640
  cpnet_address **addr_arr;
641
  int i;
642
  char *buf;
643
 
644
  do
645
    {
646
      buf = (char *)JCL_malloc(env, buflen);
647
 
648
#ifdef HAVE_GETHOSTBYNAME_R
649
# if defined(HAVE_FUNC_GETHOSTBYNAME_R_6)
650
      ret = gethostbyname_r (hostname, &hret, buf, buflen, &result, &herr);
651
# elif defined(HAVE_FUNC_GETHOSTBYNAME_R_5)
652
      result = gethostbyname_r(hostname, &hret, buf, buflen, &herr);
653
# elif defined(HAVE_FUNC_GETHOSTBYNAME_R_3)
654
#  error IMPLEMENT ME!
655
# else
656
#  error unknown number of arguments for gethostbyname_r
657
# endif
658
#else
659
      hret.h_addr_list = NULL;
660
      hret.h_addrtype = 0;
661
 
662
      result = gethostbyname (hostname);
663
      if (result == NULL)
664
        return -errno;
665
      memcpy (&hret, result, sizeof (struct hostent));
666
#endif
667
      if (ret != 0 || result == NULL)
668
        {
669
          if (herr == ERANGE)
670
            {
671
              buflen *= 2;
672
              JCL_free(env, buf);
673
              continue;
674
            }
675
          JCL_free(env, buf);
676
 
677
          return -herr;
678
        }
679
 
680
      break;
681
    }
682
  while (1);
683
 
684
  while (hret.h_addr_list[counter] != NULL)
685
    counter++;
686
 
687
  *addresses_count = counter;
688
  addr_arr = *addresses = JCL_malloc(env, sizeof(cpnet_address *) * counter);
689
  switch (hret.h_addrtype)
690
    {
691
    case AF_INET:
692
      for (i = 0; i < counter; i++)
693
        {
694
          addr_arr[i] = cpnet_newIPV4Address(env);
695
          cpnet_bytesToIPV4Address(addr_arr[i], (jbyte *)hret.h_addr_list[i]);
696
        }
697
      break;
698
#ifdef HAVE_INET6
699
    case AF_INET6:
700
      for (i = 0; i < counter; i++)
701
        {
702
          addr_arr[i] = cpnet_newIPV6Address(env);
703
          cpnet_bytesToIPV6Address(addr_arr[i], (jbyte *)hret.h_addr_list[i]);
704
        }
705
      break;
706
#endif
707
    default:
708
      *addresses_count = 0;
709
      JCL_free(env, addr_arr);
710
      break;
711
    }
712
 
713
  JCL_free(env, buf);
714
 
715
  return 0;
716
}
717
 
718
jint cpnet_getHostByAddr (JNIEnv *env UNUSED, cpnet_address *addr, char *hostname, jint hostname_len)
719
{
720
  union
721
  {
722
    struct sockaddr_in *addr_v4;
723
    struct sockaddr_in6 *addr_v6;
724
    char *data;
725
  } haddr;
726
  void *raw_addr;
727
  int addr_type;
728
  struct hostent *ret;
729
  int addr_len;
730
 
731
  haddr.data = addr->data;
732
 
733
  if (haddr.addr_v4->sin_family == AF_INET)
734
    {
735
      raw_addr = &haddr.addr_v4->sin_addr;
736
      addr_len = sizeof(haddr.addr_v4->sin_addr);
737
      addr_type = AF_INET;
738
    }
739
#ifdef HAVE_INET6
740
  else if (haddr.addr_v6->sin6_family == AF_INET6)
741
    {
742
      raw_addr = &haddr.addr_v6->sin6_addr;
743
      addr_type = AF_INET6;
744
      addr_len = sizeof(haddr.addr_v6->sin6_addr);
745
    }
746
#endif
747
  else
748
    return EINVAL;
749
 
750
  /* Here we do not have any thread safe call. VM implementors will have to
751
   * do a big lock. Or it should be put on the Classpath VM interface.
752
   */
753
  ret = gethostbyaddr(raw_addr, addr_len, addr_type);
754
  if (ret == NULL)
755
    {
756
      /* The trouble here is how to distinguish the two cases ? */
757
      if (h_errno != 0)
758
        return h_errno;
759
      else
760
        return errno;
761
 
762
    }
763
  strncpy(hostname, ret->h_name, hostname_len);
764
 
765
  return 0;
766
}
767
 
768
jint cpnet_aton (JNIEnv *env, const char *hostname, cpnet_address **addr)
769
{
770
  jbyte *bytes = NULL;
771
 
772
#if defined(HAVE_INET_PTON) && defined(HAVE_INET6)
773
  jbyte inet6_addr[16];
774
#endif
775
 
776
#ifdef HAVE_INET_ATON
777
  struct in_addr laddr;
778
  if (inet_aton (hostname, &laddr))
779
    {
780
      bytes = (jbyte *) &laddr;
781
    }
782
#elif defined(HAVE_INET_ADDR)
783
#if ! HAVE_IN_ADDR_T
784
  typedef jint in_addr_t;
785
#endif
786
  in_addr_t laddr = inet_addr (hostname);
787
  if (laddr != (in_addr_t)(-1))
788
    {
789
      bytes = (jbyte *) &laddr;
790
    }
791
#endif
792
  if (bytes)
793
    {
794
      *addr = cpnet_newIPV4Address(env);
795
      cpnet_bytesToIPV4Address(*addr, bytes);
796
      return 0;
797
    }
798
 
799
#if defined(HAVE_INET_PTON) && defined(HAVE_INET6)
800
  if (inet_pton (AF_INET6, hostname, inet6_addr) > 0)
801
    {
802
      *addr = cpnet_newIPV6Address(env);
803
      cpnet_bytesToIPV6Address(*addr, inet6_addr);
804
      return 0;
805
    }
806
#endif
807
 
808
  *addr = NULL;
809
  return 0;
810
}
811
 
812
void cpnet_freeAddresses(JNIEnv * env, cpnet_address **addr, jint addresses_count)
813
{
814
  jint i;
815
 
816
  for (i = 0; i < addresses_count; i++)
817
    cpnet_freeAddress(env, addr[i]);
818
}

powered by: WebSVN 2.1.0

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