vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

ifspec.c (4672B)


      1 // $Id$
      2 
      3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      4 // based on ifspec.cc by Jacques Gelinas
      5 //  
      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)
      9 // any later version.
     10 //  
     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.
     15 //  
     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.
     19 
     20 /*
     21 	Prints the specs of a network device in shell like form
     22 
     23 	ADDR=
     24 	NETMASK=
     25 	BCAST=
     26 */
     27 #ifdef HAVE_CONFIG_H
     28 #  include <config.h>
     29 #endif
     30 
     31 #include <stdio.h>
     32 #include <stdlib.h>
     33 #include <string.h>
     34 #include <ctype.h>
     35 #include <unistd.h>
     36 #include <sys/socket.h>
     37 #include <sys/ioctl.h>
     38 #include <netinet/in.h>
     39 #include <net/if.h>
     40 
     41 static void usage()
     42 {
     43 	fprintf (stderr,"ifspec version %s\n",VERSION);
     44 	fprintf (stderr
     45 		,"ifspec network-device [ ipaddr netmask broadcast ]\n"
     46 		 "prints device specification in a shell usable way\n");
     47 	exit (-1);
     48 }
     49 
     50 static int ifconfig_ioctl(
     51 	int fd,
     52 	const char *ifname,
     53 	int cmd,
     54 	struct ifreq *ifr)
     55 {
     56 	strcpy(ifr->ifr_name, ifname);
     57 	return ioctl(fd, cmd,ifr);
     58 }
     59 
     60 static unsigned long ip_cnv (const char *str)
     61 {
     62 	const char *start_str = str;
     63 	unsigned tb[4];
     64 	int no = 0;
     65 	unsigned long ret;
     66 	  
     67 	memset (tb,-1,sizeof(tb));
     68 	while (*str != '\0' && no < 4){
     69 		if (isdigit(*str)){
     70 			int val = atoi(str);
     71 			if (val > 255) break;
     72 			tb[no++] = val;
     73 			while (isdigit(*str)) str++;
     74 			if (*str == '.'){
     75 				str++;
     76 			}else{
     77 				break;
     78 			}
     79 		}else{
     80 			break;
     81 		}
     82 	}
     83 
     84 	ret = (tb[0] << 24) | (tb[1]<<16) | (tb[2] << 8) | tb[3];
     85 	if (no != 4 || *str != '\0'){
     86 		fprintf (stderr,"Invalid IP number or netmask: %s\n",start_str);
     87 		ret = 0xffffffff;
     88 	}
     89 	return ret;
     90 }
     91 
     92 
     93 /*
     94 	Fetch the IP number of an interface from the kernel.
     95 	Assume the device is already available in the kernel
     96 	Return -1 if any error.
     97 */
     98 int ifconfig_print (
     99 	const char *ifname,
    100 	const char *addrstr,
    101 	const char *maskstr,
    102 	const char *bcaststr)
    103 {
    104 	int ret = -1;
    105 	int skfd = socket(AF_INET, SOCK_DGRAM, 0);
    106 	if (skfd != -1){
    107 		struct ifreq ifr;
    108 		struct {
    109 			unsigned long addr;
    110 			unsigned long mask;
    111 		} solved = {0,0};
    112 		if (addrstr != NULL && addrstr[0] != '\0'){
    113 			printf ("ADDR=%s\n",addrstr);
    114 			solved.addr = ip_cnv (addrstr);
    115 		}else if (ifconfig_ioctl(skfd,ifname,SIOCGIFADDR, &ifr) >= 0){
    116 			struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
    117 			unsigned long addr = ntohl(sin->sin_addr.s_addr);
    118 			printf ("ADDR=%lu.%lu.%lu.%lu\n"
    119 				,(addr>>24)&0xff
    120 				,(addr>>16)&0xff
    121 				,(addr>>8)&0xff
    122 				,addr&0xff);
    123 			solved.addr = addr;
    124 			ret = 0;
    125 		}
    126 		else {
    127 		  perror("ifspec: ioctl(SIOCGIFADDR)");
    128 		}
    129 		
    130 		if (maskstr != NULL && maskstr[0] != '\0'){
    131 			printf ("NETMASK=%s\n",maskstr);
    132 			solved.mask = ip_cnv (maskstr);
    133 		}else		if (ifconfig_ioctl(skfd,ifname,SIOCGIFNETMASK, &ifr) >= 0){
    134 			struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
    135 			unsigned long addr = ntohl(sin->sin_addr.s_addr);
    136 			printf ("NETMASK=%lu.%lu.%lu.%lu\n"
    137 				,(addr>>24)&0xff
    138 				,(addr>>16)&0xff
    139 				,(addr>>8)&0xff
    140 				,addr&0xff);
    141 			solved.mask = addr;
    142 			ret = 0;
    143 		}
    144 		else {
    145 		  perror("ifspec: ioctl(SIOCGIFNETMASK)");
    146 		}
    147 		
    148 		if (bcaststr != NULL && bcaststr[0] != '\0'){
    149 			printf ("BCAST=%s\n",bcaststr);
    150 		}else if (ifconfig_ioctl(skfd,ifname,SIOCGIFBRDADDR, &ifr) >= 0){
    151 			struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr;
    152 			unsigned long addr = ntohl(sin->sin_addr.s_addr);
    153 			printf ("BCAST=%lu.%lu.%lu.%lu\n"
    154 				,(addr>>24)&0xff
    155 				,(addr>>16)&0xff
    156 				,(addr>>8)&0xff
    157 				,addr&0xff);
    158 			ret = 0;
    159 		}else if (solved.addr!=0 && solved.mask!=0) {
    160 			// Can't get it from the kernel, compute it from the IP
    161 			// and the netmask
    162 			unsigned long addr = (solved.addr & solved.mask)
    163 				| ~solved.mask;
    164 			printf ("BCAST=%lu.%lu.%lu.%lu\n"
    165 				,(addr>>24)&0xff
    166 				,(addr>>16)&0xff
    167 				,(addr>>8)&0xff
    168 				,addr&0xff);
    169 			
    170 		}
    171 		close (skfd);
    172 	}
    173 	return ret;
    174 }
    175 
    176 
    177 int main (int argc, char *argv[])
    178 {
    179 	int ret = -1;
    180 	if (argc < 2){
    181 		usage();
    182 	}else{
    183 		const char *addrstr = argc >= 3 ? argv[2] : NULL;
    184 		const char *maskstr = argc >= 4 ? argv[3] : NULL;
    185 		const char *bcaststr = argc >= 5 ? argv[4] : NULL;
    186 		ret = ifconfig_print (argv[1],addrstr,maskstr,bcaststr);
    187 	}
    188 	return ret;
    189 }
    190 
    191 
    192