3

I found recently that if I have a dial-up connection (this is for a kiosk) and a local area network connection, when the dial-up connection is established (with internet access), my multicast sendto would default to the dial-up rather than my LAN NIC. This made the multicast go out to the dial-up connection instead rather than to my LAN which has several multicast subscribers.

I understand that I need to use IP_MULTICAST_IF to set the interface on my multicast socket. Question is how do I enumerate the interfaces and how do I use IP_MULTICAST_IF in setsockopt? On the kiosk Windows XP Embedded, there's always going to be just one local area connection NIC. How do I get this interface and pass its IP address (is this what IP_MULTICAST_IF is expecting??) to setsockopt?

Zach Saw
  • 4,308
  • 3
  • 33
  • 49

2 Answers2

4

Apparently setsockopt and IP_MULTICAST_IF don't work if wsock32.dll is used instead of ws2_32.dll. I thought I was doing it wrong when I kept getting 1.0.0.0 as the IP address even when it was something else that I've set with setsockopt. Funny thing is, before the call to IP_MULTICAST_IF, it would return 0.0.0.0, so setsockopt` did change something, just not correctly.

Someone else who had this same problem way back in 2004 - http://us.generation-nt.com/ip-multicast-problem-help-37595922.html. When we #include "winsock2.h" we need to use ws2_32.dll. However, with C++ Builder, it's impossible to use ws2_32.dll when we use winsock2.h - the RTL implicitly links in wsock32.dll and you can't link ws2_32.dll even if you explicitly specify #pragma comment(lib, "ws2_32.lib"). Embarcadero really need to fix this! Someone in the RTL team must've decided it's clever to implicitly include wsock32.dll. The only 'clever' thing it did was users didn't have to include one line in their code - #pragma comment(lib, "wsock32.lib"). While they're at that, they might as well include every single DLL files known to mankind.

Zach Saw
  • 4,308
  • 3
  • 33
  • 49
0

Use GetAdaptersAddresses() to enumerate all available interface IP addresses.

IP_MULTICAST_IF is for IPv4 addresses only. It expects you to pass a DWORD value containing the desired IPv4 address (in network byte order) to setsockopt(), eg:

DWORD dwIP = ...;
setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&dwIP, sizeof(dwIP));
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • I know how to enumerate IP addresses but my question was how do I get the local area connection NIC IP? – Zach Saw Oct 07 '11 at 09:58
  • GetAdaptersAddresses() tells you what type of interface each address belongs to. You can differentiate between dialup and LAN connections with that. – Remy Lebeau Oct 07 '11 at 15:20
  • `setsockopt IP_MULTICAST_IF` doesn't work with C++ Builder. It links to wsock32.dll instead (we need ws2_32.dll to make it work). – Zach Saw Oct 07 '11 at 23:23
  • That would work but I shouldn't have to. Anyway I found what the problem was -- import32.lib brings in wsock32.dll implicitly so we're all forced to use it even when we choose to use ws2_32.dll. The RTL team really need to fix this. I've recompiled the RTL to make it work. – Zach Saw Oct 08 '11 at 10:45