summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mdk-stage1/doc/TECH-INFOS1
-rw-r--r--mdk-stage1/network.c47
2 files changed, 48 insertions, 0 deletions
diff --git a/mdk-stage1/doc/TECH-INFOS b/mdk-stage1/doc/TECH-INFOS
index e66c9daa5..e52134da5 100644
--- a/mdk-stage1/doc/TECH-INFOS
+++ b/mdk-stage1/doc/TECH-INFOS
@@ -37,6 +37,7 @@ if nfs/ftp/http:
if multiple interfaces detected:
`interface' <- (list-of-detected-interfaces)
+ (if "auto", use the first interface with a link beat)
fi
diff --git a/mdk-stage1/network.c b/mdk-stage1/network.c
index 29ea5dc10..513c4784b 100644
--- a/mdk-stage1/network.c
+++ b/mdk-stage1/network.c
@@ -598,6 +598,45 @@ static enum return_type bringup_networking(struct interface_info * intf)
}
+static char * auto_select_up_intf(void)
+{
+#define SIOCETHTOOL 0x8946
+#define ETHTOOL_GLINK 0x0000000a /* Get link status (ethtool_value) */
+
+ struct ethtool_value {
+ uint32_t cmd;
+ uint32_t data;
+ };
+
+ char ** interfaces, ** ptr;
+ interfaces = get_net_devices();
+
+ int s;
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ return NULL;
+ }
+
+ ptr = interfaces;
+ while (ptr && *ptr) {
+ struct ifreq ifr;
+ struct ethtool_value edata;
+ strncpy(ifr.ifr_name, *ptr, IFNAMSIZ);
+ edata.cmd = ETHTOOL_GLINK;
+ ifr.ifr_data = (caddr_t)&edata;
+ if (ioctl(s, SIOCETHTOOL, &ifr) == 0 && edata.data) {
+ close(s);
+ return *ptr;
+ }
+ ptr++;
+ }
+
+ close(s);
+
+ return NULL;
+}
+
+
static char * interface_select(void)
{
char ** interfaces, ** ptr;
@@ -626,6 +665,14 @@ static char * interface_select(void)
if (count == 1)
return *interfaces;
+ /* this can't be done in ask_from_list_comments_auto because "auto" isn't in the interfaces list */
+ choice = get_auto_value("interface");
+ if (choice && streq(choice, "auto")) {
+ choice = auto_select_up_intf();
+ if (choice)
+ return choice;
+ }
+
i = 0;
while (interfaces[i]) {
descriptions[i] = get_net_intf_description(interfaces[i]);