libexplain  1.4.D001
libexplain/iocontrol/disambiguate/net_dev_name.c
Go to the documentation of this file.
00001 /*
00002  * libexplain - Explain errno values returned by libc functions
00003  * Copyright (C) 2010, 2011, 2013 Peter Miller
00004  * Written by Peter Miller <pmiller@opensource.org.au>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 3 of the License, or (at
00009  * your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program. If not, see <http://www.gnu.org/licenses/>.
00018  */
00019 
00020 #include <libexplain/ac/ctype.h>
00021 #include <libexplain/ac/net/if.h> /* not Solaris */
00022 #include <libexplain/ac/string.h>
00023 #include <libexplain/ac/sys/ioctl.h>
00024 #include <libexplain/ac/sys/sockio.h> /* Solaris */
00025 
00026 #include <libexplain/iocontrol.h>
00027 
00028 
00029 int
00030 explain_iocontrol_disambiguate_net_dev_name(int fildes, const char *name)
00031 {
00032 #if defined(SIOCGIFINDEX) && defined(SIOCGIFNAME)
00033     struct ifreq    ifr;
00034     int             interface_index;
00035     size_t          name_len;
00036     const char      *cp;
00037 
00038     /*
00039      * We ask the file descriptor for its network interface index; if it says
00040      * no, this file descriptor isn't suitable.
00041      */
00042     memset(&ifr, 0, sizeof(ifr));
00043     if (ioctl(fildes, SIOCGIFINDEX, &ifr) < 0)
00044         return DISAMBIGUATE_DO_NOT_USE;
00045     interface_index = ifr.ifr_ifindex ;
00046 
00047     /*
00048      * We ask the file descriptor for its network interface name (based on the
00049      * interface index); if it says no, this file descriptor isn't suitable.
00050      */
00051     memset(&ifr, 0, sizeof(ifr));
00052     ifr.ifr_ifindex = interface_index;
00053     if (ioctl(fildes, SIOCGIFNAME, &ifr) < 0)
00054         return DISAMBIGUATE_DO_NOT_USE;
00055 
00056     /*
00057      * Finally, we test the interface name.
00058      * It could have an optional trailing number.
00059      */
00060     name_len = strlen(name);
00061     if (0 != memcmp(ifr.ifr_name, name, name_len))
00062         return DISAMBIGUATE_DO_NOT_USE;
00063     cp = ifr.ifr_name + name_len;
00064     while (isdigit(*cp))
00065         ++cp;
00066     if (*cp)
00067         return DISAMBIGUATE_DO_NOT_USE;
00068 
00069     /*
00070      * Looks good.
00071      */
00072     return DISAMBIGUATE_USE;
00073 #else
00074     return DISAMBIGUATE_DO_NOT_USE;
00075 #endif
00076 }
00077 
00078 
00079 /* vim: set ts=8 sw=4 et : */