X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2Fifspec.c;fp=src%2Fifspec.c;h=c375bcc083c2789f3813760f54ee9668655923ed;hb=06e1018272502e1d15d6d8f32b80fa96420785b8;hp=0000000000000000000000000000000000000000;hpb=8a59994861a17eb92c11553d88631757ee8e63c3;p=util-vserver.git diff --git a/src/ifspec.c b/src/ifspec.c new file mode 100644 index 0000000..c375bcc --- /dev/null +++ b/src/ifspec.c @@ -0,0 +1,188 @@ +// $Id: ifspec.c,v 1.1.4.1 2003/11/21 16:01:09 ensc Exp $ + +// Copyright (C) 2003 Enrico Scholz +// based on ifspec.cc by Jacques Gelinas +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +/* + Prints the specs of a network device in shell like form + + ADDR= + NETMASK= + BCAST= +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void usage() +{ + fprintf (stderr,"ifspec version %s\n",VERSION); + fprintf (stderr + ,"ifspec network-device [ ipaddr netmask broadcast ]\n" + "prints device specification in a shell usable way\n"); + exit (-1); +} + +static int ifconfig_ioctl( + int fd, + const char *ifname, + int cmd, + struct ifreq *ifr) +{ + strcpy(ifr->ifr_name, ifname); + return ioctl(fd, cmd,ifr); +} + +static unsigned long ip_cnv (const char *str) +{ + const char *start_str = str; + unsigned tb[4]; + int no = 0; + unsigned long ret; + + memset (tb,-1,sizeof(tb)); + while (*str != '\0' && no < 4){ + if (isdigit(*str)){ + int val = atoi(str); + if (val > 255) break; + tb[no++] = val; + while (isdigit(*str)) str++; + if (*str == '.'){ + str++; + }else{ + break; + } + }else{ + break; + } + } + + ret = (tb[0] << 24) | (tb[1]<<16) | (tb[2] << 8) | tb[3]; + if (no != 4 || *str != '\0'){ + fprintf (stderr,"Invalid IP number or netmask: %s\n",start_str); + ret = 0xffffffff; + } + return ret; +} + + +/* + Fetch the IP number of an interface from the kernel. + Assume the device is already available in the kernel + Return -1 if any error. +*/ +int ifconfig_print ( + const char *ifname, + const char *addrstr, + const char *maskstr, + const char *bcaststr) +{ + int ret = -1; + int skfd = socket(AF_INET, SOCK_DGRAM, 0); + if (skfd != -1){ + struct ifreq ifr; + struct { + unsigned long addr; + unsigned long mask; + } solved = {0,0}; + if (addrstr != NULL && addrstr[0] != '\0'){ + printf ("ADDR=%s\n",addrstr); + solved.addr = ip_cnv (addrstr); + }else if (ifconfig_ioctl(skfd,ifname,SIOCGIFADDR, &ifr) >= 0){ + struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr; + unsigned long addr = ntohl(sin->sin_addr.s_addr); + printf ("ADDR=%lu.%lu.%lu.%lu\n" + ,(addr>>24)&0xff + ,(addr>>16)&0xff + ,(addr>>8)&0xff + ,addr&0xff); + solved.addr = addr; + ret = 0; + } + else { + perror("ioctl(SIOCGIFADDR)"); + } + + if (maskstr != NULL && maskstr[0] != '\0'){ + printf ("NETMASK=%s\n",maskstr); + solved.mask = ip_cnv (maskstr); + }else if (ifconfig_ioctl(skfd,ifname,SIOCGIFNETMASK, &ifr) >= 0){ + struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr; + unsigned long addr = ntohl(sin->sin_addr.s_addr); + printf ("NETMASK=%lu.%lu.%lu.%lu\n" + ,(addr>>24)&0xff + ,(addr>>16)&0xff + ,(addr>>8)&0xff + ,addr&0xff); + solved.mask = addr; + ret = 0; + } + else { + perror("ioctl(SIOCGIFNETMASK)"); + } + + if (bcaststr != NULL && bcaststr[0] != '\0'){ + printf ("BCAST=%s\n",bcaststr); + }else if (ifconfig_ioctl(skfd,ifname,SIOCGIFBRDADDR, &ifr) >= 0){ + struct sockaddr_in *sin = (struct sockaddr_in*)&ifr.ifr_addr; + unsigned long addr = ntohl(sin->sin_addr.s_addr); + printf ("BCAST=%lu.%lu.%lu.%lu\n" + ,(addr>>24)&0xff + ,(addr>>16)&0xff + ,(addr>>8)&0xff + ,addr&0xff); + ret = 0; + }else if (solved.addr!=0 && solved.mask!=0) { + // Can't get it from the kernel, compute it from the IP + // and the netmask + unsigned long addr = (solved.addr & solved.mask) + | ~solved.mask; + printf ("BCAST=%lu.%lu.%lu.%lu\n" + ,(addr>>24)&0xff + ,(addr>>16)&0xff + ,(addr>>8)&0xff + ,addr&0xff); + + } + close (skfd); + } + return ret; +} + + +int main (int argc, char *argv[]) +{ + int ret = -1; + if (argc < 2){ + usage(); + }else{ + const char *addrstr = argc >= 3 ? argv[2] : NULL; + const char *maskstr = argc >= 4 ? argv[3] : NULL; + const char *bcaststr = argc >= 5 ? argv[4] : NULL; + ret = ifconfig_print (argv[1],addrstr,maskstr,bcaststr); + } + return ret; +} + + +