Consider a Ping Request packet arriving on a computer with 2 NICs (multi-homed
PC). The packet is received on 1 of the interfaces. Now the computer has to send
the Ping Response packet. To fill the source IP and source MAC address the
computer does which of the following? - Computer first determines which
interface should be used as the egress interface by looking at the Destination
IP address. Destination IP address was taken from source IP address field of
Ping Request packet. Once it determines egress port, it will enter that
interface’s IP and MAC address in the Ping Response packet. - Computer takes the
destination IP and MAC address of the Ping Request packet and just flips them
over to fill source IP and MAC address in Ping Response packet.
I added more comments on the original post which describes the situation a bit more.
Don’t know what’s a good way to get the comments linked to this post.
Do take a look if you are interested.
Have a look here at the ICMP source code in the Linux kernel at line 400. That is the ICMP reply code.
At lines 433/434 you can see the collection of the source and destination MAC addresses from the incoming packet. The source is just lifted directly from the packet, the destination is done with a helper function that presumably looks at which interface it arrived on and returns the MAC address of that interface.
Lines 441 onwards construct the reply packet and push it to the generic ICMP transmit function (which is a bit higher up in the source code), which then pushes it on to the network stack.
Hope that gives you an idea of how it works internally! It’s really only a slightly more detailed version of the actual standard, there are a few checks to make sure that we are not exceeding network rate limits in the stack and etc, but it’s a quite simple bit of code.
Added edit: it’s “simple” at this point because a lot of the work has already been done. The packet has arrived via the network stack, it has been determined to be an ICMP packet, and it was sent here to this function. There are already functions that send packets out via the network stack, so this chunk of code just builds an appropriate packet and hands it on to be sent.
Woah! Thanks for taking the time to write the detailed response. Will take a look at the source code. Really appreciate the effort ❤️