title: creating Ethernet frame in SOCK_RAW communication
body: <p>I did a simple <strong>ping</strong> program , in that i created a <strong>buffer</strong> and in that only i filled the <strong><code>IP frame</code></strong> and <strong><code>icmp stucture</code></strong> and when i run the program it's working correctly .</p>
  
  <p>I have looked the execution in <strong>Wireshark</strong> and the ethernet frame has been included correctly in the <strong>echo request</strong> with correct target <strong>MAC address</strong> (the MAC would probably found in arp cache), but ethernet frame has been created automatically even if I did not fill that in the buffer which I used in the <code>sock_raw</code> socket communication.</p>
  
  <p>Another problem is my friend tried the same code , but when he checked in the <strong>Wireshark</strong> in the <strong>ethernet header</strong> the MAC address was <strong>00.00.00.00.00.00</strong> ,which means it will send to every device and the according device with the correct IP will reply , but its is not the case for me </p>
  
  <p>and the code is here</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;netdb.h&gt;
  #include &lt;netinet/in.h&gt;
  #include &lt;netinet/in_systm.h&gt;
  #include &lt;netinet/ip.h&gt;
  #include &lt;netinet/ip_icmp.h&gt;
  #include &lt;string.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;sys/socket.h&gt;
  
  
  #define BUFFER_SIZE 100
  #define DEFAULT_NUM_PACKETS 10
  
  char buf[BUFFER_SIZE]; 
  char *message = "\n ./output_file &lt;sender_ip_addr&gt; &lt;dest_ip_addr&gt; &lt;no_of_reqs&gt;\n \
          &lt;no_of_req&gt; = is the number of requests to send and 10 is the default and mentioning 0  is infinite\n";
  
  void set_ip_layer_fields(struct icmphdr *icmp, struct ip *ip)
  {
      // IP layer
      ip-&gt;ip_v = 4;
      ip-&gt;ip_hl = sizeof*ip &gt;&gt; 2;
      ip-&gt;ip_tos = 0;
      ip-&gt;ip_len = htons(sizeof(buf));
      ip-&gt;ip_id = 0;
      ip-&gt;ip_off = 0;
      ip-&gt;ip_ttl = 255;
      ip-&gt;ip_p = 1;
      ip-&gt;ip_sum = 0; 
  
      // ICMP Layer
      icmp-&gt;type = 8;
      icmp-&gt;code = 0;     
      icmp-&gt;checksum = htons(~(ICMP_ECHO &lt;&lt; 8));  
  }
  
  int main(int argc, char *argv[])
  {
      int s, i ;  
      struct ip *ip = (struct ip *)buf;
      struct icmphdr *icmp = (struct icmphdr *)(ip + 1);
      struct hostent *hp, *hp2;
      struct sockaddr_in dst;                               
      int num = DEFAULT_NUM_PACKETS;
  
      if(argc &lt; 3)
      {
          fprintf(stdout, "%s\n",message);
          exit(1);
      }
  
      // If enough arguments supplied 
      if(argc == 4)
          num = atoi(argv[3]);
  
      // Loop based on the no of requests
      for(i = 1; num == 0 ? num == 0 : i &lt;= num; i++)
      {
          memset(buf, 0, sizeof(buf));
  
          if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) &lt; 0)
          {
              perror("socket() error");
              exit(1);
          }
  
          if((hp = gethostbyname(argv[2])) == NULL)
          {
              if((ip-&gt;ip_dst.s_addr = inet_addr(argv[2])) == -1)
              {
                  fprintf(stderr, "%s: unknown host.\n", argv[2]);
                  exit(1);
              }
          }
  
          else
              memcpy(&amp;ip-&gt;ip_dst.s_addr, hp-&gt;h_addr_list[0], hp-&gt;h_length);
  
          if((hp2 = gethostbyname(argv[1])) == NULL)
          {
              if((ip-&gt;ip_src.s_addr = inet_addr(argv[1])) == -1)
              {
                  fprintf(stderr, "%s: unknown host\n", argv[1]);
                  exit(1);
              }
          }
          else
              memcpy(&amp;ip-&gt;ip_src.s_addr, hp2-&gt;h_addr_list[0], hp-&gt;h_length);
  
          set_ip_layer_fields(icmp, ip);
  
          dst.sin_addr = ip-&gt;ip_dst;
          dst.sin_family = AF_INET;
  
          if(sendto(s, buf, sizeof(buf), 0, (struct sockaddr *)&amp;dst, sizeof(dst)) &lt; 0)
          {
              fprintf(stderr, "error while sending\n");
          }
          else
              printf("request:%d sended successfully\n",i);
  
          close(s);
  
      }
      return 0;
  }
  </code></pre>