Dhclient fix for systems with media settings

From: Martin Blapp <mb_at_imp.ch>
Date: Tue, 5 Aug 2003 10:45:18 +0200 (CEST)
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
_at__at_ -782,6 +782,7 _at__at_
 	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
_at__at_ -257,7 +257,9 _at__at_
 			    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,
_at__at_ -412,7 +414,16 _at__at_
 					     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)
_at__at_ -1385,9 +1396,6 _at__at_
 	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;

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

+	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
_at__at_ -3215,14 +3226,29 _at__at_
 	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__ */

_at__at_ -3231,7 +3257,7 _at__at_
 }

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

 	struct ieee80211req     ireq;
 	u_int8_t                data[32];
_at__at_ -3267,12 +3293,20 _at__at_
 #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");
_at__at_ -3281,7 +3315,11 _at__at_
 		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) {
_at__at_ -3310,18 +3348,29 _at__at_
 					}
 			 	}
 				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 */
Received on Mon Aug 04 2003 - 23:45:24 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:17 UTC