RFR:JDK-8021372 NetworkInterface.getNetworkInterfaces() returns duplicate hardware address
Mark Sheppard
mark.sheppard at oracle.com
Tue Sep 3 04:07:25 PDT 2013
Thanks for the feedback.
yes, we can merge the conditional,
that was my comment about the getAdapter function and the if else statement
because of a spurious IPv4 comment.
the 267(old) and 281(new) is the core of the issue
old
262 if (nif->index == index) {
263 /* found the interface entry
264 * set the index to the IPv6 index and add the
265 * IPv6 addresses
266 */
267 nif->index = ptr->Ipv6IfIndex;
268 c = getAddrsFromAdapter(ptr, &nif->addrs);
269 nif->naddrs += c;
270 break;
271 }
new
276 if (nif->index == index) {
277 /* found the interface entry
278 * set the index to the IPv6 index and add the
279 * IPv6 addresses
280 */
281 nif->ipv6Index = ptr->Ipv6IfIndex;
282 c = getAddrsFromAdapter(ptr, &nif->addrs);
283 nif->naddrs += c;
284 break;
285 }
the nif->index is already set in the IPv4 case, hence if (nif->index == index) .
In the original code the assignment was overwriting this value with
Ipv6IfIndex, but this can be zero, if IPv6 is not available for that adapter, but IPv6 is enabled in the OS.
Hence, NetworkInterface.getHardwareAddress returns the physical address associated with index 0.
When, both IPv4 and IPv6 are configured for an interface then this discrepancy
is not seen.
As netif has an ipv6Index member, the Ipv6IfIndex assignment seemed appropriate.
This is then supplemented with an additional check against the Ipv6IfIndex member of IP_ADAPTER_ADDRESSES when checking
the index.
when both IPv4 and IPv6 are available on an interface, then the index should be the same.
As such, an OS can be enabled for both IPv4 and IPv6, while an interface may be configured for
IPv4 only, which coincidentally was how I managed to reproduce the issue!
regards
Mark
On 03/09/2013 11:27, Michael McMahon wrote:
> On 03/09/13 10:45, Dmitry Samersoff wrote:
>> Mark,
>>
>> 1. If I read the code correctly,
>>
>> ll. 168 - 177 is exactly the same as ll. 180 - 189
>>
>> Could you refactor the fix to avoid code duplication?
>>
>> Would something like
>>
>> if (
>> (ptr->IfIndex != 0 && ptr->IfIndex == index) ||
>> (ptr->Ipv6IfIndex != 0 && ptr->Ipv6IfIndex == index)
>> ) {
>> ...
>> }
>>
>> work?
>
> I think this makes sense.
>
> Also, I'm not sure I understand the purpose of the change
> at line 267 (old) 281 (new). What the old code seemed to be doing
> was interpreting an IPv6 index as actually an IPv4 one.
> Was that not correct? This code is rather brittle unfortunately
> and not the easiest to understand.
>
> Michael
>
>
>
>>
>> 2. It seems to me passed index couldn't be 0 so null check is redundant,
>> but I don't mind to keep it.
>> It might make sense to explicitly check passed index for 0 above
>> loop.
>>
>> -Dmitry
>>
>>
>>
>> On 2013-09-03 13:23, Mark Sheppard wrote:
>>> Hi
>>> please oblige and review the fix below to address the issue in
>>> JDK-8021372:
>>> NetworkInterface.getNetworkInterfaces() returns duplicate hardware
>>> address
>>>
>>> http://cr.openjdk.java.net/~msheppar/8021372/webrev/
>>>
>>> the handling of the Ipv6IfIndex was suspect when setting the
>>> interface index and when retrieving the mac address using the index.
>>>
>>> in the getAdpaters function, the conditaionalstatement could be rolled
>>> into one.
>>> But, as there was a spurious IPv4 comment, I structured it as an if
>>> else. statement.
>>>
>>> It should be noted that IfIndex and the Ipv6IfIndex can be zero, which
>>> implies that the
>>> IPv4 or IPv6 interface is not available. This may be at odds with the
>>> setting of a default index to 0 in the Java NetworkInterface
>>> abstraction,
>>> where a defaultIndex of zero is used.
>>>
>>> JPRTs have been run and show no side effects.
>>>
>>> regards
>>> Mark
>>
>
More information about the net-dev
mailing list