Dhclient fix for systems with media settings

Martin Blapp mb at imp.ch
Tue Aug 5 01:45:24 PDT 2003


Hi all,

If you used wi(4) or en(4) wavelan cards and you had problems with dhclient,
you should try this patch, which treats interfaces with media settings
differently.

http://people.freebsd.org/~mbr/patches/dhclient-interfacepolling-fixup.diff

I'll produce a more clean patch this evening, and also adapt the patch to
the ISC style, so it can be submitted again.

--- src/contrib/isc-dhcp/includes/dhcpd.h.orig	Mon Aug  4 23:57:06 2003
+++ src/contrib/isc-dhcp/includes/dhcpd.h	Mon Aug  4 23:57:37 2003
@@ -782,6 +782,7 @@
 	char name [IFNAMSIZ];		/* Its name... */
 	int linkstatus;			/* Link status */
 	int ieee802;			/* True if media is ieee802 */
+	int mediaflag;			/* True if dhclient.conf has media settings */
 	int index;			/* Its index. */
 	int rfdesc;			/* Its read file descriptor. */
 	int wfdesc;			/* Its write file descriptor, if
--- src/contrib/isc-dhcp/client/dhclient.c.orig	Tue Aug  5 00:42:37 2003
+++ src/contrib/isc-dhcp/client/dhclient.c	Tue Aug  5 10:01:17 2003
@@ -257,7 +257,9 @@
 			    log_fatal ("%s: interface name too long (max %ld)",
 				       argv [i], (long)strlen (argv [i]));
  		    strlcpy (tmp -> name, argv [i], IFNAMSIZ);
-		    set_ieee802(tmp);
+#ifdef __FreeBSD__
+		    set_ieee80211(tmp);
+#endif
 		    tmp->linkstatus = interface_active(tmp);
 		    if (interfaces) {
 			    interface_reference (&tmp -> next,
@@ -412,7 +414,16 @@
 					     INTERFACE_AUTOMATIC)) !=
 			     INTERFACE_REQUESTED))
 				continue;
-			set_ieee802(ip);
+#ifdef __FreeBSD__
+			set_ieee80211(ip);
+#endif
+#ifdef ENABLE_POLLING_MODE
+			if (ip -> client -> config -> media != NULL)
+				ip->mediaflag = 1;
+			else
+				ip->mediaflag = 0;
+#endif /* ifdef ENABLE_POLLING_MODE */
+
 			script_init (ip -> client,
 				     "PREINIT", (struct string_list *)0);
 			if (ip -> client -> alias)
@@ -1385,9 +1396,6 @@
 	int interval;
 	int increase = 1;

-	if (interface_active(client -> interface) == 0)
-		return;
-
 	/* Figure out how long it's been since we started transmitting. */
 	interval = cur_time - client -> first_sending;

@@ -1427,6 +1435,9 @@
 		}
 	}

+	if (interface_active(client -> interface) == 0)
+		return;
+
 	/* If we're supposed to increase the interval, do so.  If it's
 	   currently zero (i.e., we haven't sent any packets yet), set
 	   it to one; otherwise, add to it a random number between
@@ -3215,14 +3226,29 @@
 	if (ifmr.ifm_status & IFM_AVALID) {
 		if (ip->ieee802) {
 			if ((IFM_TYPE(ifmr.ifm_active) == IFM_IEEE80211) &&
-			     (ifmr.ifm_status & IFM_ACTIVE))
+			     (ifmr.ifm_status & IFM_ACTIVE)) {
+				if (ip->mediaflag &&
+				    ip -> client -> state != S_BOUND)
+					return (2);
 				return (1);
+			}
 		} else {
-			if (ifmr.ifm_status & IFM_ACTIVE)
+			if (ifmr.ifm_status & IFM_ACTIVE) {
+				if (ip->mediaflag &&
+				    ip -> client -> state != S_BOUND)
+					return (2);
 				return (1);
+			}
 		}
 	}

+	/*
+	 * If dhclient.conf contains media settings, we cannot
+	 * abort if the interface is not set to active mode.
+	 */
+	if (ip->mediaflag && ip -> client -> state != S_BOUND)
+		return (1);
+
 	return (0);
 #else /* ifdef __FreeBSD__ */

@@ -3231,7 +3257,7 @@
 }

 #ifdef __FreeBSD__
-set_ieee802 (struct interface_info *ip) {
+set_ieee80211 (struct interface_info *ip) {

 	struct ieee80211req     ireq;
 	u_int8_t                data[32];
@@ -3267,12 +3293,20 @@
 #endif /* __FreeBSD__ */

 #ifdef ENABLE_POLLING_MODE
+/* Go to background after some time */
+void state_background (cpp)
+	void *cpp;
+{
+	go_daemon ();
+}
+
 /* Check the state of the NICs if we have link */
 void state_link (cpp)
         void *cpp;
 {
 	struct interface_info *ip;
 	struct client_state *client;
+	int result;

 #ifdef DEBUG
 	printf("Polling interface status\n");
@@ -3281,7 +3315,11 @@
 		if (ip->linkstatus == 0 || doinitcheck == 0) {
 			if (interface_active(ip)) {
 #ifdef DEBUG
-				printf("%s: Found Link on interface\n", ip->name);
+				if (ip->mediaflag)
+					printf("%s: Trying different media settings on interface\n",
+						ip->name);
+				else
+					printf("%s: Found Link on interface\n", ip->name);
 #endif
 				for (client = ip -> client;
 				     client; client = client -> next) {
@@ -3310,18 +3348,29 @@
 					}
 			 	}
 				ip->linkstatus = 0;
+				if (! ip->mediaflag && ! doinitcheck) {
+					add_timeout(cur_time + (polling_interval * 2),
+					             state_background, client, 0, 0);
+				}
 			}
 		} else {
-			if (interface_active(ip) == 0) {
+			if ((result = interface_active(ip)) == 0) {
 #ifdef DEBUG
 				printf("%s: Lost Link on interface\n", ip->name);
 #endif
 				ip->linkstatus = 0;
 			}
+			if (result == 2) {
+				for (client = ip -> client;
+                                     client; client = client -> next) {
+					cancel_timeout(state_init, client);
+					add_timeout(cur_time + random () % 5,
+						state_reboot, client, 0, 0);
+                                }
+				ip->linkstatus = 1;
+			}
 		}
 	}
-	if (doinitcheck)
-		go_daemon ();
 	doinitcheck = 1;
 }
 #endif /* ifdef ENABLE_POLLING_MODE */


More information about the freebsd-current mailing list