1
votes

For various reasons, I'm trying to construct and send raw TCP packets to a remote host (ex. google.com) with raw sockets. I'm trying to use pcap, so the raw socket code can be ported to Windows at some point.

Looks pretty straightforward... 1. ethernet header 2. ip header 3. tcp header 4. segment (optional)

2,3,4 are straightforward. #1 is the rub because I don't know what to use for the destination MAC address of google.com. From what I can tell, ARP is useless for telling me that MAC because I have to be connected to google's router for it to work. Snag.

So that makes me ask this question:

Should I use the MAC of MY router as the destination MAC address in the ethernet header when sending to a host not in LAN? And when the packet is forwarded, does every router it hits tear out that Ethernet header and replace it with the appropriate source/destination MACs so it gets to Google.com? That is the only thing that sounds reasonable.

Side note, I think this was the motivation here, but the question never quite made it: how to determinate destination MAC address

2

2 Answers

3
votes

That's right. The source MAC address in the ethernet header should be the MAC address of the interface you're sending from, and the destination MAC address should be your router's MAC on its interface that is connected to your LAN.

It's important to remember that Link-Layer addresses are used within networks (in this case, both your MAC address and your router's internal interface are on your LAN), while Network Layer (IPv4/IPv6) addressing is used to route your packet from the source host to the destination host (this is ignoring NAT and a whole bunch of other grossness that arises in IPv4).

What will happen when you send your Ethernet frame out of your interface is the following:

  1. Your router will end up with the frame after it travels through 0 or more switches, which know where your router's internal MAC address is from receiving traffic from it in the past. Your router knows the frame is for it because its internal MAC address is the destination MAC.
  2. Your router will strip off the Ethernet header. Then, it will inspect the destination IP address, and determine how to forward that packet based on that address. If we're talking about your home router, it is probably also changing the source IP address (something called Network Address Translation, or NAT), but since it isn't in the scope of your question I'll leave that alone.
  3. Before it forwards the packet to the next router on the path toward the destination IP address, the router needs to put another Link-Layer header back on the IP datagram because it stripped off the one you had put on it. So, it will create a new Link-Layer header using its outgoing interface's MAC address as the source MAC, and the MAC address of the next router's internal MAC address as the destination. In this way, the Link-Layer header is re-written "hop-by-hop".
2
votes

Somedays before even I faced the same confusion. So long story short yes the destination MAC address will be the gateway router MAC address. And about how I determined is - like this -

  1. I used the command

    route -n
    
  2. Then I used the command

    arp -n
    

The output is as you can see -

goutbose@####:~$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.39.51.1      0.0.0.0         UG    0      0        0 enp2s0f0 
goutbose@###:~$ arp -n
Address                  HWtype  HWaddress           Flags Mask            Iface
10.39.51.130             ether   00:1a:c5:01:12:94   C                     enp2s0f0

Now you can hardcode your destination MAC in your packets as I did as an easy hack or if you want you can design your own ARP resolution which is way out of my knowledge scope to help you out. My implementation to implement my own ICMP ping request using raw sockets is as follows -

https://github.com/Goutam1511/Socket-Programming-with-C/blob/master/myping.c

Although a late reply I hope it may help somebody else out because there are very little resources related to using raw socket in the link layer.