From nobody@FreeBSD.org  Sun Dec 18 14:25:58 2011
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id E541E1065673
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 18 Dec 2011 14:25:57 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id CA34C8FC0C
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 18 Dec 2011 14:25:57 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id pBIEPvOm033814
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 18 Dec 2011 14:25:57 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id pBIEPvRx033813;
	Sun, 18 Dec 2011 14:25:57 GMT
	(envelope-from nobody)
Message-Id: <201112181425.pBIEPvRx033813@red.freebsd.org>
Date: Sun, 18 Dec 2011 14:25:57 GMT
From: Fabian Keil <fk@fabiankeil.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: dhclient regression after r228259: leases rejected due to domain search option
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         163431
>Category:       bin
>Synopsis:       [patch] dhclient(8) regression after r228259: leases rejected due to domain search option
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    dumbbell
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sun Dec 18 14:30:15 UTC 2011
>Closed-Date:    Fri Dec 30 15:00:12 UTC 2011
>Last-Modified:  Thu Jan 26 22:10:12 UTC 2012
>Originator:     Fabian Keil
>Release:        HEAD
>Organization:
>Environment:
FreeBSD r500.local 10.0-CURRENT FreeBSD 10.0-CURRENT #384 r+8098cd1-dirty: Sat Dec 10 19:11:01 CET 2011     fk@r500.local:/usr/obj/usr/src/sys/ZOEY  amd64
>Description:
There's a DHCP server on a public WLAN whose responses
dhclient rejects after r228259, apparently because the
responses are deemed invalid:

wlan0: no link ........ got link
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 6
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 15
Invalid forward pointer in DHCP Domain Search option compression.

Earlier dhclient versions didn't request the domain search
option and thus had no complaints.
>How-To-Repeat:
dhclient wlan0 with a DHCP server that triggers the problem.
>Fix:
The attached patch turns a couple of hard errors into
warnings and lets dhclient skip the "Domain Search" related
part of the response.

This seems to be sufficient to get a lease:

wlan0: no link ...... got link
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPNAK from 192.168.10.1
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 4
Invalid forward pointer in DHCP Domain Search option compression.
DHCPOFFER from 192.168.10.1
Bogus domain search list 119: \015bruesselerplatz\002de (\015bruesselerplatz\002de)
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
Invalid forward pointer in DHCP Domain Search option compression.
DHCPACK from 192.168.10.1
Bogus domain search list 119: \015bruesselerplatz\002de (\015bruesselerplatz\002de)
bound to 192.168.10.218 -- renewal in 3000 seconds.

I suppose configuring dhclient to not request the domain search
option would be a viable workaround, but I'd prefer dhclient to
get a lease without user interaction.

Note that the patch does not adjust the regression tests.

Patch attached with submission follows:

From 87fb896aa21badb55200c1d6e7b7abc5ca3dfea6 Mon Sep 17 00:00:00 2001
From: Fabian Keil <fk@fabiankeil.de>
Date: Sat, 10 Dec 2011 10:46:53 +0100
Subject: [PATCH] Deal with find_search_domain_name_len() failures gracefully

---
 sbin/dhclient/options.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

diff --git sbin/dhclient/options.c sbin/dhclient/options.c
index b9122c7..033f8de 100644
--- sbin/dhclient/options.c
+++ sbin/dhclient/options.c
@@ -224,9 +224,11 @@ expand_domain_search(struct packet *packet)
 	expanded_len = 0;
 	offset = 0;
 	while (offset < option->len) {
+		expanded_len = find_search_domain_name_len(option, &offset);
+		if (expanded_len == 0)
+		    return;
 		/* We add 1 for the space between domain names. */
-		expanded_len +=
-		    find_search_domain_name_len(option, &offset) + 1;
+		expanded_len++;
 	}
 	if (expanded_len > 0)
 		/* Remove 1 for the superfluous trailing space. */
@@ -271,8 +273,9 @@ find_search_domain_name_len(struct option_data *option, int *offset)
 			/* This is a pointer to another list of labels. */
 			if (i + 1 >= option->len) {
 				/* The pointer is truncated. */
-				error("Truncated pointer in DHCP Domain "
+				warning("Truncated pointer in DHCP Domain "
 				    "Search option.");
+				return (0);
 			}
 
 			pointer = ((label_len & ~(0xC0)) << 8) +
@@ -282,8 +285,9 @@ find_search_domain_name_len(struct option_data *option, int *offset)
 				 * The pointer must indicates a prior
 				 * occurance.
 				 */
-				error("Invalid forward pointer in DHCP Domain "
+				warning("Invalid forward pointer in DHCP Domain "
 				    "Search option compression.");
+				return (0);
 			}
 
 			pointed_len = find_search_domain_name_len(option,
@@ -295,7 +299,8 @@ find_search_domain_name_len(struct option_data *option, int *offset)
 		}
 
 		if (i + label_len >= option->len) {
-			error("Truncated label in DHCP Domain Search option.");
+			warning("Truncated label in DHCP Domain Search option.");
+			return (0);
 		}
 
 		/*
@@ -308,7 +313,7 @@ find_search_domain_name_len(struct option_data *option, int *offset)
 		i += label_len + 1;
 	}
 
-	error("Truncated DHCP Domain Search option.");
+	warning("Truncated DHCP Domain Search option.");
 
 	return (0);
 }
-- 
1.7.8



>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->dumbbell 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Wed Dec 21 13:52:48 UTC 2011 
Responsible-Changed-Why:  
Over to author of r228259 

http://www.freebsd.org/cgi/query-pr.cgi?pr=163431 

From: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?=
 <jean-sebastien.pedron@dumbbell.fr>
To: bug-followup@FreeBSD.org, fk@fabiankeil.de
Cc:  
Subject: Re: bin/163431: dhclient regression after r228259: leases rejected
 due to domain search option
Date: Wed, 21 Dec 2011 21:30:36 +0100

 This is a multi-part message in MIME format.
 --------------090109090207050804080905
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 8bit
 
 Hi Fabian,
 
 Thank you for providing a patch with your report. I attached a modified
 version to this follow-up. The changes are:
     o  Change error code of find_search_domain_name_len() from 0 to -1;
        just because -1 looks more like an error code :)
     o  Fix expanded_len handling in expand_domain_search(). Each return
        value of find_search_domain_name_len() is added to the previous
        one.
     o  style(9) fixes.
     o  Update the regression testsuite.
 
 Could you please tell me if this patch works for you?
 
 And just for my curiosity, does your DHCP server runs on Windows?
 Because someone else reported invalid DHCP Domain Search option value
 like yours and his problem came from an incomplete support for this
 feature in Windows' DHCP server.
 
 To be clear (and so that search engines points here), Microsoft's
 documentation[1] says that one should specify domains as
 "example.com;foobar.net" for "option 119" (Domain Search option). The
 problem is that their DHCP server sends this value as is. The following
 article describes this issue and explains how to forge a raw value to
 work around it:
 http://www.mattzuba.com/2011/03/windows-2008-rc2-dhcp-server-option-119/
 
 [1] http://technet.microsoft.com/en-us/library/dd572752%28office.13%29.aspx
 
 -- 
 Jean-Sbastien Pdron
 
 --------------090109090207050804080905
 Content-Type: text/plain;
  name="dhclient-domain-search-pr163431-a.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="dhclient-domain-search-pr163431-a.patch"
 
 Index: tools/regression/sbin/dhclient/fake.c
 ===================================================================
 --- tools/regression/sbin/dhclient/fake.c	(revision 228787)
 +++ tools/regression/sbin/dhclient/fake.c	(working copy)
 @@ -32,7 +32,11 @@
  	va_end(ap);
  	fprintf(stderr, "\n");
  
 -	return ret;
 +	/*
 +	 * The original warning() would return "ret" here. We do this to
 +	 * check warnings explicitely.
 +	 */
 +	longjmp(env, 1);
  }
  
  int
 Index: sbin/dhclient/options.c
 ===================================================================
 --- sbin/dhclient/options.c	(revision 228787)
 +++ sbin/dhclient/options.c	(working copy)
 @@ -211,7 +211,7 @@
  void
  expand_domain_search(struct packet *packet)
  {
 -	int offset, expanded_len;
 +	int offset, expanded_len, next_domain_len;
  	struct option_data *option;
  	unsigned char *domain_search, *cursor;
  
 @@ -224,9 +224,13 @@
  	expanded_len = 0;
  	offset = 0;
  	while (offset < option->len) {
 +		next_domain_len = find_search_domain_name_len(option, &offset);
 +		if (next_domain_len < 0)
 +			/* The Domain Search option value is invalid. */
 +			return;
 +
  		/* We add 1 for the space between domain names. */
 -		expanded_len +=
 -		    find_search_domain_name_len(option, &offset) + 1;
 +		expanded_len += next_domain_len + 1;
  	}
  	if (expanded_len > 0)
  		/* Remove 1 for the superfluous trailing space. */
 @@ -271,8 +275,9 @@
  			/* This is a pointer to another list of labels. */
  			if (i + 1 >= option->len) {
  				/* The pointer is truncated. */
 -				error("Truncated pointer in DHCP Domain "
 +				warning("Truncated pointer in DHCP Domain "
  				    "Search option.");
 +				return (-1);
  			}
  
  			pointer = ((label_len & ~(0xC0)) << 8) +
 @@ -282,8 +287,9 @@
  				 * The pointer must indicates a prior
  				 * occurance.
  				 */
 -				error("Invalid forward pointer in DHCP Domain "
 -				    "Search option compression.");
 +				warning("Invalid forward pointer in DHCP "
 +				    "Domain Search option compression.");
 +				return (-1);
  			}
  
  			pointed_len = find_search_domain_name_len(option,
 @@ -295,7 +301,9 @@
  		}
  
  		if (i + label_len >= option->len) {
 -			error("Truncated label in DHCP Domain Search option.");
 +			warning("Truncated label in DHCP Domain Search "
 +			    "option.");
 +			return (-1);
  		}
  
  		/*
 @@ -308,9 +316,9 @@
  		i += label_len + 1;
  	}
  
 -	error("Truncated DHCP Domain Search option.");
 +	warning("Truncated DHCP Domain Search option.");
  
 -	return (0);
 +	return (-1);
  }
  
  void
 
 --------------090109090207050804080905--

From: Fabian Keil <fk@fabiankeil.de>
To: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?=
 <jean-sebastien.pedron@dumbbell.fr>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/163431: dhclient regression after r228259: leases rejected
 due to domain search option
Date: Fri, 23 Dec 2011 00:11:39 +0100

 --Sig_/DbcuIeHvh4ST9BYFfhm7Diu
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 Jean-S=E9bastien P=E9dron <jean-sebastien.pedron@dumbbell.fr> wrote:
 
 > Thank you for providing a patch with your report. I attached a modified
 > version to this follow-up. The changes are:
 >     o  Change error code of find_search_domain_name_len() from 0 to -1;
 >        just because -1 looks more like an error code :)
 >     o  Fix expanded_len handling in expand_domain_search(). Each return
 >        value of find_search_domain_name_len() is added to the previous
 >        one.
 >     o  style(9) fixes.
 >     o  Update the regression testsuite.
 >
 > Could you please tell me if this patch works for you?
 
 Looks good to me, thanks. I'll try to test it this weekend.
 
 > And just for my curiosity, does your DHCP server runs on Windows?
 
 I have no idea. The DHCP server is part of the public WLAN of
 a bar (Hallmackenreuther, Br=FCsseler Platz 9, 50674 Cologne,
 Germany) and outside my control.
 
 Fabian
 
 --Sig_/DbcuIeHvh4ST9BYFfhm7Diu
 Content-Type: application/pgp-signature; name=signature.asc
 Content-Disposition: attachment; filename=signature.asc
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.18 (FreeBSD)
 
 iEYEARECAAYFAk7zuTAACgkQSMVSH78upWNddACeJficl43hsHn0Ql3sUx9Vg+2I
 p5QAn0c5Unqzs8hRKo4MT7K6ei+Emn7T
 =IYqo
 -----END PGP SIGNATURE-----
 
 --Sig_/DbcuIeHvh4ST9BYFfhm7Diu--

From: Fabian Keil <fk@fabiankeil.de>
To: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?=
 <jean-sebastien.pedron@dumbbell.fr>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/163431: dhclient regression after r228259: leases rejected
 due to domain search option
Date: Fri, 23 Dec 2011 14:56:56 +0100

 --Sig_/S7VaetXo3xPHVach1li5Mm_
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: quoted-printable
 
 Fabian Keil <fk@fabiankeil.de> wrote:
 
 > Jean-S=E9bastien P=E9dron <jean-sebastien.pedron@dumbbell.fr> wrote:
 >=20
 > > Thank you for providing a patch with your report. I attached a modified
 > > version to this follow-up. The changes are:
 > >     o  Change error code of find_search_domain_name_len() from 0 to -1;
 > >        just because -1 looks more like an error code :)
 > >     o  Fix expanded_len handling in expand_domain_search(). Each return
 > >        value of find_search_domain_name_len() is added to the previous
 > >        one.
 > >     o  style(9) fixes.
 > >     o  Update the regression testsuite.
 > >
 > > Could you please tell me if this patch works for you?
 >=20
 > Looks good to me, thanks. I'll try to test it this weekend.
 
 The modified patch works as expected:
 
 wlan0: no link ...... got link
 DHCPREQUEST on wlan0 to 255.255.255.255 port 67
 DHCPNAK from 192.168.10.1
 DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 3
 Invalid forward pointer in DHCP Domain Search option compression.
 DHCPOFFER from 192.168.10.1
 Bogus domain search list 119: \015bruesselerplatz\002de (\015bruesselerplat=
 z\002de)
 DHCPREQUEST on wlan0 to 255.255.255.255 port 67
 Invalid forward pointer in DHCP Domain Search option compression.
 DHCPACK from 192.168.10.1
 Bogus domain search list 119: \015bruesselerplatz\002de (\015bruesselerplat=
 z\002de)
 bound to 192.168.10.183 -- renewal in 3000 seconds.
 
 Fabian
 
 --Sig_/S7VaetXo3xPHVach1li5Mm_
 Content-Type: application/pgp-signature; name=signature.asc
 Content-Disposition: attachment; filename=signature.asc
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.18 (FreeBSD)
 
 iEYEARECAAYFAk70iKoACgkQSMVSH78upWOXWgCdHPh8qaWUZZVPESCNiEsMIvdR
 wIoAnirfuwESUSp+/pv3kgbcC91uWzwD
 =+/o5
 -----END PGP SIGNATURE-----
 
 --Sig_/S7VaetXo3xPHVach1li5Mm_--
State-Changed-From-To: open->analyzed 
State-Changed-By: linimon 
State-Changed-When: Fri Dec 23 14:01:26 UTC 2011 
State-Changed-Why:  
apparently the suggested patch works. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=163431 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/163431: commit references a PR
Date: Fri, 30 Dec 2011 14:33:22 +0000 (UTC)

 Author: dumbbell
 Date: Fri Dec 30 14:33:08 2011
 New Revision: 229000
 URL: http://svn.freebsd.org/changeset/base/229000
 
 Log:
   Invalid Domain Search option isn't considered as a fatal error
   
   In the original Domain Search option patch, an invalid option value
   would cause the whole lease to be rejected. However, DHCP servers who
   emit such an invalid value are more common than I thought. With this new
   patch, just the option is rejected, not the entire lease.
   
   PR:		bin/163431
   Submitted by:	Fabian Keil <fk@fabiankeil.de> (earlier version)
   Reviewed by:	Fabian Keil <fk@fabiankeil.de>
   Sponsored by:	Yakaz (http://www.yakaz.com)
 
 Modified:
   head/sbin/dhclient/options.c
 
 Modified: head/sbin/dhclient/options.c
 ==============================================================================
 --- head/sbin/dhclient/options.c	Fri Dec 30 14:30:16 2011	(r228999)
 +++ head/sbin/dhclient/options.c	Fri Dec 30 14:33:08 2011	(r229000)
 @@ -211,7 +211,7 @@ parse_option_buffer(struct packet *packe
  void
  expand_domain_search(struct packet *packet)
  {
 -	int offset, expanded_len;
 +	int offset, expanded_len, next_domain_len;
  	struct option_data *option;
  	unsigned char *domain_search, *cursor;
  
 @@ -224,9 +224,13 @@ expand_domain_search(struct packet *pack
  	expanded_len = 0;
  	offset = 0;
  	while (offset < option->len) {
 +		next_domain_len = find_search_domain_name_len(option, &offset);
 +		if (next_domain_len < 0)
 +			/* The Domain Search option value is invalid. */
 +			return;
 +
  		/* We add 1 for the space between domain names. */
 -		expanded_len +=
 -		    find_search_domain_name_len(option, &offset) + 1;
 +		expanded_len += next_domain_len + 1;
  	}
  	if (expanded_len > 0)
  		/* Remove 1 for the superfluous trailing space. */
 @@ -271,8 +275,9 @@ find_search_domain_name_len(struct optio
  			/* This is a pointer to another list of labels. */
  			if (i + 1 >= option->len) {
  				/* The pointer is truncated. */
 -				error("Truncated pointer in DHCP Domain "
 +				warning("Truncated pointer in DHCP Domain "
  				    "Search option.");
 +				return (-1);
  			}
  
  			pointer = ((label_len & ~(0xC0)) << 8) +
 @@ -282,8 +287,9 @@ find_search_domain_name_len(struct optio
  				 * The pointer must indicates a prior
  				 * occurance.
  				 */
 -				error("Invalid forward pointer in DHCP Domain "
 -				    "Search option compression.");
 +				warning("Invalid forward pointer in DHCP "
 +				    "Domain Search option compression.");
 +				return (-1);
  			}
  
  			pointed_len = find_search_domain_name_len(option,
 @@ -295,7 +301,9 @@ find_search_domain_name_len(struct optio
  		}
  
  		if (i + label_len >= option->len) {
 -			error("Truncated label in DHCP Domain Search option.");
 +			warning("Truncated label in DHCP Domain Search "
 +			    "option.");
 +			return (-1);
  		}
  
  		/*
 @@ -308,9 +316,9 @@ find_search_domain_name_len(struct optio
  		i += label_len + 1;
  	}
  
 -	error("Truncated DHCP Domain Search option.");
 +	warning("Truncated DHCP Domain Search option.");
  
 -	return (0);
 +	return (-1);
  }
  
  void
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/163431: commit references a PR
Date: Fri, 30 Dec 2011 14:41:57 +0000 (UTC)

 Author: dumbbell
 Date: Fri Dec 30 14:41:47 2011
 New Revision: 229001
 URL: http://svn.freebsd.org/changeset/base/229001
 
 Log:
   Adapt testsuite following change in Domain Search error handling
   
   In this testsuite, warning() and error() have the same behaviour.
   
   PR:		bin/163431
   Sponsored by:	Yakaz (http://www.yakaz.com)
 
 Modified:
   head/tools/regression/sbin/dhclient/fake.c
 
 Modified: head/tools/regression/sbin/dhclient/fake.c
 ==============================================================================
 --- head/tools/regression/sbin/dhclient/fake.c	Fri Dec 30 14:33:08 2011	(r229000)
 +++ head/tools/regression/sbin/dhclient/fake.c	Fri Dec 30 14:41:47 2011	(r229001)
 @@ -32,7 +32,11 @@ warning(char *fmt, ...)
  	va_end(ap);
  	fprintf(stderr, "\n");
  
 -	return ret;
 +	/*
 +	 * The original warning() would return "ret" here. We do this to
 +	 * check warnings explicitely.
 +	 */
 +	longjmp(env, 1);
  }
  
  int
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: analyzed->closed 
State-Changed-By: dumbbell 
State-Changed-When: Fri Dec 30 14:53:31 UTC 2011 
State-Changed-Why:  
Fixed in r229000. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=163431 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/163431: commit references a PR
Date: Thu, 26 Jan 2012 19:46:29 +0000 (UTC)

 Author: dumbbell
 Date: Thu Jan 26 19:46:13 2012
 New Revision: 230597
 URL: http://svn.freebsd.org/changeset/base/230597
 
 Log:
   MFC r228259:
   Support domain-search in dhclient(8)
   
   The "domain-search" option (option 119) allows a DHCP server to publish
   a list of implicit domain suffixes used during name lookup. This option
   is described in RFC 3397.
   
   For instance, if the domain-search option says:
       ".example.org .example.com"
   and one wants to resolve "foobar", the resolver will try:
       1. "foobar.example.org"
       2. "foobar.example.com"
   
   The file /etc/resolv.conf is updated with a "search" directive if the
   DHCP server provides "domain-search".
   
   A regression test suite is included in this patch under
   tools/regression/sbin/dhclient.
   
   PR:		bin/151940
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229000:
   Invalid Domain Search option isn't considered as a fatal error
   
   In the original Domain Search option patch, an invalid option value
   would cause the whole lease to be rejected. However, DHCP servers who
   emit such an invalid value are more common than I thought. With this new
   patch, just the option is rejected, not the entire lease.
   
   PR:		bin/163431
   Submitted by:	Fabian Keil <fk@fabiankeil.de> (earlier version)
   Reviewed by:	Fabian Keil <fk@fabiankeil.de>
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229001:
   Adapt testsuite following change in Domain Search error handling
   
   In this testsuite, warning() and error() have the same behaviour.
   
   PR:		bin/163431
   Sponsored by:	Yakaz (http://www.yakaz.com)
 
 Added:
   stable/9/tools/regression/sbin/dhclient/
      - copied from r228259, head/tools/regression/sbin/dhclient/
 Modified:
   stable/9/sbin/dhclient/clparse.c
   stable/9/sbin/dhclient/dhclient-script
   stable/9/sbin/dhclient/dhclient.c
   stable/9/sbin/dhclient/dhcp-options.5
   stable/9/sbin/dhclient/dhcp.h
   stable/9/sbin/dhclient/options.c
   stable/9/sbin/dhclient/tables.c
   stable/9/tools/regression/sbin/Makefile
   stable/9/tools/regression/sbin/dhclient/fake.c
 Directory Properties:
   stable/9/sbin/dhclient/   (props changed)
   stable/9/tools/   (props changed)
 
 Modified: stable/9/sbin/dhclient/clparse.c
 ==============================================================================
 --- stable/9/sbin/dhclient/clparse.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/clparse.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -100,6 +100,8 @@ read_client_conf(void)
  	    DHO_DOMAIN_NAME_SERVERS;
  	top_level_config.requested_options
  	    [top_level_config.requested_option_count++] = DHO_HOST_NAME;
 +	top_level_config.requested_options
 +	    [top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
  
  	if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
  		do {
 
 Modified: stable/9/sbin/dhclient/dhclient-script
 ==============================================================================
 --- stable/9/sbin/dhclient/dhclient-script	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhclient-script	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -201,7 +201,9 @@ add_new_resolv_conf() {
  	local tmpres=/var/run/resolv.conf.${interface}
  	rm -f $tmpres
  
 -	if [ -n "$new_domain_name" ]; then
 +	if [ -n "$new_domain_search" ]; then
 +		echo "search $new_domain_search" >>$tmpres
 +	elif [ -n "$new_domain_name" ]; then
  		echo "search $new_domain_name" >>$tmpres
  	fi
  
 
 Modified: stable/9/sbin/dhclient/dhclient.c
 ==============================================================================
 --- stable/9/sbin/dhclient/dhclient.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhclient.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -2368,6 +2368,7 @@ check_option(struct client_lease *l, int
  		}
  		return (1);
  	case DHO_DOMAIN_NAME:
 +	case DHO_DOMAIN_SEARCH:
  		if (!res_hnok(sbuf)) {
  			if (!check_search(sbuf)) {
  				warning("Bogus domain search list %d: %s (%s)",
 
 Modified: stable/9/sbin/dhclient/dhcp-options.5
 ==============================================================================
 --- stable/9/sbin/dhclient/dhcp-options.5	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhcp-options.5	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -265,6 +265,10 @@ character set.
  .It Ic option domain-name Ar string ;
  This option specifies the domain name that the client should use when
  resolving hostnames via the Domain Name System.
 +.It Ic option domain-search Ar string ;
 +This option specifies a list of domain names that the client should use
 +when resolving hostnames via the Domain Name System. This option is
 +defined in RFC 3397.
  .It Ic option swap-server Ar ip-address ;
  This specifies the IP address of the client's swap server.
  .It Ic option root-path Ar string ;
 
 Modified: stable/9/sbin/dhclient/dhcp.h
 ==============================================================================
 --- stable/9/sbin/dhclient/dhcp.h	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhcp.h	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -169,6 +169,7 @@ struct dhcp_packet {
  #define	DHO_STREETTALK_SERVER		75
  #define	DHO_STREETTALK_DA_SERVER	76
  #define DHO_DHCP_USER_CLASS_ID		77
 +#define	DHO_DOMAIN_SEARCH		119
  #define DHO_CLASSLESS_ROUTES		121
  #define DHO_END				255
  
 
 Modified: stable/9/sbin/dhclient/options.c
 ==============================================================================
 --- stable/9/sbin/dhclient/options.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/options.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -55,6 +55,10 @@ void	parse_options(struct packet *);
  void	parse_option_buffer(struct packet *, unsigned char *, int);
  int	store_options(unsigned char *, int, struct tree_cache **,
  	    unsigned char *, int, int, int, int);
 +void	expand_domain_search(struct packet *packet);
 +int	find_search_domain_name_len(struct option_data *option, int *offset);
 +void	expand_search_domain_name(struct option_data *option, int *offset,
 +	    unsigned char **domain_search);
  
  
  /*
 @@ -94,6 +98,11 @@ parse_options(struct packet *packet)
  			    (unsigned char *)packet->raw->sname,
  			    sizeof(packet->raw->sname));
  	}
 +
 +	/* Expand DHCP Domain Search option. */
 +	if (packet->options_valid) {
 +		expand_domain_search(packet);
 +	}
  }
  
  /*
 @@ -194,6 +203,171 @@ parse_option_buffer(struct packet *packe
  }
  
  /*
 + * Expand DHCP Domain Search option. The value of this option is
 + * encoded like DNS' list of labels. See:
 + *   RFC 3397
 + *   RFC 1035
 + */
 +void
 +expand_domain_search(struct packet *packet)
 +{
 +	int offset, expanded_len, next_domain_len;
 +	struct option_data *option;
 +	unsigned char *domain_search, *cursor;
 +
 +	if (packet->options[DHO_DOMAIN_SEARCH].data == NULL)
 +		return;
 +
 +	option = &packet->options[DHO_DOMAIN_SEARCH];
 +
 +	/* Compute final expanded length. */
 +	expanded_len = 0;
 +	offset = 0;
 +	while (offset < option->len) {
 +		next_domain_len = find_search_domain_name_len(option, &offset);
 +		if (next_domain_len < 0)
 +			/* The Domain Search option value is invalid. */
 +			return;
 +
 +		/* We add 1 for the space between domain names. */
 +		expanded_len += next_domain_len + 1;
 +	}
 +	if (expanded_len > 0)
 +		/* Remove 1 for the superfluous trailing space. */
 +		--expanded_len;
 +
 +	domain_search = malloc(expanded_len + 1);
 +	if (domain_search == NULL)
 +		error("Can't allocate storage for expanded domain-search\n");
 +
 +	offset = 0;
 +	cursor = domain_search;
 +	while (offset < option->len) {
 +		expand_search_domain_name(option, &offset, &cursor);
 +		cursor[0] = ' ';
 +		cursor++;
 +	}
 +	domain_search[expanded_len] = '\0';
 +
 +	free(option->data);
 +	option->len = expanded_len;
 +	option->data = domain_search;
 +}
 +
 +int
 +find_search_domain_name_len(struct option_data *option, int *offset)
 +{
 +	int domain_name_len, i, label_len, pointer, pointed_len;
 +
 +	domain_name_len = 0;
 +
 +	i = *offset;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			return (domain_name_len);
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			if (i + 1 >= option->len) {
 +				/* The pointer is truncated. */
 +				warning("Truncated pointer in DHCP Domain "
 +				    "Search option.");
 +				return (-1);
 +			}
 +
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +			if (pointer >= *offset) {
 +				/*
 +				 * The pointer must indicates a prior
 +				 * occurance.
 +				 */
 +				warning("Invalid forward pointer in DHCP "
 +				    "Domain Search option compression.");
 +				return (-1);
 +			}
 +
 +			pointed_len = find_search_domain_name_len(option,
 +			    &pointer);
 +			domain_name_len += pointed_len;
 +
 +			*offset = i + 2;
 +			return (domain_name_len);
 +		}
 +
 +		if (i + label_len >= option->len) {
 +			warning("Truncated label in DHCP Domain Search "
 +			    "option.");
 +			return (-1);
 +		}
 +
 +		/*
 +		 * Update the domain name length with the length of the
 +		 * current label, plus a trailing dot ('.').
 +		 */
 +		domain_name_len += label_len + 1;
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +	}
 +
 +	warning("Truncated DHCP Domain Search option.");
 +
 +	return (-1);
 +}
 +
 +void
 +expand_search_domain_name(struct option_data *option, int *offset,
 +    unsigned char **domain_search)
 +{
 +	int i, label_len, pointer;
 +	unsigned char *cursor;
 +
 +	/*
 +	 * This is the same loop than the function above
 +	 * (find_search_domain_name_len). Therefore, we remove checks,
 +	 * they're already done. Here, we just make the copy.
 +	 */
 +	i = *offset;
 +	cursor = *domain_search;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			*domain_search = cursor;
 +			return;
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +
 +			expand_search_domain_name(option, &pointer, &cursor);
 +
 +			*offset = i + 2;
 +			*domain_search = cursor;
 +			return;
 +		}
 +
 +		/* Copy the label found. */
 +		memcpy(cursor, option->data + i + 1, label_len);
 +		cursor[label_len] = '.';
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +		cursor += label_len + 1;
 +	}
 +}
 +
 +/*
   * cons options into a big buffer, and then split them out into the
   * three separate buffers if needed.  This allows us to cons up a set of
   * vendor options using the same routine.
 
 Modified: stable/9/sbin/dhclient/tables.c
 ==============================================================================
 --- stable/9/sbin/dhclient/tables.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/tables.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -184,7 +184,7 @@ struct option dhcp_options[256] = {
  	{ "option-116", "X",				&dhcp_universe, 116 },
  	{ "option-117", "X",				&dhcp_universe, 117 },
  	{ "option-118", "X",				&dhcp_universe, 118 },
 -	{ "option-119", "X",				&dhcp_universe, 119 },
 +	{ "domain-search", "t",				&dhcp_universe, 119 },
  	{ "option-120", "X",				&dhcp_universe, 120 },
  	{ "classless-routes", "BA",			&dhcp_universe, 121 },
  	{ "option-122", "X",				&dhcp_universe, 122 },
 @@ -400,12 +400,13 @@ unsigned char dhcp_option_default_priori
  	DHO_IRC_SERVER,
  	DHO_STREETTALK_SERVER,
  	DHO_STREETTALK_DA_SERVER,
 +	DHO_DOMAIN_SEARCH,
  
  	/* Presently-undefined options... */
  	62, 63, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
  	106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
 -	118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
 +	118,      120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
  	131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
  	143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
  	155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
 
 Modified: stable/9/tools/regression/sbin/Makefile
 ==============================================================================
 --- stable/9/tools/regression/sbin/Makefile	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/tools/regression/sbin/Makefile	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -1,5 +1,5 @@
  # $FreeBSD$
  
 -SUBDIR=	growfs
 +SUBDIR=	dhclient growfs
  
  .include <bsd.subdir.mk>
 
 Modified: stable/9/tools/regression/sbin/dhclient/fake.c
 ==============================================================================
 --- head/tools/regression/sbin/dhclient/fake.c	Sun Dec  4 14:44:31 2011	(r228259)
 +++ stable/9/tools/regression/sbin/dhclient/fake.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -32,7 +32,11 @@ warning(char *fmt, ...)
  	va_end(ap);
  	fprintf(stderr, "\n");
  
 -	return ret;
 +	/*
 +	 * The original warning() would return "ret" here. We do this to
 +	 * check warnings explicitely.
 +	 */
 +	longjmp(env, 1);
  }
  
  int
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/163431: commit references a PR
Date: Thu, 26 Jan 2012 19:46:30 +0000 (UTC)

 Author: dumbbell
 Date: Thu Jan 26 19:46:13 2012
 New Revision: 230597
 URL: http://svn.freebsd.org/changeset/base/230597
 
 Log:
   MFC r228259:
   Support domain-search in dhclient(8)
   
   The "domain-search" option (option 119) allows a DHCP server to publish
   a list of implicit domain suffixes used during name lookup. This option
   is described in RFC 3397.
   
   For instance, if the domain-search option says:
       ".example.org .example.com"
   and one wants to resolve "foobar", the resolver will try:
       1. "foobar.example.org"
       2. "foobar.example.com"
   
   The file /etc/resolv.conf is updated with a "search" directive if the
   DHCP server provides "domain-search".
   
   A regression test suite is included in this patch under
   tools/regression/sbin/dhclient.
   
   PR:		bin/151940
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229000:
   Invalid Domain Search option isn't considered as a fatal error
   
   In the original Domain Search option patch, an invalid option value
   would cause the whole lease to be rejected. However, DHCP servers who
   emit such an invalid value are more common than I thought. With this new
   patch, just the option is rejected, not the entire lease.
   
   PR:		bin/163431
   Submitted by:	Fabian Keil <fk@fabiankeil.de> (earlier version)
   Reviewed by:	Fabian Keil <fk@fabiankeil.de>
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229001:
   Adapt testsuite following change in Domain Search error handling
   
   In this testsuite, warning() and error() have the same behaviour.
   
   PR:		bin/163431
   Sponsored by:	Yakaz (http://www.yakaz.com)
 
 Added:
   stable/9/tools/regression/sbin/dhclient/
      - copied from r228259, head/tools/regression/sbin/dhclient/
 Modified:
   stable/9/sbin/dhclient/clparse.c
   stable/9/sbin/dhclient/dhclient-script
   stable/9/sbin/dhclient/dhclient.c
   stable/9/sbin/dhclient/dhcp-options.5
   stable/9/sbin/dhclient/dhcp.h
   stable/9/sbin/dhclient/options.c
   stable/9/sbin/dhclient/tables.c
   stable/9/tools/regression/sbin/Makefile
   stable/9/tools/regression/sbin/dhclient/fake.c
 Directory Properties:
   stable/9/sbin/dhclient/   (props changed)
   stable/9/tools/   (props changed)
 
 Modified: stable/9/sbin/dhclient/clparse.c
 ==============================================================================
 --- stable/9/sbin/dhclient/clparse.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/clparse.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -100,6 +100,8 @@ read_client_conf(void)
  	    DHO_DOMAIN_NAME_SERVERS;
  	top_level_config.requested_options
  	    [top_level_config.requested_option_count++] = DHO_HOST_NAME;
 +	top_level_config.requested_options
 +	    [top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
  
  	if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
  		do {
 
 Modified: stable/9/sbin/dhclient/dhclient-script
 ==============================================================================
 --- stable/9/sbin/dhclient/dhclient-script	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhclient-script	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -201,7 +201,9 @@ add_new_resolv_conf() {
  	local tmpres=/var/run/resolv.conf.${interface}
  	rm -f $tmpres
  
 -	if [ -n "$new_domain_name" ]; then
 +	if [ -n "$new_domain_search" ]; then
 +		echo "search $new_domain_search" >>$tmpres
 +	elif [ -n "$new_domain_name" ]; then
  		echo "search $new_domain_name" >>$tmpres
  	fi
  
 
 Modified: stable/9/sbin/dhclient/dhclient.c
 ==============================================================================
 --- stable/9/sbin/dhclient/dhclient.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhclient.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -2368,6 +2368,7 @@ check_option(struct client_lease *l, int
  		}
  		return (1);
  	case DHO_DOMAIN_NAME:
 +	case DHO_DOMAIN_SEARCH:
  		if (!res_hnok(sbuf)) {
  			if (!check_search(sbuf)) {
  				warning("Bogus domain search list %d: %s (%s)",
 
 Modified: stable/9/sbin/dhclient/dhcp-options.5
 ==============================================================================
 --- stable/9/sbin/dhclient/dhcp-options.5	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhcp-options.5	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -265,6 +265,10 @@ character set.
  .It Ic option domain-name Ar string ;
  This option specifies the domain name that the client should use when
  resolving hostnames via the Domain Name System.
 +.It Ic option domain-search Ar string ;
 +This option specifies a list of domain names that the client should use
 +when resolving hostnames via the Domain Name System. This option is
 +defined in RFC 3397.
  .It Ic option swap-server Ar ip-address ;
  This specifies the IP address of the client's swap server.
  .It Ic option root-path Ar string ;
 
 Modified: stable/9/sbin/dhclient/dhcp.h
 ==============================================================================
 --- stable/9/sbin/dhclient/dhcp.h	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/dhcp.h	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -169,6 +169,7 @@ struct dhcp_packet {
  #define	DHO_STREETTALK_SERVER		75
  #define	DHO_STREETTALK_DA_SERVER	76
  #define DHO_DHCP_USER_CLASS_ID		77
 +#define	DHO_DOMAIN_SEARCH		119
  #define DHO_CLASSLESS_ROUTES		121
  #define DHO_END				255
  
 
 Modified: stable/9/sbin/dhclient/options.c
 ==============================================================================
 --- stable/9/sbin/dhclient/options.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/options.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -55,6 +55,10 @@ void	parse_options(struct packet *);
  void	parse_option_buffer(struct packet *, unsigned char *, int);
  int	store_options(unsigned char *, int, struct tree_cache **,
  	    unsigned char *, int, int, int, int);
 +void	expand_domain_search(struct packet *packet);
 +int	find_search_domain_name_len(struct option_data *option, int *offset);
 +void	expand_search_domain_name(struct option_data *option, int *offset,
 +	    unsigned char **domain_search);
  
  
  /*
 @@ -94,6 +98,11 @@ parse_options(struct packet *packet)
  			    (unsigned char *)packet->raw->sname,
  			    sizeof(packet->raw->sname));
  	}
 +
 +	/* Expand DHCP Domain Search option. */
 +	if (packet->options_valid) {
 +		expand_domain_search(packet);
 +	}
  }
  
  /*
 @@ -194,6 +203,171 @@ parse_option_buffer(struct packet *packe
  }
  
  /*
 + * Expand DHCP Domain Search option. The value of this option is
 + * encoded like DNS' list of labels. See:
 + *   RFC 3397
 + *   RFC 1035
 + */
 +void
 +expand_domain_search(struct packet *packet)
 +{
 +	int offset, expanded_len, next_domain_len;
 +	struct option_data *option;
 +	unsigned char *domain_search, *cursor;
 +
 +	if (packet->options[DHO_DOMAIN_SEARCH].data == NULL)
 +		return;
 +
 +	option = &packet->options[DHO_DOMAIN_SEARCH];
 +
 +	/* Compute final expanded length. */
 +	expanded_len = 0;
 +	offset = 0;
 +	while (offset < option->len) {
 +		next_domain_len = find_search_domain_name_len(option, &offset);
 +		if (next_domain_len < 0)
 +			/* The Domain Search option value is invalid. */
 +			return;
 +
 +		/* We add 1 for the space between domain names. */
 +		expanded_len += next_domain_len + 1;
 +	}
 +	if (expanded_len > 0)
 +		/* Remove 1 for the superfluous trailing space. */
 +		--expanded_len;
 +
 +	domain_search = malloc(expanded_len + 1);
 +	if (domain_search == NULL)
 +		error("Can't allocate storage for expanded domain-search\n");
 +
 +	offset = 0;
 +	cursor = domain_search;
 +	while (offset < option->len) {
 +		expand_search_domain_name(option, &offset, &cursor);
 +		cursor[0] = ' ';
 +		cursor++;
 +	}
 +	domain_search[expanded_len] = '\0';
 +
 +	free(option->data);
 +	option->len = expanded_len;
 +	option->data = domain_search;
 +}
 +
 +int
 +find_search_domain_name_len(struct option_data *option, int *offset)
 +{
 +	int domain_name_len, i, label_len, pointer, pointed_len;
 +
 +	domain_name_len = 0;
 +
 +	i = *offset;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			return (domain_name_len);
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			if (i + 1 >= option->len) {
 +				/* The pointer is truncated. */
 +				warning("Truncated pointer in DHCP Domain "
 +				    "Search option.");
 +				return (-1);
 +			}
 +
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +			if (pointer >= *offset) {
 +				/*
 +				 * The pointer must indicates a prior
 +				 * occurance.
 +				 */
 +				warning("Invalid forward pointer in DHCP "
 +				    "Domain Search option compression.");
 +				return (-1);
 +			}
 +
 +			pointed_len = find_search_domain_name_len(option,
 +			    &pointer);
 +			domain_name_len += pointed_len;
 +
 +			*offset = i + 2;
 +			return (domain_name_len);
 +		}
 +
 +		if (i + label_len >= option->len) {
 +			warning("Truncated label in DHCP Domain Search "
 +			    "option.");
 +			return (-1);
 +		}
 +
 +		/*
 +		 * Update the domain name length with the length of the
 +		 * current label, plus a trailing dot ('.').
 +		 */
 +		domain_name_len += label_len + 1;
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +	}
 +
 +	warning("Truncated DHCP Domain Search option.");
 +
 +	return (-1);
 +}
 +
 +void
 +expand_search_domain_name(struct option_data *option, int *offset,
 +    unsigned char **domain_search)
 +{
 +	int i, label_len, pointer;
 +	unsigned char *cursor;
 +
 +	/*
 +	 * This is the same loop than the function above
 +	 * (find_search_domain_name_len). Therefore, we remove checks,
 +	 * they're already done. Here, we just make the copy.
 +	 */
 +	i = *offset;
 +	cursor = *domain_search;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			*domain_search = cursor;
 +			return;
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +
 +			expand_search_domain_name(option, &pointer, &cursor);
 +
 +			*offset = i + 2;
 +			*domain_search = cursor;
 +			return;
 +		}
 +
 +		/* Copy the label found. */
 +		memcpy(cursor, option->data + i + 1, label_len);
 +		cursor[label_len] = '.';
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +		cursor += label_len + 1;
 +	}
 +}
 +
 +/*
   * cons options into a big buffer, and then split them out into the
   * three separate buffers if needed.  This allows us to cons up a set of
   * vendor options using the same routine.
 
 Modified: stable/9/sbin/dhclient/tables.c
 ==============================================================================
 --- stable/9/sbin/dhclient/tables.c	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/sbin/dhclient/tables.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -184,7 +184,7 @@ struct option dhcp_options[256] = {
  	{ "option-116", "X",				&dhcp_universe, 116 },
  	{ "option-117", "X",				&dhcp_universe, 117 },
  	{ "option-118", "X",				&dhcp_universe, 118 },
 -	{ "option-119", "X",				&dhcp_universe, 119 },
 +	{ "domain-search", "t",				&dhcp_universe, 119 },
  	{ "option-120", "X",				&dhcp_universe, 120 },
  	{ "classless-routes", "BA",			&dhcp_universe, 121 },
  	{ "option-122", "X",				&dhcp_universe, 122 },
 @@ -400,12 +400,13 @@ unsigned char dhcp_option_default_priori
  	DHO_IRC_SERVER,
  	DHO_STREETTALK_SERVER,
  	DHO_STREETTALK_DA_SERVER,
 +	DHO_DOMAIN_SEARCH,
  
  	/* Presently-undefined options... */
  	62, 63, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
  	106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
 -	118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
 +	118,      120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
  	131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
  	143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
  	155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
 
 Modified: stable/9/tools/regression/sbin/Makefile
 ==============================================================================
 --- stable/9/tools/regression/sbin/Makefile	Thu Jan 26 19:18:10 2012	(r230596)
 +++ stable/9/tools/regression/sbin/Makefile	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -1,5 +1,5 @@
  # $FreeBSD$
  
 -SUBDIR=	growfs
 +SUBDIR=	dhclient growfs
  
  .include <bsd.subdir.mk>
 
 Modified: stable/9/tools/regression/sbin/dhclient/fake.c
 ==============================================================================
 --- head/tools/regression/sbin/dhclient/fake.c	Sun Dec  4 14:44:31 2011	(r228259)
 +++ stable/9/tools/regression/sbin/dhclient/fake.c	Thu Jan 26 19:46:13 2012	(r230597)
 @@ -32,7 +32,11 @@ warning(char *fmt, ...)
  	va_end(ap);
  	fprintf(stderr, "\n");
  
 -	return ret;
 +	/*
 +	 * The original warning() would return "ret" here. We do this to
 +	 * check warnings explicitely.
 +	 */
 +	longjmp(env, 1);
  }
  
  int
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/163431: commit references a PR
Date: Thu, 26 Jan 2012 22:01:27 +0000 (UTC)

 Author: dumbbell
 Date: Thu Jan 26 22:01:05 2012
 New Revision: 230603
 URL: http://svn.freebsd.org/changeset/base/230603
 
 Log:
   MFC r228259:
   Support domain-search in dhclient(8)
   
   The "domain-search" option (option 119) allows a DHCP server to publish
   a list of implicit domain suffixes used during name lookup. This option
   is described in RFC 3397.
   
   For instance, if the domain-search option says:
       ".example.org .example.com"
   and one wants to resolve "foobar", the resolver will try:
       1. "foobar.example.org"
       2. "foobar.example.com"
   
   The file /etc/resolv.conf is updated with a "search" directive if the
   DHCP server provides "domain-search".
   
   A regression test suite is included in this patch under
   tools/regression/sbin/dhclient.
   
   PR:		bin/151940
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229000:
   Invalid Domain Search option isn't considered as a fatal error
   
   In the original Domain Search option patch, an invalid option value
   would cause the whole lease to be rejected. However, DHCP servers who
   emit such an invalid value are more common than I thought. With this new
   patch, just the option is rejected, not the entire lease.
   
   PR:		bin/163431
   Submitted by:	Fabian Keil <fk@fabiankeil.de> (earlier version)
   Reviewed by:	Fabian Keil <fk@fabiankeil.de>
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229001:
   Adapt testsuite following change in Domain Search error handling
   
   In this testsuite, warning() and error() have the same behaviour.
   
   PR:		bin/163431
   Sponsored by:	Yakaz (http://www.yakaz.com)
 
 Added:
   stable/8/tools/regression/sbin/dhclient/
      - copied from r228259, head/tools/regression/sbin/dhclient/
 Modified:
   stable/8/sbin/dhclient/clparse.c
   stable/8/sbin/dhclient/dhclient-script
   stable/8/sbin/dhclient/dhclient.c
   stable/8/sbin/dhclient/dhcp-options.5
   stable/8/sbin/dhclient/dhcp.h
   stable/8/sbin/dhclient/options.c
   stable/8/sbin/dhclient/tables.c
   stable/8/tools/regression/sbin/Makefile
   stable/8/tools/regression/sbin/dhclient/fake.c
 Directory Properties:
   stable/8/sbin/dhclient/   (props changed)
   stable/8/tools/   (props changed)
 
 Modified: stable/8/sbin/dhclient/clparse.c
 ==============================================================================
 --- stable/8/sbin/dhclient/clparse.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/clparse.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -100,6 +100,8 @@ read_client_conf(void)
  	    DHO_DOMAIN_NAME_SERVERS;
  	top_level_config.requested_options
  	    [top_level_config.requested_option_count++] = DHO_HOST_NAME;
 +	top_level_config.requested_options
 +	    [top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
  
  	if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
  		do {
 
 Modified: stable/8/sbin/dhclient/dhclient-script
 ==============================================================================
 --- stable/8/sbin/dhclient/dhclient-script	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhclient-script	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -201,7 +201,9 @@ add_new_resolv_conf() {
  	local tmpres=/var/run/resolv.conf.${interface}
  	rm -f $tmpres
  
 -	if [ -n "$new_domain_name" ]; then
 +	if [ -n "$new_domain_search" ]; then
 +		echo "search $new_domain_search" >>$tmpres
 +	elif [ -n "$new_domain_name" ]; then
  		echo "search $new_domain_name" >>$tmpres
  	fi
  
 
 Modified: stable/8/sbin/dhclient/dhclient.c
 ==============================================================================
 --- stable/8/sbin/dhclient/dhclient.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhclient.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -2368,6 +2368,7 @@ check_option(struct client_lease *l, int
  		}
  		return (1);
  	case DHO_DOMAIN_NAME:
 +	case DHO_DOMAIN_SEARCH:
  		if (!res_hnok(sbuf)) {
  			if (!check_search(sbuf)) {
  				warning("Bogus domain search list %d: %s (%s)",
 
 Modified: stable/8/sbin/dhclient/dhcp-options.5
 ==============================================================================
 --- stable/8/sbin/dhclient/dhcp-options.5	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhcp-options.5	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -265,6 +265,10 @@ character set.
  .It Ic option domain-name Ar string ;
  This option specifies the domain name that the client should use when
  resolving hostnames via the Domain Name System.
 +.It Ic option domain-search Ar string ;
 +This option specifies a list of domain names that the client should use
 +when resolving hostnames via the Domain Name System. This option is
 +defined in RFC 3397.
  .It Ic option swap-server Ar ip-address ;
  This specifies the IP address of the client's swap server.
  .It Ic option root-path Ar string ;
 
 Modified: stable/8/sbin/dhclient/dhcp.h
 ==============================================================================
 --- stable/8/sbin/dhclient/dhcp.h	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhcp.h	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -169,6 +169,7 @@ struct dhcp_packet {
  #define	DHO_STREETTALK_SERVER		75
  #define	DHO_STREETTALK_DA_SERVER	76
  #define DHO_DHCP_USER_CLASS_ID		77
 +#define	DHO_DOMAIN_SEARCH		119
  #define DHO_CLASSLESS_ROUTES		121
  #define DHO_END				255
  
 
 Modified: stable/8/sbin/dhclient/options.c
 ==============================================================================
 --- stable/8/sbin/dhclient/options.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/options.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -55,6 +55,10 @@ void	parse_options(struct packet *);
  void	parse_option_buffer(struct packet *, unsigned char *, int);
  int	store_options(unsigned char *, int, struct tree_cache **,
  	    unsigned char *, int, int, int, int);
 +void	expand_domain_search(struct packet *packet);
 +int	find_search_domain_name_len(struct option_data *option, int *offset);
 +void	expand_search_domain_name(struct option_data *option, int *offset,
 +	    unsigned char **domain_search);
  
  
  /*
 @@ -94,6 +98,11 @@ parse_options(struct packet *packet)
  			    (unsigned char *)packet->raw->sname,
  			    sizeof(packet->raw->sname));
  	}
 +
 +	/* Expand DHCP Domain Search option. */
 +	if (packet->options_valid) {
 +		expand_domain_search(packet);
 +	}
  }
  
  /*
 @@ -194,6 +203,171 @@ parse_option_buffer(struct packet *packe
  }
  
  /*
 + * Expand DHCP Domain Search option. The value of this option is
 + * encoded like DNS' list of labels. See:
 + *   RFC 3397
 + *   RFC 1035
 + */
 +void
 +expand_domain_search(struct packet *packet)
 +{
 +	int offset, expanded_len, next_domain_len;
 +	struct option_data *option;
 +	unsigned char *domain_search, *cursor;
 +
 +	if (packet->options[DHO_DOMAIN_SEARCH].data == NULL)
 +		return;
 +
 +	option = &packet->options[DHO_DOMAIN_SEARCH];
 +
 +	/* Compute final expanded length. */
 +	expanded_len = 0;
 +	offset = 0;
 +	while (offset < option->len) {
 +		next_domain_len = find_search_domain_name_len(option, &offset);
 +		if (next_domain_len < 0)
 +			/* The Domain Search option value is invalid. */
 +			return;
 +
 +		/* We add 1 for the space between domain names. */
 +		expanded_len += next_domain_len + 1;
 +	}
 +	if (expanded_len > 0)
 +		/* Remove 1 for the superfluous trailing space. */
 +		--expanded_len;
 +
 +	domain_search = malloc(expanded_len + 1);
 +	if (domain_search == NULL)
 +		error("Can't allocate storage for expanded domain-search\n");
 +
 +	offset = 0;
 +	cursor = domain_search;
 +	while (offset < option->len) {
 +		expand_search_domain_name(option, &offset, &cursor);
 +		cursor[0] = ' ';
 +		cursor++;
 +	}
 +	domain_search[expanded_len] = '\0';
 +
 +	free(option->data);
 +	option->len = expanded_len;
 +	option->data = domain_search;
 +}
 +
 +int
 +find_search_domain_name_len(struct option_data *option, int *offset)
 +{
 +	int domain_name_len, i, label_len, pointer, pointed_len;
 +
 +	domain_name_len = 0;
 +
 +	i = *offset;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			return (domain_name_len);
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			if (i + 1 >= option->len) {
 +				/* The pointer is truncated. */
 +				warning("Truncated pointer in DHCP Domain "
 +				    "Search option.");
 +				return (-1);
 +			}
 +
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +			if (pointer >= *offset) {
 +				/*
 +				 * The pointer must indicates a prior
 +				 * occurance.
 +				 */
 +				warning("Invalid forward pointer in DHCP "
 +				    "Domain Search option compression.");
 +				return (-1);
 +			}
 +
 +			pointed_len = find_search_domain_name_len(option,
 +			    &pointer);
 +			domain_name_len += pointed_len;
 +
 +			*offset = i + 2;
 +			return (domain_name_len);
 +		}
 +
 +		if (i + label_len >= option->len) {
 +			warning("Truncated label in DHCP Domain Search "
 +			    "option.");
 +			return (-1);
 +		}
 +
 +		/*
 +		 * Update the domain name length with the length of the
 +		 * current label, plus a trailing dot ('.').
 +		 */
 +		domain_name_len += label_len + 1;
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +	}
 +
 +	warning("Truncated DHCP Domain Search option.");
 +
 +	return (-1);
 +}
 +
 +void
 +expand_search_domain_name(struct option_data *option, int *offset,
 +    unsigned char **domain_search)
 +{
 +	int i, label_len, pointer;
 +	unsigned char *cursor;
 +
 +	/*
 +	 * This is the same loop than the function above
 +	 * (find_search_domain_name_len). Therefore, we remove checks,
 +	 * they're already done. Here, we just make the copy.
 +	 */
 +	i = *offset;
 +	cursor = *domain_search;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			*domain_search = cursor;
 +			return;
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +
 +			expand_search_domain_name(option, &pointer, &cursor);
 +
 +			*offset = i + 2;
 +			*domain_search = cursor;
 +			return;
 +		}
 +
 +		/* Copy the label found. */
 +		memcpy(cursor, option->data + i + 1, label_len);
 +		cursor[label_len] = '.';
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +		cursor += label_len + 1;
 +	}
 +}
 +
 +/*
   * cons options into a big buffer, and then split them out into the
   * three separate buffers if needed.  This allows us to cons up a set of
   * vendor options using the same routine.
 
 Modified: stable/8/sbin/dhclient/tables.c
 ==============================================================================
 --- stable/8/sbin/dhclient/tables.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/tables.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -184,7 +184,7 @@ struct option dhcp_options[256] = {
  	{ "option-116", "X",				&dhcp_universe, 116 },
  	{ "option-117", "X",				&dhcp_universe, 117 },
  	{ "option-118", "X",				&dhcp_universe, 118 },
 -	{ "option-119", "X",				&dhcp_universe, 119 },
 +	{ "domain-search", "t",				&dhcp_universe, 119 },
  	{ "option-120", "X",				&dhcp_universe, 120 },
  	{ "classless-routes", "BA",			&dhcp_universe, 121 },
  	{ "option-122", "X",				&dhcp_universe, 122 },
 @@ -400,12 +400,13 @@ unsigned char dhcp_option_default_priori
  	DHO_IRC_SERVER,
  	DHO_STREETTALK_SERVER,
  	DHO_STREETTALK_DA_SERVER,
 +	DHO_DOMAIN_SEARCH,
  
  	/* Presently-undefined options... */
  	62, 63, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
  	106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
 -	118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
 +	118,      120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
  	131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
  	143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
  	155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
 
 Modified: stable/8/tools/regression/sbin/Makefile
 ==============================================================================
 --- stable/8/tools/regression/sbin/Makefile	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/tools/regression/sbin/Makefile	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -1,5 +1,5 @@
  # $FreeBSD$
  
 -SUBDIR=	growfs
 +SUBDIR=	dhclient growfs
  
  .include <bsd.subdir.mk>
 
 Modified: stable/8/tools/regression/sbin/dhclient/fake.c
 ==============================================================================
 --- head/tools/regression/sbin/dhclient/fake.c	Sun Dec  4 14:44:31 2011	(r228259)
 +++ stable/8/tools/regression/sbin/dhclient/fake.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -32,7 +32,11 @@ warning(char *fmt, ...)
  	va_end(ap);
  	fprintf(stderr, "\n");
  
 -	return ret;
 +	/*
 +	 * The original warning() would return "ret" here. We do this to
 +	 * check warnings explicitely.
 +	 */
 +	longjmp(env, 1);
  }
  
  int
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/163431: commit references a PR
Date: Thu, 26 Jan 2012 22:01:28 +0000 (UTC)

 Author: dumbbell
 Date: Thu Jan 26 22:01:05 2012
 New Revision: 230603
 URL: http://svn.freebsd.org/changeset/base/230603
 
 Log:
   MFC r228259:
   Support domain-search in dhclient(8)
   
   The "domain-search" option (option 119) allows a DHCP server to publish
   a list of implicit domain suffixes used during name lookup. This option
   is described in RFC 3397.
   
   For instance, if the domain-search option says:
       ".example.org .example.com"
   and one wants to resolve "foobar", the resolver will try:
       1. "foobar.example.org"
       2. "foobar.example.com"
   
   The file /etc/resolv.conf is updated with a "search" directive if the
   DHCP server provides "domain-search".
   
   A regression test suite is included in this patch under
   tools/regression/sbin/dhclient.
   
   PR:		bin/151940
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229000:
   Invalid Domain Search option isn't considered as a fatal error
   
   In the original Domain Search option patch, an invalid option value
   would cause the whole lease to be rejected. However, DHCP servers who
   emit such an invalid value are more common than I thought. With this new
   patch, just the option is rejected, not the entire lease.
   
   PR:		bin/163431
   Submitted by:	Fabian Keil <fk@fabiankeil.de> (earlier version)
   Reviewed by:	Fabian Keil <fk@fabiankeil.de>
   Sponsored by:	Yakaz (http://www.yakaz.com)
   
   MFC r229001:
   Adapt testsuite following change in Domain Search error handling
   
   In this testsuite, warning() and error() have the same behaviour.
   
   PR:		bin/163431
   Sponsored by:	Yakaz (http://www.yakaz.com)
 
 Added:
   stable/8/tools/regression/sbin/dhclient/
      - copied from r228259, head/tools/regression/sbin/dhclient/
 Modified:
   stable/8/sbin/dhclient/clparse.c
   stable/8/sbin/dhclient/dhclient-script
   stable/8/sbin/dhclient/dhclient.c
   stable/8/sbin/dhclient/dhcp-options.5
   stable/8/sbin/dhclient/dhcp.h
   stable/8/sbin/dhclient/options.c
   stable/8/sbin/dhclient/tables.c
   stable/8/tools/regression/sbin/Makefile
   stable/8/tools/regression/sbin/dhclient/fake.c
 Directory Properties:
   stable/8/sbin/dhclient/   (props changed)
   stable/8/tools/   (props changed)
 
 Modified: stable/8/sbin/dhclient/clparse.c
 ==============================================================================
 --- stable/8/sbin/dhclient/clparse.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/clparse.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -100,6 +100,8 @@ read_client_conf(void)
  	    DHO_DOMAIN_NAME_SERVERS;
  	top_level_config.requested_options
  	    [top_level_config.requested_option_count++] = DHO_HOST_NAME;
 +	top_level_config.requested_options
 +	    [top_level_config.requested_option_count++] = DHO_DOMAIN_SEARCH;
  
  	if ((cfile = fopen(path_dhclient_conf, "r")) != NULL) {
  		do {
 
 Modified: stable/8/sbin/dhclient/dhclient-script
 ==============================================================================
 --- stable/8/sbin/dhclient/dhclient-script	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhclient-script	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -201,7 +201,9 @@ add_new_resolv_conf() {
  	local tmpres=/var/run/resolv.conf.${interface}
  	rm -f $tmpres
  
 -	if [ -n "$new_domain_name" ]; then
 +	if [ -n "$new_domain_search" ]; then
 +		echo "search $new_domain_search" >>$tmpres
 +	elif [ -n "$new_domain_name" ]; then
  		echo "search $new_domain_name" >>$tmpres
  	fi
  
 
 Modified: stable/8/sbin/dhclient/dhclient.c
 ==============================================================================
 --- stable/8/sbin/dhclient/dhclient.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhclient.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -2368,6 +2368,7 @@ check_option(struct client_lease *l, int
  		}
  		return (1);
  	case DHO_DOMAIN_NAME:
 +	case DHO_DOMAIN_SEARCH:
  		if (!res_hnok(sbuf)) {
  			if (!check_search(sbuf)) {
  				warning("Bogus domain search list %d: %s (%s)",
 
 Modified: stable/8/sbin/dhclient/dhcp-options.5
 ==============================================================================
 --- stable/8/sbin/dhclient/dhcp-options.5	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhcp-options.5	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -265,6 +265,10 @@ character set.
  .It Ic option domain-name Ar string ;
  This option specifies the domain name that the client should use when
  resolving hostnames via the Domain Name System.
 +.It Ic option domain-search Ar string ;
 +This option specifies a list of domain names that the client should use
 +when resolving hostnames via the Domain Name System. This option is
 +defined in RFC 3397.
  .It Ic option swap-server Ar ip-address ;
  This specifies the IP address of the client's swap server.
  .It Ic option root-path Ar string ;
 
 Modified: stable/8/sbin/dhclient/dhcp.h
 ==============================================================================
 --- stable/8/sbin/dhclient/dhcp.h	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/dhcp.h	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -169,6 +169,7 @@ struct dhcp_packet {
  #define	DHO_STREETTALK_SERVER		75
  #define	DHO_STREETTALK_DA_SERVER	76
  #define DHO_DHCP_USER_CLASS_ID		77
 +#define	DHO_DOMAIN_SEARCH		119
  #define DHO_CLASSLESS_ROUTES		121
  #define DHO_END				255
  
 
 Modified: stable/8/sbin/dhclient/options.c
 ==============================================================================
 --- stable/8/sbin/dhclient/options.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/options.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -55,6 +55,10 @@ void	parse_options(struct packet *);
  void	parse_option_buffer(struct packet *, unsigned char *, int);
  int	store_options(unsigned char *, int, struct tree_cache **,
  	    unsigned char *, int, int, int, int);
 +void	expand_domain_search(struct packet *packet);
 +int	find_search_domain_name_len(struct option_data *option, int *offset);
 +void	expand_search_domain_name(struct option_data *option, int *offset,
 +	    unsigned char **domain_search);
  
  
  /*
 @@ -94,6 +98,11 @@ parse_options(struct packet *packet)
  			    (unsigned char *)packet->raw->sname,
  			    sizeof(packet->raw->sname));
  	}
 +
 +	/* Expand DHCP Domain Search option. */
 +	if (packet->options_valid) {
 +		expand_domain_search(packet);
 +	}
  }
  
  /*
 @@ -194,6 +203,171 @@ parse_option_buffer(struct packet *packe
  }
  
  /*
 + * Expand DHCP Domain Search option. The value of this option is
 + * encoded like DNS' list of labels. See:
 + *   RFC 3397
 + *   RFC 1035
 + */
 +void
 +expand_domain_search(struct packet *packet)
 +{
 +	int offset, expanded_len, next_domain_len;
 +	struct option_data *option;
 +	unsigned char *domain_search, *cursor;
 +
 +	if (packet->options[DHO_DOMAIN_SEARCH].data == NULL)
 +		return;
 +
 +	option = &packet->options[DHO_DOMAIN_SEARCH];
 +
 +	/* Compute final expanded length. */
 +	expanded_len = 0;
 +	offset = 0;
 +	while (offset < option->len) {
 +		next_domain_len = find_search_domain_name_len(option, &offset);
 +		if (next_domain_len < 0)
 +			/* The Domain Search option value is invalid. */
 +			return;
 +
 +		/* We add 1 for the space between domain names. */
 +		expanded_len += next_domain_len + 1;
 +	}
 +	if (expanded_len > 0)
 +		/* Remove 1 for the superfluous trailing space. */
 +		--expanded_len;
 +
 +	domain_search = malloc(expanded_len + 1);
 +	if (domain_search == NULL)
 +		error("Can't allocate storage for expanded domain-search\n");
 +
 +	offset = 0;
 +	cursor = domain_search;
 +	while (offset < option->len) {
 +		expand_search_domain_name(option, &offset, &cursor);
 +		cursor[0] = ' ';
 +		cursor++;
 +	}
 +	domain_search[expanded_len] = '\0';
 +
 +	free(option->data);
 +	option->len = expanded_len;
 +	option->data = domain_search;
 +}
 +
 +int
 +find_search_domain_name_len(struct option_data *option, int *offset)
 +{
 +	int domain_name_len, i, label_len, pointer, pointed_len;
 +
 +	domain_name_len = 0;
 +
 +	i = *offset;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			return (domain_name_len);
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			if (i + 1 >= option->len) {
 +				/* The pointer is truncated. */
 +				warning("Truncated pointer in DHCP Domain "
 +				    "Search option.");
 +				return (-1);
 +			}
 +
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +			if (pointer >= *offset) {
 +				/*
 +				 * The pointer must indicates a prior
 +				 * occurance.
 +				 */
 +				warning("Invalid forward pointer in DHCP "
 +				    "Domain Search option compression.");
 +				return (-1);
 +			}
 +
 +			pointed_len = find_search_domain_name_len(option,
 +			    &pointer);
 +			domain_name_len += pointed_len;
 +
 +			*offset = i + 2;
 +			return (domain_name_len);
 +		}
 +
 +		if (i + label_len >= option->len) {
 +			warning("Truncated label in DHCP Domain Search "
 +			    "option.");
 +			return (-1);
 +		}
 +
 +		/*
 +		 * Update the domain name length with the length of the
 +		 * current label, plus a trailing dot ('.').
 +		 */
 +		domain_name_len += label_len + 1;
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +	}
 +
 +	warning("Truncated DHCP Domain Search option.");
 +
 +	return (-1);
 +}
 +
 +void
 +expand_search_domain_name(struct option_data *option, int *offset,
 +    unsigned char **domain_search)
 +{
 +	int i, label_len, pointer;
 +	unsigned char *cursor;
 +
 +	/*
 +	 * This is the same loop than the function above
 +	 * (find_search_domain_name_len). Therefore, we remove checks,
 +	 * they're already done. Here, we just make the copy.
 +	 */
 +	i = *offset;
 +	cursor = *domain_search;
 +	while (i < option->len) {
 +		label_len = option->data[i];
 +		if (label_len == 0) {
 +			/*
 +			 * A zero-length label marks the end of this
 +			 * domain name.
 +			 */
 +			*offset = i + 1;
 +			*domain_search = cursor;
 +			return;
 +		} else if (label_len & 0xC0) {
 +			/* This is a pointer to another list of labels. */
 +			pointer = ((label_len & ~(0xC0)) << 8) +
 +			    option->data[i + 1];
 +
 +			expand_search_domain_name(option, &pointer, &cursor);
 +
 +			*offset = i + 2;
 +			*domain_search = cursor;
 +			return;
 +		}
 +
 +		/* Copy the label found. */
 +		memcpy(cursor, option->data + i + 1, label_len);
 +		cursor[label_len] = '.';
 +
 +		/* Move cursor. */
 +		i += label_len + 1;
 +		cursor += label_len + 1;
 +	}
 +}
 +
 +/*
   * cons options into a big buffer, and then split them out into the
   * three separate buffers if needed.  This allows us to cons up a set of
   * vendor options using the same routine.
 
 Modified: stable/8/sbin/dhclient/tables.c
 ==============================================================================
 --- stable/8/sbin/dhclient/tables.c	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/sbin/dhclient/tables.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -184,7 +184,7 @@ struct option dhcp_options[256] = {
  	{ "option-116", "X",				&dhcp_universe, 116 },
  	{ "option-117", "X",				&dhcp_universe, 117 },
  	{ "option-118", "X",				&dhcp_universe, 118 },
 -	{ "option-119", "X",				&dhcp_universe, 119 },
 +	{ "domain-search", "t",				&dhcp_universe, 119 },
  	{ "option-120", "X",				&dhcp_universe, 120 },
  	{ "classless-routes", "BA",			&dhcp_universe, 121 },
  	{ "option-122", "X",				&dhcp_universe, 122 },
 @@ -400,12 +400,13 @@ unsigned char dhcp_option_default_priori
  	DHO_IRC_SERVER,
  	DHO_STREETTALK_SERVER,
  	DHO_STREETTALK_DA_SERVER,
 +	DHO_DOMAIN_SEARCH,
  
  	/* Presently-undefined options... */
  	62, 63, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91,
  	92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105,
  	106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117,
 -	118, 119, 120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
 +	118,      120, 122, 123, 124, 125, 126, 127, 128, 129, 130,
  	131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
  	143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154,
  	155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
 
 Modified: stable/8/tools/regression/sbin/Makefile
 ==============================================================================
 --- stable/8/tools/regression/sbin/Makefile	Thu Jan 26 21:43:11 2012	(r230602)
 +++ stable/8/tools/regression/sbin/Makefile	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -1,5 +1,5 @@
  # $FreeBSD$
  
 -SUBDIR=	growfs
 +SUBDIR=	dhclient growfs
  
  .include <bsd.subdir.mk>
 
 Modified: stable/8/tools/regression/sbin/dhclient/fake.c
 ==============================================================================
 --- head/tools/regression/sbin/dhclient/fake.c	Sun Dec  4 14:44:31 2011	(r228259)
 +++ stable/8/tools/regression/sbin/dhclient/fake.c	Thu Jan 26 22:01:05 2012	(r230603)
 @@ -32,7 +32,11 @@ warning(char *fmt, ...)
  	va_end(ap);
  	fprintf(stderr, "\n");
  
 -	return ret;
 +	/*
 +	 * The original warning() would return "ret" here. We do this to
 +	 * check warnings explicitely.
 +	 */
 +	longjmp(env, 1);
  }
  
  int
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
