From hburch@lumeta.com  Tue Oct  8 06:52:29 2002
Return-Path: <hburch@lumeta.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 4D05D37B401
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  8 Oct 2002 06:52:29 -0700 (PDT)
Received: from exgw2.lumeta.com (exgw2.lumeta.com [65.198.68.66])
	by mx1.FreeBSD.org (Postfix) with ESMTP id B3E5643E4A
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  8 Oct 2002 06:52:28 -0700 (PDT)
	(envelope-from hburch@lumeta.com)
Received: from lucy.corp.lumeta.com (h65-198-68-133.lumeta.com [65.198.68.133])
	by exgw2.lumeta.com (Postfix) with ESMTP id 3152D37383A
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  8 Oct 2002 09:52:28 -0400 (EDT)
Received: from localhost (localhost [127.0.0.1])
	by lucy.corp.lumeta.com (Postfix) with ESMTP id 0E85D1084F
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  8 Oct 2002 09:52:28 -0400 (EDT)
Received: from hburch.corp.lumeta.com (hburch.corp.lumeta.com [65.198.68.240])
	by lucy.corp.lumeta.com (Postfix) with ESMTP id 2C7021084E
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  8 Oct 2002 09:52:27 -0400 (EDT)
Received: from hburch.corp.lumeta.com (localhost [127.0.0.1])
	by hburch.corp.lumeta.com (Postfix) with ESMTP id 1152A3D4
	for <FreeBSD-gnats-submit@freebsd.org>; Tue,  8 Oct 2002 09:52:25 -0400 (EDT)
Message-Id: <20021008135225.1152A3D4@hburch.corp.lumeta.com>
Date: Tue, 08 Oct 2002 09:52:24 -0400
From: Hal Burch <hburch@lumeta.com>
Sender: hburch@lumeta.com
Reply-To: Hal Burch <hburch@lumeta.com>
To: FreeBSD-gnats-submit@freebsd.org
Subject: dhclient on 'no carrier' interfaces takes too long
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         43826
>Category:       bin
>Synopsis:       dhclient on 'no carrier' interfaces takes too long
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    mbr
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 08 07:00:17 PDT 2002
>Closed-Date:    Mon Jul 28 11:55:19 PDT 2003
>Last-Modified:  Mon Jul 28 11:55:19 PDT 2003
>Originator:     Hal Burch
>Release:        FreeBSD 4.6.2-RELEASE i386
>Organization:
Lumeta Corporation
>Environment:
System: FreeBSD hburch-lap.lumeta.com 4.6.2-RELEASE FreeBSD 4.6.2-RELEASE #0: Tue Oct 8 08:37:59 EDT 2002 root@hburch-lap.lumeta.com:/usr/src/sys/compile/LOCAL i386
>Description:
Running dhclient <interface> on an interface which is not attached (my
laptop with built-in Ethernet when travelling, for example) attempts
to sends DHCP requests and waits for responses.

dhclient should (IMO) notice that the status is no carrier and
immediately stop.

Note that this has been the behavior since I started using FreeBSD
most recently (4.3) and does not appear related to the ISC 3.0.1
import.
>How-To-Repeat:
Kill dhclients running, unplug your Ethernet, run dhclient <interface>,
and wait.
>Fix:
For specified interfaces in dhclient, check to make sure SIOCGIFMEDIA
does not return a valid non-active media status (code yanked from
ifconfig).  This is not optimal, as this will not affect running
dhclient without an interface list, but the standard rc files do not
do this, so boot-up is greatly improved.

I made diffs from the head of RELENG_4_6_2_RELEASE, although I am using
an older version.  Although I did not see anything that implied there
might be a conflict with the changes, I have not tested this combination.

diff -u -r /root/orig/client/dhclient.c /usr/src/contrib/isc-dhcp/client/dhclient.c
--- /root/orig/client/dhclient.c	Tue Oct  8 09:37:24 2002
+++ /usr/src/contrib/isc-dhcp/client/dhclient.c	Tue Oct  8 09:37:38 2002
@@ -228,6 +228,10 @@
 			    log_fatal ("%s: interface name too long (max %ld)",
 				       argv [i], (long)strlen (argv [i]));
  		    strlcpy (tmp -> name, argv [i], IFNAMSIZ);
+		    if (!interface_active(argv[i])) {
+			log_fatal("Interface %s is not attached properly (media is not active)", argv[i]);
+		    }
+
 		    if (interfaces) {
 			    interface_reference (&tmp -> next,
 						 interfaces, MDL);
diff -u -r /root/orig/common/discover.c /usr/src/contrib/isc-dhcp/common/discover.c
--- /root/orig/common/discover.c	Tue Oct  8 09:37:22 2002
+++ /usr/src/contrib/isc-dhcp/common/discover.c	Tue Oct  8 09:37:38 2002
@@ -48,6 +48,7 @@
 
 #include "dhcpd.h"
 #include <sys/ioctl.h>
+#include <net/if_media.h>
 
 struct interface_info *interfaces, *dummy_interfaces, *fallback_interface;
 int interfaces_invalidated;
@@ -123,6 +124,40 @@
 	struct interface_info *ip = (struct interface_info *)ipo;
 	ip -> rfdesc = ip -> wfdesc = -1;
 	return ISC_R_SUCCESS;
+}
+
+/* Check to see if there's a wire plugged in */
+int
+interface_active(const char *ifname) {
+	struct ifmediareq ifmr;
+	int *media_list, i;
+	int sock;
+
+	if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
+		log_fatal ("Can't create interface_active socket");
+
+	(void) memset(&ifmr, 0, sizeof(ifmr));
+	(void) strncpy(ifmr.ifm_name, ifname, sizeof(ifmr.ifm_name));
+
+	if (ioctl(sock, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
+		/*
+		 * Interface doesn't support SIOCGIFMEDIA, presume okay
+		 */
+		return 1;
+	}
+
+	if (ifmr.ifm_count == 0) {
+		/*
+		 * this is unexpected (to me), but we'll just assume
+		 * that this means interface does not support SIOCGIFMEDIA
+		 */
+		return 1;
+	}
+
+	if (ifmr.ifm_status & IFM_AVALID)
+		return (ifmr.ifm_status & IFM_ACTIVE);
+	else
+		return 1;
 }
 
 /* Use the SIOCGIFCONF ioctl to get a list of all the attached interfaces.
diff -u -r /root/orig/includes/dhcpd.h /usr/src/contrib/isc-dhcp/includes/dhcpd.h
--- /root/orig/includes/dhcpd.h	Tue Oct  8 09:37:22 2002
+++ /usr/src/contrib/isc-dhcp/includes/dhcpd.h	Tue Oct  8 09:37:38 2002
@@ -1750,6 +1750,7 @@
 extern int interface_count;
 extern int interface_max;
 isc_result_t interface_initialize (omapi_object_t *, const char *, int);
+int interface_active PROTO ((const char *));
 void discover_interfaces PROTO ((int));
 int setup_fallback (struct interface_info **, const char *, int);
 int if_readsocket PROTO ((omapi_object_t *));
>Release-Note:
>Audit-Trail:

From: hburch@lumeta.com (Hal Burch)
To: freebsd-gnats-submit@FreeBSD.org, hburch@lumeta.com
Cc:  
Subject: Re: bin/43826: dhclient on %27no carrier%27 interfaces takes too long
Date: Thu, 10 Oct 2002 11:01:47 -0400 (EDT)

 After further review, I failed to close sock before returning.
Responsible-Changed-From-To: freebsd-bugs->murray 
Responsible-Changed-By: johan 
Responsible-Changed-When: Fri Oct 11 11:06:12 PDT 2002 
Responsible-Changed-Why:  
Over to dhcp maintainer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=43826 
Responsible-Changed-From-To: murray->mbr 
Responsible-Changed-By: mbr 
Responsible-Changed-When: Mon Feb 10 01:35:46 PST 2003 
Responsible-Changed-Why:  
I'll work on dhclient, take this PR 

http://www.freebsd.org/cgi/query-pr.cgi?pr=43826 
State-Changed-From-To: open->analyzed 
State-Changed-By: mbr 
State-Changed-When: Sat Apr 26 16:43:36 PDT 2003 
State-Changed-Why:  
A smiliar patch will be committed to the ISC 
cvs repo. I expect this to be part of isc-dhcpd 
3.0.2 package. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=43826 
State-Changed-From-To: analyzed->closed 
State-Changed-By: mbr 
State-Changed-When: Mon Jul 28 11:54:55 PDT 2003 
State-Changed-Why:  
Fixed in CURRENT. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=43826 
>Unformatted:
