diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2004-02-10 13:12:49 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2004-02-10 13:12:49 +0000 |
commit | 10fa0369f249ffe04ff828dec04ee7a463bd8cdb (patch) | |
tree | 9a24823deeaaa74b40cb3f83b342d41a924c5d37 /sbin | |
parent | 067bdac86badf9c64b2581cfe7d696192ab0144d (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.c | 11 | ||||
-rw-r--r-- | sbin/dhclient/dhcpd.h | 3 | ||||
-rw-r--r-- | sbin/dhclient/dispatch.c | 34 |
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); +} |