Re: HW address w/o connection in iphlpapi

2006-01-25 Thread Michael Ost
On Wed, 2006-01-25 at 11:13 -0800, Juan Lang wrote:
> I'm not the decider here, really.  Alexandre is.  While I'd like to see my
> recent patch get in because it removes a lot of unnecessary junk from
> ifenum.c and improves the situation for most people, it's not the end of
> the story.  Wine's policy is to try to run on as many systems as possible,
> regardless of what system it was built on.  From that perspective, using
> your approach is more correct.  Assuming my patch from today gets in, feel
> free to improve on it.

Got it. I have something that works for my product (rh8 based, wine
20050419). I'll keep an eye on this when we get around to upgrading. 

I think what makes most sense is to use if_nameindex() unless it is
known not to work, using if_indextoname() only as a work around. Seems
like this could be done with a config flag, given that the only time
you'll see the problem is on a system with the old libc which means that
the wine was also built against the old libc. So a compile time flag
would do the trick. Does that sound right, or does it have to be
detected at runtime?

- mo






Re: HW address w/o connection in iphlpapi

2006-01-25 Thread Juan Lang
> The function does seem to be provided by libc. And so the diff must be
> in the implementations of that. Is there any precedent in Wine of making
> a runtime decision based on the c library?

Probably, but see below..

> Would you be OK with a patch that uses if_indextoname() only in the
> special case of glibc-2.2.93 (I believe that's the RH8 libc), but
> if_nameindex() otherwise?

I'm not the decider here, really.  Alexandre is.  While I'd like to see my
recent patch get in because it removes a lot of unnecessary junk from
ifenum.c and improves the situation for most people, it's not the end of
the story.  Wine's policy is to try to run on as many systems as possible,
regardless of what system it was built on.  From that perspective, using
your approach is more correct.  Assuming my patch from today gets in, feel
free to improve on it.

--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




Re: HW address w/o connection in iphlpapi

2006-01-25 Thread Michael Ost
On Wed, 2006-01-25 at 10:42 -0800, Juan Lang wrote:
> > > Although I don't like the idea of predefined limits :)  I'll probably
> > 
> > Me neither, which is why I used that prominent macro
> > MOST_INTERFACES_IMAGINABLE. Can you even imagine a system with 50 (or
> > 100?) ethernet interfaces? How about an application that needs more than
> > 256K (showing my age with that one... %)? 
> 
> Yes, you're right, it is changeable, but it's less the number of
> interfaces than the value of the indexes.  The interface implies that
> there will never be an interface with index 0, since if_nametoindex
> returns 0 to indicate no such interface, but what's to prevent interface
> indexes to be something other than 1, 2, 3, 4?  They don't happen to be at
> the moment, but if some enterprising kernel guy decides to randomize them
> for some cute reason, this approach won't work.

Agreed. I can't find any docs explaining what indexes are legal or their
order. I guess the reality is that it isn't specified.

The function does seem to be provided by libc. And so the diff must be
in the implementations of that. Is there any precedent in Wine of making
a runtime decision based on the c library? Would you be OK with a patch
that uses if_indextoname() only in the special case of glibc-2.2.93 (I
believe that's the RH8 libc), but if_nameindex() otherwise?

- mo





Re: HW address w/o connection in iphlpapi

2006-01-25 Thread Juan Lang
> > Although I don't like the idea of predefined limits :)  I'll probably
> 
> Me neither, which is why I used that prominent macro
> MOST_INTERFACES_IMAGINABLE. Can you even imagine a system with 50 (or
> 100?) ethernet interfaces? How about an application that needs more than
> 256K (showing my age with that one... %)? 

Yes, you're right, it is changeable, but it's less the number of
interfaces than the value of the indexes.  The interface implies that
there will never be an interface with index 0, since if_nametoindex
returns 0 to indicate no such interface, but what's to prevent interface
indexes to be something other than 1, 2, 3, 4?  They don't happen to be at
the moment, but if some enterprising kernel guy decides to randomize them
for some cute reason, this approach won't work.

> Well... that's not too thrilling since it doesn't actually fix the
> problem I found. 

Yep, that's the other side of the coin:  your approach works on all known
systems, whereas mine only works more often than the SIOCGIFCONF approach.

> Maybe we need to drill down into which systems if_nameindex works and
> doesn't work with and have alternate versions of enumerateInterfaces
> based on that. I have a FC4 system and I'll see how it behaves and let
> you know. ... mo

Yeah, maybe so.  Portability always sucks, doesn't it?
--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




Re: HW address w/o connection in iphlpapi

2006-01-25 Thread Michael Ost
On Tue, 2006-01-24 at 21:44 -0800, Juan Lang wrote:
> > Right. if_nameindex does not return eth0 if I boot up without an
> > ethernet connection. Maybe this is a system dependent thing?
> > I am running on a RH8 based system.
> 
> Or a libc thing?  I'm running on FC2.
> 
> > The if_nameindex code looked a little nicer, but a loop on
> > if_indextoname() is  not so bad.
> 
> Although I don't like the idea of predefined limits :)  I'll probably

Me neither, which is why I used that prominent macro
MOST_INTERFACES_IMAGINABLE. Can you even imagine a system with 50 (or
100?) ethernet interfaces? How about an application that needs more than
256K (showing my age with that one... %)? 

> submit a patch based on if_nameindex in the meantime, hopefully tomorrow

Well... that's not too thrilling since it doesn't actually fix the
problem I found. 

Maybe we need to drill down into which systems if_nameindex works and
doesn't work with and have alternate versions of enumerateInterfaces
based on that. I have a FC4 system and I'll see how it behaves and let
you know. ... mo





Re: HW address w/o connection in iphlpapi

2006-01-24 Thread Juan Lang
> Right. if_nameindex does not return eth0 if I boot up without an
> ethernet connection. Maybe this is a system dependent thing?
> I am running on a RH8 based system.

Or a libc thing?  I'm running on FC2.

> The if_nameindex code looked a little nicer, but a loop on
> if_indextoname() is  not so bad.

Although I don't like the idea of predefined limits :)  I'll probably
submit a patch based on if_nameindex in the meantime, hopefully tomorrow
if Alexandre commits the patch I already sent today.  It removes a lot of
the silliness of ifenum.c, so aside from not directly solving your
problem, take a look at that and perhaps patch it.

--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




Re: HW address w/o connection in iphlpapi

2006-01-24 Thread most
> Really?  It works for me.  You mean boot with no link, or what?  I did
> that, and if_nameindex still returned eth0.

Right. if_nameindex does not return eth0 if I boot up without an ethernet
connection. Maybe this is a system dependent thing? I am running on a RH8
based system.

The if_nameindex code looked a little nicer, but a loop on
if_indextoname() is  not so bad.

- mo




Re: HW address w/o connection in iphlpapi

2006-01-24 Thread Juan Lang
> Yikes! It turns out if_nameindex() doesn't return info for down devices,
> but if_indextoname() does. It's all so touchy... So, attached is an
> alternate patch using if_indextoname() that does work; my last one
> doesn't.

Really?  It works for me.  You mean boot with no link, or what?  I did
that, and if_nameindex still returned eth0.

--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




Re: HW address w/o connection in iphlpapi

2006-01-24 Thread most
>> Wait. This works better than getifaddrs. It successfully returns info
>> for "down" devices on my RH8 based linux box, with my creaky old
>> wine-20050419.
> (snip)

Yikes! It turns out if_nameindex() doesn't return info for down devices,
but if_indextoname() does. It's all so touchy... So, attached is an
alternate patch using if_indextoname() that does work; my last one
doesn't.

Just for kicks I also attached a cpp file adapted from MSDN that can do a
quick test. To build it do:

$ wineg++ -c show-eths.cpp
$ wineg++ -o show-eths.exe.so show-eths.o
$ wine ./show-eths.exe.so

You should get a listing for eth0 whether you boot with an ethernet
connection or not. Note that to witness the problem you have to actually
reboot with no ethernet connection. Just doing "ifdown eth0" isn't enough.

> Cool, thanks for that.  Like I mention in the comments, if_nameindex has
> the disadvantage that it doesn't handle virtual interfaces.  I'll try to
> hack this up to use a combination of if_nameindex and SIOCGIFCONF if I
> can, but feel free to beat me to it ;)

I'm betting you'll get there first! %) ... mo

wine-20050419-muse-ifenum.patch
Description: Binary data


show-eths.cpp
Description: Binary data



Re: HW address w/o connection in iphlpapi

2006-01-19 Thread Juan Lang
> Wait. This works better than getifaddrs. It successfully returns info
> for "down" devices on my RH8 based linux box, with my creaky old
> wine-20050419.
(snip)
> You made comments in the source about if_indextoname having issues. So
> perhaps this patch won't be useful to you. But it works for us, so I'll
> apply it to our wine sources unless/until something better comes along.

Cool, thanks for that.  Like I mention in the comments, if_nameindex has
the disadvantage that it doesn't handle virtual interfaces.  I'll try to
hack this up to use a combination of if_nameindex and SIOCGIFCONF if I
can, but feel free to beat me to it ;)

--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




Re: HW address w/o connection in iphlpapi

2006-01-18 Thread Michael Ost
> Hi Michael, 
> 
>> When you boot a linux box without an ethernet connection, and eth0 
>> configuration fails, GetAdaptersInfo does not return MAC address info
>> for eth0. 
>> The problem seems to be that enumerateInterfaces (in 
>> dlls/iphlpapi/ifenum.c) doesn't create a record for eth0, because 
>> SIOCGIFCONF doesn't return one. 
> 
> Mmm.  Yeah, I think an alternative to SIOCGIFCONF might be the thing. 

Wait. This works better than getifaddrs. It successfully returns info
for "down" devices on my RH8 based linux box, with my creaky old
wine-20050419. get_ifaddrs makes the same calls that you were, in its
implementation. So it has the same problem. But it's alot easier to
program with than the ioctl you used. 

You made comments in the source about if_indextoname having issues. So
perhaps this patch won't be useful to you. But it works for us, so I'll
apply it to our wine sources unless/until something better comes along.
Have at it! 

Cheers... mo 

--- wine-20050419/dlls/iphlpapi/ifenum.c.20050419   2006-01-16 
17:33:15.0 -0800
+++ wine-20050419/dlls/iphlpapi/ifenum.c2006-01-17 17:26:01.0 
-0800
@@ -184,40 +184,6 @@
   return map;
 }
 
-static int isLoopbackInterface(int fd, const char *name)
-{
-  int ret = 0;
-
-  if (name) {
-struct ifreq ifr;
-
-lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
-if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
-  ret = ifr.ifr_flags & IFF_LOOPBACK;
-  }
-  return ret;
-}
-
-static void countInterfaces(int fd, caddr_t buf, size_t len)
-{
-  caddr_t ifPtr = buf;
-  DWORD numNonLoopbackInterfaces = 0, numLoopbackInterfaces = 0;
-
-  while (ifPtr && ifPtr < buf + len) {
-struct ifreq *ifr = (struct ifreq *)ifPtr;
-
-if (isLoopbackInterface(fd, ifr->ifr_name))
-  numLoopbackInterfaces++;
-else
-  numNonLoopbackInterfaces++;
-ifPtr += ifreq_len(ifr);
-  }
-  gNonLoopbackInterfaceMap = sizeMap(gNonLoopbackInterfaceMap,
-   numNonLoopbackInterfaces);
-  gLoopbackInterfaceMap = sizeMap(gLoopbackInterfaceMap,
-   numLoopbackInterfaces);
-}
-
 /* Stores the name in the given map, and increments the map's numInterfaces
  * member if stored successfully.  Will store in the same slot as previously if
  * usedLastPass is set, otherwise will store in a new slot.
@@ -272,6 +238,104 @@
   }
 }
 
+#ifdef HAVE_NET_IF_H
+static int isLoopbackInterface(int fd, const char *name)
+{
+  int ret = 0;
+
+  if (name) {
+struct ifreq ifr;
+
+lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
+if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
+  ret = ifr.ifr_flags & IFF_LOOPBACK;
+  }
+  return ret;
+}
+
+static void enumerateInterfaces(void)
+{
+  int fd;
+  int nonLoopbacks;
+  int loopbacks;
+  struct if_nameindex* ifnames;
+  struct if_nameindex* ifn;
+
+  fd = socket(PF_INET, SOCK_DGRAM, 0);
+  if (fd != -1) {
+ifnames = if_nameindex();
+   if (ifnames) {
+  EnterCriticalSection(&mapCS);
+
+  nonLoopbacks = 0;
+  loopbacks = 0;
+ for (ifn = ifnames; ifn->if_name != 0; ifn = &ifn[1]) {
+   if (isLoopbackInterface(fd, ifn->if_name))
+  loopbacks++;
+else
+  nonLoopbacks++;
+   }
+
+  gNonLoopbackInterfaceMap = sizeMap(gNonLoopbackInterfaceMap,
+   nonLoopbacks);
+  gLoopbackInterfaceMap = sizeMap(gLoopbackInterfaceMap,
+   loopbacks);
+
+  markOldInterfaces(gNonLoopbackInterfaceMap);
+  markOldInterfaces(gLoopbackInterfaceMap);
+
+  /* add table entries for them them */
+ for (ifn = ifnames; ifn->if_name != 0; ifn = &ifn[1]) {
+   if (isLoopbackInterface(fd, ifn->if_name))
+  storeInterfaceInMap(gLoopbackInterfaceMap, ifn->if_name);
+else
+  storeInterfaceInMap(gNonLoopbackInterfaceMap, ifn->if_name);
+  }
+
+  LeaveCriticalSection(&mapCS);
+  if_freenameindex(ifnames);
+   }
+else 
+  perror("iphlpapi/ifenum.c::if_nameindex()");
+  }
+  else
+perror("iphlpapi/ifenum.c::socket()");
+}
+#else   // !HAVE_NET_IF_H
+static int isLoopbackInterface(int fd, const char *name)
+{
+  int ret = 0;
+
+  if (name) {
+struct ifreq ifr;
+
+lstrcpynA(ifr.ifr_name, name, IFNAMSIZ);
+if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0)
+  ret = ifr.ifr_flags & IFF_LOOPBACK;
+  }
+  return ret;
+}
+
+static void countInterfaces(int fd, caddr_t buf, size_t len)
+{
+  caddr_t ifPtr = buf;
+  DWORD numNonLoopbackInterfaces = 0, numLoopbackInterfaces = 0;
+
+  while (ifPtr && ifPtr < buf + len) {
+struct ifreq *ifr = (struct ifreq *)ifPtr;
+
+if (isLoopbackInterface(fd, ifr->ifr_name))
+  numLoopbackInterfaces++;
+else
+  numNonLoopbackInterfaces++;
+ifPtr += ifreq_len(ifr);
+  }
+  gNonLoopbackInterfaceMap = sizeMap(gNonLoopbackInterfaceMap,
+   numNonLoopbackInterfaces);
+  gLoopbackInterfaceMap = sizeMap(gLoopbackInterfaceMap,
+   numLoopbackInterfaces);
+}
+
 static void classifyInterfaces(int fd, caddr_t buf, size_t len)
 {
   caddr_t ifPtr = buf;
@@ -335,6 +399,7 @@
 close(fd)

Re: HW address w/o connection in iphlpapi

2006-01-17 Thread Juan Lang
> Dang. It doesn't work for down devices.
> When I run strace on a program
> that uses getifaddrs, the socket is opened with IPROTO_IP:
> 
> socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 14
> ioctl(14, 0x8912, 0x2084d3a8)   = 0

That's SIOCGIFCONF.  So it looks like getifaddrs isn't doing anything
different than SIOCGIFCONF, at least on Linux.

> I can't figure out what these ioctls are either...?

Take a look at 

> I'll keep digging, but if you have any clues I would love to hear them!

ifconfig -a reports down interfaces.  It may just process /proc/net/dev.

--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




Re: HW address w/o connection in iphlpapi

2006-01-17 Thread most
Juan,

>> When you boot a linux box without an ethernet connection, and eth0
>> configuration fails, GetAdaptersInfo does not return MAC address info
>> for eth0.
>> The problem seems to be that enumerateInterfaces (in
>> dlls/iphlpapi/ifenum.c) doesn't create a record for eth0, because
>> SIOCGIFCONF doesn't return one.
>
> Mmm.  Yeah, I think an alternative to SIOCGIFCONF might be the thing.
> getifaddrs is pretty nice, and it has the additional advantage that it can
> support IPv6, which SIOCGIFCONF does not.  I'm not certain whether it
> returns "down" interfaces or not, but we can hope so.  Unfortunately it's

Dang. It doesn't work for down devices. When I run strace on a program
that uses getifaddrs, the socket is opened with IPROTO_IP:

socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 14
ioctl(14, 0x8912, 0x2084d3a8)   = 0
ioctl(14, 0x8912, 0x2084d3a8)   = 0
ioctl(14, 0x8913, 0x7804ab38)   = 0
ioctl(14, 0x891b, 0x7804ab38)   = 0
ioctl(14, 0x8919, 0x7804ab38)   = 0
ioctl(14, 0x8913, 0x7804ab58)   = 0
ioctl(14, 0x891b, 0x7804ab58)   = 0
ioctl(14, 0x8919, 0x7804ab58)   = 0

Could it be that eth0 doesn't appear because it isn't configured for IP...
that is, has no IP address? I can't figure out what these ioctls are
either...?

I'll keep digging, but if you have any clues I would love to hear them! I
am shuffling in the dark here... mo

PS: I've attached a diff file that implements getifaddrs for our Wine,
20050419. I didn't do the "configure" step, but put HAVE_IFADDRS_H in.
Your code is left in if HAVE_IFADDRS_H is not defined. If you want, take
it, check it out and adapt it to the current wine.


ifenum.patch
Description: Binary data



Re: HW address w/o connection in iphlpapi

2006-01-16 Thread Juan Lang
Hi Michael,

> When you boot a linux box without an ethernet connection, and eth0
> configuration fails, GetAdaptersInfo does not return MAC address info
> for eth0.
> The problem seems to be that enumerateInterfaces (in
> dlls/iphlpapi/ifenum.c) doesn't create a record for eth0, because
> SIOCGIFCONF doesn't return one.

Mmm.  Yeah, I think an alternative to SIOCGIFCONF might be the thing. 
getifaddrs is pretty nice, and it has the additional advantage that it can
support IPv6, which SIOCGIFCONF does not.  I'm not certain whether it
returns "down" interfaces or not, but we can hope so.  Unfortunately it's
not universally available; when I wrote this code at least, it wasn't
around on Debian, though that's since changed.  So a configure check and
an ifdef would probably be in order.

> Near as I can tell (and I am no networking guru by any stretch)
> GetAdaptersInfo is supposed to return MAC info for eth0, even if eth0
> has no IP address.

You're correct, this is a Wine bug.

> PS: I cc'd Juan Lang who is noted as the author of the code. I hope that
> isn't bad etiquette...?

I prefer it in fact.
--Juan

__
Do You Yahoo!?
Tired of spam?  Yahoo! Mail has the best spam protection around 
http://mail.yahoo.com 




HW address w/o connection in iphlpapi

2006-01-16 Thread most
We ran into an obscure problem with iphlpapi that I'd like to get help
with. When you boot a linux box without an ethernet connection, and eth0
configuration fails, GetAdaptersInfo does not return MAC address info for
eth0.

The problem seems to be that enumerateInterfaces (in
dlls/iphlpapi/ifenum.c) doesn't create a record for eth0, because
SIOCGIFCONF doesn't return one. Then when GetAdaptersInfo (in
dlls/iphlpapi/iphlpapi_main.c) is looping through the interfaces, eth0
isn't there so it doesn't call getInterfacePhysicalByIndex to get the MAC
address.

I verified that if I hack an eth0 entry into the table built by
enumerateInterfaces, the call to getInterfacePhysicalByIndex works just
fine. So the problem is simply a disconnect between what
enumerateInterfaces is scanning and what GetAdaptersInfo is trying to
scan.

Near as I can tell (and I am no networking guru by any stretch)
GetAdaptersInfo is supposed to return MAC info for eth0, even if eth0 has
no IP address. Near as I can tell too Windows does return MAC info in this
situation. So this looks, again near as I can tell %), like a Wine bug.

Is it a wine bug? Any suggestions for a fix? ... mo

PS: I cc'd Juan Lang who is noted as the author of the code. I hope that
isn't bad etiquette...?