Note that there are some explanatory texts on larger screens.

plurals
  1. POSending a raw tcp packet with syn flag set just goes through the lo interface, not eth0 as I want
    primarykey
    data
    text
    <p>I would like to send a syn packet to my httpd server and get a responding syn-ack packet. But when I monitor with Wireshark, the packet is beeing sent by my local interface, <code>lo</code> and not <code>eth0</code>. </p> <p>I have tried to set some different values in <code>setsockopt</code> as you can see in the code below, but none seems to work, it is always using the <code>lo</code> interface and not <code>eth0</code>. I don't know if it something wrong in the tcp packet that makes it go through local interface, or if it is something else. </p> <pre><code>#include &lt;cstdlib&gt; #include &lt;stdio.h&gt; #include &lt;unistd.h&gt; #include &lt;sys/socket.h&gt; #include &lt;netinet/ip.h&gt; #include &lt;netinet/tcp.h&gt; #include &lt;arpa/inet.h&gt; #include &lt;linux/if_packet.h&gt; #include &lt;linux/if_ether.h&gt; #define PCKT_LEN 8192 unsigned short csum(unsigned short *buf, int len) { unsigned long sum; for(sum=0; len&gt;0; len--) sum += *buf++; sum = (sum &gt;&gt; 16) + (sum &amp;0xffff); sum += (sum &gt;&gt; 16); return (unsigned short)(~sum); } int main(int argc, char** argv) { char *buffer = new char[PCKT_LEN](); class iphdr *ip = (struct iphdr *) buffer; class tcphdr *tcp = (struct tcphdr *) (buffer + sizeof(struct iphdr)); class sockaddr_in sin; int sd = socket(PF_INET, SOCK_RAW, IPPROTO_TCP); if(sd &lt; 0) { perror("socket() error"); exit(-1); } else { printf("socket()-SOCK_RAW and tcp protocol is OK.\n"); } sin.sin_family = AF_INET; // Address family sin.sin_port = htons(atoi("2345")); // Source port inet_pton(AF_INET, "192.168.1.11", &amp;(sin.sin_addr.s_addr)); // Dest IP - ERROR WAS WRONG IP ip-&gt;ihl = 5; ip-&gt;version = 4; ip-&gt;tos = 16; ip-&gt;tot_len = sizeof(class iphdr) + sizeof(class tcphdr); ip-&gt;id = htons(54321); ip-&gt;frag_off = 0; ip-&gt;ttl = 32; ip-&gt;protocol = 6; // TCP ip-&gt;check = 0; // Done by kernel inet_pton(AF_INET, "192.168.1.10", &amp;(ip-&gt;saddr)); // Source IP inet_pton(AF_INET, "192.168.1.11", &amp;(ip-&gt;daddr)); // Destination IP // The TCP structure tcp-&gt;source = htons(atoi("2345")); tcp-&gt;dest = htons(atoi("80")); // Destination port tcp-&gt;seq = htonl(1); tcp-&gt;ack_seq = random(); tcp-&gt;doff = 5; tcp-&gt;syn = 1; tcp-&gt;ack = 0; tcp-&gt;window = htons(32767); tcp-&gt;check = 0; // Done by kernel tcp-&gt;rst = 0; tcp-&gt;urg_ptr = 0; ip-&gt;check = csum((unsigned short *) buffer, (sizeof(class iphdr) + sizeof(class tcphdr))); // Bind socket to interface int iface = 1; const int *val = &amp;iface; char *opt = "eth0"; if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, val, sizeof(iface)) &lt; 0) { //if(setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, opt, 4) &lt; 0) { perror("setsockopt() error"); exit(-1); } else printf("setsockopt() is OK\n"); if(sendto(sd, buffer, ip-&gt;tot_len, 0, (sockaddr*)&amp;sin, sizeof(class sockaddr_in)) &lt; 0) { perror("sendto() error"); exit(-1); } else printf("Send OK!"); close(sd); return 0; } </code></pre> <p>My interfaces: </p> <pre><code># ip a 1: lo: &lt;LOOPBACK,UP,LOWER_UP&gt; mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: &lt;BROADCAST,MULTICAST,UP,LOWER_UP&gt; mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000 link/ether 00:0c:29:6e:82:29 brd ff:ff:ff:ff:ff:ff inet 192.168.1.10/24 brd 192.168.1.255 scope global eth0 inet6 fe80::20c:29ff:fe6e:8229/64 scope link valid_lft forever preferred_lft forever </code></pre> <p><strong>EDIT</strong></p> <pre><code>... #include &lt;sys/ioctl.h&gt; #include &lt;net/if.h&gt; ... struct ifreq ifr; memset(&amp;ifr, 0, sizeof(ifr)); snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0"); if(ioctl(sd, SIOCGIFINDEX, &amp;ifr) &lt; 0) { perror("ioctl failed!"); return EXIT_FAILURE; } if(setsockopt(sd, IPPROTO_IP, IP_HDRINCL, &amp;ifr, sizeof(ifr)) &lt; 0) { perror("setsockopt() error"); exit(-1); } printf("setsockopt() is OK\n"); </code></pre> <p>But it still goes through <code>lo</code> interface. Is it something with the bridged networking interface in my virtual machine?</p> <p><strong>EDIT 2</strong></p> <p>I have now compared my raw ip packets with the ones that hping2 sends and the only thing that differs is the interface id (specified in the frame) and that the ethernet layer does not contain any MAC address information. hping2 sends through the <code>eth0</code> interface and contains all MAC address information. My program does send it through <code>lo</code> and does NOT contain any MAC information (<strong>maybe it is sent through <code>lo</code> interface because it does not contain any MAC address information in the packet???</strong>). Look at this picture: <img src="https://i.stack.imgur.com/QB1jL.png" alt="Ethernet frame does not contain MAC address information"></p> <p>I have also compared the source code of hping2 with my code in how to construct a raw IP packet and I cannot see anything that would make the packets go through the <code>lo</code> interface as in my case. And I have not clue at all why the heck my program won't include any MAC addresses in my packets. Everything else in my packet is equal to the contents in the hping2 packets, except sequence number which is randomized. </p> <p>Any other ideas?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload