[omniORB] Warning: WSAIoctl SIO_ADDRESS_LIST_QUERY failed

Mac mlarner@ihug.co.nz
Thu, 04 Apr 2002 17:50:10 -0800


This is a multi-part message in MIME format.

------=_NextPart_000_002F_01C1DC01.2A239EA0
Content-Type: text/plain;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable


yep i came across this too..here's a fix...the function below uses =
SIO_GET_INTERFACE_LIST instead of SIO_ADDRESS_LIST_QUERY in the ioctl =
call. I've only tested this on NT sp6a (not w2000). & i don't think =
it'll work for pre sp4 versions of NT due to a tweak they made with the =
INTERFACE_INFO struct to accomdate IPv6.

so inside tcpTransportImpl.cc replace the win32_get_ifinfo func with the =
one below.

static
void win32_get_ifinfo(omnivector<const char*>& ifaddrs) {

  SocketHandle_t sock;

  sock =3D socket(INETSOCKET,SOCK_STREAM,0);

  DWORD lastlen =3D 0;
  DWORD len =3D 10 * sizeof(INTERFACE_INFO);
  DWORD retlen=3D0;
 =20
  INTERFACE_INFO *addressBuffer=3DNULL;

  while ( 1 )=20
  {
    // There is no way to know for sure the buffer is big enough to get
    // the info for all the interfaces. We work around this by calling
    // the ioctl 2 times and increases the buffer size in the 2nd call.
    addressBuffer =3D (INTERFACE_INFO*) malloc(len);


    if ( WSAIoctl(sock,SIO_GET_INTERFACE_LIST, NULL,0, =
(LPVOID)addressBuffer,(DWORD)len,(LPDWORD)&retlen,
                  NULL,NULL) =3D=3D SOCKET_ERROR )    =20
 {
=20
  int err =3D WSAGetLastError();

  free(addressBuffer);

  if ( err !=3D WSAENOBUFS || lastlen !=3D 0 )=20
  {
   if ( omniORB::trace(2) )=20
   {
     omniORB::logger log;
     log << "Warning: WSAIoctl SIO_ADDRESS_LIST_QUERY failed. Unable to =
obtain the list of all interface addresses.\n";
   }
   return;
  }
  len *=3D 2;
    }
    else=20
 {
  if ( retlen <=3D len )=20
   break; // Success, len is large enough
=20
  len =3D retlen;    =20
    }
   =20
  }
  CLOSESOCKET(sock);

  int numAddresses =3D retlen / sizeof(INTERFACE_INFO);
  for (int i =3D 0; i < numAddresses; i++)=20
  {
 // Only add the address if the interface is running
 if (addressBuffer[i].iiFlags & IFF_UP)
 {
  if (addressBuffer[i].iiAddress.Address.sa_family =3D=3D INETSOCKET )=20
  {
    struct sockaddr_in* iaddr =3D &addressBuffer[i].iiAddress.AddressIn;
    CORBA::String_var s;
    s =3D tcpConnection::ip4ToString(iaddr->sin_addr.s_addr);
    ifaddrs.push_back(s._retn());
  }
 }
  }
  free(addressBuffer);


  if ( orbParameters::dumpConfiguration || omniORB::trace(20) ) {
    omniORB::logger log;
    omnivector<const char*>::iterator i =3D ifaddrs.begin();
    omnivector<const char*>::iterator last =3D ifaddrs.end();
    log << "My addresses are: \n";
    while ( i !=3D last ) {
      log << "omniORB: " << (const char*)(*i) << "\n";
      i++;
    }
  }
}


oh and you may need to #include <ws2tcpip.h>



------=_NextPart_000_002F_01C1DC01.2A239EA0
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META content=3D"text/html; charset=3Diso-8859-1" =
http-equiv=3DContent-Type>
<META content=3D"MSHTML 5.00.2314.1000" name=3DGENERATOR>
<STYLE></STYLE>
</HEAD>
<BODY bgColor=3D#ffffff>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>yep i came across this too..here's a fix...the =
function below=20
uses SIO_GET_INTERFACE_LIST instead of SIO_ADDRESS_LIST_QUERY in the =
ioctl call.=20
I've only tested this on NT sp6a (not w2000). &amp; i don't think it'll =
work for=20
pre sp4 versions of NT due to a tweak they made with the INTERFACE_INFO=20
struct&nbsp;to accomdate IPv6.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>so inside tcpTransportImpl.cc replace the =
win32_get_ifinfo=20
func with the one below.</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>static<BR>void win32_get_ifinfo(omnivector&lt;const=20
char*&gt;&amp; ifaddrs) {</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp; SocketHandle_t sock;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp; sock =3D =
socket(INETSOCKET,SOCK_STREAM,0);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp; DWORD lastlen =3D 0;<BR>&nbsp; DWORD len =3D =
10 *=20
sizeof(INTERFACE_INFO);<BR>&nbsp; DWORD retlen=3D0;<BR>&nbsp; <BR>&nbsp; =

INTERFACE_INFO *addressBuffer=3DNULL;</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp; while ( 1 ) <BR>&nbsp; =
{<BR>&nbsp;&nbsp;&nbsp; // There=20
is no way to know for sure the buffer is big enough to =
get<BR>&nbsp;&nbsp;&nbsp;=20
// the info for all the interfaces. We work around this by=20
calling<BR>&nbsp;&nbsp;&nbsp; // the ioctl 2 times and increases the =
buffer size=20
in the 2nd call.<BR>&nbsp;&nbsp;&nbsp; addressBuffer =3D =
(INTERFACE_INFO*)=20
malloc(len);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2><BR>&nbsp;&nbsp;&nbsp; if (=20
WSAIoctl(sock,SIO_GET_INTERFACE_LIST, NULL,0,=20
(LPVOID)addressBuffer,(DWORD)len,(LPDWORD)&amp;retlen,<BR>&nbsp;&nbsp;&nb=
sp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;=20
NULL,NULL) =3D=3D SOCKET_ERROR ) &nbsp;&nbsp;&nbsp;=20
<BR>&nbsp;{<BR>&nbsp;<BR>&nbsp;&nbsp;int err =3D =
WSAGetLastError();</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;free(addressBuffer);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp;&nbsp;if ( err !=3D WSAENOBUFS || lastlen !=3D =
0 )=20
<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;if ( omniORB::trace(2) )=20
<BR>&nbsp;&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp; omniORB::logger=20
log;<BR>&nbsp;&nbsp;&nbsp;&nbsp; log &lt;&lt; "Warning: WSAIoctl=20
SIO_ADDRESS_LIST_QUERY failed. Unable to obtain the list of all =
interface=20
addresses.\n";<BR>&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;return;<BR>&nb=
sp;&nbsp;}<BR>&nbsp;&nbsp;len=20
*=3D 2;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; else=20
<BR>&nbsp;{<BR>&nbsp;&nbsp;if ( retlen &lt;=3D len ) =
<BR>&nbsp;&nbsp;&nbsp;break;=20
// Success, len is large enough<BR>&nbsp;<BR>&nbsp;&nbsp;len =3D=20
retlen;&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; =
}<BR>&nbsp;&nbsp;&nbsp;=20
<BR>&nbsp; }<BR>&nbsp; CLOSESOCKET(sock);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2>&nbsp; int numAddresses =3D retlen /=20
sizeof(INTERFACE_INFO);<BR>&nbsp; for (int i =3D 0; i &lt; numAddresses; =
i++)=20
<BR>&nbsp; {<BR>&nbsp;// Only add the address if the interface is=20
running<BR>&nbsp;if (addressBuffer[i].iiFlags &amp;=20
IFF_UP)<BR>&nbsp;{<BR>&nbsp;&nbsp;if=20
(addressBuffer[i].iiAddress.Address.sa_family =3D=3D INETSOCKET )=20
<BR>&nbsp;&nbsp;{<BR>&nbsp;&nbsp;&nbsp; struct sockaddr_in* iaddr =3D=20
&amp;addressBuffer[i].iiAddress.AddressIn;<BR>&nbsp;&nbsp;&nbsp;=20
CORBA::String_var s;<BR>&nbsp;&nbsp;&nbsp; s =3D=20
tcpConnection::ip4ToString(iaddr-&gt;sin_addr.s_addr);<BR>&nbsp;&nbsp;&nb=
sp;=20
ifaddrs.push_back(s._retn());<BR>&nbsp;&nbsp;}<BR>&nbsp;}<BR>&nbsp; =
}<BR>&nbsp;=20
free(addressBuffer);</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2><BR>&nbsp; if ( orbParameters::dumpConfiguration ||=20
omniORB::trace(20) ) {<BR>&nbsp;&nbsp;&nbsp; omniORB::logger=20
log;<BR>&nbsp;&nbsp;&nbsp; omnivector&lt;const char*&gt;::iterator i =3D =

ifaddrs.begin();<BR>&nbsp;&nbsp;&nbsp; omnivector&lt;const =
char*&gt;::iterator=20
last =3D ifaddrs.end();<BR>&nbsp;&nbsp;&nbsp; log &lt;&lt; "My addresses =
are:=20
\n";<BR>&nbsp;&nbsp;&nbsp; while ( i !=3D last )=20
{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log &lt;&lt; "omniORB: " &lt;&lt; =
(const=20
char*)(*i) &lt;&lt; "\n";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=20
i++;<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp; }<BR>}</FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV>
<DIV><FONT size=3D2><FONT size=3D2>oh and you may need&nbsp;to #include=20
&lt;ws2tcpip.h&gt;</FONT></FONT></DIV>
<DIV>&nbsp;</DIV>
<DIV>&nbsp;</DIV></BODY></HTML>

------=_NextPart_000_002F_01C1DC01.2A239EA0--