First, let me describe the problem briefly. I have two programs which send IP packets from a host( to another host( These two programs are written respectively with C and C++ but have the same functionalities.

If I run the C program, when a raw socket is going to send IP packets (the program makes the IP packet without MAC/Ethernet header) with destination IP of, from tcpdump-captured packets, I notice the host broadcast an ARP query for the MAC of, and so it can successfully deliver the packets to that host.

If I run the C++ program, it doesn't broadcast ARP to query for the MAC of and it add a wrong MAC header to the IP packets and thus develiver it to the wrong host(which is also communicating with the host in both C program and C++ program scenarios )

I'm really puzzled by the fact that ARP broadcast happens in the first scenario but not in the second scenario, are there any potential reasons for such difference? why doesn't the system do ARP request broadcasting in the second scenario, thus leading to wrong delivery?

Long story:

I have three laptops in a WLAN, A and C uses wlan0, but B is connected to the wireless router via cable, and it uses eth0.

I wrote a C program to do a TCP hijacking experiment, and then modified it to C++ program.

  1. A establishes a TCP connection with B
  2. C runs the program and masquerades as B, so it sends out packets with src_ip = IP(B) and dst_ip = IP(A)
  3. I use tcpdump to capture packets on A, B, and C
  4. It is expected that tcpdump on A can capture the IP spoofing packets. With the original C program, this is the case. But when I run the C++ program, it is strange that tcpdump on B captures the packets but tcpdump on A can't.

After some investigation, I noticed it is due to the MAC address. When the C++ program ran, the kernel/system adds the MAC address of B as destination MAC to the IP-spoofing packets (it is expected that the kernel adds the MAC address of A because the destination IP address is of A). However, I wrote packets on IP level and I used a raw socket as below in both C program and C++ program:

send_sd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW));
sendto(send_sd, packet, ip_len, 0, (struct sockaddr*)&client_addr, addr_len);

It is strange that when I ran these two programs, the kernel/system added different destination MAC addresses. What are the potential causes?

  • 1
    (1) I trust you are rebooting between experiments (to clear cached information).  (2) What OS(s) are you using?  (3) Have you tried running the programs under strace (or comparable tool)? – G-Man Nov 19 '15 at 0:51
  • 2
    how are you checking what is going on with arp? windows has a command arp -a. Wireshark might be clearer than tcpdump. Given that you say your program in the c++ case has the wrong mac for the ip, Check whether the arp table has the right/wrong mac for that ip. if wrong one then go to wireshark and fins the arp info that put it there. The arp table doesnt fill without arp req / response / broadcasts. – barlop Nov 19 '15 at 1:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.