Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/native/java/net/NetworkInterface_winXP.c
32287 views
1
/*
2
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
#include <stdlib.h>
27
#include <windows.h>
28
#include <winsock2.h> /* needed for htonl */
29
#include <iprtrmib.h>
30
#include <assert.h>
31
#include <limits.h>
32
33
#include "java_net_NetworkInterface.h"
34
#include "jni_util.h"
35
36
#include "NetworkInterface.h"
37
#include "net_util.h"
38
39
/*
40
* Windows implementation of the java.net.NetworkInterface native methods.
41
* This module provides the implementations of getAll, getByName, getByIndex,
42
* and getByAddress.
43
*/
44
45
extern int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP);
46
int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);
47
48
#ifdef DEBUG
49
void printnif (netif *nif) {
50
#ifdef _WIN64
51
printf ("nif:0x%I64x name:%s\n", nif,nif->name);
52
#else
53
printf ("nif:0x%x name:%s\n", nif,nif->name);
54
#endif
55
if (nif->dNameIsUnicode) {
56
printf ("dName:%S index:%d ", nif->displayName,nif->index);
57
} else {
58
printf ("dName:%s index:%d ", nif->displayName,nif->index);
59
}
60
printf ("naddrs:%d\n", nif->naddrs);
61
}
62
63
void printnifs (netif *netifPP, char *str) {
64
netif *nif;
65
printf ("%s\n", str);
66
for (nif=netifPP; nif!=NULL; nif=nif->next) {
67
printnif (nif);
68
}
69
printf("-----------------\n");
70
}
71
72
#endif
73
74
const ULONG BUFF_SIZE = 15360;
75
const int MAX_TRIES = 3;
76
77
/*
78
* return an array of IP_ADAPTER_ADDRESSES containing one element
79
* for each adapter on the system. Returned in *adapters.
80
* Buffer is malloc'd and must be freed (unless error returned)
81
*/
82
static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {
83
DWORD ret, flags;
84
IP_ADAPTER_ADDRESSES *adapterInfo;
85
ULONG len;
86
int try;
87
88
89
adapterInfo = (IP_ADAPTER_ADDRESSES *) malloc(BUFF_SIZE);
90
if (adapterInfo == NULL) {
91
JNU_ThrowByName(env, "java/lang/OutOfMemoryError",
92
"Native heap allocation failure");
93
return -1;
94
}
95
96
len = BUFF_SIZE;
97
flags = GAA_FLAG_SKIP_DNS_SERVER;
98
flags |= GAA_FLAG_SKIP_MULTICAST;
99
flags |= GAA_FLAG_INCLUDE_PREFIX;
100
ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
101
102
for (try = 0; ret == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {
103
IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
104
if (len < (ULONG_MAX - BUFF_SIZE)) {
105
len += BUFF_SIZE;
106
}
107
newAdapterInfo =
108
(IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
109
if (newAdapterInfo == NULL) {
110
free(adapterInfo);
111
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
112
return -1;
113
}
114
115
adapterInfo = newAdapterInfo;
116
117
ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
118
}
119
120
if (ret != ERROR_SUCCESS) {
121
free (adapterInfo);
122
JNU_ThrowByName(env, "java/lang/Error",
123
"IP Helper Library GetAdaptersAddresses function failed");
124
return -1;
125
}
126
*adapters = adapterInfo;
127
return ERROR_SUCCESS;
128
}
129
130
/*
131
* return an array of IP_ADAPTER_ADDRESSES containing one element
132
* for each adapter on the system. Returned in *adapters.
133
* Buffer is malloc'd and must be freed (unless error returned)
134
*/
135
IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) {
136
DWORD flags, val;
137
IP_ADAPTER_ADDRESSES *adapterInfo, *ptr, *ret;
138
ULONG len;
139
int try;
140
adapterInfo = (IP_ADAPTER_ADDRESSES *) malloc(BUFF_SIZE);
141
if (adapterInfo == NULL) {
142
JNU_ThrowByName(env, "java/lang/OutOfMemoryError",
143
"Native heap allocation failure");
144
return NULL;
145
}
146
len = BUFF_SIZE;
147
flags = GAA_FLAG_SKIP_DNS_SERVER;
148
flags |= GAA_FLAG_SKIP_MULTICAST;
149
flags |= GAA_FLAG_INCLUDE_PREFIX;
150
val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
151
for (try = 0; val == ERROR_BUFFER_OVERFLOW && try < MAX_TRIES; ++try) {
152
IP_ADAPTER_ADDRESSES * newAdapterInfo = NULL;
153
if (len < (ULONG_MAX - BUFF_SIZE)) {
154
len += BUFF_SIZE;
155
}
156
newAdapterInfo =
157
(IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
158
if (newAdapterInfo == NULL) {
159
free(adapterInfo);
160
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
161
return NULL;
162
}
163
164
adapterInfo = newAdapterInfo;
165
166
val = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, adapterInfo, &len);
167
}
168
169
if (val != ERROR_SUCCESS) {
170
free (adapterInfo);
171
JNU_ThrowByName(env, "java/lang/Error",
172
"IP Helper Library GetAdaptersAddresses function failed");
173
return NULL;
174
}
175
ptr = adapterInfo;
176
ret = NULL;
177
while (ptr != NULL) {
178
// in theory the IPv4 index and the IPv6 index can be the same
179
// where an interface is enabled for v4 and v6
180
// IfIndex == 0 IPv4 not available on this interface
181
// Ipv6IfIndex == 0 IPv6 not available on this interface
182
if (((ptr->IfIndex != 0)&&(ptr->IfIndex == index)) ||
183
((ptr->Ipv6IfIndex !=0) && (ptr->Ipv6IfIndex == index))) {
184
ret = (IP_ADAPTER_ADDRESSES *) malloc(sizeof(IP_ADAPTER_ADDRESSES));
185
if (ret == NULL) {
186
free(adapterInfo);
187
JNU_ThrowByName(env, "java/lang/OutOfMemoryError", "Native heap allocation failure");
188
return NULL;
189
}
190
191
//copy the memory and break out of the while loop.
192
memcpy(ret, ptr, sizeof(IP_ADAPTER_ADDRESSES));
193
break;
194
195
}
196
ptr=ptr->Next;
197
}
198
free(adapterInfo);
199
return ret;
200
}
201
202
static int ipinflen = 2048;
203
204
/*
205
*/
206
int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
207
{
208
DWORD ret;
209
IP_ADAPTER_ADDRESSES *ptr, *adapters=NULL;
210
ULONG len=ipinflen, count=0;
211
netif *nif=NULL, *dup_nif, *last=NULL, *loopif=NULL, *curr;
212
int tun=0, net=0;
213
214
*netifPP = NULL;
215
/*
216
* Get the IPv4 interfaces. This information is the same
217
* as what previous JDK versions would return.
218
*/
219
220
ret = enumInterfaces(env, netifPP);
221
if (ret == -1) {
222
return -1;
223
} else {
224
count = ret;
225
}
226
227
/* locate the loopback (and the last) interface */
228
for (nif=*netifPP, last=nif; nif!=NULL; nif=nif->next) {
229
if (nif->ifType == MIB_IF_TYPE_LOOPBACK) {
230
loopif = nif;
231
}
232
last = nif;
233
}
234
235
// Retrieve IPv4 addresses with the IP Helper API
236
curr = *netifPP;
237
while (curr != NULL) {
238
netaddr *netaddrP;
239
ret = enumAddresses_win(env, curr, &netaddrP);
240
if (ret == -1) {
241
return -1;
242
}
243
curr->addrs = netaddrP;
244
curr->naddrs += ret;
245
curr = curr->next;
246
}
247
248
ret = getAdapters (env, &adapters);
249
if (ret != ERROR_SUCCESS) {
250
goto err;
251
}
252
253
/* Now get the IPv6 information. This includes:
254
* (a) IPv6 information associated with interfaces already found
255
* (b) IPv6 information for IPv6 only interfaces (probably tunnels)
256
*
257
* For compatibility with previous releases we use the naming
258
* information gotten from enumInterfaces() for (a) entries
259
* However, the index numbers are taken from the new API.
260
*
261
* The procedure is to go through the list of adapters returned
262
* by the new API looking for entries that correspond to IPv4 interfaces
263
* already found.
264
*/
265
266
ptr = adapters;
267
while (ptr != NULL) {
268
int c;
269
netif *nif0;
270
if (ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK && (loopif != NULL)) {
271
c = getAddrsFromAdapter(ptr, &loopif->addrs);
272
if (c == -1) {
273
goto err;
274
}
275
loopif->naddrs += c;
276
} else {
277
int index = ptr->IfIndex;
278
if (index != 0) {
279
/* This entry is associated with an IPv4 interface */
280
for (nif=*netifPP; nif!=NULL; nif=nif->next) {
281
if (nif->index == index) {
282
/* found the interface entry
283
* set the index to the IPv6 index and add the
284
* IPv6 addresses
285
*/
286
nif->ipv6Index = ptr->Ipv6IfIndex;
287
c = getAddrsFromAdapter(ptr, &nif->addrs);
288
nif->naddrs += c;
289
break;
290
}
291
}
292
} else {
293
/* This entry is IPv6 only */
294
char newname [128];
295
int c;
296
297
/* Windows allocates duplicate adapter entries
298
* for tunnel interfaces when there are multiple
299
* physical adapters. Need to check
300
* if this is a duplicate (ipv6Index is the same)
301
*/
302
dup_nif = 0;
303
for (nif0=*netifPP; nif0!=NULL; nif0=nif0->next) {
304
if (nif0->hasIpv6Address &&
305
ptr->Ipv6IfIndex == nif0->ipv6Index) {
306
dup_nif = nif0;
307
break;
308
}
309
}
310
if (dup_nif == 0) {
311
/* new interface */
312
nif = (netif *) calloc (1, sizeof(netif));
313
if (nif == 0) {
314
goto err;
315
}
316
if (ptr->IfType == IF_TYPE_TUNNEL) {
317
sprintf (newname, "tun%d", tun);
318
tun ++;
319
} else {
320
sprintf (newname, "net%d", net);
321
net ++;
322
}
323
nif->name = malloc (strlen(newname)+1);
324
nif->displayName = malloc (wcslen(ptr->FriendlyName)*2+2);
325
if (nif->name == 0 || nif->displayName == 0) {
326
goto err;
327
}
328
strcpy (nif->name, newname);
329
wcscpy ((PWCHAR)nif->displayName, ptr->FriendlyName);
330
nif->dNameIsUnicode = TRUE;
331
332
// the java.net.NetworkInterface abstraction only has index
333
// so the Ipv6IfIndex needs to map onto index
334
nif->index = ptr->Ipv6IfIndex;
335
nif->ipv6Index = ptr->Ipv6IfIndex;
336
nif->hasIpv6Address = TRUE;
337
338
last->next = nif;
339
last = nif;
340
count++;
341
c = getAddrsFromAdapter(ptr, &nif->addrs);
342
if (c == -1) {
343
goto err;
344
}
345
nif->naddrs += c;
346
} else {
347
/* add the addresses from this adapter to the
348
* original (dup_nif)
349
*/
350
c = getAddrsFromAdapter(ptr, &dup_nif->addrs);
351
if (c == -1) {
352
goto err;
353
}
354
dup_nif->naddrs += c;
355
}
356
}
357
}
358
ptr=ptr->Next;
359
}
360
361
free (adapters);
362
return count;
363
364
err:
365
if (*netifPP) {
366
free_netif (*netifPP);
367
}
368
if (adapters) {
369
free (adapters);
370
}
371
return -1;
372
}
373
374
/* If *netaddrPP is null, then the addresses are allocated and the beginning
375
* of the allocated chain is returned in *netaddrPP.
376
* If *netaddrPP is not null, then the addresses allocated here are appended
377
* to the existing chain.
378
*
379
* Returns count of addresses or -1 on error.
380
*/
381
382
static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP) {
383
LPSOCKADDR sock;
384
int count = 0;
385
netaddr *curr, *start = NULL, *prev = NULL;
386
PIP_ADAPTER_UNICAST_ADDRESS uni_addr;
387
PIP_ADAPTER_ANYCAST_ADDRESS any_addr;
388
PIP_ADAPTER_PREFIX prefix;
389
390
/* If chain passed in, find end */
391
if (*netaddrPP != NULL) {
392
for (start=*netaddrPP; start->next!=NULL; start=start->next)
393
;
394
395
prev=start;
396
}
397
398
prefix = ptr->FirstPrefix;
399
/* Unicast */
400
uni_addr = ptr->FirstUnicastAddress;
401
while (uni_addr != NULL) {
402
/* address is only usable if dad state is preferred or deprecated */
403
if (uni_addr->DadState == IpDadStateDeprecated ||
404
uni_addr->DadState == IpDadStatePreferred) {
405
sock = uni_addr->Address.lpSockaddr;
406
407
// IPv4 addresses already retrieved with enumAddresses_win
408
if (sock->sa_family == AF_INET) {
409
uni_addr = uni_addr->Next;
410
continue;
411
}
412
413
curr = (netaddr *)calloc (1, sizeof (netaddr));
414
415
if (curr == NULL)
416
goto freeAllocatedMemory;
417
418
if (start == NULL)
419
start = curr;
420
421
if (prev != NULL)
422
prev->next = curr;
423
424
prev = curr;
425
SOCKETADDRESS_COPY (&curr->addr, sock);
426
if (prefix != NULL) {
427
curr->mask = (short)prefix->PrefixLength;
428
prefix = prefix->Next;
429
}
430
count ++;
431
}
432
uni_addr = uni_addr->Next;
433
}
434
/* Anycast */
435
any_addr = ptr->FirstAnycastAddress;
436
while (any_addr != NULL) {
437
curr = (netaddr *)calloc (1, sizeof (netaddr));
438
439
if (curr == NULL)
440
goto freeAllocatedMemory;
441
442
if (start == NULL)
443
start = curr;
444
445
if (prev != NULL)
446
prev->next = curr;
447
448
prev = curr;
449
sock = any_addr->Address.lpSockaddr;
450
SOCKETADDRESS_COPY (&curr->addr, sock);
451
count ++;
452
any_addr = any_addr->Next;
453
}
454
if (*netaddrPP == NULL) {
455
*netaddrPP = start;
456
}
457
return count;
458
459
freeAllocatedMemory:
460
461
if (*netaddrPP != NULL) {
462
//N.B. the variable "start" cannot be NULL at this point because we started with an
463
//existing list.
464
curr=start->next;
465
start->next = NULL;
466
start = curr;
467
}
468
// otherwise, "start" points to the beginning of an incomplete list that we must deallocate.
469
470
while (start != NULL) {
471
curr = start->next;
472
free(start);
473
start = curr;
474
}
475
476
return -1;
477
}
478
479
/*
480
* Create a NetworkInterface object, populate the name and index, and
481
* populate the InetAddress array based on the IP addresses for this
482
* interface.
483
*/
484
static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
485
{
486
jobject netifObj;
487
jobject name, displayName;
488
jobjectArray addrArr, bindsArr, childArr;
489
netaddr *addrs;
490
jint addr_index;
491
int netaddrCount = ifs->naddrs;
492
netaddr *netaddrP = ifs->addrs;
493
netaddr *netaddrPToFree = NULL;
494
jint bind_index;
495
496
/*
497
* Create a NetworkInterface object and populate it
498
*/
499
netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
500
if (netifObj == NULL) {
501
return NULL;
502
}
503
name = (*env)->NewStringUTF(env, ifs->name);
504
if (name == NULL) {
505
return NULL;
506
}
507
if (ifs->dNameIsUnicode) {
508
displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
509
(jsize)wcslen ((PWCHAR)ifs->displayName));
510
} else {
511
displayName = (*env)->NewStringUTF(env, ifs->displayName);
512
}
513
if (displayName == NULL) {
514
return NULL;
515
}
516
(*env)->SetObjectField(env, netifObj, ni_nameID, name);
517
(*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
518
(*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
519
/*
520
* Get the IP addresses for this interface if necessary
521
* Note that 0 is a valid number of addresses.
522
*/
523
if (netaddrCount < 0) {
524
netaddrCount = enumAddresses_win(env, ifs, &netaddrPToFree);
525
if (netaddrCount == -1) {
526
return NULL;
527
}
528
netaddrP = netaddrPToFree;
529
}
530
531
addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
532
if (addrArr == NULL) {
533
free_netaddr(netaddrPToFree);
534
return NULL;
535
}
536
537
bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
538
if (bindsArr == NULL) {
539
free_netaddr(netaddrPToFree);
540
return NULL;
541
}
542
543
addrs = netaddrP;
544
addr_index = 0;
545
bind_index = 0;
546
while (addrs != NULL) {
547
jobject iaObj, ia2Obj;
548
jobject ibObj = NULL;
549
if (addrs->addr.him.sa_family == AF_INET) {
550
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
551
if (iaObj == NULL) {
552
free_netaddr(netaddrPToFree);
553
return NULL;
554
}
555
/* default ctor will set family to AF_INET */
556
557
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
558
if ((*env)->ExceptionCheck(env)) {
559
free_netaddr(netaddrPToFree);
560
return NULL;
561
}
562
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
563
if (ibObj == NULL) {
564
free_netaddr(netaddrPToFree);
565
return NULL;
566
}
567
(*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
568
ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
569
if (ia2Obj == NULL) {
570
free_netaddr(netaddrPToFree);
571
return NULL;
572
}
573
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
574
if ((*env)->ExceptionCheck(env)) {
575
free_netaddr(netaddrPToFree);
576
return NULL;
577
}
578
(*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
579
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
580
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
581
} else /* AF_INET6 */ {
582
int scope;
583
int ret;
584
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
585
if (iaObj == NULL) {
586
free_netaddr(netaddrPToFree);
587
return NULL;
588
}
589
ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
590
if (ret == JNI_FALSE) {
591
free_netaddr(netaddrPToFree);
592
return NULL;
593
}
594
scope = addrs->addr.him6.sin6_scope_id;
595
if (scope != 0) { /* zero is default value, no need to set */
596
setInet6Address_scopeid(env, iaObj, scope);
597
setInet6Address_scopeifname(env, iaObj, netifObj);
598
}
599
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
600
if (ibObj == NULL) {
601
free_netaddr(netaddrPToFree);
602
return NULL;
603
}
604
(*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
605
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
606
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
607
}
608
(*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
609
addrs = addrs->next;
610
addr_index++;
611
}
612
(*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
613
(*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
614
615
free_netaddr(netaddrPToFree);
616
617
/*
618
* Windows doesn't have virtual interfaces, so child array
619
* is always empty.
620
*/
621
childArr = (*env)->NewObjectArray(env, 0, ni_class, NULL);
622
if (childArr == NULL) {
623
return NULL;
624
}
625
(*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
626
627
/* return the NetworkInterface */
628
return netifObj;
629
}
630
631
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
632
(JNIEnv *env, jclass cls, jstring name)
633
{
634
netif *ifList, *curr;
635
jboolean isCopy;
636
const char *name_utf;
637
jobject netifObj = NULL;
638
639
if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
640
return NULL;
641
}
642
643
/* get the name as a C string */
644
name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
645
646
/* Search by name */
647
curr = ifList;
648
while (curr != NULL) {
649
if (strcmp(name_utf, curr->name) == 0) {
650
break;
651
}
652
curr = curr->next;
653
}
654
655
/* if found create a NetworkInterface */
656
if (curr != NULL) {
657
netifObj = createNetworkInterfaceXP(env, curr);
658
}
659
660
/* release the UTF string */
661
(*env)->ReleaseStringUTFChars(env, name, name_utf);
662
663
/* release the interface list */
664
free_netif(ifList);
665
666
return netifObj;
667
}
668
669
/*
670
* Class: NetworkInterface
671
* Method: getByIndex0_XP
672
* Signature: (I)LNetworkInterface;
673
*/
674
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0_XP
675
(JNIEnv *env, jclass cls, jint index)
676
{
677
netif *ifList, *curr;
678
jobject netifObj = NULL;
679
680
if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
681
return NULL;
682
}
683
684
/* search by index */
685
curr = ifList;
686
while (curr != NULL) {
687
if (index == curr->index) {
688
break;
689
}
690
curr = curr->next;
691
}
692
693
/* if found create a NetworkInterface */
694
if (curr != NULL) {
695
netifObj = createNetworkInterfaceXP(env, curr);
696
}
697
698
/* release the interface list */
699
free_netif(ifList);
700
701
return netifObj;
702
}
703
704
/*
705
* Class: java_net_NetworkInterface
706
* Method: getByInetAddress0
707
* Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
708
*/
709
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0_XP
710
(JNIEnv *env, jclass cls, jobject iaObj)
711
{
712
netif *ifList, *curr;
713
jobject netifObj = NULL;
714
715
/* get the list of interfaces */
716
if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
717
return NULL;
718
}
719
720
/*
721
* Enumerate the addresses on each interface until we find a
722
* matching address.
723
*/
724
curr = ifList;
725
while (curr != NULL) {
726
netaddr *addrList = curr->addrs;
727
netaddr *addrP;
728
729
/* iterate through each address */
730
addrP = addrList;
731
732
while (addrP != NULL) {
733
if (NET_SockaddrEqualsInetAddress(env,
734
(struct sockaddr*)&addrP->addr, iaObj)) {
735
break;
736
}
737
addrP = addrP->next;
738
}
739
740
/*
741
* Address matched so create NetworkInterface for this interface
742
* and address list.
743
*/
744
if (addrP != NULL) {
745
netifObj = createNetworkInterfaceXP(env, curr);
746
break;
747
}
748
749
/* on next interface */
750
curr = curr->next;
751
}
752
753
/* release the interface list */
754
free_netif(ifList);
755
756
return netifObj;
757
}
758
759
/*
760
* Class: java_net_NetworkInterface
761
* Method: getAll
762
* Signature: ()[Ljava/net/NetworkInterface;
763
*/
764
JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll_XP
765
(JNIEnv *env, jclass cls)
766
{
767
int count;
768
netif *ifList, *curr;
769
jobjectArray netIFArr;
770
jint arr_index;
771
772
/*
773
* Get list of interfaces
774
*/
775
count = getAllInterfacesAndAddresses (env, &ifList);
776
if (count < 0) {
777
return NULL;
778
}
779
780
/* allocate a NetworkInterface array */
781
netIFArr = (*env)->NewObjectArray(env, count, cls, NULL);
782
if (netIFArr == NULL) {
783
free_netif(ifList);
784
return NULL;
785
}
786
787
/*
788
* Iterate through the interfaces, create a NetworkInterface instance
789
* for each array element and populate the object.
790
*/
791
curr = ifList;
792
arr_index = 0;
793
while (curr != NULL) {
794
jobject netifObj;
795
796
netifObj = createNetworkInterfaceXP(env, curr);
797
if (netifObj == NULL) {
798
free_netif(ifList);
799
return NULL;
800
}
801
802
/* put the NetworkInterface into the array */
803
(*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
804
curr = curr->next;
805
}
806
807
/* release the interface list */
808
free_netif(ifList);
809
810
return netIFArr;
811
}
812
813
/*
814
* Class: java_net_NetworkInterface
815
* Method: supportsMulticast0
816
* Signature: (Ljava/lang/String;I)Z
817
*/
818
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0_XP
819
(JNIEnv *env, jclass cls, jstring name, jint index) {
820
IP_ADAPTER_ADDRESSES *ptr;
821
jboolean val = JNI_TRUE;
822
823
ptr = getAdapter(env, index);
824
if (ptr != NULL) {
825
val = ptr->Flags & IP_ADAPTER_NO_MULTICAST ? JNI_FALSE : JNI_TRUE;
826
free(ptr);
827
}
828
return val;
829
}
830
831
/*
832
* Class: java_net_NetworkInterface
833
* Method: isUp0
834
* Signature: (Ljava/lang/String;I)Z
835
*/
836
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0_XP
837
(JNIEnv *env, jclass cls, jstring name, jint index) {
838
IP_ADAPTER_ADDRESSES *ptr;
839
jboolean val = JNI_FALSE;
840
841
ptr = getAdapter(env, index);
842
if (ptr != NULL) {
843
val = ptr->OperStatus == IfOperStatusUp ? JNI_TRUE : JNI_FALSE;
844
free(ptr);
845
}
846
return val;
847
}
848
849
/*
850
* Class: java_net_NetworkInterface
851
* Method: getMacAddr0
852
* Signature: (Ljava/lang/String;I)Z
853
*/
854
JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0_XP
855
(JNIEnv *env, jclass cls, jstring name, jint index) {
856
IP_ADAPTER_ADDRESSES *ptr;
857
jbyteArray ret = NULL;
858
int len;
859
860
ptr = getAdapter(env, index);
861
if (ptr != NULL) {
862
len = ptr->PhysicalAddressLength;
863
if (len > 0) {
864
ret = (*env)->NewByteArray(env, len);
865
if (!IS_NULL(ret)) {
866
(*env)->SetByteArrayRegion(env, ret, 0, len,
867
(jbyte*) ptr->PhysicalAddress);
868
}
869
}
870
free(ptr);
871
}
872
return ret;
873
}
874
875
/*
876
* Class: java_net_NetworkInterface
877
* Method: getMTU0
878
* Signature: ([bLjava/lang/String;I)I
879
*/
880
JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
881
(JNIEnv *env, jclass cls, jstring name, jint index) {
882
IP_ADAPTER_ADDRESSES *ptr;
883
jint ret = -1;
884
885
ptr = getAdapter(env, index);
886
if (ptr != NULL) {
887
ret = ptr->Mtu;
888
free(ptr);
889
}
890
return ret;
891
}
892
893
/*
894
* Class: java_net_NetworkInterface
895
* Method: isLoopback0
896
* Signature: (Ljava/lang/String;I)Z
897
*/
898
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
899
(JNIEnv *env, jclass cls, jstring name, jint index) {
900
IP_ADAPTER_ADDRESSES *ptr;
901
jboolean val = JNI_FALSE;
902
903
ptr = getAdapter(env, index);
904
if (ptr != NULL) {
905
val = ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? JNI_TRUE : JNI_FALSE;
906
free(ptr);
907
}
908
return val;
909
}
910
911
/*
912
* Class: java_net_NetworkInterface
913
* Method: isP2P0
914
* Signature: (Ljava/lang/String;I)Z
915
*/
916
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0_XP
917
(JNIEnv *env, jclass cls, jstring name, jint index) {
918
IP_ADAPTER_ADDRESSES *ptr;
919
jboolean val = JNI_FALSE;
920
921
ptr = getAdapter(env, index);
922
if (ptr != NULL) {
923
if (ptr->IfType == IF_TYPE_PPP || ptr->IfType == IF_TYPE_SLIP ||
924
ptr->IfType == IF_TYPE_TUNNEL) {
925
val = JNI_TRUE;
926
}
927
free(ptr);
928
}
929
return val;
930
}
931
932