Why does IPAddress.MapToIPv4() throw ArgumentOutOfRangeException?

独自空忆成欢 提交于 2019-12-03 11:03:02

Ok, I've actually verified this, so let me post this as an answer.

The IPAddress class has an error when mapping the address back to IPv4.

According to the .NET reference code, it does this:

long address = 
  (((m_Numbers[6] & 0x0000FF00) >> 8) | ((m_Numbers[6] & 0x000000FF) << 8)) |
  ((((m_Numbers[7] & 0x0000FF00) >> 8) | ((m_Numbers[7] & 0x000000FF) << 8)) << 16);

The problem should be quite obvious to anyone doing bitwise operations in .NET - the numbers are all ints. So shifting the second ushort (m_Numbers[7]) will give a negative value, because the most significant bit is 1. This means that all IPv4 addresses that end with a byte higher than 127 will cause an error when mapping back from IPv6.

The simple fix would be this:

long address = 
 (((m_Numbers[6] & 0x0000FF00) >> 8) | ((m_Numbers[6] & 0x000000FF) << 8)) 
 |
 (
  (uint)(((m_Numbers[7] & 0x0000FF00) >> 8) | ((m_Numbers[7] & 0x000000FF) << 8))
  << 16
 );

Just by casting the int to an uint before doing the bitshift does the trick.

Bitwise operations can be quite tricky when you factor in signed types. I guess the code was copied from a C++ library or something, where this issue wouldn't manifest.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!