title: How to use inet_pton and struct ifreq for setting up ip address from C program
body: <p>I am trying to set ip address of a network interface from a C program. I looked around and found out that I can do it using <code>ioctl()</code> and <code>inet_pton()</code>. My problem is, I am not able to figure out where in <code>struct ifreq</code> am I supposed to store the converted address. I keep on getting <code>ioctl() - invalid argument</code> error.</p>
  
  <p>I have particularly looked at the example <a href="https://stackoverflow.com/questions/6652384/how-to-set-the-ip-address-from-c-in-linux">How to set the IP address from C in linux</a>. This says that we can cast <code>ifr.ifr_addr</code> to <code>struct sockaddr_in</code>. However, after doing the address conversion, <code>ioctl()</code> fails with invalid argument error.</p>
  
  <p>Following is the code:</p>
  
  <pre><code>280 void setip (int fd) {
  281 
  282     struct ifreq ifr;
  283     struct sockaddr_in * addr;
  284     int stat;
  285 
  286     strcpy(ifr.ifr_name, in.dev.device);          // in.dev.device = tun2
  287     addr = (struct sockaddr_in *) &amp;ifr.ifr_addr;
  288 
  289     addr-&gt;sin_family = AF_INET;
  290 
  291     stat = inet_pton(addr-&gt;sin_family, in.dev.ip_addr, &amp;addr-&gt;sin_addr); // in.dev.ip_addr = "100.0.0.10"
  292     if (stat == 0)
  293         raise_error("inet_pton() - invalid ip");
  294     if (stat == -1)
  295         raise_error("inet_pton() - invalid family");
  296 
  297     if (stat == 1);
  298     else
  299         raise_error("inet_pton()");
  300 
  301     /* This is just to test if address conversion happened properly */
  302     char buff[BUFF_SIZE];
  303     char * foo;
  304     foo = inet_ntop(AF_INET, &amp;addr-&gt;sin_addr, buff, BUFF_SIZE);
  305     if (foo == NULL)
  306         raise_error("inet_ntop()");
  307     else
  308         printf("main = %s, addr = %s\n",in.dev.ip_addr, buff);
  309     
  310     if (ioctl(fd, SIOCSIFADDR, &amp;ifr, sizeof(ifr)) == -1)
  311         raise_error("ioctl() - SIOCSIFADDR");
  312 }
  </code></pre>
  
  <p>Edit: <code>raise_error</code> function is:</p>
  
  <pre><code>void raise_error (const char * msg) {
  
      perror(msg);
      exit(1);
  }
  </code></pre>
  
  <p>Output I get is:</p>
  
  <pre><code>main = 100.0.0.10, addr = 100.0.0.10
  ioctl() - SIOCSIFADDR: Invalid argument
  </code></pre>
  
  <p>I am guessing the converted the address is getting placed at wrong location in <code>struct ifreq</code>, but I am not able to figure out exactly what location it should be placed. 
  I also tried using <code>ifr.ifr_addr</code> for address conversion but that didn't work either.</p>
  
  <p>Edit: I am running the program as root.</p>
  
  <p>Any help will be much appreciated. Please let me know if I need to post more code or debugging output.</p>
  
  <p>Thanks</p>