ifnet: handle 'biosdevname' interface names better (bgo #674765) (lp:962587)
authorJiří Klimeš <jklimes@redhat.com>
Thu, 10 May 2012 13:40:48 +0000 (15:40 +0200)
committerJiří Klimeš <jklimes@redhat.com>
Fri, 18 May 2012 08:19:13 +0000 (10:19 +0200)
Finding out interface type from interface name string is fragile. It is easily
broken, e.g. by biosdevname changing interface names to em<n> or p<n>*p<n>.
Sadly, Gentoo network configuration scripts are rather stupid, using format:
variable_${interface|mac|essid|apmac}.
http://www.gentoo.org/doc/en/handbook/2007.0/handbook-x86.xml?full=1#book_part4_chap2
The entries interface|mac|essid|apmac are basically indistinguishable. It's not
possible to say whether 'p1p1' is an interface or SSID, for example.

Fix the current behaviour a bit by checking whether the string is an interface.
If so, and it is not a Wi-Fi one, set the connection type as wired. Else it is
regarded as wireless.

src/settings/plugins/ifnet/Makefile.am
src/settings/plugins/ifnet/net_parser.c
src/settings/plugins/ifnet/tests/Makefile.am

index 84deda5..07a2fc8 100644 (file)
@@ -1,5 +1,6 @@
 SUBDIRS = . tests
 INCLUDES = \
+       -I$(top_srcdir)/src/wifi \
        -I$(top_srcdir)/src/settings \
        -I$(top_srcdir)/include \
        -I$(top_srcdir)/libnm-glib \
@@ -52,6 +53,7 @@ lib_ifnet_io_la_CPPFLAGS = \
        -DSBINDIR=\"$(sbindir)\"
 
 lib_ifnet_io_la_LIBADD = \
+        $(top_builddir)/src/wifi/libwifi-utils.la \
         $(top_builddir)/libnm-util/libnm-util.la \
         $(GLIB_LIBS)\
         $(GIO_LIBS)
index 66caa74..2562e61 100644 (file)
 #include <string.h>
 #include <nm-system-config-interface.h>
 #include <stdio.h>
+
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <unistd.h>
+
 #include "plugin.h"
+#include "wifi-utils.h"
+
 #include "net_parser.h"
 #include "net_utils.h"
 
@@ -122,6 +129,24 @@ is_global_setting (char *key)
        return 0;
 }
 
+/* Find out whether the 'iface' is an interface */
+static gboolean
+name_is_interface (const char *iface)
+{
+       int fd;
+       struct ifreq ifr;
+       gboolean is_iface = FALSE;
+
+       fd = socket (PF_INET, SOCK_DGRAM, 0);
+       if (fd >= 0) {
+               strncpy (ifr.ifr_name, iface, IFNAMSIZ);
+               if (ioctl (fd, SIOCGIFHWADDR, &ifr) == 0)
+                       is_iface = TRUE;
+               close (fd);
+       }
+       return is_iface;
+}
+
 /* Parse a complete line */
 /* Connection type is determined here */
 static void
@@ -166,8 +191,12 @@ init_block_by_line (gchar * buf)
                        /* ignored connection */
                        conn = add_new_connection_config ("ignore", pos);
                } else
-                       /* wireless connection */
-                       conn = add_new_connection_config ("wireless", pos);
+                       if (name_is_interface (pos) && !wifi_utils_is_wifi (pos, NULL))
+                               /* wired connection */
+                               conn = add_new_connection_config ("wired", pos);
+                       else
+                               /* wireless connection */
+                               conn = add_new_connection_config ("wireless", pos);
        }
        data = g_strdup (key_value[1]);
        tmp = strip_string (data, '"');
index 20a2680..85d4238 100644 (file)
@@ -10,7 +10,8 @@ check_ifnet_CPPFLAGS = $(CHECK_CFLAGS) $(GLIB_CFLAGS)
 check_ifnet_LDADD = $(top_builddir)/libnm-util/libnm-util.la \
                    $(builddir)/../lib-ifnet-io.la \
                    $(CHECK_LIBS) \
-                   $(GLIB_LIBS)
+                   $(GLIB_LIBS) \
+                   $(LIBM)
 EXTRA_DIST = hostname \
                         net \
                         net.all \