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