Есть ли причина, по которой я получаю «eth15» в качестве имени моего интерфейса?
Это потребовало некоторого копания. В мире Java NetworkInterfaces
перечисляются java.net.NetworkInterface::getNetworkInterfaces()
, что вызывает native java.net.NetworkInterface::getAll()
.
Мы можем найти собственный исходный код для getAll()
в OpenJDK 11 здесь мы находим этот комментарий:
/*
* Windows implementation of the java.net.NetworkInterface native methods.
* This module provides the implementations of getAll, getByName, getByIndex,
* and getByAddress.
*
* Interfaces and addresses are enumerated using the IP helper routines
* GetIfTable, GetIfAddrTable resp. These routines are available on Windows
* 98, NT SP+4, 2000, and XP. They are also available on Windows 95 if
* IE is upgraded to 5.x.
*
* Windows does not have any standard for device names so we are forced
* to use our own convention which is based on the normal Unix naming
* convention ("lo" for the loopback, eth0, eth1, .. for ethernet devices,
* tr0, tr1, .. for token ring, and so on). This convention gives us
* consistency across multiple Windows editions and also consistency with
* Solaris/Linux device names. Note that we always enumerate in index
* order and this ensures consistent device number across invocations.
*/
Итак, когда-то давно, когда Windows 95 еще существовала, кто-то решил не читать настоящие имена интерфейсов Windows, а вместо этого использовать «наше собственное соглашение». Почему? Без понятия. Я бы предпочел получить отдельные deviceName()
и ourOwnConventionWhichHasNothingToDoWithTheActualNameDeviceName()
, но, к сожалению, со мной не посоветовались.
Базовый вызов Windows API GetIfTable возвращает имя для каждого интерфейса в виде массива MIB_IFROW:
typedef struct _MIB_IFROW {
WCHAR wszName[MAX_INTERFACE_NAME_LEN];
IF_INDEX dwIndex;
IFTYPE dwType;
DWORD dwMtu;
DWORD dwSpeed;
DWORD dwPhysAddrLen;
UCHAR bPhysAddr[MAXLEN_PHYSADDR];
DWORD dwAdminStatus;
INTERNAL_IF_OPER_STATUS dwOperStatus;
DWORD dwLastChange;
DWORD dwInOctets;
DWORD dwInUcastPkts;
DWORD dwInNUcastPkts;
DWORD dwInDiscards;
DWORD dwInErrors;
DWORD dwInUnknownProtos;
DWORD dwOutOctets;
DWORD dwOutUcastPkts;
DWORD dwOutNUcastPkts;
DWORD dwOutDiscards;
DWORD dwOutErrors;
DWORD dwOutQLen;
DWORD dwDescrLen;
UCHAR bDescr[MAXLEN_IFDESCR];
} MIB_IFROW, *PMIB_IFROW;
JVM кажется прочитайте этот массив, затем генерировать "подходящее" имя и, наконец, переопределить предоставленное ОС имя сгенерированным.
Короче говоря, не похоже, что реализация изменилась за много лет, и, вероятно, на данный момент это невозможно изменить, не создав совершенно новый API. В противном случае вы рискуете взломать код людей.
Как я это вижу, есть два способа получить фактические имена интерфейсов:
- Используйте JNI, чтобы сделать собственный вызов
GetIfTable
самостоятельно.
- Выполните
netsh
и проанализируйте ответ.
Оба решения довольно уродливы и требуют от вас убедиться, что вы работаете в Windows.
person
Malt
schedule
30.10.2019