3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 // based on chbind.cc by Jacques Gelinas
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2, or (at your option)
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include <sys/socket.h>
30 #include <sys/ioctl.h>
31 #include <netinet/in.h>
40 fprintf (stderr,"chbind version %s\n",VERSION);
41 fprintf (stderr,"chbind [ --silent ] [ --ip ip_num[/mask] ] [ --bcast broadcast ] command argument\n");
46 Check if a network device exist in /proc/net/dev.
47 This is used because ifconfig_ioctl triggers modprobe if requesting
48 information about non existant devices.
50 Return != 0 if the device exist.
52 static int chbind_devexist (const char *dev)
55 FILE *fin = fopen ("/proc/net/dev","r");
57 int len = strlen(dev);
59 fgets(buf,sizeof(buf)-1,fin); // Skip one line
60 while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
61 const char *pt = strstr(buf,dev);
62 if (pt != NULL && pt[len] == ':'){
73 static int ifconfig_ioctl(
79 strcpy(ifr->ifr_name, ifname);
80 return ioctl(fd, cmd,ifr);
84 Fetch the IP number of an interface from the kernel.
85 Assume the device is already available in the kernel
86 Return -1 if any error.
88 int ifconfig_getaddr (
95 if (chbind_devexist(ifname)){
96 int skfd = socket(AF_INET, SOCK_DGRAM, 0);
101 if (ifconfig_ioctl(skfd,ifname,SIOCGIFADDR, &ifr) >= 0){
102 struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
103 *addr = sin->sin_addr.s_addr;
106 if (ifconfig_ioctl(skfd,ifname,SIOCGIFNETMASK, &ifr) >= 0){
107 struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
108 *mask = sin->sin_addr.s_addr;
111 if (ifconfig_ioctl(skfd,ifname,SIOCGIFBRDADDR, &ifr) >= 0){
112 struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
113 *bcast = sin->sin_addr.s_addr;
125 int main (int argc, char *argv[])
130 struct vc_ip_mask_pair ips[16];
132 unsigned long bcast = 0xffffffff;
133 for (i=1; i<argc; i++){
134 const char *arg = argv[i];
135 const char *opt = argv[i+1];
136 if (strcmp(arg,"--ip")==0){
137 unsigned long addr,mask;
139 fprintf (stderr,"Too many IP numbers, max 16, ignored\n");
141 }else if (ifconfig_getaddr(opt,&addr,&mask,&bcast)==-1){
142 unsigned long mask = 0x00ffffff;
143 const char *pt = strchr(opt,'/');
144 char tmpopt[strlen(opt)+1];
149 tmpopt[pt-opt] = '\0';
152 if (strchr(pt,'.')==NULL){
153 // Ok, we have a network size, not a netmask
157 for (i=0; i<size; i++){
163 struct hostent *h = gethostbyname (pt);
165 memcpy (&mask,h->h_addr,sizeof(mask));
167 fprintf (stderr,"Invalid netmask: %s\n",pt);
174 h = gethostbyname (opt);
176 fprintf (stderr,"Invalid IP number or host name: %s\n",opt);
179 memcpy (&addr,h->h_addr,sizeof(addr));
180 ips[nbaddrs].ip = addr;
181 ips[nbaddrs].mask = mask;
185 ips[nbaddrs].ip = addr;
186 ips[nbaddrs].mask = mask;
190 }else if (strcmp(arg,"--bcast")==0){
192 if (ifconfig_getaddr(opt,&tmp,&tmp,&bcast)==-1){
193 struct hostent *h = gethostbyname (opt);
195 fprintf (stderr,"Invalid broadcast number: %s\n",opt);
198 memcpy (&bcast,h->h_addr,sizeof(bcast));
202 }else if (strcmp(arg,"--silent")==0){
210 }else if (argv[i][0] == '-'){
213 if (vc_set_ipv4root(bcast,nbaddrs,ips)==0){
216 printf ("ipv4root is now");
217 for (i=0; i<nbaddrs; i++){
218 unsigned long hostaddr = ntohl(ips[i].ip);
219 printf (" %ld.%ld.%ld.%ld"
227 execvp (argv[i],argv+i);
228 fprintf (stderr,"Can't exec %s (%s)\n",argv[i],strerror(errno));
230 fprintf (stderr,"Can't set the ipv4 root (%s)\n",strerror(errno));