title: Add arp entry Linux
body: <p><strong>Read the question carefully in order to propose a solution, please</strong></p>
  
  <p>I need to add <strong>permanent</strong> arp entry in Linux somehow. </p>
  
  <p>The problem is: if I add an entry via shell, or via sockets, it always gets <strong>flag 0x6</strong>. Even if I use the code posted downhere, where I specify the flag, it remains the same, 0x6. </p>
  
  <p>I found this information about 0x6 flag: </p>
  
  <blockquote>
    <p>Notice the ARP flag of "0x6".  The ASIC ARP entry with flag 0x6 is
    MAC-cache related entry.   It is caused by arp lookup failure when
    installing the session.   The session will try to use the source MAC
    address of incoming packet, but it is not necessary for using this mac
    address.  We can get the MAC address when the reply packet arrives by
    sending an ARP packet to the source host.</p>
  </blockquote>
  
  <p>So anytime I add any arp entry, then I ping the same ip address, it always results in <strong>ARP request broadcast</strong>. </p>
  
  <p>The question is, <strong>is there a way how to add a permanent ARP entry with proper flag? So I add an entry, and in case of any comunication afterwards, there wont be any ARP broadcast?</strong></p>
  
  <p>Btw, to get into what I am up to: I am sending a broadcast(L3) from PC1 containing PC1's IP and MAC, PC2 gets the packet and add addresses them into ARP table and establish TCP session, but always first run ARP broadcast.</p>
  
  <p>via shell:</p>
  
  <pre><code>#!/bin/sh
  arp -s $1 $2 2&gt;/dev/null
  </code></pre>
  
  <p>via sockets:</p>
  
  <pre><code>char *mac_ntoa(unsigned char *ptr){
      static char address[30];
  
      sprintf(address, "%02X:%02X:%02X:%02X:%02X:%02X",
          ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
  
      return(address);
  } /* End of mac_ntoa */
  
  int mac_aton(char *addr, unsigned char *ptr){
      int i, v[6];
      if((i = sscanf(addr, "%x:%x:%x:%x:%x:%x", &amp;v[0], &amp;v[1], &amp;v[2], &amp;v[3],
              &amp;v[4], &amp;v[5])) !=6){
  
          fprintf(stderr, "arp: invalid Ethernet address '%s'\n", addr);
          return(1);
      } /* End of If*/
  
      for(i = 0; i &lt; 6; i++){
          ptr[i] = v[i];
      } /* End of For */
  
      return(0);
  }
  
  int main(int argc, char* argv[]){
      if(argc &lt; 3 || argc &gt; 4){
          fprintf(stderr,"usage: %s &lt;ip_addr&gt; &lt;hw_addr&gt; [temp|pub|perm|trail]\n",
              argv[0]);
          fprintf(stderr, "default: temp.\n");
          exit(-1);
      } /* End of If */
  
      int s, flags;
      char *host = argv[1];
  
      struct arpreq req;
      struct hostent *hp;
      struct sockaddr_in *sin;
  
      bzero((caddr_t)&amp;req, sizeof(req)); /* caddr_t is not really needed. */
  
      sin = (struct sockaddr_in *)&amp;req.arp_pa;
      sin-&gt;sin_family = AF_INET;
      sin-&gt;sin_addr.s_addr = inet_addr(host);
  
      if(sin-&gt;sin_addr.s_addr ==-1){
          if(!(hp = gethostbyname(host))){
              fprintf(stderr, "arp: %s ", host);
              herror((char *)NULL);
              return(-1);
          } /* End of If */
          bcopy((char *)hp-&gt;h_addr,
              (char *)&amp;sin-&gt;sin_addr, sizeof(sin-&gt;sin_addr));
      } /* End of If */
  
      if(mac_aton(argv[2], req.arp_ha.sa_data)){ /* If address is valid... */
          return(-1);
      }
  
      argc -=2;
      argv +=2;
  
      flags = ATF_PERM | ATF_COM;
  
      while(argc-- &gt; 0){
          if(!(strncmp(argv[0], "temp", 4))){
              flags &amp;= ~ATF_PERM;
          } else if(!(strncmp(argv[0], "pub", 3))){
              flags |= ATF_PUBL;
          } else if(!(strncmp(argv[0], "trail", 5))){
              flags |= ATF_USETRAILERS;
          } else if(!(strncmp(argv[0], "dontpub", 7))){ /* Not working yet */
              flags |= ATF_DONTPUB;
          } else if(!(strncmp(argv[0], "perm", 4))){
              flags = ATF_PERM;
          } else {
              flags &amp;= ~ATF_PERM;
          } /* End of Else*/
      argv++;
      }/* End of While */
  
      req.arp_flags = flags; /* Finally, asign the flags to the structure */
      strcpy(req.arp_dev, "eth0"); /* Asign the device.  */
  
      if((s = socket(AF_INET, SOCK_DGRAM, 0)) &lt; 0){
          perror("socket() failed.");
          exit(-1);
      } /* End of If */
  
      if(ioctl(s, SIOCSARP, (caddr_t)&amp;req) &lt;0){ /* caddr_t not really needed. */
          perror(host);
          exit(-1);
      } /* End of If */
  
      printf("ARP cache entry successfully added.\n");
      close(s);
      return(0);
  }
  </code></pre>