summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2004-02-10 13:12:49 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2004-02-10 13:12:49 +0000
commit10fa0369f249ffe04ff828dec04ee7a463bd8cdb (patch)
tree9a24823deeaaa74b40cb3f83b342d41a924c5d37 /sbin
parent067bdac86badf9c64b2581cfe7d696192ab0144d (diff)
at startup, before sending several DHCPDISCOVER and waiting ages for answers,
check the link state of the interface(s) in question and don't try on intrfaces that for sure have no link. interfaces with unknown linkstates are treated as if they had a link, not all drivers are capable of reporting linkstate upstream, and for some media there is no such thing as a link state. saves quite sme time when booting notebooks configured for dhcp without teh cable inserted... note that this is the not yet active copy of dhclient ok grange@ mcbride@ pb@ naddy@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/dhclient/dhclient.c11
-rw-r--r--sbin/dhclient/dhcpd.h3
-rw-r--r--sbin/dhclient/dispatch.c34
3 files changed, 45 insertions, 3 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index 4204113267d..4d1ae26a229 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.8 2004/02/07 14:03:48 henning Exp $ */
+/* $OpenBSD: dhclient.c,v 1.9 2004/02/10 13:12:48 henning Exp $ */
/* DHCP Client. */
@@ -223,6 +223,7 @@ main(int argc, char *argv[])
int seed;
int quiet = 0;
char *s;
+ int ifs = 0;
s = strrchr(argv[0], '/');
if (!s)
@@ -343,6 +344,9 @@ main(int argc, char *argv[])
INTERFACE_AUTOMATIC)) !=
INTERFACE_REQUESTED))
continue;
+ if (!interface_link_status(ip->name))
+ continue;
+ ifs++;
script_init(ip, "PREINIT", NULL);
if (ip->client->alias)
script_write_params(ip, "alias_",
@@ -351,6 +355,11 @@ main(int argc, char *argv[])
}
}
+ if (ifs == 0) {
+ note("No active interfaces found - exiting.");
+ exit(0);
+ }
+
routefd = socket(PF_ROUTE, SOCK_RAW, 0);
if (routefd != -1)
add_protocol("AF_ROUTE", routefd, routehandler, interfaces);
diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h
index 2e3397644c1..8c89fe191ca 100644
--- a/sbin/dhclient/dhcpd.h
+++ b/sbin/dhclient/dhcpd.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhcpd.h,v 1.4 2004/02/07 13:26:35 henning Exp $ */
+/* $OpenBSD: dhcpd.h,v 1.5 2004/02/10 13:12:48 henning Exp $ */
/* Definitions for dhcpd... */
@@ -701,6 +701,7 @@ void add_timeout(TIME, void (*)(void *), void *);
void cancel_timeout(void (*)(void *), void *);
void add_protocol(char *, int, void (*)(struct protocol *), void *);
void remove_protocol(struct protocol *);
+int interface_link_status(char *);
/* hash.c */
struct hash_table *new_hash(void);
diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c
index 7d8a28aed2b..8934ca12055 100644
--- a/sbin/dhclient/dispatch.c
+++ b/sbin/dhclient/dispatch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dispatch.c,v 1.6 2004/02/07 11:40:17 henning Exp $ */
+/* $OpenBSD: dispatch.c,v 1.7 2004/02/10 13:12:48 henning Exp $ */
/* Network input dispatcher... */
@@ -683,3 +683,35 @@ remove_protocol(struct protocol *proto)
}
}
}
+
+int
+interface_link_status(char *ifname)
+{
+ int sock;
+ struct ifmediareq ifmr;
+
+ if ((sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+ error("Can't create socket");
+
+ memset(&ifmr, 0, sizeof(ifmr));
+ strlcpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
+ if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
+ /* EINVAL -> link state unknown. treat as active */
+ if (errno != EINVAL)
+ syslog(LOG_DEBUG, "ioctl(SIOCGIFMEDIA) on %s: %m",
+ ifname);
+ close(sock);
+ return (1);
+ }
+ close(sock);
+
+ if (ifmr.ifm_status & IFM_AVALID)
+ if ((ifmr.ifm_active & IFM_NMASK) == IFM_ETHER) {
+ if (ifmr.ifm_status & IFM_ACTIVE)
+ return (1);
+ else
+ return (0);
+ }
+
+ return (1);
+}