views:

1516

answers:

6

The system I'm currently working on consists of a controller PC running XP with .Net 2 connected to a set of embedded systems. All these components communicate with each other over an ethernet network. I'm currently using TcpClient.Connect on the XP computer to open a connection to the embedded systems to send TCP/IP messages.

I now have to connect the XP computer to an external network to send processing data to, so there are now two network cards on the XP computer. However, the messages sent to the external network mustn't appear on the network connecting the embedded systems together (don't want to consume the bandwidth) and the messages to the embedded systems mustn't appear on the external network.

So, the assertion I'm making is that messages sent to a defined IP address are sent out on both network cards when using the TcpClient.Connect method.

How do I specify which physical network card messages are sent via, ideally using the .Net networking API. If no such method exists in .Net, then I can always P/Invoke the Win32 API.

Skizz

+1  A: 

Basically, once the TcpClient.Connect method has been successful, it will have created a mapping between the physical MAC address of the embedded system and the route it should take to that address (i.e. which network card to use).

I don't believe that all messages then sent over the TcpClient connection will be sent out via both network cards.

Do you have any data to suggest otherwise, or are you mealy guessing?

samjudson
A: 

Won't that depend on the IP address you want to reach?, or are they in the same subnet?

Sven
+1  A: 

Xp maintains a routing table where it maps ranges of ip-adresses to networks and gateways.

you can view the table using "route print", with "route add" you can add a route to your embedded device.

Mendelt
+2  A: 

Try using a Socket for your client instead of the TcpClient Class.

Then you can use Socket.Bind to target your local network adapter

    int port = 1234;

    IPHostEntry entry = Dns.GetHostEntry(Dns.GetHostName());

    //find ip address for your adapter here
    IPAddress localAddress = entry.AddressList.FirstOrDefault();

    IPEndPoint localEndPoint = new IPEndPoint(localAddress, port);

    //use socket instead of a TcpClient
    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    //binds client to the local end point
    client.Bind(localEndPoint);

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.bind.aspx

Hath
A: 

@samjudson: I don't really know much about the inner workings of networking, so I was just guessing. The machine in question is located a few miles down the road and I hope to be able to get a time slot on it to plug a sniffer into the 'external network' adapter (i.e. the one the embedded system is not connected to) and see what comes out. Nothing beats hard data.

@sven: the IP address of the external network (not the embedded network) is totally out of my control. The policies on that network are up to the sysadmins of the sites where the machine will be used (it could be static address, dhcp, same subnet, different subnet, carrier pidgeon, etc).

@Mendelt Siebenga: I tired the 'route print' command on a laptop with wireless and wired adapters and all the destinations were listed twice, once for each adapter. Usefull tool though.

@Hath: I'll look into that. It certainly looks promising. The connection to the embedded network is fixed so, by a process of elimination, it should be possible to find the other adapter's IP address.

Skizz

Skizz
+1  A: 

If you have two network cards on the machine, then there shouldn't be a problem. Normal IP behaviour should ensure that traffic for your 'private' network (embedded systems in this case) is separate from your public network, without you having to do anything in your code. All that is required is for the two networks to be on different IP subnets, and for your 'public' NIC to be the default.

Assuming your two NICs are configured as follows:

NIC A (Public): 192.168.1.10 mask 255.255.255.0
NIC B (Private): 192.168.5.10 mask 255.255.255.0

The only configuration you need to verify is that NIC A is your default. When you try to send packets to any address in your private network (192.168.50.0 - 192.168.50.255), your IP stack will look in the routing table and see a directly connected network, and forward traffic via the private NIC. Any traffic to the (directly connected) public network will be sent to NIC A, as will traffic to any address for which you do not have a more specific route in your routing table.

Your routing table (netstat -rn) should look something like this:

IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0      192.168.1.1     192.168.1.10    266 <<--
        127.0.0.0        255.0.0.0         On-link         127.0.0.1    306
        127.0.0.1  255.255.255.255         On-link         127.0.0.1    306
  127.255.255.255  255.255.255.255         On-link         127.0.0.1    306
      169.254.0.0      255.255.0.0         On-link      192.168.1.10    286
  169.254.255.255  255.255.255.255         On-link      192.168.1.10    266
      192.168.1.0    255.255.255.0         On-link      192.168.1.10    266
     192.168.1.10  255.255.255.255         On-link      192.168.1.10    266
    192.168.1.255  255.255.255.255         On-link      192.168.1.10    266
      192.168.5.0    255.255.255.0         On-link      192.168.5.10    266
     192.168.5.10  255.255.255.255         On-link      192.168.5.10    266
    192.168.5.255  255.255.255.255         On-link      192.168.5.10    266
   255.255.255.255  255.255.255.255        On-link      192.168.1.10    276
   255.255.255.255  255.255.255.255        On-link      192.168.5.10    276
===========================================================================

There will also be some multicast routes (starting with 224) which have been omitted for brevity. The '<<--' indicates the default route, which should be using the public interface.

Murali Suriar