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.c
32287 views
1
/*
2
* Copyright (c) 2000, 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
32
#include "java_net_NetworkInterface.h"
33
#include "jni_util.h"
34
35
#include "NetworkInterface.h"
36
37
/*
38
* Windows implementation of the java.net.NetworkInterface native methods.
39
* This module provides the implementations of getAll, getByName, getByIndex,
40
* and getByAddress.
41
*
42
* Interfaces and addresses are enumerated using the IP helper routines
43
* GetIfTable, GetIfAddrTable resp. These routines are available on Windows
44
* 98, NT SP+4, 2000, and XP. They are also available on Windows 95 if
45
* IE is upgraded to 5.x.
46
*
47
* Windows does not have any standard for device names so we are forced
48
* to use our own convention which is based on the normal Unix naming
49
* convention ("lo" for the loopback, eth0, eth1, .. for ethernet devices,
50
* tr0, tr1, .. for token ring, and so on). This convention gives us
51
* consistency across multiple Windows editions and also consistency with
52
* Solaris/Linux device names. Note that we always enumerate in index
53
* order and this ensures consistent device number across invocations.
54
*/
55
56
/* various JNI ids */
57
58
jclass ni_class; /* NetworkInterface */
59
60
jmethodID ni_ctor; /* NetworkInterface() */
61
62
jfieldID ni_indexID; /* NetworkInterface.index */
63
jfieldID ni_addrsID; /* NetworkInterface.addrs */
64
jfieldID ni_bindsID; /* NetworkInterface.bindings */
65
jfieldID ni_nameID; /* NetworkInterface.name */
66
jfieldID ni_displayNameID; /* NetworkInterface.displayName */
67
jfieldID ni_childsID; /* NetworkInterface.childs */
68
69
jclass ni_ibcls; /* InterfaceAddress */
70
jmethodID ni_ibctrID; /* InterfaceAddress() */
71
jfieldID ni_ibaddressID; /* InterfaceAddress.address */
72
jfieldID ni_ibbroadcastID; /* InterfaceAddress.broadcast */
73
jfieldID ni_ibmaskID; /* InterfaceAddress.maskLength */
74
75
/*
76
* Support routines to free netif and netaddr lists
77
*/
78
void free_netif(netif *netifP) {
79
netif *curr = netifP;
80
while (curr != NULL) {
81
if (curr->name != NULL)
82
free(curr->name);
83
if (curr->displayName != NULL)
84
free(curr->displayName);
85
if (curr->addrs != NULL)
86
free_netaddr (curr->addrs);
87
netifP = netifP->next;
88
free(curr);
89
curr = netifP;
90
}
91
}
92
93
void free_netaddr(netaddr *netaddrP) {
94
netaddr *curr = netaddrP;
95
while (curr != NULL) {
96
netaddrP = netaddrP->next;
97
free(curr);
98
curr = netaddrP;
99
}
100
}
101
102
/*
103
* Returns the interface structure from the table with the matching index.
104
*/
105
MIB_IFROW *getIF(jint index) {
106
MIB_IFTABLE *tableP;
107
MIB_IFROW *ifrowP, *ret = NULL;
108
ULONG size;
109
DWORD i, count;
110
jint ifindex;
111
112
/*
113
* Ask the IP Helper library to enumerate the adapters
114
*/
115
size = sizeof(MIB_IFTABLE);
116
tableP = (MIB_IFTABLE *)malloc(size);
117
if(tableP == NULL)
118
return NULL;
119
120
count = GetIfTable(tableP, &size, TRUE);
121
if (count == ERROR_INSUFFICIENT_BUFFER || count == ERROR_BUFFER_OVERFLOW) {
122
MIB_IFTABLE* newTableP = (MIB_IFTABLE *)realloc(tableP, size);
123
if (newTableP == NULL) {
124
free(tableP);
125
return NULL;
126
}
127
tableP = newTableP;
128
129
count = GetIfTable(tableP, &size, TRUE);
130
}
131
132
if (count != NO_ERROR) {
133
free(tableP);
134
return NULL;
135
}
136
137
{
138
ifrowP = tableP->table;
139
for (i=0; i<tableP->dwNumEntries; i++) {
140
/*
141
* Warning: the real index is obtained by GetFriendlyIfIndex()
142
*/
143
ifindex = GetFriendlyIfIndex(ifrowP->dwIndex);
144
if (ifindex == index) {
145
/*
146
* Create a copy of the entry so that we can free the table.
147
*/
148
ret = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
149
if (ret == NULL) {
150
free(tableP);
151
return NULL;
152
}
153
memcpy(ret, ifrowP, sizeof(MIB_IFROW));
154
break;
155
}
156
157
/* onto the next interface */
158
ifrowP++;
159
}
160
free(tableP);
161
}
162
return ret;
163
}
164
165
/*
166
* Enumerate network interfaces using IP Helper Library routine GetIfTable.
167
* We use GetIfTable rather than other IP helper routines because it's
168
* available on 98 & NT SP4+.
169
*
170
* Returns the number of interfaces found or -1 if error. If no error
171
* occurs then netifPP be returned as list of netif structures or NULL
172
* if no interfaces are found.
173
*/
174
int enumInterfaces(JNIEnv *env, netif **netifPP)
175
{
176
MIB_IFTABLE *tableP;
177
MIB_IFROW *ifrowP;
178
ULONG size;
179
DWORD ret;
180
int count;
181
netif *netifP;
182
DWORD i;
183
int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, wlan=0, net=0, wlen=0;
184
185
/*
186
* Ask the IP Helper library to enumerate the adapters
187
*/
188
size = sizeof(MIB_IFTABLE);
189
tableP = (MIB_IFTABLE *)malloc(size);
190
if (tableP == NULL) {
191
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
192
return -1;
193
}
194
195
ret = GetIfTable(tableP, &size, TRUE);
196
if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
197
MIB_IFTABLE * newTableP = (MIB_IFTABLE *)realloc(tableP, size);
198
if (newTableP == NULL) {
199
free(tableP);
200
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
201
return -1;
202
}
203
tableP = newTableP;
204
ret = GetIfTable(tableP, &size, TRUE);
205
}
206
207
if (ret != NO_ERROR) {
208
free(tableP);
209
210
JNU_ThrowByName(env, "java/lang/Error",
211
"IP Helper Library GetIfTable function failed");
212
213
return -1;
214
}
215
216
/*
217
* Iterate through the list of adapters
218
*/
219
count = 0;
220
netifP = NULL;
221
222
ifrowP = tableP->table;
223
for (i=0; i<tableP->dwNumEntries; i++) {
224
char dev_name[8];
225
netif *curr;
226
227
/*
228
* Generate a name for the device as Windows doesn't have any
229
* real concept of a device name.
230
*/
231
switch (ifrowP->dwType) {
232
case MIB_IF_TYPE_ETHERNET:
233
_snprintf_s(dev_name, 8, _TRUNCATE, "eth%d", eth++);
234
break;
235
236
case MIB_IF_TYPE_TOKENRING:
237
_snprintf_s(dev_name, 8, _TRUNCATE, "tr%d", tr++);
238
break;
239
240
case MIB_IF_TYPE_FDDI:
241
_snprintf_s(dev_name, 8, _TRUNCATE, "fddi%d", fddi++);
242
break;
243
244
case MIB_IF_TYPE_LOOPBACK:
245
/* There should only be only IPv4 loopback address */
246
if (lo > 0) {
247
continue;
248
}
249
strncpy_s(dev_name, 8, "lo", _TRUNCATE);
250
lo++;
251
break;
252
253
case MIB_IF_TYPE_PPP:
254
_snprintf_s(dev_name, 8, _TRUNCATE, "ppp%d", ppp++);
255
break;
256
257
case MIB_IF_TYPE_SLIP:
258
_snprintf_s(dev_name, 8, _TRUNCATE, "sl%d", sl++);
259
break;
260
261
case IF_TYPE_IEEE80211:
262
_snprintf_s(dev_name, 8, _TRUNCATE, "wlan%d", wlan++);
263
break;
264
265
default:
266
_snprintf_s(dev_name, 8, _TRUNCATE, "net%d", net++);
267
}
268
269
/*
270
* Allocate a netif structure and space for the name and
271
* display name (description in this case).
272
*/
273
curr = (netif *)calloc(1, sizeof(netif));
274
if (curr != NULL) {
275
wlen = MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
276
ifrowP->dwDescrLen, NULL, 0);
277
if(wlen == 0) {
278
// MultiByteToWideChar should not fail
279
// But in rare case it fails, we allow 'char' to be displayed
280
curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
281
} else {
282
curr->displayName = (wchar_t *)malloc((wlen+1)*sizeof(wchar_t));
283
}
284
285
curr->name = (char *)malloc(strlen(dev_name) + 1);
286
287
if (curr->name == NULL || curr->displayName == NULL) {
288
if (curr->name) free(curr->name);
289
if (curr->displayName) free(curr->displayName);
290
free(curr);
291
curr = NULL;
292
}
293
}
294
if (curr == NULL) {
295
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
296
free_netif(netifP);
297
free(tableP);
298
return -1;
299
}
300
301
/*
302
* Populate the interface. Note that we need to convert the
303
* index into its "friendly" value as otherwise we will expose
304
* 32-bit numbers as index values.
305
*/
306
strcpy(curr->name, dev_name);
307
if (wlen == 0) {
308
// display char type in case of MultiByteToWideChar failure
309
strncpy(curr->displayName, ifrowP->bDescr, ifrowP->dwDescrLen);
310
curr->displayName[ifrowP->dwDescrLen] = '\0';
311
} else {
312
// call MultiByteToWideChar again to fill curr->displayName
313
// it should not fail, because we have called it once before
314
if (MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
315
ifrowP->dwDescrLen, curr->displayName, wlen) == 0) {
316
JNU_ThrowByName(env, "java/lang/Error",
317
"Cannot get multibyte char for interface display name");
318
free_netif(netifP);
319
free(tableP);
320
free(curr->name);
321
free(curr->displayName);
322
free(curr);
323
return -1;
324
} else {
325
((wchar_t *)curr->displayName)[wlen] = L'\0';
326
curr->dNameIsUnicode = TRUE;
327
}
328
}
329
330
curr->dwIndex = ifrowP->dwIndex;
331
curr->ifType = ifrowP->dwType;
332
curr->index = GetFriendlyIfIndex(ifrowP->dwIndex);
333
334
/*
335
* Put the interface at tail of list as GetIfTable(,,TRUE) is
336
* returning the interfaces in index order.
337
*/
338
count++;
339
if (netifP == NULL) {
340
netifP = curr;
341
} else {
342
netif *tail = netifP;
343
while (tail->next != NULL) {
344
tail = tail->next;
345
}
346
tail->next = curr;
347
}
348
349
/* onto the next interface */
350
ifrowP++;
351
}
352
353
/*
354
* Free the interface table and return the interface list
355
*/
356
if (tableP) {
357
free(tableP);
358
}
359
*netifPP = netifP;
360
return count;
361
}
362
363
/*
364
* Enumerate the IP addresses on an interface using the IP helper library
365
* routine GetIfAddrTable and matching based on the index name. There are
366
* more efficient routines but we use GetIfAddrTable because it's avaliable
367
* on 98 and NT.
368
*
369
* Returns the count of addresses, or -1 if error. If no error occurs then
370
* netaddrPP will return a list of netaddr structures with the IP addresses.
371
*/
372
int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP)
373
{
374
MIB_IPADDRTABLE *tableP;
375
ULONG size;
376
DWORD ret;
377
DWORD i;
378
netaddr *netaddrP;
379
int count = 0;
380
unsigned long mask;
381
382
/*
383
* Use GetIpAddrTable to enumerate the IP Addresses
384
*/
385
size = sizeof(MIB_IPADDRTABLE);
386
tableP = (MIB_IPADDRTABLE *)malloc(size);
387
if (tableP == NULL) {
388
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
389
return -1;
390
}
391
392
ret = GetIpAddrTable(tableP, &size, FALSE);
393
if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
394
MIB_IPADDRTABLE * newTableP = (MIB_IPADDRTABLE *)realloc(tableP, size);
395
if (newTableP == NULL) {
396
free(tableP);
397
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
398
return -1;
399
}
400
tableP = newTableP;
401
402
ret = GetIpAddrTable(tableP, &size, FALSE);
403
}
404
if (ret != NO_ERROR) {
405
if (tableP) {
406
free(tableP);
407
}
408
JNU_ThrowByName(env, "java/lang/Error",
409
"IP Helper Library GetIpAddrTable function failed");
410
return -1;
411
}
412
413
/*
414
* Iterate through the table to find the addresses with the
415
* matching dwIndex. Ignore 0.0.0.0 addresses.
416
*/
417
count = 0;
418
netaddrP = NULL;
419
420
i = 0;
421
while (i<tableP->dwNumEntries) {
422
if (tableP->table[i].dwIndex == netifP->dwIndex &&
423
tableP->table[i].dwAddr != 0) {
424
425
netaddr *curr = (netaddr *)malloc(sizeof(netaddr));
426
if (curr == NULL) {
427
JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
428
free_netaddr(netaddrP);
429
free(tableP);
430
return -1;
431
}
432
433
curr->addr.him4.sin_family = AF_INET;
434
curr->addr.him4.sin_addr.s_addr = tableP->table[i].dwAddr;
435
/*
436
* Get netmask / broadcast address
437
*/
438
switch (netifP->ifType) {
439
case MIB_IF_TYPE_ETHERNET:
440
case MIB_IF_TYPE_TOKENRING:
441
case MIB_IF_TYPE_FDDI:
442
case MIB_IF_TYPE_LOOPBACK:
443
case IF_TYPE_IEEE80211:
444
/**
445
* Contrary to what it seems to indicate, dwBCastAddr doesn't
446
* contain the broadcast address but 0 or 1 depending on whether
447
* the broadcast address should set the bits of the host part
448
* to 0 or 1.
449
* Yes, I know it's stupid, but what can I say, it's MSFTs API.
450
*/
451
curr->brdcast.him4.sin_family = AF_INET;
452
if (tableP->table[i].dwBCastAddr == 1)
453
curr->brdcast.him4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
454
else
455
curr->brdcast.him4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
456
mask = ntohl(tableP->table[i].dwMask);
457
curr->mask = 0;
458
while (mask) {
459
mask <<= 1;
460
curr->mask++;
461
}
462
break;
463
case MIB_IF_TYPE_PPP:
464
case MIB_IF_TYPE_SLIP:
465
default:
466
/**
467
* these don't have broadcast/subnet
468
*/
469
curr->mask = -1;
470
break;
471
}
472
473
curr->next = netaddrP;
474
netaddrP = curr;
475
count++;
476
}
477
i++;
478
}
479
480
*netaddrPP = netaddrP;
481
free(tableP);
482
return count;
483
}
484
485
/*
486
* Class: java_net_NetworkInterface
487
* Method: init
488
* Signature: ()V
489
*/
490
JNIEXPORT void JNICALL
491
Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls)
492
{
493
/*
494
* Get the various JNI ids that we require
495
*/
496
ni_class = (*env)->NewGlobalRef(env, cls);
497
CHECK_NULL(ni_class);
498
ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
499
CHECK_NULL(ni_nameID);
500
ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
501
CHECK_NULL(ni_displayNameID);
502
ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
503
CHECK_NULL(ni_indexID);
504
ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
505
CHECK_NULL(ni_addrsID);
506
ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
507
CHECK_NULL(ni_bindsID);
508
ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
509
CHECK_NULL(ni_childsID);
510
ni_ctor = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
511
CHECK_NULL(ni_ctor);
512
ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
513
CHECK_NULL(ni_ibcls);
514
ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
515
CHECK_NULL(ni_ibcls);
516
ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
517
CHECK_NULL(ni_ibctrID);
518
ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
519
CHECK_NULL(ni_ibaddressID);
520
ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
521
CHECK_NULL(ni_ibbroadcastID);
522
ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
523
CHECK_NULL(ni_ibmaskID);
524
525
initInetAddressIDs(env);
526
}
527
528
/*
529
* Create a NetworkInterface object, populate the name and index, and
530
* populate the InetAddress array based on the IP addresses for this
531
* interface.
532
*/
533
jobject createNetworkInterface
534
(JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
535
{
536
jobject netifObj;
537
jobject name, displayName;
538
jobjectArray addrArr, bindsArr, childArr;
539
netaddr *addrs;
540
jint addr_index;
541
jint bind_index;
542
543
/*
544
* Create a NetworkInterface object and populate it
545
*/
546
netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
547
CHECK_NULL_RETURN(netifObj, NULL);
548
name = (*env)->NewStringUTF(env, ifs->name);
549
CHECK_NULL_RETURN(name, NULL);
550
if (ifs->dNameIsUnicode) {
551
displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName,
552
(jsize)wcslen ((PWCHAR)ifs->displayName));
553
} else {
554
displayName = (*env)->NewStringUTF(env, ifs->displayName);
555
}
556
CHECK_NULL_RETURN(displayName, NULL);
557
(*env)->SetObjectField(env, netifObj, ni_nameID, name);
558
(*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
559
(*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
560
561
/*
562
* Get the IP addresses for this interface if necessary
563
* Note that 0 is a valid number of addresses.
564
*/
565
if (netaddrCount < 0) {
566
netaddrCount = enumAddresses_win(env, ifs, &netaddrP);
567
if (netaddrCount == -1) {
568
return NULL;
569
}
570
}
571
addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
572
if (addrArr == NULL) {
573
free_netaddr(netaddrP);
574
return NULL;
575
}
576
577
bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
578
if (bindsArr == NULL) {
579
free_netaddr(netaddrP);
580
return NULL;
581
}
582
addrs = netaddrP;
583
addr_index = 0;
584
bind_index = 0;
585
while (addrs != NULL) {
586
jobject iaObj, ia2Obj;
587
jobject ibObj = NULL;
588
if (addrs->addr.him.sa_family == AF_INET) {
589
iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
590
if (iaObj == NULL) {
591
free_netaddr(netaddrP);
592
return NULL;
593
}
594
/* default ctor will set family to AF_INET */
595
596
setInetAddress_addr(env, iaObj, ntohl(addrs->addr.him4.sin_addr.s_addr));
597
if ((*env)->ExceptionCheck(env)) {
598
free_netaddr(netaddrP);
599
return NULL;
600
}
601
if (addrs->mask != -1) {
602
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
603
if (ibObj == NULL) {
604
free_netaddr(netaddrP);
605
return NULL;
606
}
607
(*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
608
ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
609
if (ia2Obj == NULL) {
610
free_netaddr(netaddrP);
611
return NULL;
612
}
613
setInetAddress_addr(env, ia2Obj, ntohl(addrs->brdcast.him4.sin_addr.s_addr));
614
if ((*env)->ExceptionCheck(env)) {
615
free_netaddr(netaddrP);
616
return NULL;
617
}
618
(*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
619
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
620
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
621
}
622
} else /* AF_INET6 */ {
623
int scope;
624
iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
625
if (iaObj) {
626
int ret = setInet6Address_ipaddress(env, iaObj, (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
627
if (ret == JNI_FALSE) {
628
free_netaddr(netaddrP);
629
return NULL;
630
}
631
632
scope = addrs->addr.him6.sin6_scope_id;
633
if (scope != 0) { /* zero is default value, no need to set */
634
setInet6Address_scopeid(env, iaObj, scope);
635
setInet6Address_scopeifname(env, iaObj, netifObj);
636
}
637
ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
638
if (ibObj == NULL) {
639
free_netaddr(netaddrP);
640
return NULL;
641
}
642
(*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
643
(*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
644
(*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
645
}
646
}
647
(*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
648
addrs = addrs->next;
649
addr_index++;
650
}
651
(*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
652
(*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
653
654
free_netaddr(netaddrP);
655
656
/*
657
* Windows doesn't have virtual interfaces, so child array
658
* is always empty.
659
*/
660
childArr = (*env)->NewObjectArray(env, 0, ni_class, NULL);
661
if (childArr == NULL) {
662
return NULL;
663
}
664
(*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
665
666
/* return the NetworkInterface */
667
return netifObj;
668
}
669
670
/*
671
* Class: java_net_NetworkInterface
672
* Method: getByName0
673
* Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
674
*/
675
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
676
(JNIEnv *env, jclass cls, jstring name)
677
{
678
netif *ifList, *curr;
679
jboolean isCopy;
680
const char *name_utf;
681
jobject netifObj = NULL;
682
683
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
684
if (ipv6_available()) {
685
return Java_java_net_NetworkInterface_getByName0_XP (env, cls, name);
686
}
687
688
/* get the list of interfaces */
689
if (enumInterfaces(env, &ifList) < 0) {
690
return NULL;
691
}
692
693
/* get the name as a C string */
694
name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
695
if (name_utf != NULL) {
696
697
/* Search by name */
698
curr = ifList;
699
while (curr != NULL) {
700
if (strcmp(name_utf, curr->name) == 0) {
701
break;
702
}
703
curr = curr->next;
704
}
705
706
/* if found create a NetworkInterface */
707
if (curr != NULL) {;
708
netifObj = createNetworkInterface(env, curr, -1, NULL);
709
}
710
711
/* release the UTF string */
712
(*env)->ReleaseStringUTFChars(env, name, name_utf);
713
} else {
714
if (!(*env)->ExceptionCheck(env))
715
JNU_ThrowOutOfMemoryError(env, NULL);
716
}
717
718
/* release the interface list */
719
free_netif(ifList);
720
721
return netifObj;
722
}
723
724
/*
725
* Class: NetworkInterface
726
* Method: getByIndex0
727
* Signature: (I)LNetworkInterface;
728
*/
729
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
730
(JNIEnv *env, jclass cls, jint index)
731
{
732
netif *ifList, *curr;
733
jobject netifObj = NULL;
734
735
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
736
if (ipv6_available()) {
737
return Java_java_net_NetworkInterface_getByIndex0_XP (env, cls, index);
738
}
739
740
/* get the list of interfaces */
741
if (enumInterfaces(env, &ifList) < 0) {
742
return NULL;
743
}
744
745
/* search by index */
746
curr = ifList;
747
while (curr != NULL) {
748
if (index == curr->index) {
749
break;
750
}
751
curr = curr->next;
752
}
753
754
/* if found create a NetworkInterface */
755
if (curr != NULL) {
756
netifObj = createNetworkInterface(env, curr, -1, NULL);
757
}
758
759
/* release the interface list */
760
free_netif(ifList);
761
762
return netifObj;
763
}
764
765
/*
766
* Class: java_net_NetworkInterface
767
* Method: getByInetAddress0
768
* Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
769
*/
770
JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
771
(JNIEnv *env, jclass cls, jobject iaObj)
772
{
773
netif *ifList, *curr;
774
jobject netifObj = NULL;
775
jint addr = getInetAddress_addr(env, iaObj);
776
JNU_CHECK_EXCEPTION_RETURN(env, NULL);
777
778
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
779
if (ipv6_available()) {
780
return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
781
}
782
783
/* get the list of interfaces */
784
if (enumInterfaces(env, &ifList) < 0) {
785
return NULL;
786
}
787
788
/*
789
* Enumerate the addresses on each interface until we find a
790
* matching address.
791
*/
792
curr = ifList;
793
while (curr != NULL) {
794
int count;
795
netaddr *addrList;
796
netaddr *addrP;
797
798
/* enumerate the addresses on this interface */
799
count = enumAddresses_win(env, curr, &addrList);
800
if (count < 0) {
801
free_netif(ifList);
802
return NULL;
803
}
804
805
/* iterate through each address */
806
addrP = addrList;
807
808
while (addrP != NULL) {
809
if ((unsigned long)addr == ntohl(addrP->addr.him4.sin_addr.s_addr)) {
810
break;
811
}
812
addrP = addrP->next;
813
}
814
815
/*
816
* Address matched so create NetworkInterface for this interface
817
* and address list.
818
*/
819
if (addrP != NULL) {
820
/* createNetworkInterface will free addrList */
821
netifObj = createNetworkInterface(env, curr, count, addrList);
822
break;
823
}
824
825
/* on next interface */
826
curr = curr->next;
827
}
828
829
/* release the interface list */
830
free_netif(ifList);
831
832
return netifObj;
833
}
834
835
/*
836
* Class: java_net_NetworkInterface
837
* Method: getAll
838
* Signature: ()[Ljava/net/NetworkInterface;
839
*/
840
JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
841
(JNIEnv *env, jclass cls)
842
{
843
int count;
844
netif *ifList, *curr;
845
jobjectArray netIFArr;
846
jint arr_index;
847
848
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
849
if (ipv6_available()) {
850
return Java_java_net_NetworkInterface_getAll_XP (env, cls);
851
}
852
853
/*
854
* Get list of interfaces
855
*/
856
count = enumInterfaces(env, &ifList);
857
if (count < 0) {
858
return NULL;
859
}
860
861
/* allocate a NetworkInterface array */
862
netIFArr = (*env)->NewObjectArray(env, count, cls, NULL);
863
if (netIFArr == NULL) {
864
free_netif(ifList);
865
return NULL;
866
}
867
868
/*
869
* Iterate through the interfaces, create a NetworkInterface instance
870
* for each array element and populate the object.
871
*/
872
curr = ifList;
873
arr_index = 0;
874
while (curr != NULL) {
875
jobject netifObj;
876
877
netifObj = createNetworkInterface(env, curr, -1, NULL);
878
if (netifObj == NULL) {
879
free_netif(ifList);
880
return NULL;
881
}
882
883
/* put the NetworkInterface into the array */
884
(*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
885
886
curr = curr->next;
887
}
888
889
/* release the interface list */
890
free_netif(ifList);
891
892
return netIFArr;
893
}
894
895
/*
896
* Class: java_net_NetworkInterface
897
* Method: isUp0
898
* Signature: (Ljava/lang/String;)Z
899
*/
900
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0
901
(JNIEnv *env, jclass cls, jstring name, jint index) {
902
jboolean ret = JNI_FALSE;
903
904
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
905
if (ipv6_available()) {
906
return Java_java_net_NetworkInterface_isUp0_XP(env, cls, name, index);
907
} else {
908
MIB_IFROW *ifRowP;
909
ifRowP = getIF(index);
910
if (ifRowP != NULL) {
911
ret = ifRowP->dwAdminStatus == MIB_IF_ADMIN_STATUS_UP &&
912
(ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL ||
913
ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED);
914
free(ifRowP);
915
}
916
}
917
return ret;
918
}
919
920
/*
921
* Class: java_net_NetworkInterface
922
* Method: isP2P0
923
* Signature: (Ljava/lang/String;I)Z
924
*/
925
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0
926
(JNIEnv *env, jclass cls, jstring name, jint index) {
927
MIB_IFROW *ifRowP;
928
jboolean ret = JNI_FALSE;
929
930
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
931
if (ipv6_available()) {
932
return Java_java_net_NetworkInterface_isP2P0_XP(env, cls, name, index);
933
} else {
934
ifRowP = getIF(index);
935
if (ifRowP != NULL) {
936
switch(ifRowP->dwType) {
937
case MIB_IF_TYPE_PPP:
938
case MIB_IF_TYPE_SLIP:
939
ret = JNI_TRUE;
940
break;
941
}
942
free(ifRowP);
943
}
944
}
945
return ret;
946
}
947
948
/*
949
* Class: java_net_NetworkInterface
950
* Method: isLoopback0
951
* Signature: (Ljava/lang/String;I)Z
952
*/
953
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0
954
(JNIEnv *env, jclass cls, jstring name, jint index) {
955
MIB_IFROW *ifRowP;
956
jboolean ret = JNI_FALSE;
957
958
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
959
if (ipv6_available()) {
960
return Java_java_net_NetworkInterface_isLoopback0_XP(env, cls, name, index);
961
} else {
962
ifRowP = getIF(index);
963
if (ifRowP != NULL) {
964
if (ifRowP->dwType == MIB_IF_TYPE_LOOPBACK)
965
ret = JNI_TRUE;
966
free(ifRowP);
967
}
968
return ret;
969
}
970
}
971
972
/*
973
* Class: java_net_NetworkInterface
974
* Method: supportsMulticast0
975
* Signature: (Ljava/lang/String;I)Z
976
*/
977
JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0
978
(JNIEnv *env, jclass cls, jstring name, jint index) {
979
return Java_java_net_NetworkInterface_supportsMulticast0_XP(env, cls,
980
name, index);
981
}
982
983
/*
984
* Class: java_net_NetworkInterface
985
* Method: getMacAddr0
986
* Signature: ([bLjava/lang/String;I)[b
987
*/
988
JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0
989
(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
990
jbyteArray ret = NULL;
991
int len;
992
MIB_IFROW *ifRowP;
993
994
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
995
if (ipv6_available()) {
996
return Java_java_net_NetworkInterface_getMacAddr0_XP(env, class, name, index);
997
} else {
998
ifRowP = getIF(index);
999
if (ifRowP != NULL) {
1000
switch(ifRowP->dwType) {
1001
case MIB_IF_TYPE_ETHERNET:
1002
case MIB_IF_TYPE_TOKENRING:
1003
case MIB_IF_TYPE_FDDI:
1004
case IF_TYPE_IEEE80211:
1005
len = ifRowP->dwPhysAddrLen;
1006
if (len > 0) {
1007
ret = (*env)->NewByteArray(env, len);
1008
if (!IS_NULL(ret)) {
1009
(*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
1010
}
1011
}
1012
break;
1013
}
1014
free(ifRowP);
1015
}
1016
return ret;
1017
}
1018
}
1019
1020
/*
1021
* Class: java_net_NetworkInterface
1022
* Method: getMTU0
1023
* Signature: ([bLjava/lang/String;I)I
1024
*/
1025
JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0
1026
(JNIEnv *env, jclass class, jstring name, jint index) {
1027
jint ret = -1;
1028
MIB_IFROW *ifRowP;
1029
1030
// Retained for now to support IPv4 only stack, java.net.preferIPv4Stack
1031
if (ipv6_available()) {
1032
return Java_java_net_NetworkInterface_getMTU0_XP(env, class, name, index);
1033
} else {
1034
ifRowP = getIF(index);
1035
if (ifRowP != NULL) {
1036
ret = ifRowP->dwMtu;
1037
free(ifRowP);
1038
}
1039
return ret;
1040
}
1041
}
1042
1043