views:

615

answers:

3

I'm writing an application that injects packets using SharpPcap (http://sourceforge.net/projects/sharppcap/).

However, since I'm constructing the packets on my own and only know the destination's IP address, I have to determine the physical address of the next hop. I can always send a ping to the remote ip address, sniff it, and get the mac address from the sniffed packet. However, I was hoping there's a less convoluted way to do so in c#.

Obviously, getting the next hop's ip address will also be very helpful, as I can then use SendArp to determine it's mac address.

edit: Getting the routing table will do. How would I obtain that using code?

Thanks,

r

A: 

Physical addresses are resolved by the Address Resolution Protocol - just send an ARP Reuest with the IP address to resolve.

If the destination is not in the local network, the packet must be send to the standard gateway and one must perform an ARP Request for the standard gateway. The standard gateway can be obtained by using methods from the System.Net.NetworkInformation namespace.

 NetworkInterface.GetAllNetworkInterfaces()[0].GetIPProperties().GatewayAddresses
Daniel Brückner
That's true if the target machine is on my lan. How would you determine the first gateway (and its mac address) in the route to a remote machine (in code, not using traceroute)
r0u1i
Just obtain the default gateway of the machine. Methods for this can be found in the System.Net.NetworkInformation namespace.
Daniel Brückner
And what would happen if there is some set of networks addresses that are routed through some other gateway, other than the default gateway?is there a way to access the routing table, and query it?
r0u1i
A: 

The completely hackish way of doing it would be to run the command "arp -a" and read and parse the results of the command (using the arp cache already held by windows).

Otherwise, you need to include ARP in you're protocol stack. This is how you're system itself works to figure out where to send frames. Or lastly if you're not worried about being inefficient, you can set you're ethernet destination as: FF:FF:FF:FF:FF:FF and flood everyone on the same LAN as you. When something responds or you get a packet, cache it yourself to have the proper destination mac.

Personally, if you did the flood everyone approach on my network, I'd hurt you, but depending on you're situation it mgiht be a fairly easy hack. However, doing a 100% full stack implementation is fairly complex, since there are alot of edge cases that should be well supported (such as handling proxy arp, gratuitous arp, etc.).

Kevin Nisbet
Let's assume I call "arp -a". How do I determine the ip address of the next gateway in the route to say, 74.125.43.104 (google.com)?
r0u1i
I see you got yourself a solution that works, but you'd also need to look at the routing table for whichever interface you bound to and figure out what you're default gateway is.
Kevin Nisbet
I think that default gateways are automatically added as a routing entries with destination 0.0.0.0 and mask 0.0.0.0, so I should go over them when I scan the routing table
r0u1i
+1  A: 

I had some troubles with WMI (it seems that one cannot correlate between an interface-index in Win32_IP4RouteTable with an actual device; MSDN documentation is wrong, and other more hackish techniques fail on some computers).

So, I chose to use the unmanaged GetBestRoute, which actually saved me a lot of time, because it lets Windows do the routing decision on itself, and returns the next hop's IP address and the NIC identifier leading to that address. It's also quite a lot faster than running a query against WMI.

You can then find the NIC itself, by looking for that identifier in the list returned by GetAdaptersInfo.

Hope it helps ...

r0u1i