]> git.pld-linux.org Git - packages/dhcp.git/commitdiff
- updated to 4.4.3, more patches from Fedora auto/th/dhcp-4.4.3-2
authorMarcin Krol <hawk@tld-linux.org>
Sun, 3 Apr 2022 17:56:37 +0000 (17:56 +0000)
committerMarcin Krol <hawk@tld-linux.org>
Sun, 3 Apr 2022 17:56:37 +0000 (17:56 +0000)
29 files changed:
bind-detect-time-changes.patch [new file with mode: 0644]
bind-system-getaddrinfo.patch [new file with mode: 0644]
dhcp-CLOEXEC.patch [new file with mode: 0644]
dhcp-add-guid-duid-to-logs.patch [new file with mode: 0644]
dhcp-capabilities.patch [new file with mode: 0644]
dhcp-client-request-release-bind-iface.patch [new file with mode: 0644]
dhcp-confparse.patch [new file with mode: 0644]
dhcp-default-requested-options.patch
dhcp-detect-time-changes.patch [new file with mode: 0644]
dhcp-duid_uuid.patch [new file with mode: 0644]
dhcp-errwarn-message.patch
dhcp-extravars.patch
dhcp-garbage-in-format-string-error.patch [new file with mode: 0644]
dhcp-handle-null-timouet.patch [new file with mode: 0644]
dhcp-hwaddress.patch [new file with mode: 0644]
dhcp-link-local-address.patch [new file with mode: 0644]
dhcp-lpf-ib.patch [new file with mode: 0644]
dhcp-manpages.patch
dhcp-no-subnet-error2info.patch [new file with mode: 0644]
dhcp-option97-pxe-client-id.patch [new file with mode: 0644]
dhcp-options.patch
dhcp-paths.patch
dhcp-ppp.patch [new file with mode: 0644]
dhcp-release-by-ifup.patch
dhcp-rfc3442-classless-static-routes.patch [new file with mode: 0644]
dhcp-stateless-duid-llt.patch [new file with mode: 0644]
dhcp-unicast-bootp.patch
dhcp.spec
systemd-notify.patch

diff --git a/bind-detect-time-changes.patch b/bind-detect-time-changes.patch
new file mode 100644 (file)
index 0000000..5a26a6f
--- /dev/null
@@ -0,0 +1,196 @@
+From 8e49f4b460ad20890c63a385c17d3e5decd45a82 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Oct 2019 16:23:24 +0200
+Subject: [PATCH 25/28] bind: Detect system time changes
+
+---
+ .../bind-9.11.36/lib/isc/include/isc/result.h |  4 +-
+ bind/bind-9.11.36/lib/isc/include/isc/util.h  |  4 ++
+ bind/bind-9.11.36/lib/isc/result.c            |  2 +
+ bind/bind-9.11.36/lib/isc/unix/app.c          | 41 +++++++++++++++++--
+ .../lib/isc/unix/include/isc/time.h           | 20 +++++++++
+ bind/bind-9.11.36/lib/isc/unix/time.c         | 22 ++++++++++
+ 6 files changed, 89 insertions(+), 4 deletions(-)
+
+diff --git a/bind/bind-9.11.36/lib/isc/include/isc/result.h b/bind/bind-9.11.36/lib/isc/include/isc/result.h
+index 916641f..51c2468 100644
+--- a/bind/bind-9.11.36/lib/isc/include/isc/result.h
++++ b/bind/bind-9.11.36/lib/isc/include/isc/result.h
+@@ -89,7 +89,9 @@
+ #define ISC_R_DISCFULL                        67      /*%< disc full */
+ #define ISC_R_DEFAULT                 68      /*%< default */
+ #define ISC_R_IPV4PREFIX              69      /*%< IPv4 prefix */
+-#define ISC_R_NRESULTS                        70
++#define ISC_R_TIMESHIFTED               70      /*%< system time changed */
++/*% Not a result code: the number of results. */
++#define ISC_R_NRESULTS                        71
+ ISC_LANG_BEGINDECLS
+diff --git a/bind/bind-9.11.36/lib/isc/include/isc/util.h b/bind/bind-9.11.36/lib/isc/include/isc/util.h
+index 9111c2a..20a05b4 100644
+--- a/bind/bind-9.11.36/lib/isc/include/isc/util.h
++++ b/bind/bind-9.11.36/lib/isc/include/isc/util.h
+@@ -325,6 +325,10 @@ extern void mock_assert(const int result, const char* const expression,
+  * Time
+  */
+ #define TIME_NOW(tp)  RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
++#ifdef CLOCK_BOOTTIME
++#define TIME_MONOTONIC(tp)    RUNTIME_CHECK(isc_time_boottime((tp)) == ISC_R_SUCCESS)
++#endif
++
+ /*%
+  * Alignment
+diff --git a/bind/bind-9.11.36/lib/isc/result.c b/bind/bind-9.11.36/lib/isc/result.c
+index 887b08c..2106a3a 100644
+--- a/bind/bind-9.11.36/lib/isc/result.c
++++ b/bind/bind-9.11.36/lib/isc/result.c
+@@ -105,6 +105,7 @@ static const char *description[ISC_R_NRESULTS] = {
+       "disc full",                            /*%< 67 */
+       "default",                              /*%< 68 */
+       "IPv4 prefix",                          /*%< 69 */
++        "time changed",                         /*%< 70 */
+ };
+ static const char *identifier[ISC_R_NRESULTS] = {
+@@ -178,6 +179,7 @@ static const char *identifier[ISC_R_NRESULTS] = {
+       "ISC_R_DISCFULL",
+       "ISC_R_DEFAULT",
+       "ISC_R_IPV4PREFIX",
++        "ISC_R_TIMESHIFTED",
+ };
+ #define ISC_RESULT_RESULTSET                  2
+diff --git a/bind/bind-9.11.36/lib/isc/unix/app.c b/bind/bind-9.11.36/lib/isc/unix/app.c
+index 8189c63..4aabaa4 100644
+--- a/bind/bind-9.11.36/lib/isc/unix/app.c
++++ b/bind/bind-9.11.36/lib/isc/unix/app.c
+@@ -442,15 +442,51 @@ isc__app_ctxonrun(isc_appctx_t *ctx0, isc_mem_t *mctx, isc_task_t *task,
+ static isc_result_t
+ evloop(isc__appctx_t *ctx) {
+       isc_result_t result;
++        isc_time_t now;
++#ifdef CLOCK_BOOTTIME
++        isc_time_t monotonic;
++        uint64_t diff  = 0;
++#else
++        isc_time_t prev;
++        TIME_NOW(&prev);
++#endif
++
++
++
+       while (!ctx->want_shutdown) {
+               int n;
+-              isc_time_t when, now;
++              isc_time_t when;
++                
+               struct timeval tv, *tvp;
+               isc_socketwait_t *swait;
+               bool readytasks;
+               bool call_timer_dispatch = false;
++                uint64_t us; 
++
++#ifdef CLOCK_BOOTTIME
++                // TBD macros for following three lines
++                TIME_NOW(&now);
++                TIME_MONOTONIC(&monotonic);
++                INSIST(now.seconds > monotonic.seconds)
++                us = isc_time_microdiff (&now, &monotonic);
++                if (us < diff){ 
++                  us = diff - us;
++                  if (us > 1000000){ // ignoring shifts less than one second
++                    return ISC_R_TIMESHIFTED;
++                  };
++                  diff = isc_time_microdiff (&now, &monotonic);
++                } else {
++                  diff = isc_time_microdiff (&now, &monotonic);
++                  // not implemented
++                }
++#else
++                TIME_NOW(&now);
++                if (isc_time_compare (&now, &prev) < 0)
++                  return ISC_R_TIMESHIFTED;
++                TIME_NOW(&prev);
++#endif                
+               /*
+                * Check the reload (or suspend) case first for exiting the
+                * loop as fast as possible in case:
+@@ -475,9 +511,8 @@ evloop(isc__appctx_t *ctx) {
+                       if (result != ISC_R_SUCCESS)
+                               tvp = NULL;
+                       else {
+-                              uint64_t us;
+-
+                               TIME_NOW(&now);
++
+                               us = isc_time_microdiff(&when, &now);
+                               if (us == 0)
+                                       call_timer_dispatch = true;
+diff --git a/bind/bind-9.11.36/lib/isc/unix/include/isc/time.h b/bind/bind-9.11.36/lib/isc/unix/include/isc/time.h
+index 03512c1..99e0dfa 100644
+--- a/bind/bind-9.11.36/lib/isc/unix/include/isc/time.h
++++ b/bind/bind-9.11.36/lib/isc/unix/include/isc/time.h
+@@ -132,6 +132,26 @@ isc_time_isepoch(const isc_time_t *t);
+  *\li 't' is a valid pointer.
+  */
++#ifdef CLOCK_BOOTTIME
++isc_result_t
++isc_time_boottime(isc_time_t *t);
++/*%<
++ * Set 't' to monotonic time from previous boot
++ * it's not affected by system time change. It also
++ * includes the time system was suspended
++ *
++ * Requires:
++ *\li 't' is a valid pointer.
++ *
++ * Returns:
++ *
++ *\li Success
++ *\li Unexpected error
++ *            Getting the time from the system failed.
++ */
++#endif /* CLOCK_BOOTTIME */
++ 
++
+ isc_result_t
+ isc_time_now(isc_time_t *t);
+ /*%<
+diff --git a/bind/bind-9.11.36/lib/isc/unix/time.c b/bind/bind-9.11.36/lib/isc/unix/time.c
+index bcca41b..af6ea7f 100644
+--- a/bind/bind-9.11.36/lib/isc/unix/time.c
++++ b/bind/bind-9.11.36/lib/isc/unix/time.c
+@@ -498,3 +498,25 @@ isc_time_formatISO8601ms(const isc_time_t *t, char *buf, unsigned int len) {
+                        t->nanoseconds / NS_PER_MS);
+       }
+ }
++
++
++#ifdef CLOCK_BOOTTIME
++isc_result_t
++isc_time_boottime(isc_time_t *t) {
++  struct timespec ts;
++  
++  char strbuf[ISC_STRERRORSIZE];
++
++  if (clock_gettime (CLOCK_BOOTTIME, &ts) != 0){
++    isc__strerror(errno, strbuf, sizeof(strbuf));
++    UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
++    return (ISC_R_UNEXPECTED);    
++  }
++
++  t->seconds = ts.tv_sec;
++  t->nanoseconds = ts.tv_nsec;
++
++  return (ISC_R_SUCCESS);
++  
++};
++#endif
+-- 
+2.35.1
+
diff --git a/bind-system-getaddrinfo.patch b/bind-system-getaddrinfo.patch
new file mode 100644 (file)
index 0000000..b86936e
--- /dev/null
@@ -0,0 +1,117 @@
+From 9970114f558927564d9c19be969c3c35db3b0edf Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Jun 2021 06:58:40 +0200
+Subject: [PATCH 28/28] Use system getaddrinfo for dhcp
+
+---
+ .../lib/irs/include/irs/netdb.h.in            | 94 +++++++++++++++++++
+ 1 file changed, 94 insertions(+)
+
+diff --git a/bind/bind-9.11.36/lib/irs/include/irs/netdb.h.in b/bind/bind-9.11.36/lib/irs/include/irs/netdb.h.in
+index 427fef8..74069b5 100644
+--- a/bind/bind-9.11.36/lib/irs/include/irs/netdb.h.in
++++ b/bind/bind-9.11.36/lib/irs/include/irs/netdb.h.in
+@@ -150,6 +150,100 @@ struct addrinfo {
+ #define       NI_NUMERICSERV  0x00000008
+ #define       NI_DGRAM        0x00000010
++/*
++ * Define to map into irs_ namespace.
++ */
++
++#define IRS_NAMESPACE
++
++#ifdef IRS_NAMESPACE
++
++/*
++ * Use our versions not the ones from the C library.
++ */
++
++#ifdef getnameinfo
++#undef getnameinfo
++#endif
++#define getnameinfo irs_getnameinfo
++
++#ifdef getaddrinfo
++#undef getaddrinfo
++#endif
++#define getaddrinfo irs_getaddrinfo
++
++#ifdef freeaddrinfo
++#undef freeaddrinfo
++#endif
++#define freeaddrinfo irs_freeaddrinfo
++
++#ifdef gai_strerror
++#undef gai_strerror
++#endif
++#define gai_strerror irs_gai_strerror
++
++#endif
++
++extern int getaddrinfo (const char *name,
++                      const char *service,
++                      const struct addrinfo *req,
++                      struct addrinfo **pai);
++extern int getnameinfo (const struct sockaddr *sa,
++                      socklen_t salen, char *host,
++                      socklen_t hostlen, char *serv,
++                      socklen_t servlen, int flags);
++extern void freeaddrinfo (struct addrinfo *ai);
++extern const char *gai_strerror (int ecode);
++
++/*
++ * Define to map into irs_ namespace.
++ */
++
++#define IRS_NAMESPACE
++
++#ifdef IRS_NAMESPACE
++
++/*
++ * Use our versions not the ones from the C library.
++ */
++
++#ifdef getnameinfo
++#undef getnameinfo
++#endif
++#define getnameinfo irs_getnameinfo
++
++#ifdef getaddrinfo
++#undef getaddrinfo
++#endif
++#define getaddrinfo irs_getaddrinfo
++
++#ifdef freeaddrinfo
++#undef freeaddrinfo
++#endif
++#define freeaddrinfo irs_freeaddrinfo
++
++#ifdef gai_strerror
++#undef gai_strerror
++#endif
++#define gai_strerror irs_gai_strerror
++
++int
++getaddrinfo(const char *hostname, const char *servname,
++          const struct addrinfo *hints, struct addrinfo **res);
++
++int
++getnameinfo(const struct sockaddr *sa, IRS_GETNAMEINFO_SOCKLEN_T salen,
++          char *host, IRS_GETNAMEINFO_BUFLEN_T hostlen,
++          char *serv, IRS_GETNAMEINFO_BUFLEN_T servlen,
++          IRS_GETNAMEINFO_FLAGS_T flags);
++
++void freeaddrinfo (struct addrinfo *ai);
++
++IRS_GAISTRERROR_RETURN_T
++gai_strerror(int ecode);
++
++#endif
++
+ /*
+  * Tell Emacs to use C mode on this file.
+  * Local variables:
+-- 
+2.35.1
+
diff --git a/dhcp-CLOEXEC.patch b/dhcp-CLOEXEC.patch
new file mode 100644 (file)
index 0000000..46ac860
--- /dev/null
@@ -0,0 +1,366 @@
+From 39ce1ca26128f4a5d018a567157320ba1f68f4ea Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:27:18 +0100
+Subject: [PATCH 08/28] Make sure all open file descriptors are closed-on-exec
+ for SELinux
+
+ISC-bug: #19148
+---
+ client/clparse.c  |  4 ++--
+ client/dhclient.c | 28 ++++++++++++++--------------
+ common/bpf.c      |  2 +-
+ common/dlpi.c     |  2 +-
+ common/nit.c      |  2 +-
+ common/resolv.c   |  2 +-
+ common/upf.c      |  2 +-
+ omapip/trace.c    |  6 +++---
+ relay/dhcrelay.c  | 10 +++++-----
+ server/confpars.c |  2 +-
+ server/db.c       |  4 ++--
+ server/dhcpd.c    | 14 +++++++-------
+ server/ldap.c     |  2 +-
+ 13 files changed, 40 insertions(+), 40 deletions(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index e63ea08..902b523 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
+@@ -291,7 +291,7 @@ int read_client_conf_file (const char *name, struct interface_info *ip,
+       int token;
+       isc_result_t status;
+-      if ((file = open (name, O_RDONLY)) < 0)
++      if ((file = open (name, O_RDONLY | O_CLOEXEC)) < 0)
+               return uerr2isc (errno);
+       cfile = NULL;
+@@ -367,7 +367,7 @@ void read_client_leases ()
+       /* Open the lease file.   If we can't open it, just return -
+          we can safely trust the server to remember our state. */
+-      if ((file = open (path_dhclient_db, O_RDONLY)) < 0)
++      if ((file = open (path_dhclient_db, O_RDONLY | O_CLOEXEC)) < 0)
+               return;
+       cfile = NULL;
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 07679a7..aefc119 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -279,11 +279,11 @@ main(int argc, char **argv) {
+       /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
+          2 (stderr) are open. To do this, we assume that when we
+          open a file the lowest available file descriptor is used. */
+-      fd = open("/dev/null", O_RDWR);
++      fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+       if (fd == 0)
+-              fd = open("/dev/null", O_RDWR);
++              fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+       if (fd == 1)
+-              fd = open("/dev/null", O_RDWR);
++              fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+       if (fd == 2)
+               log_perror = 0; /* No sense logging to /dev/null. */
+       else if (fd != -1)
+@@ -771,7 +771,7 @@ main(int argc, char **argv) {
+               long temp;
+               int e;
+-              if ((pidfd = fopen(path_dhclient_pid, "r")) != NULL) {
++              if ((pidfd = fopen(path_dhclient_pid, "re")) != NULL) {
+                       e = fscanf(pidfd, "%ld\n", &temp);
+                       oldpid = (pid_t)temp;
+@@ -826,7 +826,7 @@ main(int argc, char **argv) {
+                                       strncpy(new_path_dhclient_pid, path_dhclient_pid, pfx);
+                                       sprintf(new_path_dhclient_pid + pfx, "-%s.pid", ip->name);
+-                                      if ((pidfd = fopen(new_path_dhclient_pid, "r")) != NULL) {
++                                      if ((pidfd = fopen(new_path_dhclient_pid, "re")) != NULL) {
+                                               e = fscanf(pidfd, "%ld\n", &temp);
+                                               oldpid = (pid_t)temp;
+@@ -851,7 +851,7 @@ main(int argc, char **argv) {
+               int dhc_running = 0;
+               char procfn[256] = "";
+-              if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
++              if ((pidfp = fopen(path_dhclient_pid, "re")) != NULL) {
+                       if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
+                               snprintf(procfn,256,"/proc/%u",dhcpid);
+                               dhc_running = (access(procfn, F_OK) == 0);
+@@ -4054,7 +4054,7 @@ void rewrite_client_leases ()
+       if (leaseFile != NULL)
+               fclose (leaseFile);
+-      leaseFile = fopen (path_dhclient_db, "w");
++      leaseFile = fopen (path_dhclient_db, "we");
+       if (leaseFile == NULL) {
+               log_error ("can't create %s: %m", path_dhclient_db);
+               return;
+@@ -4249,7 +4249,7 @@ write_duid(struct data_string *duid)
+               return DHCP_R_INVALIDARG;
+       if (leaseFile == NULL) {        /* XXX? */
+-              leaseFile = fopen(path_dhclient_db, "w");
++              leaseFile = fopen(path_dhclient_db, "we");
+               if (leaseFile == NULL) {
+                       log_error("can't create %s: %m", path_dhclient_db);
+                       return ISC_R_IOERROR;
+@@ -4453,7 +4453,7 @@ int write_client_lease (client, lease, rewrite, makesure)
+               return 1;
+       if (leaseFile == NULL) {        /* XXX */
+-              leaseFile = fopen (path_dhclient_db, "w");
++              leaseFile = fopen (path_dhclient_db, "we");
+               if (leaseFile == NULL) {
+                       log_error ("can't create %s: %m", path_dhclient_db);
+                       return 0;
+@@ -5039,9 +5039,9 @@ void detach ()
+       (void) close(2);
+       /* Reopen them on /dev/null. */
+-      (void) open("/dev/null", O_RDWR);
+-      (void) open("/dev/null", O_RDWR);
+-      (void) open("/dev/null", O_RDWR);
++      (void) open("/dev/null", O_RDWR | O_CLOEXEC);
++      (void) open("/dev/null", O_RDWR | O_CLOEXEC);
++      (void) open("/dev/null", O_RDWR | O_CLOEXEC);
+       write_client_pid_file ();
+@@ -5059,14 +5059,14 @@ void write_client_pid_file ()
+               return;
+       }
+-      pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
++      pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
+       if (pfdesc < 0) {
+               log_error ("Can't create %s: %m", path_dhclient_pid);
+               return;
+       }
+-      pf = fdopen (pfdesc, "w");
++      pf = fdopen (pfdesc, "we");
+       if (!pf) {
+               close(pfdesc);
+               log_error ("Can't fdopen %s: %m", path_dhclient_pid);
+diff --git a/common/bpf.c b/common/bpf.c
+index 0bffcbf..d2a0549 100644
+--- a/common/bpf.c
++++ b/common/bpf.c
+@@ -94,7 +94,7 @@ int if_register_bpf (info)
+       for (b = 0; 1; b++) {
+               /* %Audit% 31 bytes max. %2004.06.17,Safe% */
+               sprintf(filename, BPF_FORMAT, b);
+-              sock = open (filename, O_RDWR, 0);
++              sock = open (filename, O_RDWR | O_CLOEXEC, 0);
+               if (sock < 0) {
+                       if (errno == EBUSY) {
+                               continue;
+diff --git a/common/dlpi.c b/common/dlpi.c
+index f2332c0..bf6e21f 100644
+--- a/common/dlpi.c
++++ b/common/dlpi.c
+@@ -817,7 +817,7 @@ dlpiopen(const char *ifname) {
+       }
+       *dp = '\0';
+-      return open (devname, O_RDWR, 0);
++      return open (devname, O_RDWR | O_CLOEXEC, 0);
+ }
+ /*
+diff --git a/common/nit.c b/common/nit.c
+index ba62488..4ebfa4a 100644
+--- a/common/nit.c
++++ b/common/nit.c
+@@ -75,7 +75,7 @@ int if_register_nit (info)
+       struct strioctl sio;
+       /* Open a NIT device */
+-      sock = open ("/dev/nit", O_RDWR);
++      sock = open ("/dev/nit", O_RDWR | O_CLOEXEC);
+       if (sock < 0)
+               log_fatal ("Can't open NIT device for %s: %m", info -> name);
+diff --git a/common/resolv.c b/common/resolv.c
+index 5fd683f..3535f3e 100644
+--- a/common/resolv.c
++++ b/common/resolv.c
+@@ -43,7 +43,7 @@ void read_resolv_conf (parse_time)
+       struct domain_search_list *dp, *dl, *nd;
+       isc_result_t status;
+-      if ((file = open (path_resolv_conf, O_RDONLY)) < 0) {
++      if ((file = open (path_resolv_conf, O_RDONLY | O_CLOEXEC)) < 0) {
+               log_error ("Can't open %s: %m", path_resolv_conf);
+               return;
+       }
+diff --git a/common/upf.c b/common/upf.c
+index 37e5cb2..b7c0649 100644
+--- a/common/upf.c
++++ b/common/upf.c
+@@ -71,7 +71,7 @@ int if_register_upf (info)
+               /* %Audit% Cannot exceed 36 bytes. %2004.06.17,Safe% */
+               sprintf(filename, "/dev/pf/pfilt%d", b);
+-              sock = open (filename, O_RDWR, 0);
++              sock = open (filename, O_RDWR | O_CLOEXEC, 0);
+               if (sock < 0) {
+                       if (errno == EBUSY) {
+                               continue;
+diff --git a/omapip/trace.c b/omapip/trace.c
+index dc9185f..a605d18 100644
+--- a/omapip/trace.c
++++ b/omapip/trace.c
+@@ -136,10 +136,10 @@ isc_result_t trace_begin (const char *filename,
+               return DHCP_R_INVALIDARG;
+       }
+-      traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL, 0600);
++      traceoutfile = open (filename, O_CREAT | O_WRONLY | O_EXCL | O_CLOEXEC, 0600);
+       if (traceoutfile < 0 && errno == EEXIST) {
+               log_error ("WARNING: Overwriting trace file \"%s\"", filename);
+-              traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC,
++              traceoutfile = open (filename, O_WRONLY | O_EXCL | O_TRUNC | O_CLOEXEC,
+                                    0600);
+       }
+@@ -427,7 +427,7 @@ void trace_file_replay (const char *filename)
+       isc_result_t result;
+       int len;
+-      traceinfile = fopen (filename, "r");
++      traceinfile = fopen (filename, "re");
+       if (!traceinfile) {
+               log_error("Can't open tracefile %s: %m", filename);
+               return;
+diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
+index 946ef1b..a7b1286 100644
+--- a/relay/dhcrelay.c
++++ b/relay/dhcrelay.c
+@@ -305,11 +305,11 @@ main(int argc, char **argv) {
+       /* Make sure that file descriptors 0(stdin), 1,(stdout), and
+          2(stderr) are open. To do this, we assume that when we
+          open a file the lowest available file descriptor is used. */
+-      fd = open("/dev/null", O_RDWR);
++      fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+       if (fd == 0)
+-              fd = open("/dev/null", O_RDWR);
++              fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+       if (fd == 1)
+-              fd = open("/dev/null", O_RDWR);
++              fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+       if (fd == 2)
+               log_perror = 0; /* No sense logging to /dev/null. */
+       else if (fd != -1)
+@@ -800,13 +800,13 @@ main(int argc, char **argv) {
+               /* Create the pid file. */
+               if (no_pid_file == ISC_FALSE) {
+                       pfdesc = open(path_dhcrelay_pid,
+-                                    O_CREAT | O_TRUNC | O_WRONLY, 0644);
++                                    O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC, 0644);
+                       if (pfdesc < 0) {
+                               log_error("Can't create %s: %m",
+                                         path_dhcrelay_pid);
+                       } else {
+-                              pf = fdopen(pfdesc, "w");
++                              pf = fdopen(pfdesc, "we");
+                               if (!pf)
+                                       log_error("Can't fdopen %s: %m",
+                                                 path_dhcrelay_pid);
+diff --git a/server/confpars.c b/server/confpars.c
+index 103af1e..5a6396b 100644
+--- a/server/confpars.c
++++ b/server/confpars.c
+@@ -118,7 +118,7 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+       }
+ #endif
+-      if ((file = open (filename, O_RDONLY)) < 0) {
++      if ((file = open (filename, O_RDONLY | O_CLOEXEC)) < 0) {
+               if (leasep) {
+                       log_error ("Can't open lease database %s: %m --",
+                                  path_dhcpd_db);
+diff --git a/server/db.c b/server/db.c
+index cecbf6b..4243a92 100644
+--- a/server/db.c
++++ b/server/db.c
+@@ -1154,7 +1154,7 @@ int new_lease_file (int test_mode)
+                    path_dhcpd_db, (int)t) >= sizeof newfname)
+               log_fatal("new_lease_file: lease file path too long");
+-      db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT, 0664);
++      db_fd = open (newfname, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0664);
+       if (db_fd < 0) {
+               log_error ("Can't create new lease file: %m");
+               return 0;
+@@ -1175,7 +1175,7 @@ int new_lease_file (int test_mode)
+       }
+ #endif /* PARANOIA */
+-      if ((new_db_file = fdopen(db_fd, "w")) == NULL) {
++      if ((new_db_file = fdopen(db_fd, "we")) == NULL) {
+               log_error("Can't fdopen new lease file: %m");
+               close(db_fd);
+               goto fdfail;
+diff --git a/server/dhcpd.c b/server/dhcpd.c
+index 3522889..845d0cc 100644
+--- a/server/dhcpd.c
++++ b/server/dhcpd.c
+@@ -300,11 +300,11 @@ main(int argc, char **argv) {
+         /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
+            2 (stderr) are open. To do this, we assume that when we
+            open a file the lowest available file descriptor is used. */
+-        fd = open("/dev/null", O_RDWR);
++        fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+         if (fd == 0)
+-                fd = open("/dev/null", O_RDWR);
++                fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+         if (fd == 1)
+-                fd = open("/dev/null", O_RDWR);
++                fd = open("/dev/null", O_RDWR | O_CLOEXEC);
+         if (fd == 2)
+                 log_perror = 0; /* No sense logging to /dev/null. */
+         else if (fd != -1)
+@@ -975,7 +975,7 @@ main(int argc, char **argv) {
+        * appropriate.
+        */
+       if (no_pid_file == ISC_FALSE) {
+-              i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644);
++              i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0644);
+               if (i >= 0) {
+                       sprintf(pbuf, "%d\n", (int) getpid());
+                       IGNORE_RET(write(i, pbuf, strlen(pbuf)));
+@@ -1028,9 +1028,9 @@ main(int argc, char **argv) {
+                 (void) close(2);
+                 /* Reopen them on /dev/null. */
+-                (void) open("/dev/null", O_RDWR);
+-                (void) open("/dev/null", O_RDWR);
+-                (void) open("/dev/null", O_RDWR);
++                (void) open("/dev/null", O_RDWR | O_CLOEXEC);
++                (void) open("/dev/null", O_RDWR | O_CLOEXEC);
++                (void) open("/dev/null", O_RDWR | O_CLOEXEC);
+                 log_perror = 0; /* No sense logging to /dev/null. */
+                       IGNORE_RET (chdir("/"));
+diff --git a/server/ldap.c b/server/ldap.c
+index e3e48f4..1a68936 100644
+--- a/server/ldap.c
++++ b/server/ldap.c
+@@ -1447,7 +1447,7 @@ ldap_start (void)
+   if (ldap_debug_file != NULL && ldap_debug_fd == -1)
+     {
+-      if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY,
++      if ((ldap_debug_fd = open (ldap_debug_file, O_CREAT | O_TRUNC | O_WRONLY | O_CLOEXEC,
+                                  S_IRUSR | S_IWUSR)) < 0)
+         log_error ("Error opening debug LDAP log file %s: %s", ldap_debug_file,
+                    strerror (errno));
+-- 
+2.35.1
+
diff --git a/dhcp-add-guid-duid-to-logs.patch b/dhcp-add-guid-duid-to-logs.patch
new file mode 100644 (file)
index 0000000..d5596b8
--- /dev/null
@@ -0,0 +1,327 @@
+From 3baf35269555e2223dbd1733cb1c475cb7f2ed7a Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:35:47 +0100
+Subject: [PATCH 15/28] Add GUID/DUID to dhcpd logs (#1064416)
+
+---
+ client/dhclient.c | 70 ++++++++++++++++++++++++++++++++++--------
+ server/dhcp.c     | 78 ++++++++++++++++++++++++++++-------------------
+ 2 files changed, 105 insertions(+), 43 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 48edddf..181f6e1 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -1176,6 +1176,26 @@ main(int argc, char **argv) {
+               }
+       }
++      /* We create a backup seed before rediscovering interfaces in order to
++         have a seed built using all of the available interfaces
++         It's interesting if required interfaces doesn't let us defined
++         a really unique seed due to a lack of valid HW addr later
++         (this is the case with DHCP over IB)
++         We only use the last device as using a sum could broke the
++         uniqueness of the seed among multiple nodes
++       */
++      unsigned backup_seed = 0;
++      for (ip = interfaces; ip; ip = ip -> next) {
++              int junk;
++              if ( ip -> hw_address.hlen <= sizeof seed )
++                continue;
++              memcpy (&junk,
++                      &ip -> hw_address.hbuf [ip -> hw_address.hlen -
++                                              sizeof seed], sizeof seed);
++              backup_seed = junk;
++      }
++
++
+       /* At this point, all the interfaces that the script thinks
+          are relevant should be running, so now we once again call
+          discover_interfaces(), and this time ask it to actually set
+@@ -1204,14 +1224,34 @@ main(int argc, char **argv) {
+                  Not much entropy, but we're booting, so we're not likely to
+                  find anything better. */
++              int seed_flag = 0;
+               for (ip = interfaces; ip; ip = ip->next) {
+                       int junk;
++                      if ( ip -> hw_address.hlen <= sizeof seed )
++                        continue;
+                       memcpy(&junk,
+                              &ip->hw_address.hbuf[ip->hw_address.hlen -
+                                                   sizeof seed], sizeof seed);
+                       seed += junk;
++                      seed_flag = 1;
+               }
+-              seed += cur_time + (unsigned)getpid();
++              if ( seed_flag == 0 ) {
++                      if ( backup_seed != 0 ) {
++                        seed = backup_seed;
++                        log_info ("xid: rand init seed (0x%x) built using all"
++                                  " available interfaces",seed);
++                      }
++                      else {
++                        seed = cur_time^((unsigned) gethostid()) ;
++                        log_info ("xid: warning: no netdev with useable HWADDR found"
++                                  " for seed's uniqueness enforcement");
++                        log_info ("xid: rand init seed (0x%x) built using gethostid",
++                                  seed);
++                      }
++                      /* we only use seed and no current time as a broadcast reply */
++                      /* will certainly be used by the hwaddrless interface */
++              }
++              seed += ((unsigned)(cur_tv.tv_usec * 1000000)) + (unsigned)getpid();
+       }
+       srandom(seed);
+@@ -1869,9 +1909,10 @@ void dhcpack (packet)
+               return;
+       }
+-      log_info ("DHCPACK of %s from %s",
++      log_info ("DHCPACK of %s from %s (xid=0x%x)",
+                 inet_ntoa(packet->raw->yiaddr),
+-                piaddr (packet->client_addr));
++                piaddr (packet -> client_addr),
++                ntohl(client -> xid));
+       /* Check v6only first. */
+       v6only_wait = check_v6only(packet, client);
+@@ -2825,7 +2866,7 @@ void dhcpnak (packet)
+               return;
+       }
+-      log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));
++      log_info ("DHCPNAK from %s (xid=0x%x)", piaddr (packet -> client_addr), ntohl(client -> xid));
+       if (!client -> active) {
+ #if defined (DEBUG)
+@@ -2958,10 +2999,10 @@ void send_discover (cpp)
+                         (long)(client -> interval));
+       } else
+ #endif
+-      log_info ("DHCPDISCOVER on %s to %s port %d interval %ld",
++      log_info ("DHCPDISCOVER on %s to %s port %d interval %ld (xid=0x%x)",
+             client -> name ? client -> name : client -> interface -> name,
+             inet_ntoa (sockaddr_broadcast.sin_addr),
+-            ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval));
++            ntohs (sockaddr_broadcast.sin_port), (long)(client -> interval), ntohl(client -> xid));
+       /* Send out a packet. */
+ #if defined(DHCPv6) && defined(DHCP4o6)
+@@ -3355,10 +3396,12 @@ void send_request (cpp)
+       }
+       strncpy(rip_buf, rip_str, sizeof(rip_buf)-1);
+-      log_info ("DHCPREQUEST for %s on %s to %s port %d", rip_buf,
++      log_info ("DHCPREQUEST for %s on %s to %s port %d (xid=0x%x)",
++                  rip_buf,
+                 client->name ? client->name : client->interface->name,
+                 inet_ntoa(destination.sin_addr),
+-                ntohs (destination.sin_port));
++                ntohs (destination.sin_port),
++                  ntohl(client -> xid));
+ #if defined(DHCPv6) && defined(DHCP4o6)
+       if (dhcpv4_over_dhcpv6) {
+@@ -3415,11 +3458,13 @@ void send_decline (cpp)
+               log_info ("DHCPDECLINE");
+       } else
+ #endif
+-      log_info ("DHCPDECLINE of %s on %s to %s port %d",
++      log_info ("DHCPDECLINE of %s on %s to %s port %d (xid=0x%x)",                  
+                 piaddr(client->requested_address),
+                 (client->name ? client->name : client->interface->name),
+                 inet_ntoa(sockaddr_broadcast.sin_addr),
+-                ntohs(sockaddr_broadcast.sin_port));
++                ntohs(sockaddr_broadcast.sin_port),
++                  ntohl(client -> xid));
++
+       /* Send out a packet. */
+ #if defined(DHCPv6) && defined(DHCP4o6)
+@@ -3478,11 +3523,12 @@ void send_release (cpp)
+               log_info ("DHCPRELEASE");
+       } else
+ #endif
+-      log_info ("DHCPRELEASE of %s on %s to %s port %d",
++      log_info ("DHCPRELEASE of %s on %s to %s port %d (xid=0x%x)",
+                 piaddr(client->active->address),
+                 client->name ? client->name : client->interface->name,
+                 inet_ntoa (destination.sin_addr),
+-                ntohs (destination.sin_port));
++                ntohs (destination.sin_port),
++                  ntohl(client -> xid));
+ #if defined(DHCPv6) && defined(DHCP4o6)
+       if (dhcpv4_over_dhcpv6) {
+diff --git a/server/dhcp.c b/server/dhcp.c
+index ae805a6..8363840 100644
+--- a/server/dhcp.c
++++ b/server/dhcp.c
+@@ -93,6 +93,42 @@ const int dhcp_type_name_max = ((sizeof dhcp_type_names) / sizeof (char *));
+ static TIME leaseTimeCheck(TIME calculated, TIME alternate);
++char *print_client_identifier_from_packet (packet)
++      struct packet *packet;
++{
++      struct option_cache *oc;
++      struct data_string client_identifier;
++      char *ci;
++
++      memset (&client_identifier, 0, sizeof client_identifier);
++
++      oc = lookup_option (&dhcp_universe, packet -> options,
++                      DHO_DHCP_CLIENT_IDENTIFIER);
++      if (oc &&
++          evaluate_option_cache (&client_identifier,
++                                  packet, (struct lease *)0,
++                                  (struct client_state *)0,
++                                  packet -> options,
++                                  (struct option_state *)0,
++                                  &global_scope, oc, MDL)) {
++              ci = print_hw_addr (HTYPE_INFINIBAND, client_identifier.len, client_identifier.data);
++              data_string_forget (&client_identifier, MDL);
++              return ci;
++      } else
++              return "\"no client id\"";
++}
++
++char *print_hw_addr_or_client_id (packet)
++      struct packet *packet;
++{
++      if (packet -> raw -> htype == HTYPE_INFINIBAND)
++              return print_client_identifier_from_packet (packet);
++      else
++              return print_hw_addr (packet -> raw -> htype,
++                                    packet -> raw -> hlen,
++                                    packet -> raw -> chaddr);
++}
++
+ void
+ dhcp (struct packet *packet) {
+       int ms_nulltp = 0;
+@@ -135,9 +171,7 @@ dhcp (struct packet *packet) {
+               log_info("%s from %s via %s: %s", s,
+                        (packet->raw->htype
+-                        ? print_hw_addr(packet->raw->htype,
+-                                        packet->raw->hlen,
+-                                        packet->raw->chaddr)
++                        ? print_hw_addr_or_client_id(packet)
+                         : "<no identifier>"),
+                        packet->raw->giaddr.s_addr
+                        ? inet_ntoa(packet->raw->giaddr)
+@@ -334,9 +368,7 @@ void dhcpdiscover (packet, ms_nulltp)
+ #endif
+       snprintf (msgbuf, sizeof msgbuf, "DHCPDISCOVER from %s %s%s%svia %s",
+                (packet -> raw -> htype
+-                ? print_hw_addr (packet -> raw -> htype,
+-                                 packet -> raw -> hlen,
+-                                 packet -> raw -> chaddr)
++                ? print_hw_addr_or_client_id (packet)
+                 : (lease
+                    ? print_hex_1(lease->uid_len, lease->uid, 60)
+                    : "<no identifier>")),
+@@ -548,9 +580,7 @@ void dhcprequest (packet, ms_nulltp, ip_lease)
+                "DHCPREQUEST for %s%s from %s %s%s%svia %s",
+                piaddr (cip), smbuf,
+                (packet -> raw -> htype
+-                ? print_hw_addr (packet -> raw -> htype,
+-                                 packet -> raw -> hlen,
+-                                 packet -> raw -> chaddr)
++                ? print_hw_addr_or_client_id(packet)
+                 : (lease
+                    ? print_hex_1(lease->uid_len, lease->uid, 60)
+                    : "<no identifier>")),
+@@ -791,9 +821,7 @@ void dhcprelease (packet, ms_nulltp)
+       if ((oc = lookup_option (&dhcp_universe, packet -> options,
+                                DHO_DHCP_REQUESTED_ADDRESS))) {
+               log_info ("DHCPRELEASE from %s specified requested-address.",
+-                    print_hw_addr (packet -> raw -> htype,
+-                                   packet -> raw -> hlen,
+-                                   packet -> raw -> chaddr));
++                    print_hw_addr_or_client_id(packet));
+       }
+       oc = lookup_option (&dhcp_universe, packet -> options,
+@@ -885,9 +913,7 @@ void dhcprelease (packet, ms_nulltp)
+                "DHCPRELEASE of %s from %s %s%s%svia %s (%sfound)",
+                cstr,
+                (packet -> raw -> htype
+-                ? print_hw_addr (packet -> raw -> htype,
+-                                 packet -> raw -> hlen,
+-                                 packet -> raw -> chaddr)
++                ? print_hw_addr_or_client_id(packet)
+                 : (lease
+                    ? print_hex_1(lease->uid_len, lease->uid, 60)
+                    : "<no identifier>")),
+@@ -992,9 +1018,7 @@ void dhcpdecline (packet, ms_nulltp)
+                "DHCPDECLINE of %s from %s %s%s%svia %s",
+                piaddr (cip),
+                (packet -> raw -> htype
+-                ? print_hw_addr (packet -> raw -> htype,
+-                                 packet -> raw -> hlen,
+-                                 packet -> raw -> chaddr)
++                ? print_hw_addr_or_client_id(packet)
+                 : (lease
+                    ? print_hex_1(lease->uid_len, lease->uid, 60)
+                    : "<no identifier>")),
+@@ -1740,8 +1764,7 @@ void dhcpinform (packet, ms_nulltp)
+       /* Report what we're sending. */
+       snprintf(msgbuf, sizeof msgbuf, "DHCPACK to %s (%s) via", piaddr(cip),
+                (packet->raw->htype && packet->raw->hlen) ?
+-                      print_hw_addr(packet->raw->htype, packet->raw->hlen,
+-                                    packet->raw->chaddr) :
++                      print_hw_addr_or_client_id(packet) :
+                       "<no client hardware address>");
+       log_info("%s %s", msgbuf, gip.len ? piaddr(gip) :
+                                           packet->interface->name);
+@@ -1926,9 +1949,7 @@ void nak_lease (packet, cip, network_group)
+ #endif
+       log_info ("DHCPNAK on %s to %s via %s",
+             piaddr (*cip),
+-            print_hw_addr (packet -> raw -> htype,
+-                           packet -> raw -> hlen,
+-                           packet -> raw -> chaddr),
++            print_hw_addr_or_client_id(packet),
+             packet -> raw -> giaddr.s_addr
+             ? inet_ntoa (packet -> raw -> giaddr)
+             : packet -> interface -> name);
+@@ -4044,7 +4065,7 @@ void dhcp_reply (lease)
+                  ? (state -> offer == DHCPACK ? "DHCPACK" : "DHCPOFFER")
+                  : "BOOTREPLY"),
+                 piaddr (lease -> ip_addr),
+-                (lease -> hardware_addr.hlen
++                (lease -> hardware_addr.hlen > 1
+                  ? print_hw_addr (lease -> hardware_addr.hbuf [0],
+                                   lease -> hardware_addr.hlen - 1,
+                                   &lease -> hardware_addr.hbuf [1])
+@@ -4605,10 +4626,7 @@ int find_lease (struct lease **lp,
+                       if (uid_lease) {
+                           if (uid_lease->binding_state == FTS_ACTIVE) {
+                               log_error ("client %s has duplicate%s on %s",
+-                                         (print_hw_addr
+-                                          (packet -> raw -> htype,
+-                                           packet -> raw -> hlen,
+-                                           packet -> raw -> chaddr)),
++                                         (print_hw_addr_or_client_id(packet)),
+                                          " leases",
+                                          (ip_lease -> subnet ->
+                                           shared_network -> name));
+@@ -4775,9 +4793,7 @@ int find_lease (struct lease **lp,
+                       log_error("uid lease %s for client %s is duplicate "
+                                 "on %s",
+                                 piaddr(uid_lease->ip_addr),
+-                                print_hw_addr(packet->raw->htype,
+-                                              packet->raw->hlen,
+-                                              packet->raw->chaddr),
++                                print_hw_addr_or_client_id(packet),
+                                 uid_lease->subnet->shared_network->name);
+                       if (!packet -> raw -> ciaddr.s_addr &&
+-- 
+2.35.1
+
diff --git a/dhcp-capabilities.patch b/dhcp-capabilities.patch
new file mode 100644 (file)
index 0000000..3ac1973
--- /dev/null
@@ -0,0 +1,266 @@
+From 7ea2433d716172f160c9380ed0bb852fafe845a2 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:30:28 +0100
+Subject: [PATCH 11/28] Drop unnecessary capabilities
+
+dhclient (#517649, #546765), dhcpd/dhcrelay (#699713)
+---
+ client/Makefile.am       |  3 ++-
+ client/dhclient-script.8 | 10 ++++++++++
+ client/dhclient.8        | 29 +++++++++++++++++++++++++++++
+ client/dhclient.c        | 24 ++++++++++++++++++++++++
+ configure.ac             | 35 +++++++++++++++++++++++++++++++++++
+ relay/Makefile.am        |  3 ++-
+ relay/dhcrelay.c         | 29 +++++++++++++++++++++++++++++
+ 7 files changed, 131 insertions(+), 2 deletions(-)
+
+diff -urNp -x '*.orig' dhcp-4.4.3.org/client/Makefile.am dhcp-4.4.3/client/Makefile.am
+--- dhcp-4.4.3.org/client/Makefile.am  2022-03-08 09:26:03.000000000 +0000
++++ dhcp-4.4.3/client/Makefile.am      2022-04-03 17:02:38.643517435 +0000
+@@ -17,6 +17,7 @@ dhclient_LDADD = ../common/libdhcp.@A@ .
+                @BINDLIBIRSDIR@/libirs.@A@ \
+                @BINDLIBDNSDIR@/libdns.@A@ \
+                @BINDLIBISCCFGDIR@/libisccfg.@A@ \
+-               @BINDLIBISCDIR@/libisc.@A@
++               @BINDLIBISCDIR@/libisc.@A@ \
++               $(CAPNG_LDADD)
+ man_MANS = dhclient.8 dhclient-script.8 dhclient.conf.5 dhclient.leases.5
+ EXTRA_DIST = $(man_MANS)
+diff -urNp -x '*.orig' dhcp-4.4.3.org/client/dhclient-script.8 dhcp-4.4.3/client/dhclient-script.8
+--- dhcp-4.4.3.org/client/dhclient-script.8    2022-04-03 17:02:38.454517007 +0000
++++ dhcp-4.4.3/client/dhclient-script.8        2022-04-03 17:02:38.643517435 +0000
+@@ -249,6 +249,16 @@ repeatedly initialized to the values pro
+ the other.   Assuming the information provided by both servers is
+ valid, this shouldn't cause any real problems, but it could be
+ confusing.
++.PP
++Normally, if dhclient was compiled with libcap-ng support,
++dhclient drops most capabilities immediately upon startup.
++While more secure, this greatly restricts the additional actions that
++hooks in dhclient-script can take. For example, any daemons that
++dhclient-script starts or restarts will inherit the restricted
++capabilities as well, which may interfere with their correct operation.
++Thus, the
++.BI \-nc
++option can be used to prevent dhclient from dropping capabilities.
+ .SH SEE ALSO
+ dhclient(8), dhcpd(8), dhcrelay(8), dhclient.conf(5) and
+ dhclient.leases(5).
+diff -urNp -x '*.orig' dhcp-4.4.3.org/client/dhclient.8 dhcp-4.4.3/client/dhclient.8
+--- dhcp-4.4.3.org/client/dhclient.8   2022-04-03 17:02:38.455517009 +0000
++++ dhcp-4.4.3/client/dhclient.8       2022-04-03 17:02:38.643517435 +0000
+@@ -135,6 +135,9 @@ dhclient - Dynamic Host Configuration Pr
+ .B -w
+ ]
+ [
++.B -nc
++]
++[
+ .B -B
+ ]
+ [
+@@ -330,6 +333,32 @@ program can then be used to notify the c
+ has been added or removed, so that the client can attempt to configure an IP
+ address on that interface.
+ .TP
++.BI \-nc
++Do not drop capabilities.
++
++Normally, if
++.B dhclient
++was compiled with libcap-ng support,
++.B dhclient
++drops most capabilities immediately upon startup.  While more secure,
++this greatly restricts the additional actions that hooks in
++.B dhclient-script (8)
++can take.  (For example, any daemons that 
++.B dhclient-script (8)
++starts or restarts will inherit the restricted capabilities as well,
++which may interfere with their correct operation.)  Thus, the
++.BI \-nc
++option can be used to prevent
++.B dhclient
++from dropping capabilities.
++
++The
++.BI \-nc
++option is ignored if
++.B dhclient
++was not compiled with libcap-ng support.
++
++.TP
+ .BI \-n
+ Do not configure any interfaces.  This is most likely to be useful in
+ combination with the
+diff -urNp -x '*.orig' dhcp-4.4.3.org/client/dhclient.c dhcp-4.4.3/client/dhclient.c
+--- dhcp-4.4.3.org/client/dhclient.c   2022-04-03 17:02:38.461517023 +0000
++++ dhcp-4.4.3/client/dhclient.c       2022-04-03 17:02:38.644517437 +0000
+@@ -41,6 +41,10 @@
+ #include <sys/wait.h>
+ #include <limits.h>
++#ifdef HAVE_LIBCAP_NG
++#include <cap-ng.h>
++#endif
++
+ /*
+  * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
+  * that when building ISC code.
+@@ -269,6 +273,9 @@ main(int argc, char **argv) {
+       int timeout_arg = 0;
+       char *arg_conf = NULL;
+       int arg_conf_len = 0;
++#ifdef HAVE_LIBCAP_NG
++      int keep_capabilities = 0;
++#endif
+       /* Initialize client globals. */
+       memset(&default_duid, 0, sizeof(default_duid));
+@@ -668,6 +675,10 @@ main(int argc, char **argv) {
+                       dhclient_request_options = argv[i];
++              } else if (!strcmp(argv[i], "-nc")) {
++#ifdef HAVE_LIBCAP_NG
++                  keep_capabilities = 1;
++#endif
+               } else if (argv[i][0] == '-') {
+                       usage("Unknown command: %s", argv[i]);
+               } else if (interfaces_requested < 0) {
+@@ -728,6 +739,19 @@ main(int argc, char **argv) {
+               path_dhclient_script = s;
+       }
++#ifdef HAVE_LIBCAP_NG
++      /* Drop capabilities */
++      if (!keep_capabilities) {
++              capng_clear(CAPNG_SELECT_CAPS);
++              capng_update(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++                              CAP_DAC_OVERRIDE); // Drop this someday
++              capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++                              CAP_NET_ADMIN, CAP_NET_RAW,
++                              CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, -1);
++              capng_apply(CAPNG_SELECT_CAPS);
++      }
++#endif
++
+       /* Set up the initial dhcp option universe. */
+       initialize_common_option_spaces();
+diff -urNp -x '*.orig' dhcp-4.4.3.org/configure.ac dhcp-4.4.3/configure.ac
+--- dhcp-4.4.3.org/configure.ac        2022-04-03 17:02:38.459517018 +0000
++++ dhcp-4.4.3/configure.ac    2022-04-03 17:02:38.644517437 +0000
+@@ -603,6 +603,41 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],
+ # Look for optional headers.
+ AC_CHECK_HEADERS(sys/socket.h net/if_dl.h net/if6.h regex.h)
++# look for capabilities library
++AC_ARG_WITH(libcap-ng,
++    [  --with-libcap-ng=[auto/yes/no]  Add Libcap-ng support [default=auto]],,
++    with_libcap_ng=auto)
++
++# Check for Libcap-ng API
++#
++# libcap-ng detection
++if test x$with_libcap_ng = xno ; then
++    have_libcap_ng=no;
++else
++    # Start by checking for header file
++    AC_CHECK_HEADER(cap-ng.h, capng_headers=yes, capng_headers=no)
++
++    # See if we have libcap-ng library
++    AC_CHECK_LIB(cap-ng, capng_clear,
++                 CAPNG_LDADD=-lcap-ng,)
++
++    # Check results are usable
++    if test x$with_libcap_ng = xyes -a x$CAPNG_LDADD = x ; then
++       AC_MSG_ERROR(libcap-ng support was requested and the library was not found)
++    fi
++    if test x$CAPNG_LDADD != x -a $capng_headers = no ; then
++       AC_MSG_ERROR(libcap-ng libraries found but headers are missing)
++    fi
++fi
++AC_SUBST(CAPNG_LDADD)
++AC_MSG_CHECKING(whether to use libcap-ng)
++if test x$CAPNG_LDADD != x ; then
++    AC_DEFINE(HAVE_LIBCAP_NG,1,[libcap-ng support])
++    AC_MSG_RESULT(yes)
++else
++    AC_MSG_RESULT(no)
++fi
++
+ # Solaris needs some libraries for functions
+ AC_SEARCH_LIBS(socket, [socket])
+ AC_SEARCH_LIBS(inet_ntoa, [nsl])
+diff -urNp -x '*.orig' dhcp-4.4.3.org/relay/Makefile.am dhcp-4.4.3/relay/Makefile.am
+--- dhcp-4.4.3.org/relay/Makefile.am   2022-03-08 09:26:03.000000000 +0000
++++ dhcp-4.4.3/relay/Makefile.am       2022-04-03 17:02:38.644517437 +0000
+@@ -8,6 +8,7 @@ dhcrelay_LDADD = ../common/libdhcp.@A@ .
+                @BINDLIBIRSDIR@/libirs.@A@ \
+                @BINDLIBDNSDIR@/libdns.@A@ \
+                @BINDLIBISCCFGDIR@/libisccfg.@A@ \
+-               @BINDLIBISCDIR@/libisc.@A@
++               @BINDLIBISCDIR@/libisc.@A@ \
++               $(CAPNG_LDADD)
+ man_MANS = dhcrelay.8
+ EXTRA_DIST = $(man_MANS)
+diff -urNp -x '*.orig' dhcp-4.4.3.org/relay/dhcrelay.c dhcp-4.4.3/relay/dhcrelay.c
+--- dhcp-4.4.3.org/relay/dhcrelay.c    2022-04-03 17:02:38.462517025 +0000
++++ dhcp-4.4.3/relay/dhcrelay.c        2022-04-03 17:02:38.645517439 +0000
+@@ -36,6 +36,11 @@
+ #include <systemd/sd-daemon.h>
+ #endif
++#ifdef HAVE_LIBCAP_NG
++#  include <cap-ng.h>
++   int keep_capabilities = 0;
++#endif
++
+ TIME default_lease_time = 43200; /* 12 hours... */
+ TIME max_lease_time = 86400; /* 24 hours... */
+ struct tree_cache *global_options[256];
+@@ -616,6 +621,10 @@ main(int argc, char **argv) {
+                               usage(use_noarg, argv[i-1]);
+                       dhcrelay_sub_id = argv[i];
+ #endif
++              } else if (!strcmp(argv[i], "-nc")) {
++#ifdef HAVE_LIBCAP_NG
++                      keep_capabilities = 1;
++#endif
+               } else if (!strcmp(argv[i], "-pf")) {
+                       if (++i == argc)
+                               usage(use_noarg, argv[i-1]);
+@@ -685,6 +694,17 @@ main(int argc, char **argv) {
+ #endif
+       }
++#ifdef HAVE_LIBCAP_NG
++      /* Drop capabilities */
++      if (!keep_capabilities) {
++              capng_clear(CAPNG_SELECT_BOTH);
++              capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++                              CAP_NET_RAW, CAP_NET_BIND_SERVICE, -1);
++              capng_apply(CAPNG_SELECT_BOTH);
++              log_info ("Dropped all unnecessary capabilities.");
++      }
++#endif
++
+       if (!quiet) {
+               log_info("%s %s", message, PACKAGE_VERSION);
+               log_info(copyright);
+@@ -849,6 +869,15 @@ main(int argc, char **argv) {
+                    (unsigned long) getpid());
+ #endif
++#ifdef HAVE_LIBCAP_NG
++      /* Drop all capabilities */
++      if (!keep_capabilities) {
++              capng_clear(CAPNG_SELECT_BOTH);
++              capng_apply(CAPNG_SELECT_BOTH);
++              log_info ("Dropped all capabilities.");
++      }
++#endif
++
+       /* Start dispatching packets and timeouts... */
+       dispatch();
diff --git a/dhcp-client-request-release-bind-iface.patch b/dhcp-client-request-release-bind-iface.patch
new file mode 100644 (file)
index 0000000..37482a0
--- /dev/null
@@ -0,0 +1,76 @@
+From d45463c2007a78623f2c90c250bb8e2f3e34a852 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:39:36 +0100
+Subject: [PATCH 17/28] Send unicast request/release via correct interface
+
+(#800561, #1177351)
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #30544])
+---
+ client/dhclient.c | 30 ++++++++++++++++++++++++++++++
+ 1 file changed, 30 insertions(+)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 444d251..d607975 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -3417,6 +3417,14 @@ void send_request (cpp)
+ #endif
+       if (destination.sin_addr.s_addr != INADDR_BROADCAST &&
+           fallback_interface) {
++#if defined(SO_BINDTODEVICE)
++              if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++                             SO_BINDTODEVICE, client->interface->name,
++                             strlen(client->interface->name)) < 0) {
++                      log_error("%s:%d: Failed to bind fallback interface"
++                                " to %s: %m", MDL, client->interface->name);
++              }
++#endif
+               result = send_packet(fallback_interface, NULL, &client->packet,
+                                    client->packet_length, from, &destination,
+                                    NULL);
+@@ -3426,6 +3434,13 @@ void send_request (cpp)
+                                 client->packet_length,
+                                 fallback_interface->name);
+               }
++#if defined(SO_BINDTODEVICE)
++              if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++                             SO_BINDTODEVICE, NULL, 0) < 0) {
++                      log_fatal("%s:%d: Failed to unbind fallback interface:"
++                                " %m", MDL);
++              }
++#endif
+         }
+       else {
+               /* Send out a packet. */
+@@ -3543,6 +3558,14 @@ void send_release (cpp)
+       } else
+ #endif
+       if (fallback_interface) {
++#if defined(SO_BINDTODEVICE)
++              if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++                             SO_BINDTODEVICE, client->interface->name,
++                             strlen(client->interface->name)) < 0) {
++                      log_error("%s:%d: Failed to bind fallback interface"
++                                " to %s: %m", MDL, client->interface->name);
++              }
++#endif
+               result = send_packet(fallback_interface, NULL, &client->packet,
+                                     client->packet_length, from, &destination,
+                                     NULL);
+@@ -3552,6 +3575,13 @@ void send_release (cpp)
+                                 client->packet_length,
+                                 fallback_interface->name);
+               }
++#if defined(SO_BINDTODEVICE)
++              if (setsockopt(fallback_interface -> wfdesc, SOL_SOCKET,
++                             SO_BINDTODEVICE, NULL, 0) < 0) {
++                      log_fatal("%s:%d: Failed to unbind fallback interface:"
++                                " %m", MDL);
++              }
++#endif
+         } else {
+               /* Send out a packet. */
+               result = send_packet(client->interface, NULL, &client->packet,
+-- 
+2.35.1
+
diff --git a/dhcp-confparse.patch b/dhcp-confparse.patch
new file mode 100644 (file)
index 0000000..25824fd
--- /dev/null
@@ -0,0 +1,56 @@
+From bdbbb4be07bb33fe083baef2bd0ef38b91c11120 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:44:06 +0100
+Subject: [PATCH 21/28] Load leases DB in non-replay mode only
+
+---
+ server/confpars.c | 12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/server/confpars.c b/server/confpars.c
+index 5a6396b..6e08ad7 100644
+--- a/server/confpars.c
++++ b/server/confpars.c
+@@ -134,6 +134,11 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+       cfile = (struct parse *)0;
+ #if defined (TRACING)
++      // No need to dmalloc huge memory region if we're not going to re-play
++      if (!trace_record()){
++              status = new_parse(&cfile, file, NULL, 0, filename, 0);
++              goto noreplay;
++      };
+       flen = lseek (file, (off_t)0, SEEK_END);
+       if (flen < 0) {
+             boom:
+@@ -165,7 +170,6 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+       if (result != ulen)
+               log_fatal ("%s: short read of %d bytes instead of %d.",
+                          filename, ulen, result);
+-      close (file);
+       memfile:
+       /* If we're recording, write out the filename and file contents. */
+       if (trace_record ())
+@@ -174,6 +178,9 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+ #else
+       status = new_parse(&cfile, file, NULL, 0, filename, 0);
+ #endif
++      noreplay:
++      if (!trace_playback())
++              close (file);
+       if (status != ISC_R_SUCCESS || cfile == NULL)
+               return status;
+@@ -183,7 +190,8 @@ isc_result_t read_conf_file (const char *filename, struct group *group,
+               status = conf_file_subparse (cfile, group, group_type);
+       end_parse (&cfile);
+ #if defined (TRACING)
+-      dfree (dbuf, MDL);
++      if (trace_record())
++          dfree (dbuf, MDL);
+ #endif
+       return status;
+ }
+-- 
+2.35.1
+
index f57fa1fbdf6c21fc1ca1c4671aaa231cc30a7cb7..98c1957c9764a7f3a2cd84bb555f0ed9009d7628 100644 (file)
@@ -1,6 +1,18 @@
-diff -up dhcp-4.3.4/client/clparse.c.requested dhcp-4.3.4/client/clparse.c
---- dhcp-4.3.4/client/clparse.c.requested      2016-04-29 12:18:50.157151352 +0200
-+++ dhcp-4.3.4/client/clparse.c        2016-04-29 12:19:22.235137243 +0200
+From f994c4d208a8fe88cbf78d4374c8d44793f0598e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:24:24 +0100
+Subject: [PATCH 05/28] Change default requested options
+
+Add NIS domain, NIS servers, NTP servers, interface-mtu and domain-search
+to the list of default requested DHCP options
+---
+ client/clparse.c | 27 ++++++++++++++++++++++++++-
+ 1 file changed, 26 insertions(+), 1 deletion(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index bb63825..e63ea08 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
 @@ -31,7 +31,7 @@
  
  struct client_config top_level_config;
@@ -10,7 +22,7 @@ diff -up dhcp-4.3.4/client/clparse.c.requested dhcp-4.3.4/client/clparse.c
  /* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
  struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
  
-@@ -116,6 +116,31 @@ isc_result_t read_client_conf ()
+@@ -119,6 +119,31 @@ isc_result_t read_client_conf ()
        option_code_hash_lookup(&default_requested_options[8],
                                dhcpv6_universe.code_hash, &code, 0, MDL);
  
@@ -42,3 +54,6 @@ diff -up dhcp-4.3.4/client/clparse.c.requested dhcp-4.3.4/client/clparse.c
        for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
                if (default_requested_options[code] == NULL)
                        log_fatal("Unable to find option definition for "
+-- 
+2.35.1
+
diff --git a/dhcp-detect-time-changes.patch b/dhcp-detect-time-changes.patch
new file mode 100644 (file)
index 0000000..77df3fd
--- /dev/null
@@ -0,0 +1,92 @@
+From a2fb8759ab48c88e3f8df94ae6e156c357d932a2 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Oct 2019 16:23:01 +0200
+Subject: [PATCH 24/28] Detect system time changes
+
+---
+ client/dhclient.c |  6 ++++++
+ common/dispatch.c | 11 ++++++++++-
+ includes/dhcpd.h  |  3 ++-
+ server/dhcpd.c    |  6 ++++++
+ 4 files changed, 24 insertions(+), 2 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 60836b4..fd18813 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -5665,6 +5665,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+                 case server_awaken:
+                   state_reboot (client);
+                   break;
++
++                  case server_time_changed:
++                    if (client->active){
++                      state_reboot (client);
++                    }
++                    break;
+               }
+           }
+       }
+diff --git a/common/dispatch.c b/common/dispatch.c
+index 9741ff5..11c1787 100644
+--- a/common/dispatch.c
++++ b/common/dispatch.c
+@@ -118,7 +118,6 @@ dispatch(void)
+                * signal. It will return ISC_R_RELOAD in that
+                * case. That is a normal behavior.
+                */
+-
+               if (status == ISC_R_RELOAD) {
+                       /*
+                        * dhcp_set_control_state() will do the job.
+@@ -129,6 +128,16 @@ dispatch(void)
+                       if (status == ISC_R_SUCCESS)
+                               status = ISC_R_RELOAD;
+               }
++
++                
++                if (status == ISC_R_TIMESHIFTED){
++                  status = dhcp_set_control_state(server_time_changed,
++                                                  server_time_changed);
++                  status = ISC_R_RELOAD;
++                  log_info ("System time has been changed. Unable to use existing leases. Restarting");
++                  // do nothing, restart context
++                };
++
+       } while (status == ISC_R_RELOAD);
+       log_fatal ("Dispatch routine failed: %s -- exiting",
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index fabad01..9663508 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -524,7 +524,8 @@ typedef enum {
+       server_running = 1,
+       server_shutdown = 2,
+       server_hibernate = 3,
+-      server_awaken = 4
++      server_awaken = 4,
++        server_time_changed = 5
+ } control_object_state_t;
+ typedef struct {
+diff --git a/server/dhcpd.c b/server/dhcpd.c
+index 845d0cc..3b3bd3b 100644
+--- a/server/dhcpd.c
++++ b/server/dhcpd.c
+@@ -1767,6 +1767,12 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
+ {
+       struct timeval tv;
++        if (newstate == server_time_changed){
++          log_error ("System time has been changed. Leases information unreliable!");
++          return ISC_R_SUCCESS;
++        }
++
++                
+       if (newstate != server_shutdown)
+               return DHCP_R_INVALIDARG;
+       /* Re-entry. */
+-- 
+2.35.1
+
diff --git a/dhcp-duid_uuid.patch b/dhcp-duid_uuid.patch
new file mode 100644 (file)
index 0000000..e7f4e7e
--- /dev/null
@@ -0,0 +1,125 @@
+From 0a0a7e1afa171289b9e9d855c519101bbd71b5fe Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:36:30 +0100
+Subject: [PATCH 16/28] Turn on creating/sending of DUID
+
+as client identifier with DHCPv4 clients (#560361c#40, rfc4361)
+---
+ client/dhclient.c | 74 ++++++++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 70 insertions(+), 4 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 181f6e1..444d251 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -4267,6 +4267,59 @@ write_options(struct client_state *client, struct option_state *options,
+       }
+ }
++int unhexchar(char c) {
++
++      if (c >= '0' && c <= '9')
++              return c - '0';
++
++      if (c >= 'a' && c <= 'f')
++              return c - 'a' + 10;
++
++      if (c >= 'A' && c <= 'F')
++              return c - 'A' + 10;
++
++      return -1;
++}
++
++isc_result_t
++read_uuid(u_int8_t* uuid) {
++      const char *id_fname = "/etc/machine-id";
++      char id[32];
++      size_t nread;
++      FILE * file = fopen( id_fname , "r");
++      if (!file) {
++              log_debug("Cannot open %s", id_fname);
++              return ISC_R_IOERROR;
++      }
++      nread = fread(id, 1, sizeof id, file);
++      fclose(file);
++
++      if (nread < 32) {
++              log_debug("Not enough data in %s", id_fname);
++              return ISC_R_IOERROR;
++      }
++      int j;
++      for (j = 0; j < 16; j++) {
++              int a, b;
++
++              a = unhexchar(id[j*2]);
++              b = unhexchar(id[j*2+1]);
++
++              if (a < 0 || b < 0) {
++                      log_debug("Wrong data in %s", id_fname);
++                        return ISC_R_IOERROR;
++              }
++              uuid[j] = a << 4 | b;
++      }
++
++      /* Set UUID version to 4 --- truly random generation */
++      uuid[6] = (uuid[6] & 0x0F) | 0x40;
++      /* Set the UUID variant to DCE */
++      uuid[8] = (uuid[8] & 0x3F) | 0x80;
++
++      return ISC_R_SUCCESS;
++}
++
+ /*
+  * The "best" default DUID, since we cannot predict any information
+  * about the system (such as whether or not the hardware addresses are
+@@ -4287,6 +4340,7 @@ form_duid(struct data_string *duid, const char *file, int line)
+       struct interface_info *ip;
+       int len;
+       char *str;
++      u_int8_t uuid[16];
+       /* For now, just use the first interface on the list. */
+       ip = interfaces;
+@@ -4307,9 +4361,16 @@ form_duid(struct data_string *duid, const char *file, int line)
+           (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
+               log_fatal("Impossible hardware address length at %s:%d.", MDL);
+-      if (duid_type == 0)
+-              duid_type = stateless ? DUID_LL : DUID_LLT;
+-
++      if (duid_type == 0) {
++              if (read_uuid(uuid) == ISC_R_SUCCESS)
++                  duid_type = DUID_UUID;
++              else
++                  duid_type = stateless ? DUID_LL : DUID_LLT;
++      }
++      
++      if (duid_type == DUID_UUID)
++              len = 2 + sizeof (uuid);
++      else {
+       /*
+        * 2 bytes for the 'duid type' field.
+        * 2 bytes for the 'htype' field.
+@@ -4320,13 +4381,18 @@ form_duid(struct data_string *duid, const char *file, int line)
+       len = 4 + (ip->hw_address.hlen - 1);
+       if (duid_type == DUID_LLT)
+               len += 4;
++      }
+       if (!buffer_allocate(&duid->buffer, len, MDL))
+               log_fatal("no memory for default DUID!");
+       duid->data = duid->buffer->data;
+       duid->len = len;
++      if (duid_type == DUID_UUID) {
++              putUShort(duid->buffer->data, DUID_UUID);
++              memcpy(duid->buffer->data + 2, uuid, sizeof(uuid));
++      }
+       /* Basic Link Local Address type of DUID. */
+-      if (duid_type == DUID_LLT) {
++      else if (duid_type == DUID_LLT) {
+               putUShort(duid->buffer->data, DUID_LLT);
+               putUShort(duid->buffer->data + 2, ip->hw_address.hbuf[0]);
+               putULong(duid->buffer->data + 4, cur_time - DUID_TIME_EPOCH);
+-- 
+2.35.1
+
index c90f0bde3e7377871fc9ee0272648b1e248cb4f2..8c8211f7f374a42128878b1e4c7b9b6d87e69925 100644 (file)
@@ -1,7 +1,17 @@
-diff -up dhcp-4.3.5/omapip/errwarn.c.errwarn dhcp-4.3.5/omapip/errwarn.c
---- dhcp-4.3.5/omapip/errwarn.c.errwarn        2016-09-27 21:16:50.000000000 +0200
-+++ dhcp-4.3.5/omapip/errwarn.c        2016-11-29 19:44:03.515031147 +0100
-@@ -49,6 +49,41 @@ void (*log_cleanup) (void);
+From 5e9162c5ad7aa98f7f673ac7a7f46905ba2deea4 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:09:57 +0100
+Subject: [PATCH 01/28] change bug url
+
+---
+ omapip/errwarn.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 42 insertions(+), 5 deletions(-)
+
+diff --git a/omapip/errwarn.c b/omapip/errwarn.c
+index 38dd9c5..d88e392 100644
+--- a/omapip/errwarn.c
++++ b/omapip/errwarn.c
+@@ -48,6 +48,41 @@ void (*log_cleanup) (void);
  static char mbuf [CVT_BUF_MAX + 1];
  static char fbuf [CVT_BUF_MAX + 1];
  
@@ -62,3 +72,6 @@ diff -up dhcp-4.3.5/omapip/errwarn.c.errwarn dhcp-4.3.5/omapip/errwarn.c
    log_error ("%s", "");
    log_error ("exiting.");
  
+-- 
+2.35.1
+
index dbbbe0bd90163cd20e912b201003ea635fba38e8..e1461bf19994ae16598092f189a6b08c4da68e22 100644 (file)
@@ -1,33 +1,37 @@
---- dhcp-4.4.2/client/dhclient.c.extravars     2021-04-02 12:50:00.989139908 +0000
-+++ dhcp-4.4.2/client/dhclient.c               2021-04-02 12:55:15.477409996 +0000
-@@ -89,8 +89,6 @@ static const char message [] = "Internet
+diff -ur dhcp-4.4.3.orig/client/dhclient.c dhcp-4.4.3/client/dhclient.c
+--- dhcp-4.4.3.orig/client/dhclient.c  2022-04-03 16:57:37.339835264 +0000
++++ dhcp-4.4.3/client/dhclient.c       2022-04-03 16:59:11.169047699 +0000
+@@ -89,9 +89,6 @@
  static const char url [] = "For info, please visit https://www.isc.org/software/dhcp/";
  #endif /* UNIT_TEST */
  
--u_int16_t local_port = 0;
--u_int16_t remote_port = 0;
+-extern u_int16_t local_port;
+-extern u_int16_t remote_port;
+-
  #if defined(DHCPv6) && defined(DHCP4o6)
  int dhcp4o6_state = -1; /* -1 = stopped, 0 = polling, 1 = started */
  #endif
---- dhcp-4.4.2/relay/dhcrelay.c.extravars      2021-04-02 13:05:13.513727484 +0000
-+++ dhcp-4.4.2/relay/dhcrelay.c                        2021-04-02 13:05:33.690494049 +0000
-@@ -95,9 +95,6 @@ enum { forward_and_append,   /* Forward an
+diff -ur dhcp-4.4.3.orig/relay/dhcrelay.c dhcp-4.4.3/relay/dhcrelay.c
+--- dhcp-4.4.3.orig/relay/dhcrelay.c   2022-03-08 09:26:03.000000000 +0000
++++ dhcp-4.4.3/relay/dhcrelay.c        2022-04-03 16:59:31.166092971 +0000
+@@ -95,9 +95,6 @@
         forward_untouched,     /* Forward without changes. */
         discard } agent_relay_mode = forward_and_replace;
  
--u_int16_t local_port;
--u_int16_t remote_port;
+-extern u_int16_t local_port;
+-extern u_int16_t remote_port;
 -
  /* Relay agent server list. */
  struct server_list {
        struct server_list *next;
---- dhcp-4.4.2/server/mdb.c.extravars  2019-12-17 19:13:31.000000000 +0000
-+++ dhcp-4.4.2/server/mdb.c            2021-04-02 13:09:26.508311259 +0000
-@@ -67,8 +67,6 @@ static host_id_info_t *host_id_info = NU
+diff -ur dhcp-4.4.3.orig/server/mdb.c dhcp-4.4.3/server/mdb.c
+--- dhcp-4.4.3.orig/server/mdb.c       2022-03-08 09:26:03.000000000 +0000
++++ dhcp-4.4.3/server/mdb.c    2022-04-03 16:59:48.006131100 +0000
+@@ -67,8 +67,6 @@
  
  int numclasseswritten;
  
--omapi_object_type_t *dhcp_type_host;
+-extern omapi_object_type_t *dhcp_type_host;
 -
  isc_result_t enter_class(cd, dynamicp, commit)
        struct class *cd;
diff --git a/dhcp-garbage-in-format-string-error.patch b/dhcp-garbage-in-format-string-error.patch
new file mode 100644 (file)
index 0000000..5844b73
--- /dev/null
@@ -0,0 +1,26 @@
+From cfe6414644b68d5b6b5ba150bf57cff0a709a59e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:28:13 +0100
+Subject: [PATCH 09/28] Fix 'garbage in format string' error
+
+RHBZ: 450042
+---
+ common/tables.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/common/tables.c b/common/tables.c
+index be37737..ce12fcd 100644
+--- a/common/tables.c
++++ b/common/tables.c
+@@ -222,7 +222,7 @@ static struct option dhcp_options[] = {
+       { "name-service-search", "Sa",          &dhcp_universe, 117, 1 },
+ #endif
+       { "subnet-selection", "I",              &dhcp_universe, 118, 1 },
+-      { "domain-search", "Dc",                &dhcp_universe, 119, 1 },
++      { "domain-search", "D",                 &dhcp_universe, 119, 1 },
+       { "vivco", "Evendor-class.",            &dhcp_universe, 124, 1 },
+       { "vivso", "Evendor.",                  &dhcp_universe, 125, 1 },
+ #if 0
+-- 
+2.35.1
+
diff --git a/dhcp-handle-null-timouet.patch b/dhcp-handle-null-timouet.patch
new file mode 100644 (file)
index 0000000..4659e0c
--- /dev/null
@@ -0,0 +1,31 @@
+From 7653f3ea80230d4b38bff1c65164aa18c6e51519 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:29:08 +0100
+Subject: [PATCH 10/28] Handle null timeout
+
+Handle cases in add_timeout() where the function is called with a NULL
+value for the 'when' parameter
+
+ISC-Bugs: #19867 (rejected)
+---
+ common/dispatch.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/common/dispatch.c b/common/dispatch.c
+index 7def34c..9741ff5 100644
+--- a/common/dispatch.c
++++ b/common/dispatch.c
+@@ -209,6 +209,10 @@ void add_timeout (when, where, what, ref, unref)
+       isc_interval_t interval;
+       isc_time_t expires;
++      if (when == NULL) {
++              return;
++      }
++
+       /* See if this timeout supersedes an existing timeout. */
+       t = (struct timeout *)0;
+       for (q = timeouts; q; q = q->next) {
+-- 
+2.35.1
+
diff --git a/dhcp-hwaddress.patch b/dhcp-hwaddress.patch
new file mode 100644 (file)
index 0000000..8148980
--- /dev/null
@@ -0,0 +1,100 @@
+From 908ea5f3a45a050a878de16d5acde6eda1b77d9f Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:42:50 +0100
+Subject: [PATCH 20/28] Discover all hwaddress for xid uniqueness
+
+---
+ common/discover.c |  2 ++
+ common/lpf.c      | 27 ++++++++++++++++++++++-----
+ includes/dhcpd.h  |  3 +++
+ 3 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/common/discover.c b/common/discover.c
+index b4b1959..96dcdcf 100644
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -653,6 +653,8 @@ discover_interfaces(int state) {
+                       interface_dereference(&tmp, MDL);
+                       tmp = interfaces; /* XXX */
+               }
++              if (tmp != NULL)
++                      try_hw_addr(tmp);
+               if (dhcp_interface_discovery_hook) {
+                       (*dhcp_interface_discovery_hook)(tmp);
+diff --git a/common/lpf.c b/common/lpf.c
+index fcaa13d..77a5668 100644
+--- a/common/lpf.c
++++ b/common/lpf.c
+@@ -713,8 +713,22 @@ ioctl_get_ll(char *name)
+       return sll;
+ }
++// define ? 
++void try_hw_addr(struct interface_info *info){
++  get_hw_addr2(info);
++};
++
+ void
+ get_hw_addr(struct interface_info *info)
++{
++  if (get_hw_addr2(info) == ISC_R_NOTFOUND){
++    log_fatal("Unsupported device type for \"%s\"",
++              info->name);
++  }
++}
++
++isc_result_t
++get_hw_addr2(struct interface_info *info)
+ {
+       struct hardware *hw = &info->hw_address;
+       char *name = info->name;
+@@ -724,7 +738,8 @@ get_hw_addr(struct interface_info *info)
+       int sll_allocated = 0;
+       char *dup = NULL;
+       char *colon = NULL;
+-
++        isc_result_t result = ISC_R_SUCCESS;
++        
+       if (getifaddrs(&ifaddrs) == -1)
+               log_fatal("Failed to get interfaces");
+@@ -808,14 +823,16 @@ get_hw_addr(struct interface_info *info)
+                       hw->hbuf[4] = 0xef;
+                       break;
+ #endif
+-              default:
+-                      freeifaddrs(ifaddrs);
+-                      log_fatal("Unsupported device type %hu for \"%s\"",
+-                                sll->sll_hatype, name);
++        default:
++          log_error("Unsupported device type %hu for \"%s\"",
++                      sll->sll_hatype, name);
++          result = ISC_R_NOTFOUND;
++
+       }
+       if (sll_allocated)
+               dfree(sll, MDL);
+       freeifaddrs(ifaddrs);
++        return result;
+ }
+ #endif
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index e9e52e7..fabad01 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -2653,7 +2653,10 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
+ #endif
+ const char *print_time(TIME);
++
+ void get_hw_addr(struct interface_info *info);
++void try_hw_addr(struct interface_info *info);
++isc_result_t get_hw_addr2(struct interface_info *info);
+ char *buf_to_hex (const unsigned char *s, unsigned len,
+                    const char *file, int line);
+ char *format_lease_id(const unsigned char *s, unsigned len, int format,
+-- 
+2.35.1
+
diff --git a/dhcp-link-local-address.patch b/dhcp-link-local-address.patch
new file mode 100644 (file)
index 0000000..4011c9a
--- /dev/null
@@ -0,0 +1,79 @@
+From 1f8681acba9ab70fbe17c85e5a1f4ce6a648b55d Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 28 Feb 2019 15:30:21 +0100
+Subject: [PATCH 22/28] dhclient: make sure link-local address is ready in
+ stateless mode
+
+Bug-url: https://bugzilla.redhat.com/1263466
+---
+ client/dhclient.c | 30 ++++++++++++++++++++----------
+ 1 file changed, 20 insertions(+), 10 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 6bbefc7..60836b4 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -943,6 +943,12 @@ main(int argc, char **argv) {
+       inaddr_any.s_addr = INADDR_ANY;
++      /* Discover all the network interfaces. */
++      discover_interfaces(DISCOVER_UNCONFIGURED);
++
++      /* Parse the dhclient.conf file. */
++      read_client_conf();
++
+       /* Stateless special case. */
+       if (stateless) {
+               if (release_mode || (wanted_ia_na > 0) ||
+@@ -959,12 +965,6 @@ main(int argc, char **argv) {
+               finish(0);
+       }
+-      /* Discover all the network interfaces. */
+-      discover_interfaces(DISCOVER_UNCONFIGURED);
+-
+-      /* Parse the dhclient.conf file. */
+-      read_client_conf();
+-
+       /* Parse any extra command line configuration arguments: */
+       if ((dhcp_client_identifier_arg != NULL) && (*dhcp_client_identifier_arg != '\0')) {
+               arg_conf_len = asprintf(&arg_conf, "send dhcp-client-identifier \"%s\";", dhcp_client_identifier_arg);
+@@ -1433,20 +1433,30 @@ void run_stateless(int exit_mode, u_int16_t port)
+       IGNORE_UNUSED(port);
+ #endif
+-      /* Discover the network interface. */
+-      discover_interfaces(DISCOVER_REQUESTED);
++      struct interface_info *ip;
+       if (!interfaces)
+               usage("No interfaces available for stateless command: %s", "-S");
+-      /* Parse the dhclient.conf file. */
+ #ifdef DHCP4o6
+       if (dhcpv4_over_dhcpv6) {
+               /* Mark we want to request IRT too! */
+               dhcpv4_over_dhcpv6++;
+       }
+ #endif
+-      read_client_conf();
++
++      for (ip = interfaces; ip; ip = ip->next) {
++              if ((interfaces_requested > 0) &&
++                  ((ip->flags & (INTERFACE_REQUESTED |
++                                 INTERFACE_AUTOMATIC)) !=
++                   INTERFACE_REQUESTED))
++                      continue;
++              script_init(ip->client, "PREINIT6", NULL);
++              script_go(ip->client);
++      }
++
++      /* Discover the network interface. */
++      discover_interfaces(DISCOVER_REQUESTED);
+       /* Parse the lease database. */
+       read_client_leases();
+-- 
+2.35.1
+
diff --git a/dhcp-lpf-ib.patch b/dhcp-lpf-ib.patch
new file mode 100644 (file)
index 0000000..b9b15e0
--- /dev/null
@@ -0,0 +1,625 @@
+From 90d64318e17df066c27b8e99ba6ab7f51154917b Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:34:21 +0100
+Subject: [PATCH 14/28] IPoIB support (#660681)
+
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #24249])
+---
+ client/dhclient.c |  33 ++++++
+ common/bpf.c      |  32 ++++++
+ common/discover.c |   4 +-
+ common/lpf.c      | 274 ++++++++++++++++++++++++++++++++++++++++++----
+ common/socket.c   |   8 +-
+ includes/dhcpd.h  |   6 +-
+ 6 files changed, 329 insertions(+), 28 deletions(-)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index a99e21f..48edddf 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -211,6 +211,8 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
+   
+ #define DHCLIENT_USAGEH "{--version|--help|-h}"
++static void setup_ib_interface(struct interface_info *ip);
++
+ static void
+ usage(const char *sfmt, const char *sarg)
+ {
+@@ -1213,6 +1215,14 @@ main(int argc, char **argv) {
+       }
+       srandom(seed);
++      /* Setup specific Infiniband options */
++      for (ip = interfaces; ip; ip = ip->next) {
++              if (ip->client &&
++                  (ip->hw_address.hbuf[0] == HTYPE_INFINIBAND)) {
++                      setup_ib_interface(ip);
++              }
++      }
++
+       /*
+        * Establish a default DUID.  We always do so for v6 and
+        * do so if desired for v4 via the -D or -i options
+@@ -1507,6 +1517,29 @@ int find_subnet (struct subnet **sp,
+       return 0;
+ }
++static void setup_ib_interface(struct interface_info *ip)
++{
++      struct group *g;
++
++      /* Set the broadcast flag */
++      ip->client->config->bootp_broadcast_always = 1;
++
++      /*
++       * Find out if a dhcp-client-identifier option was specified either
++       * in the config file or on the command line
++       */
++      for (g = ip->client->config->on_transmission; g != NULL; g = g->next) {
++              if ((g->statements != NULL) &&
++                  (strcmp(g->statements->data.option->option->name,
++                          "dhcp-client-identifier") == 0)) {
++                      return;
++              }
++      }
++
++      /* No client ID specified */
++      log_fatal("dhcp-client-identifier must be specified for InfiniBand");
++}
++
+ /* Individual States:
+  *
+  * Each routine is called from the dhclient_state_machine() in one of
+diff --git a/common/bpf.c b/common/bpf.c
+index aede242..812cac3 100644
+--- a/common/bpf.c
++++ b/common/bpf.c
+@@ -237,11 +237,43 @@ int dhcp_bpf_relay_filter_len =
+       sizeof dhcp_bpf_relay_filter / sizeof (struct bpf_insn);
+ #endif
++/* Packet filter program for DHCP over Infiniband.
++ *
++ * XXX
++ * Changes to the filter program may require changes to the constant offsets
++ * used in lpf_gen_filter_setup to patch the port in the BPF program!
++ * XXX
++ */
++struct bpf_insn dhcp_ib_bpf_filter [] = {
++      /* Packet filter for Infiniband */
++      /* Make sure it's a UDP packet... */
++      BPF_STMT(BPF_LD + BPF_B + BPF_ABS, 9),
++      BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),
++
++      /* Make sure this isn't a fragment... */
++      BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 6),
++      BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),
++
++      /* Get the IP header length... */
++      BPF_STMT(BPF_LDX + BPF_B + BPF_MSH, 0),
++
++      /* Make sure it's to the right port... */
++      BPF_STMT(BPF_LD + BPF_H + BPF_IND, 2),
++      BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),
++
++      /* If we passed all the tests, ask for the whole packet. */
++      BPF_STMT(BPF_RET + BPF_K, (u_int)-1),
++
++      /* Otherwise, drop it. */
++      BPF_STMT(BPF_RET + BPF_K, 0),
++};
++
+ #if defined (DEC_FDDI)
+ struct bpf_insn *bpf_fddi_filter = NULL;
+ #endif
+ int dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);
++int dhcp_ib_bpf_filter_len = sizeof dhcp_ib_bpf_filter / sizeof (struct bpf_insn);
+ #if defined (HAVE_TR_SUPPORT)
+ struct bpf_insn dhcp_bpf_tr_filter [] = {
+         /* accept all token ring packets due to variable length header */
+diff --git a/common/discover.c b/common/discover.c
+index ed338b4..e562225 100644
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -899,7 +899,7 @@ discover_interfaces(int state) {
+                               if_register_send(tmp);
+                       } else {
+                               /* get_hw_addr() was called by register. */
+-                              get_hw_addr(tmp->name, &tmp->hw_address);
++                              get_hw_addr(tmp);
+                       }
+                       break;
+ #ifdef DHCPv6
+@@ -912,7 +912,7 @@ discover_interfaces(int state) {
+                                  so now we have to call it explicitly
+                                  to not leave the hardware address unknown
+                                  (some code expects it cannot be. */
+-                              get_hw_addr(tmp->name, &tmp->hw_address);
++                              get_hw_addr(tmp);
+                       } else {
+                               if_register_linklocal6(tmp);
+                       }
+diff --git a/common/lpf.c b/common/lpf.c
+index bb8822a..fcaa13d 100644
+--- a/common/lpf.c
++++ b/common/lpf.c
+@@ -45,6 +45,17 @@
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+ #include <net/if.h>
++#include <ifaddrs.h>
++
++/* Default broadcast address for IPoIB */
++static unsigned char default_ib_bcast_addr[20] = {
++      0x00, 0xff, 0xff, 0xff,
++      0xff, 0x12, 0x40, 0x1b,
++      0x00, 0x00, 0x00, 0x00,
++      0x00, 0x00, 0x00, 0x00,
++      0xff, 0xff, 0xff, 0xff
++};
++
+ #endif
+ #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
+@@ -78,10 +89,20 @@ int if_register_lpf (info)
+               struct sockaddr common;
+               } sa;
+       struct ifreq ifr;
++      int type;
++      int protocol;
++
++      get_hw_addr(info);
++      if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++              type = SOCK_DGRAM;
++              protocol = ETHERTYPE_IP;
++      } else {
++              type = SOCK_RAW;
++              protocol = ETH_P_ALL;
++      }
+       /* Make an LPF socket. */
+-      if ((sock = socket(PF_PACKET, SOCK_RAW,
+-                         htons((short)ETH_P_ALL))) < 0) {
++      if ((sock = socket(PF_PACKET, type, htons((short)protocol))) < 0) {
+               if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+                   errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
+                   errno == EAFNOSUPPORT || errno == EINVAL) {
+@@ -104,6 +125,7 @@ int if_register_lpf (info)
+       /* Bind to the interface name */
+       memset (&sa, 0, sizeof sa);
+       sa.ll.sll_family = AF_PACKET;
++      sa.ll.sll_protocol = htons(protocol);
+       sa.ll.sll_ifindex = ifr.ifr_ifindex;
+       if (bind (sock, &sa.common, sizeof sa)) {
+               if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+@@ -120,8 +142,6 @@ int if_register_lpf (info)
+       }
+-      get_hw_addr(info->name, &info->hw_address);
+-
+       return sock;
+ }
+ #endif /* USE_LPF_SEND || USE_LPF_RECEIVE */
+@@ -176,6 +196,8 @@ void if_deregister_send (info)
+    in bpf includes... */
+ extern struct sock_filter dhcp_bpf_filter [];
+ extern int dhcp_bpf_filter_len;
++extern struct sock_filter dhcp_ib_bpf_filter [];
++extern int dhcp_ib_bpf_filter_len;
+ #if defined(RELAY_PORT)
+ extern struct sock_filter dhcp_bpf_relay_filter [];
+@@ -199,11 +221,12 @@ void if_register_receive (info)
+ #ifdef PACKET_AUXDATA
+       {
+       int val = 1;
+-
+-      if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
+-                     &val, sizeof(val)) < 0) {
+-              if (errno != ENOPROTOOPT) {
+-                      log_fatal ("Failed to set auxiliary packet data: %m");
++      if (info->hw_address.hbuf[0] != HTYPE_INFINIBAND) {
++              if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
++                            &val, sizeof(val)) < 0) {
++                      if (errno != ENOPROTOOPT) {
++                              log_fatal ("Failed to set auxiliary packet data: %m");
++                      }
+               }
+       }
+       }
+@@ -253,6 +276,18 @@ static void lpf_gen_filter_setup (info)
+       memset(&p, 0, sizeof(p));
++      if (info->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++              p.len = dhcp_ib_bpf_filter_len;
++              p.filter = dhcp_ib_bpf_filter;
++
++              /* Patch the server port into the LPF program...
++                 XXX
++                 changes to filter program may require changes
++                 to the insn number(s) used below!
++                 XXX */
++              dhcp_ib_bpf_filter[6].k = ntohs (local_port);
++      } else {
++
+       /* Set up the bpf filter program structure.    This is defined in
+          bpf.c */
+       p.len = dhcp_bpf_filter_len;
+@@ -275,6 +310,8 @@ static void lpf_gen_filter_setup (info)
+ #endif
+       dhcp_bpf_filter [8].k = ntohs (local_port);
++      }
++
+       if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
+                       sizeof p) < 0) {
+               if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
+@@ -330,6 +367,54 @@ static void lpf_tr_filter_setup (info)
+ #endif /* USE_LPF_RECEIVE */
+ #ifdef USE_LPF_SEND
++ssize_t send_packet_ib(interface, packet, raw, len, from, to, hto)
++      struct interface_info *interface;
++      struct packet *packet;
++      struct dhcp_packet *raw;
++      size_t len;
++      struct in_addr from;
++      struct sockaddr_in *to;
++      struct hardware *hto;
++{
++      unsigned ibufp = 0;
++      double ih [1536 / sizeof (double)];
++      unsigned char *buf = (unsigned char *)ih;
++      ssize_t result;
++
++      union sockunion {
++              struct sockaddr sa;
++              struct sockaddr_ll sll;
++              struct sockaddr_storage ss;
++      } su;
++
++      assemble_udp_ip_header (interface, buf, &ibufp, from.s_addr,
++                              to->sin_addr.s_addr, to->sin_port,
++                              (unsigned char *)raw, len);
++      memcpy (buf + ibufp, raw, len);
++
++      memset(&su, 0, sizeof(su));
++      su.sll.sll_family = AF_PACKET;
++      su.sll.sll_protocol = htons(ETHERTYPE_IP);
++
++      if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
++              errno = ENOENT;
++              log_error ("send_packet_ib: %m - failed to get if index");
++              return -1;
++      }
++
++      su.sll.sll_hatype = htons(HTYPE_INFINIBAND);
++      su.sll.sll_halen = sizeof(interface->bcast_addr);
++      memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
++
++      result = sendto(interface->wfdesc, buf, ibufp + len, 0,
++                      &su.sa, sizeof(su));
++
++      if (result < 0)
++              log_error ("send_packet_ib: %m");
++
++      return result;
++}
++
+ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+       struct interface_info *interface;
+       struct packet *packet;
+@@ -350,6 +435,11 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+               return send_fallback (interface, packet, raw,
+                                     len, from, to, hto);
++      if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++              return send_packet_ib(interface, packet, raw, len, from,
++                                    to, hto);
++      }
++
+       if (hto == NULL && interface->anycast_mac_addr.hlen)
+               hto = &interface->anycast_mac_addr;
+@@ -370,6 +460,42 @@ ssize_t send_packet (interface, packet, raw, len, from, to, hto)
+ #endif /* USE_LPF_SEND */
+ #ifdef USE_LPF_RECEIVE
++ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
++      struct interface_info *interface;
++      unsigned char *buf;
++      size_t len;
++      struct sockaddr_in *from;
++      struct hardware *hfrom;
++{
++      int length = 0;
++      int offset = 0;
++      unsigned char ibuf [1536];
++      unsigned bufix = 0;
++      unsigned paylen;
++
++      length = read(interface->rfdesc, ibuf, sizeof(ibuf));
++
++      if (length <= 0)
++              return length;
++
++      offset = decode_udp_ip_header(interface, ibuf, bufix, from,
++                                     (unsigned)length, &paylen, 0);
++
++      if (offset < 0)
++              return 0;
++
++      bufix += offset;
++      length -= offset;
++
++      if (length < paylen)
++              log_fatal("Internal inconsistency at %s:%d.", MDL);
++
++      /* Copy out the data in the packet... */
++      memcpy(buf, &ibuf[bufix], paylen);
++
++      return (ssize_t)paylen;
++}
++
+ ssize_t receive_packet (interface, buf, len, from, hfrom)
+       struct interface_info *interface;
+       unsigned char *buf;
+@@ -408,6 +534,10 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
+       };
+ #endif /* PACKET_AUXDATA */
++      if (interface->hw_address.hbuf[0] == HTYPE_INFINIBAND) {
++              return receive_packet_ib(interface, buf, len, from, hfrom);
++      }
++
+       length = recvmsg (interface->rfdesc, &msg, 0);
+       if (length <= 0)
+               return length;
+@@ -521,11 +651,33 @@ void maybe_setup_fallback ()
+ #endif
+ #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
+-void
+-get_hw_addr(const char *name, struct hardware *hw) {
++struct sockaddr_ll *
++get_ll (struct ifaddrs *ifaddrs, struct ifaddrs **ifa, char *name)
++{
++      for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
++              if ((*ifa)->ifa_addr == NULL)
++                      continue;
++
++              if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
++                      continue;
++
++              if ((*ifa)->ifa_flags & IFF_LOOPBACK)
++                      continue;
++
++              if (strcmp((*ifa)->ifa_name, name) == 0)
++                      return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr;
++      }
++      *ifa = NULL;
++      return NULL;
++}
++
++struct sockaddr_ll *
++ioctl_get_ll(char *name)
++{
+       int sock;
+       struct ifreq tmp;
+-      struct sockaddr *sa;
++      struct sockaddr *sa = NULL;
++      struct sockaddr_ll *sll = NULL;
+       if (strlen(name) >= sizeof(tmp.ifr_name)) {
+               log_fatal("Device name too long: \"%s\"", name);
+@@ -542,13 +694,58 @@ get_hw_addr(const char *name, struct hardware *hw) {
+               log_fatal("Error getting hardware address for \"%s\": %m",
+                         name);
+       }
++      close(sock);
+       sa = &tmp.ifr_hwaddr;
+-      switch (sa->sa_family) {
++      // needs to be freed outside this function
++      sll = dmalloc (sizeof (struct sockaddr_ll), MDL);
++      if (!sll)
++              log_fatal("Unable to allocate memory for link layer address");
++      memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
++      memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
++      switch (sll->sll_hatype) {
++              case ARPHRD_INFINIBAND:
++                      sll->sll_halen = HARDWARE_ADDR_LEN_IOCTL;
++                      break;
++              default:
++                      break;
++      }
++      return sll;
++}
++
++void
++get_hw_addr(struct interface_info *info)
++{
++      struct hardware *hw = &info->hw_address;
++      char *name = info->name;
++      struct ifaddrs *ifaddrs = NULL;
++      struct ifaddrs *ifa = NULL;
++      struct sockaddr_ll *sll = NULL;
++      int sll_allocated = 0;
++      char *dup = NULL;
++      char *colon = NULL;
++
++      if (getifaddrs(&ifaddrs) == -1)
++              log_fatal("Failed to get interfaces");
++
++      if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
++              /*
++               * We were unable to get link-layer address for name.
++               * Fall back to ioctl(SIOCGIFHWADDR).
++               */
++              sll = ioctl_get_ll(name);
++              if (sll != NULL)
++                      sll_allocated = 1;
++              else
++                      // shouldn't happen
++                      log_fatal("Unexpected internal error");
++      }
++
++      switch (sll->sll_hatype) {
+               case ARPHRD_ETHER:
+                       hw->hlen = 7;
+                       hw->hbuf[0] = HTYPE_ETHER;
+-                      memcpy(&hw->hbuf[1], sa->sa_data, 6);
++                      memcpy(&hw->hbuf[1], sll->sll_addr, 6);
+                       break;
+               case ARPHRD_IEEE802:
+ #ifdef ARPHRD_IEEE802_TR
+@@ -556,18 +753,50 @@ get_hw_addr(const char *name, struct hardware *hw) {
+ #endif /* ARPHRD_IEEE802_TR */
+                       hw->hlen = 7;
+                       hw->hbuf[0] = HTYPE_IEEE802;
+-                      memcpy(&hw->hbuf[1], sa->sa_data, 6);
++                      memcpy(&hw->hbuf[1], sll->sll_addr, 6);
+                       break;
+               case ARPHRD_FDDI:
+                       hw->hlen = 7;
+                       hw->hbuf[0] = HTYPE_FDDI;
+-                      memcpy(&hw->hbuf[1], sa->sa_data, 6);
++                      memcpy(&hw->hbuf[1], sll->sll_addr, 6);
++                      break;
++              case ARPHRD_INFINIBAND:
++                      dup = strdup(name);
++                      /* Aliased infiniband interface is special case where
++                       * neither get_ll() nor ioctl_get_ll() get's correct hw
++                       * address, so we have to truncate the :0 and run
++                       * get_ll() again for the rest.
++                      */
++                      if ((colon = strchr(dup, ':')) != NULL) {
++                              *colon = '\0';
++                              if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
++                                      log_fatal("Error getting hardware address for \"%s\": %m", name);
++                      }
++                      free (dup);
++                      /* For Infiniband, save the broadcast address and store
++                       * the port GUID into the hardware address.
++                       */
++                      if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
++                              struct sockaddr_ll *bll;
++
++                              bll = (struct sockaddr_ll *)ifa->ifa_broadaddr;
++                              memcpy(&info->bcast_addr, bll->sll_addr, 20);
++                      } else {
++                              memcpy(&info->bcast_addr, default_ib_bcast_addr,
++                                     20);
++                      }
++
++                      hw->hlen = HARDWARE_ADDR_LEN_IOCTL + 1;
++                      hw->hbuf[0] = HTYPE_INFINIBAND;
++                      memcpy(&hw->hbuf[1],
++                             &sll->sll_addr[sll->sll_halen - HARDWARE_ADDR_LEN_IOCTL],
++                             HARDWARE_ADDR_LEN_IOCTL);
+                       break;
+ #if defined(ARPHRD_PPP)
+               case ARPHRD_PPP:
+                       if (local_family != AF_INET6)
+-                              log_fatal("Unsupported device type %d for \"%s\"",
+-                                         sa->sa_family, name);
++                              log_fatal("local_family != AF_INET6 for \"%s\"",
++                                        name);
+                       hw->hlen = 0;
+                       hw->hbuf[0] = HTYPE_RESERVED;
+                       /* 0xdeadbeef should never occur on the wire,
+@@ -580,10 +809,13 @@ get_hw_addr(const char *name, struct hardware *hw) {
+                       break;
+ #endif
+               default:
+-                      log_fatal("Unsupported device type %ld for \"%s\"",
+-                                (long int)sa->sa_family, name);
++                      freeifaddrs(ifaddrs);
++                      log_fatal("Unsupported device type %hu for \"%s\"",
++                                sll->sll_hatype, name);
+       }
+-      close(sock);
++      if (sll_allocated)
++              dfree(sll, MDL);
++      freeifaddrs(ifaddrs);
+ }
+ #endif
+diff --git a/common/socket.c b/common/socket.c
+index 3953eac..903d034 100644
+--- a/common/socket.c
++++ b/common/socket.c
+@@ -358,7 +358,7 @@ void if_register_send (info)
+       info->wfdesc = if_register_socket(info, AF_INET, 0, NULL);
+       /* If this is a normal IPv4 address, get the hardware address. */
+       if (strcmp(info->name, "fallback") != 0)
+-              get_hw_addr(info->name, &info->hw_address);
++              get_hw_addr(info);
+ #if defined (USE_SOCKET_FALLBACK)
+       /* Fallback only registers for send, but may need to receive as
+          well. */
+@@ -421,7 +421,7 @@ void if_register_receive (info)
+ #endif /* IP_PKTINFO... */
+       /* If this is a normal IPv4 address, get the hardware address. */
+       if (strcmp(info->name, "fallback") != 0)
+-              get_hw_addr(info->name, &info->hw_address);
++              get_hw_addr(info);
+       if (!quiet_interface_discovery)
+               log_info ("Listening on Socket/%s%s%s",
+@@ -577,7 +577,7 @@ if_register6(struct interface_info *info, int do_multicast) {
+       if (req_multi)
+               if_register_multicast(info);
+-      get_hw_addr(info->name, &info->hw_address);
++      get_hw_addr(info);
+       if (!quiet_interface_discovery) {
+               if (info->shared_network != NULL) {
+@@ -633,7 +633,7 @@ if_register_linklocal6(struct interface_info *info) {
+       info->rfdesc = sock;
+       info->wfdesc = sock;
+-      get_hw_addr(info->name, &info->hw_address);
++      get_hw_addr(info);
+       if (!quiet_interface_discovery) {
+               if (info->shared_network != NULL) {
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 4c5e877..e9e52e7 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -485,6 +485,9 @@ struct packet {
+ #define HARDWARE_ADDR_LEN 20
++/* ioctl limits hardware addresses to 8 bytes */
++#define HARDWARE_ADDR_LEN_IOCTL       8
++
+ struct hardware {
+       u_int8_t hlen;
+       u_int8_t hbuf[HARDWARE_ADDR_LEN + 1];
+@@ -1380,6 +1383,7 @@ struct interface_info {
+       struct shared_network *shared_network;
+                               /* Networks connected to this interface. */
+       struct hardware hw_address;     /* Its physical address. */
++      u_int8_t bcast_addr[20];        /* Infiniband broadcast address */
+       struct in_addr *addresses;      /* Addresses associated with this
+                                        * interface.
+                                        */
+@@ -2649,7 +2653,7 @@ void print_dns_status (int, struct dhcp_ddns_cb *, isc_result_t);
+ #endif
+ const char *print_time(TIME);
+-void get_hw_addr(const char *name, struct hardware *hw);
++void get_hw_addr(struct interface_info *info);
+ char *buf_to_hex (const unsigned char *s, unsigned len,
+                    const char *file, int line);
+ char *format_lease_id(const unsigned char *s, unsigned len, int format,
+-- 
+2.35.1
+
index 24d6972af996dfd21d9a115876c7029526692699..451979c78792747bfee44e282afed8fbb919913c 100644 (file)
@@ -1,38 +1,20 @@
-diff -up dhcp-4.3.5b1/client/dhclient.conf.5.man dhcp-4.3.5b1/client/dhclient.conf.5
---- dhcp-4.3.5b1/client/dhclient.conf.5.man    2016-08-26 20:19:53.000000000 +0200
-+++ dhcp-4.3.5b1/client/dhclient.conf.5        2016-09-12 17:09:23.243313514 +0200
-@@ -228,7 +228,8 @@ responding to the client send the client
- options.  Only the option names should be specified in the request
- statement - not option parameters.  By default, the DHCPv4 client
- requests the subnet-mask, broadcast-address, time-offset, routers,
--domain-name, domain-name-servers and host-name options while the DHCPv6
-+domain-search, domain-name, domain-name-servers, host-name, nis-domain,
-+nis-servers, ntp-servers and interface-mtu options while the DHCPv6
- client requests the dhcp6 name-servers and domain-search options.  Note
- that if you enter a \'request\' statement, you over-ride these defaults
- and these options will not be requested.
-@@ -736,6 +737,17 @@ know the DHCP service(s) anycast MAC add
- client.  The \fIlink-type\fR and \fImac-address\fR parameters are configured
- in a similar manner to the \fBhardware\fR statement.
- .PP
-+ \fBbootp-broadcast-always;\fR
-+.PP
-+The
-+.B bootp-broadcast-always
-+statement instructs dhclient to always set the bootp broadcast flag in
-+request packets, so that servers will always broadcast replies.
-+This is equivalent to supplying the dhclient -B argument, and has
-+the same effect as specifying 'always-broadcast' in the server's dhcpd.conf.
-+This option is provided as an extension to enable dhclient to work
-+on IBM s390 Linux guests.
-+.PP
- .SH SAMPLE
- The following configuration file was used on a laptop running NetBSD
- 1.3, though the domains have been modified.
-diff -up dhcp-4.3.5b1/client/dhclient-script.8.man dhcp-4.3.5b1/client/dhclient-script.8
---- dhcp-4.3.5b1/client/dhclient-script.8.man  2016-08-26 20:19:53.000000000 +0200
-+++ dhcp-4.3.5b1/client/dhclient-script.8      2016-09-12 17:08:09.516254385 +0200
-@@ -45,7 +45,7 @@ customizations are needed, they should b
+From d359a7dc30e0423f9b90129291538cad1ee6a6d9 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:25:53 +0100
+Subject: [PATCH 06/28] Various man-page-only fixes
+
+---
+ client/dhclient-script.8 | 22 +++++++++++++++++++++-
+ client/dhclient.conf.5   | 14 +++++++++++++-
+ common/dhcp-options.5    | 15 +++++++++++++++
+ server/dhcpd.conf.5      | 14 +++++++++-----
+ 4 files changed, 58 insertions(+), 7 deletions(-)
+
+diff --git a/client/dhclient-script.8 b/client/dhclient-script.8
+index 5e5bd3d..37ecdc5 100644
+--- a/client/dhclient-script.8
++++ b/client/dhclient-script.8
+@@ -43,7 +43,7 @@ customizations are needed, they should be possible using the enter and
  exit hooks provided (see HOOKS for details).   These hooks will allow the
  user to override the default behaviour of the client in creating a
  .B /etc/resolv.conf
@@ -41,7 +23,7 @@ diff -up dhcp-4.3.5b1/client/dhclient-script.8.man dhcp-4.3.5b1/client/dhclient-
  .PP
  No standard client script exists for some operating systems, even though
  the actual client may work, so a pioneering user may well need to create
-@@ -89,6 +89,26 @@ present.   The
+@@ -87,6 +87,26 @@ present.   The
  .B ETCDIR/dhclient-exit-hooks
  script can modify the valid of exit_status to change the exit status
  of dhclient-script.
@@ -68,10 +50,43 @@ diff -up dhcp-4.3.5b1/client/dhclient-script.8.man dhcp-4.3.5b1/client/dhclient-
  .SH OPERATION
  When dhclient needs to invoke the client configuration script, it
  defines a set of variables in the environment, and then invokes
-diff -up dhcp-4.3.5b1/common/dhcp-options.5.man dhcp-4.3.5b1/common/dhcp-options.5
---- dhcp-4.3.5b1/common/dhcp-options.5.man     2016-08-26 20:19:53.000000000 +0200
-+++ dhcp-4.3.5b1/common/dhcp-options.5 2016-09-12 17:08:09.517254386 +0200
-@@ -1013,6 +1013,21 @@ classless IP routing - it does not inclu
+diff --git a/client/dhclient.conf.5 b/client/dhclient.conf.5
+index dbe6f7e..8bac980 100644
+--- a/client/dhclient.conf.5
++++ b/client/dhclient.conf.5
+@@ -228,7 +228,8 @@ responding to the client send the client its values for the specified
+ options.  Only the option names should be specified in the request
+ statement - not option parameters.  By default, the DHCPv4 client
+ requests the subnet-mask, broadcast-address, time-offset, routers,
+-domain-name, domain-name-servers and host-name options while the DHCPv6
++domain-search, domain-name, domain-name-servers, host-name, nis-domain,
++nis-servers, ntp-servers and interface-mtu options while the DHCPv6
+ client requests the dhcp6 name-servers and domain-search options.  Note
+ that if you enter a \'request\' statement, you over-ride these defaults
+ and these options will not be requested.
+@@ -735,6 +736,17 @@ broadcast packets transmitted by DHCP clients, but is only useful if you
+ know the DHCP service(s) anycast MAC address prior to configuring your
+ client.  The \fIlink-type\fR and \fImac-address\fR parameters are configured
+ in a similar manner to the \fBhardware\fR statement.
++.PP
++ \fBbootp-broadcast-always;\fR
++.PP
++The
++.B bootp-broadcast-always
++statement instructs dhclient to always set the bootp broadcast flag in
++request packets, so that servers will always broadcast replies.
++This is equivalent to supplying the dhclient -B argument, and has
++the same effect as specifying 'always-broadcast' in the server's dhcpd.conf.
++This option is provided as an extension to enable dhclient to work
++on IBM s390 Linux guests.
+ .PP
+ .SH SAMPLE
+ The following configuration file was used on a laptop running NetBSD
+diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
+index 51f80f7..a784b32 100644
+--- a/common/dhcp-options.5
++++ b/common/dhcp-options.5
+@@ -1075,6 +1075,21 @@ classless IP routing - it does not include a subnet mask.  Since
  classless IP routing is now the most widely deployed routing standard,
  this option is virtually useless, and is not implemented by any of the
  popular DHCP clients, for example the Microsoft DHCP client.
@@ -93,10 +108,11 @@ diff -up dhcp-4.3.5b1/common/dhcp-options.5.man dhcp-4.3.5b1/common/dhcp-options
  .RE
  .PP
  .nf
-diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
---- dhcp-4.3.5b1/server/dhcpd.conf.5.man       2016-08-26 20:19:53.000000000 +0200
-+++ dhcp-4.3.5b1/server/dhcpd.conf.5   2016-09-12 17:10:11.205351980 +0200
-@@ -528,6 +528,9 @@ pool {
+diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
+index 691e5dd..b7e79ea 100644
+--- a/server/dhcpd.conf.5
++++ b/server/dhcpd.conf.5
+@@ -527,6 +527,9 @@ pool {
  };
  .fi
  .PP
@@ -106,7 +122,7 @@ diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
  The  server currently  does very  little  sanity checking,  so if  you
  configure it wrong, it will just  fail in odd ways.  I would recommend
  therefore that you either do  failover or don't do failover, but don't
-@@ -542,9 +545,9 @@ primary server might look like this:
+@@ -541,9 +544,9 @@ primary server might look like this:
  failover peer "foo" {
    primary;
    address anthrax.rc.example.com;
@@ -118,7 +134,7 @@ diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
    max-response-delay 60;
    max-unacked-updates 10;
    mclt 3600;
-@@ -1246,7 +1249,7 @@ the zone containing PTR records - for IS
+@@ -1323,7 +1326,7 @@ the zone containing PTR records - for ISC BIND, something like this:
  .PP
  .nf
  key DHCP_UPDATER {
@@ -127,7 +143,7 @@ diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
    secret pRP5FapFoJ95JEL06sv4PQ==;
  };
  
-@@ -1269,7 +1272,7 @@ dhcpd.conf file:
+@@ -1346,7 +1349,7 @@ dhcpd.conf file:
  .PP
  .nf
  key DHCP_UPDATER {
@@ -136,7 +152,7 @@ diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
    secret pRP5FapFoJ95JEL06sv4PQ==;
  };
  
-@@ -2742,7 +2745,8 @@ statement
+@@ -2918,7 +2921,8 @@ statement
  The \fInext-server\fR statement is used to specify the host address of
  the server from which the initial boot file (specified in the
  \fIfilename\fR statement) is to be loaded.  \fIServer-name\fR should
@@ -146,3 +162,35 @@ diff -up dhcp-4.3.5b1/server/dhcpd.conf.5.man dhcp-4.3.5b1/server/dhcpd.conf.5
  .RE
  .PP
  The
+-- 
+2.35.1
+
+From aa328eef58ff93110f2a52cb3a80002ab8cee36e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Tue, 22 Oct 2019 16:28:04 +0200
+Subject: [PATCH 26/28] Add dhclient(5) -B option description
+
+Bug-Url: https://bugzilla.redhat.com/1764088
+---
+ client/dhclient.8 | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/client/dhclient.8 b/client/dhclient.8
+index bacf3bc..76f0cc0 100644
+--- a/client/dhclient.8
++++ b/client/dhclient.8
+@@ -553,6 +553,11 @@ Path to the network configuration script invoked by
+ when it gets a lease.  If unspecified, the default
+ .B CLIENTBINDIR/dhclient-script
+ is used.  See \fBdhclient-script(8)\fR for a description of this file.
++.TP
++.BI \-B
++Always set the bootp broadcast flag in request packets, so that
++servers will always broadcast replies. This option is provided as
++an extension to enable dhclient to work on IBM s390 Linux guests.
+ .PP
+ .SH PORTS
+ During operations the client may use multiple UDP ports
+-- 
+2.35.1
+
diff --git a/dhcp-no-subnet-error2info.patch b/dhcp-no-subnet-error2info.patch
new file mode 100644 (file)
index 0000000..ec608cd
--- /dev/null
@@ -0,0 +1,62 @@
+From 840c4f2175d14fa485f2a5e50a005847940b7e1f Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:40:51 +0100
+Subject: [PATCH 18/28] No subnet declaration for <iface>' should be info, not
+ error.
+
+---
+ common/discover.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/common/discover.c b/common/discover.c
+index e562225..b4b1959 100644
+--- a/common/discover.c
++++ b/common/discover.c
+@@ -806,9 +806,9 @@ discover_interfaces(int state) {
+               /* We must have a subnet declaration for each interface. */
+               if (!tmp->shared_network && (state == DISCOVER_SERVER)) {
+-                      log_error("%s", "");
++                      log_info("%s", "");
+                       if (local_family == AF_INET) {
+-                              log_error("No subnet declaration for %s (%s).",
++                              log_info("No subnet declaration for %s (%s).",
+                                         tmp->name,
+                                         (tmp->addresses == NULL) ?
+                                          "no IPv4 addresses" :
+@@ -823,26 +823,26 @@ discover_interfaces(int state) {
+                               } else {
+                                       strcpy(abuf, "no IPv6 addresses");
+                               }
+-                              log_error("No subnet6 declaration for %s (%s).",
++                              log_info("No subnet6 declaration for %s (%s).",
+                                         tmp->name,
+                                         abuf);
+ #endif /* DHCPv6 */
+                       }
+                       if (supports_multiple_interfaces(tmp)) {
+-                              log_error ("** Ignoring requests on %s.  %s",
++                              log_info ("** Ignoring requests on %s.  %s",
+                                          tmp -> name, "If this is not what");
+-                              log_error ("   you want, please write %s",
++                              log_info ("   you want, please write %s",
+ #ifdef DHCPv6
+                                          (local_family != AF_INET) ?
+                                          "a subnet6 declaration" :
+ #endif
+                                          "a subnet declaration");
+-                              log_error ("   in your dhcpd.conf file %s",
++                              log_info ("   in your dhcpd.conf file %s",
+                                          "for the network segment");
+-                              log_error ("   to %s %s %s",
++                              log_info ("   to %s %s %s",
+                                          "which interface",
+                                          tmp -> name, "is attached. **");
+-                              log_error ("%s", "");
++                              log_info ("%s", "");
+                               goto next;
+                       } else {
+                               log_error ("You must write a %s",
+-- 
+2.35.1
+
diff --git a/dhcp-option97-pxe-client-id.patch b/dhcp-option97-pxe-client-id.patch
new file mode 100644 (file)
index 0000000..f254eb6
--- /dev/null
@@ -0,0 +1,246 @@
+From f01a29a90269c98a86accb0923d65aecf5f59b44 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 28 Feb 2019 16:40:38 +0100
+Subject: [PATCH 23/28] option 97 - pxe-client-id
+
+Bug-url: https://bugzilla.redhat.com/1058674
+ISC-Bugs #38110
+---
+ common/options.c        | 27 ++++++++++++++++++++-------
+ common/tables.c         |  3 ++-
+ includes/dhcp.h         |  1 +
+ server/dhcp.c           | 19 +++++++++++++++++++
+ server/dhcpd.conf.5     |  9 ++++++---
+ server/dhcpleasequery.c | 18 +++++++++++++++---
+ server/failover.c       |  3 +++
+ server/mdb.c            |  5 +++--
+ 8 files changed, 69 insertions(+), 16 deletions(-)
+
+diff --git a/common/options.c b/common/options.c
+index 66433c4..4e26094 100644
+--- a/common/options.c
++++ b/common/options.c
+@@ -4551,13 +4551,26 @@ int validate_packet(struct packet *packet)
+                               "a future version of ISC DHCP will reject this");
+               }
+       } else {
+-              /*
+-               * If hlen is 0 we don't have any identifier, we warn the user
+-               * but continue processing the packet as we can.
+-               */
+-              if (packet->raw->hlen == 0) {
+-                      log_debug("Received DHCPv4 packet without client-id"
+-                                " option and empty hlen field.");
++              oc = lookup_option (&dhcp_universe, packet->options,
++                                  DHO_PXE_CLIENT_ID);
++              if (oc) {
++                      /* Let's check if pxe-client-id is sane */
++                      if ((oc->data.len < 2) ||
++                          (oc->data.data[0] == '\0' &&
++                           oc->data.len != 17)) {
++                              log_debug("Dropped DHCPv4 packet with wrong "
++                                  "(len == %d) pxe-client-id", oc->data.len);
++                              return (0);
++                      }
++              } else {
++                      /*
++                       * If hlen is 0 we don't have any identifier, we warn the user
++                       * but continue processing the packet as we can.
++                       */
++                      if (packet->raw->hlen == 0) {
++                              log_debug("Received DHCPv4 packet without client-id"
++                                              " option and empty hlen field.");
++                      }
+               }
+       }
+diff --git a/common/tables.c b/common/tables.c
+index 96521a6..8034d94 100644
+--- a/common/tables.c
++++ b/common/tables.c
+@@ -200,8 +200,9 @@ static struct option dhcp_options[] = {
+       /* Defined by RFC 4578 */
+       { "pxe-system-type", "Sa",              &dhcp_universe,  93, 1 },
+       { "pxe-interface-id", "BBB",            &dhcp_universe,  94, 1 },
+-      { "pxe-client-id", "BX",                &dhcp_universe,  97, 1 },
+ #endif
++      { "pxe-client-id", "BX",                &dhcp_universe,  97, 1 },
++
+       { "uap-servers", "t",                   &dhcp_universe,  98, 1 },
+ #if defined(RFC4776_OPTIONS)
+         { "geoconf-civic", "X",                 &dhcp_universe, 99, 1 },
+diff --git a/includes/dhcp.h b/includes/dhcp.h
+index 7202f1d..4ad3874 100644
+--- a/includes/dhcp.h
++++ b/includes/dhcp.h
+@@ -158,6 +158,7 @@ struct dhcp_packet {
+ #define DHO_AUTHENTICATE                      90  /* RFC3118, was 210 */
+ #define DHO_CLIENT_LAST_TRANSACTION_TIME      91
+ #define DHO_ASSOCIATED_IP                     92
++#define DHO_PXE_CLIENT_ID                     97  /* RFC4578 */
+ #define DHO_V6_ONLY_PREFERRED                 108 /* RFC8925 */
+ #define DHO_SUBNET_SELECTION                  118 /* RFC3011! */
+ #define DHO_DOMAIN_SEARCH                     119 /* RFC3397 */
+diff --git a/server/dhcp.c b/server/dhcp.c
+index 8363840..29d9c69 100644
+--- a/server/dhcp.c
++++ b/server/dhcp.c
+@@ -228,6 +228,10 @@ dhcp (struct packet *packet) {
+               if (lease -> uid_len) {
+                       oc = lookup_option (&dhcp_universe, packet -> options,
+                                           DHO_DHCP_CLIENT_IDENTIFIER);
++                      if (!oc)
++                              oc = lookup_option (&dhcp_universe,
++                                                  packet -> options,
++                                                  DHO_PXE_CLIENT_ID);
+                       if (!oc)
+                               goto nolease;
+@@ -826,6 +830,9 @@ void dhcprelease (packet, ms_nulltp)
+       oc = lookup_option (&dhcp_universe, packet -> options,
+                           DHO_DHCP_CLIENT_IDENTIFIER);
++      if (!oc)
++              oc = lookup_option (&dhcp_universe, packet -> options,
++                                  DHO_PXE_CLIENT_ID);
+       memset (&data, 0, sizeof data);
+       if (oc &&
+           evaluate_option_cache (&data, packet, (struct lease *)0,
+@@ -1338,6 +1345,9 @@ void dhcpinform (packet, ms_nulltp)
+          */
+       oc = lookup_option(&dhcp_universe, packet->options,
+                          DHO_DHCP_CLIENT_IDENTIFIER);
++      if (!oc)
++              oc = lookup_option (&dhcp_universe, packet -> options,
++                                  DHO_PXE_CLIENT_ID);
+       memset(&d1, 0, sizeof(d1));
+       if (oc &&
+           evaluate_option_cache(&d1, packet, NULL, NULL,
+@@ -2448,6 +2458,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
+                  can be used. */
+               oc = lookup_option (&dhcp_universe, packet -> options,
+                                   DHO_DHCP_CLIENT_IDENTIFIER);
++              if (!oc)
++                      oc = lookup_option (&dhcp_universe, packet -> options,
++                                          DHO_PXE_CLIENT_ID);
+               if (oc &&
+                   evaluate_option_cache (&d1, packet, lease,
+                                          (struct client_state *)0,
+@@ -3040,6 +3053,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
+               /* Record the uid, if given... */
+               oc = lookup_option (&dhcp_universe, packet -> options,
+                                   DHO_DHCP_CLIENT_IDENTIFIER);
++              if (!oc)
++                      oc = lookup_option (&dhcp_universe, packet -> options,
++                                          DHO_PXE_CLIENT_ID);
+               if (oc &&
+                   evaluate_option_cache(&d1, packet, lease, NULL,
+                                         packet->options, state->options,
+@@ -4258,6 +4274,9 @@ int find_lease (struct lease **lp,
+          specified unique client identifier. */
+       oc = lookup_option (&dhcp_universe, packet -> options,
+                           DHO_DHCP_CLIENT_IDENTIFIER);
++      if (!oc)
++              oc = lookup_option (&dhcp_universe, packet -> options,
++                                  DHO_PXE_CLIENT_ID);
+       memset (&client_identifier, 0, sizeof client_identifier);
+       if (oc &&
+           evaluate_option_cache (&client_identifier,
+diff --git a/server/dhcpd.conf.5 b/server/dhcpd.conf.5
+index b7e79ea..2354b1d 100644
+--- a/server/dhcpd.conf.5
++++ b/server/dhcpd.conf.5
+@@ -1664,10 +1664,12 @@ should be a name identifying the host.  If a \fIhostname\fR option is
+ not specified for the host, \fIhostname\fR is used.
+ .PP
+ \fIHost\fR declarations are matched to actual DHCP or BOOTP clients
+-by matching the \fRdhcp-client-identifier\fR option specified in the
++by matching the \fIdhcp-client-identifier\fR or \fIpxe-client-id\fR
++options specified in the
+ \fIhost\fR declaration to the one supplied by the client, or, if the
+ \fIhost\fR declaration or the client does not provide a
+-\fRdhcp-client-identifier\fR option, by matching the \fIhardware\fR
++\fIdhcp-client-identifier\fR or \fIpxe-client-id\fR options,
++by matching the \fIhardware\fR
+ parameter in the \fIhost\fR declaration to the network hardware
+ address supplied by the client.  BOOTP clients do not normally
+ provide a \fIdhcp-client-identifier\fR, so the hardware address must
+@@ -1679,7 +1681,8 @@ to identify hosts.
+ .PP
+ Please be aware that
+ .B only
+-the \fIdhcp-client-identifier\fR option and the hardware address can be
++the \fIdhcp-client-identifier\fR and \fIpxe-client-id\fR
++options and the hardware address can be
+ used to match a host declaration, or the \fIhost-identifier option\fR
+ parameter for DHCPv6 servers.  For example, it is not possible to
+ match a host declaration to a \fIhost-name\fR option.  This is
+diff --git a/server/dhcpleasequery.c b/server/dhcpleasequery.c
+index 0f1d4f7..dae4ae7 100644
+--- a/server/dhcpleasequery.c
++++ b/server/dhcpleasequery.c
+@@ -276,7 +276,7 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
+                */
+               memset(&uid, 0, sizeof(uid));
+-              if (get_option(&uid, 
++              i = get_option(&uid,
+                              &dhcp_universe,
+                              packet,
+                              NULL,
+@@ -286,8 +286,20 @@ dhcpleasequery(struct packet *packet, int ms_nulltp) {
+                              packet->options, 
+                              &global_scope,
+                              DHO_DHCP_CLIENT_IDENTIFIER,
+-                             MDL)) {
+-
++                             MDL);
++              if (!i)
++                      i = get_option(&uid,
++                                     &dhcp_universe,
++                                     packet,
++                                     NULL,
++                                     NULL,
++                                     packet->options,
++                                     NULL,
++                                     packet->options,
++                                     &global_scope,
++                                     DHO_PXE_CLIENT_ID,
++                                     MDL);
++              if (i) {
+                       snprintf(dbg_info, 
+                                sizeof(dbg_info), 
+                                "client-id %s",
+diff --git a/server/failover.c b/server/failover.c
+index 5b36d3a..a641e86 100644
+--- a/server/failover.c
++++ b/server/failover.c
+@@ -5988,6 +5988,9 @@ int load_balance_mine (struct packet *packet, dhcp_failover_state_t *state)
+       oc = lookup_option(&dhcp_universe, packet->options,
+                          DHO_DHCP_CLIENT_IDENTIFIER);
++      if (!oc)
++              oc = lookup_option(&dhcp_universe, packet -> options,
++                                  DHO_PXE_CLIENT_ID);
+       memset(&ds, 0, sizeof ds);
+       if (oc &&
+           evaluate_option_cache(&ds, packet, NULL, NULL,
+diff --git a/server/mdb.c b/server/mdb.c
+index 60a40e1..2cd5605 100644
+--- a/server/mdb.c
++++ b/server/mdb.c
+@@ -129,8 +129,9 @@ static int find_uid_statement (struct executable_statement *esp,
+           esp -> data.option &&
+           (esp -> data.option -> option -> universe ==
+            &dhcp_universe) &&
+-          (esp -> data.option -> option -> code ==
+-           DHO_DHCP_CLIENT_IDENTIFIER)) {
++          ((esp -> data.option -> option -> code ==
++                                              DHO_DHCP_CLIENT_IDENTIFIER) ||
++           (esp -> data.option -> option -> code == DHO_PXE_CLIENT_ID))) {
+               if (condp) {
+                       log_error ("dhcp client identifier may not be %s",
+                                  "specified conditionally.");
+-- 
+2.35.1
+
index db427199101e7c23e762acf89eca43d20bd41b79..4b5696bafaa4be7dc54b8023d97933d724bc10c0 100644 (file)
@@ -1,6 +1,21 @@
-diff -urNp -x '*.orig' dhcp-4.4.2.org/client/clparse.c dhcp-4.4.2/client/clparse.c
---- dhcp-4.4.2.org/client/clparse.c    2020-01-21 20:21:48.000000000 +0100
-+++ dhcp-4.4.2/client/clparse.c        2021-05-15 22:10:03.054906758 +0200
+From af18c830fe55f6be0b89997a36b611d981e3c25d Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:19:47 +0100
+Subject: [PATCH 02/28] additional dhclient options
+
+---
+ client/clparse.c    |  10 +-
+ client/dhclient.8   |  27 +++++
+ client/dhclient.c   | 271 +++++++++++++++++++++++++++++++++++++++++++-
+ common/conflex.c    |   2 +
+ includes/dhcpd.h    |   3 +
+ includes/dhctoken.h |   3 +-
+ 6 files changed, 309 insertions(+), 7 deletions(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index 74ca499..bb63825 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
 @@ -192,6 +192,7 @@ isc_result_t read_client_conf ()
        /* Requested lease time, used by DHCPv6 (DHCPv4 uses the option cache)
         */
@@ -19,7 +34,7 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/clparse.c dhcp-4.4.2/client/clparse
  
  void parse_client_statement (cfile, ip, config)
        struct parse *cfile;
-@@ -820,6 +822,12 @@ void parse_client_statement (cfile, ip,
+@@ -820,6 +822,12 @@ void parse_client_statement (cfile, ip, config)
                parse_lease_id_format(cfile);
                break;
  
@@ -32,11 +47,12 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/clparse.c dhcp-4.4.2/client/clparse
  
              default:
                lose = 0;
-diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.8 dhcp-4.4.2/client/dhclient.8
---- dhcp-4.4.2.org/client/dhclient.8   2020-01-21 20:21:48.000000000 +0100
-+++ dhcp-4.4.2/client/dhclient.8       2021-05-15 22:10:03.054906758 +0200
-@@ -147,6 +147,33 @@ dhclient - Dynamic Host Configuration Pr
- .I seconds
+diff --git a/client/dhclient.8 b/client/dhclient.8
+index 861ff56..5029dac 100644
+--- a/client/dhclient.8
++++ b/client/dhclient.8
+@@ -135,6 +135,33 @@ dhclient - Dynamic Host Configuration Protocol Client
+ .B -w
  ]
  [
 +.B -B
@@ -66,82 +82,13 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.8 dhcp-4.4.2/client/dhclie
 +.I timeout
 +]
 +[
- .B -v
+ .B --dad-wait-time
+ .I seconds
  ]
- [
-@@ -302,6 +329,69 @@ not to exit when it doesn't find any suc
- program can then be used to notify the client when a network interface
- has been added or removed, so that the client can attempt to configure an IP
- address on that interface.
-+
-+.TP
-+.BI \-B
-+Set the BOOTP broadcast flag in request packets so servers will always
-+broadcast replies.
-+
-+.TP
-+.BI \-C\ <dhcp-client-identifier>
-+Specify the dhcp-client-identifier option to send to the DHCP server.
-+
-+.TP
-+.BI \-H\ <host-name>
-+Specify the host-name option to send to the DHCP server.  The host-name
-+string only contains the client's hostname prefix, to which the server will
-+append the ddns-domainname or domain-name options, if any, to derive the
-+fully qualified domain name of the client.  The
-+.B -H
-+option cannot be used with the
-+.B -F
-+option.
-+
-+.TP
-+.BI \-F\ <fqdn.fqdn>
-+Specify the fqdn.fqdn option to send to the DHCP server.  This option cannot
-+be used with the
-+.B -H
-+option.  The fqdn.fqdn option must specify the complete domain name of the
-+client host, which the server may use for dynamic DNS updates.
-+
-+.TP
-+.BI \-V\ <vendor-class-identifier>
-+Specify the vendor-class-identifier option to send to the DHCP server.
-+
-+.TP
-+.BI \--request-options\ <option>[,<option>...]
-+Specify the list of options the client is to request from the server.  The
-+option list must be a single string consisting of option names separated
-+by at least one command and optional space characters.  The default option
-+list is:
-+
-+.BR
-+    subnet-mask, broadcast-address, time-offset, routers,
-+.BR
-+    domain-search, domain-name, domain-name-servers, host-name, 
-+.BR
-+    nis-domain, nis-servers, ntp-servers, interface-mtu
-+
-+.TP
-+.B --request-options
-+option does not append options to the default request, it overrides the
-+default request list.  Keep this in mind if you want to request an
-+additional option besides the default request list.  You will have to
-+specify all option names for the
-+.B --request-options
-+parameter.
-+
-+.TP
-+.BI \--timeout\ <timeout>
-+Specify the time after which
-+.B dhclient
-+will decide that no DHCP servers can be contacted when no responses have been
-+received.
-+
- .TP
- .BI \-n
- Do not configure any interfaces.  This is most likely to be useful in
-diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclient.c
---- dhcp-4.4.2.org/client/dhclient.c   2021-05-15 22:10:02.951572212 +0200
-+++ dhcp-4.4.2/client/dhclient.c       2021-05-15 22:10:03.054906758 +0200
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 46dc3a7..6c1c09a 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
 @@ -41,6 +41,12 @@
  #include <sys/wait.h>
  #include <limits.h>
@@ -155,7 +102,7 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
  TIME default_lease_time = 43200; /* 12 hours... */
  TIME max_lease_time = 86400; /* 24 hours... */
  
-@@ -112,6 +118,10 @@ char *mockup_relay = NULL;
+@@ -113,6 +119,10 @@ char *mockup_relay = NULL;
  
  char *progname = NULL;
  
@@ -166,25 +113,27 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
  void run_stateless(int exit_mode, u_int16_t port);
  
  static isc_result_t write_duid(struct data_string *duid);
-@@ -188,7 +198,11 @@ static const char use_v6command[] = "Com
+@@ -189,8 +199,12 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
  "                [-s server-addr] [-cf config-file]\n" \
  "                [-df duid-file] [-lf lease-file]\n" \
  "                [-pf pid-file] [--no-pid] [-e VAR=val]\n" \
 -"                [-sf script-file] [interface]*"
+-
 +"                [-sf script-file] [interface]*\n" \
 +"                [-C <dhcp-client-identifier>] [-B]\n" \
 +"                [-H <host-name> | -F <fqdn.fqdn>] [--timeout <timeout>]\n" \
 +"                [-V <vendor-class-identifier>]\n" \
 +"                [--request-options <request option list>]"
++  
  #define DHCLIENT_USAGEH "{--version|--help|-h}"
  
-@@ -251,6 +265,17 @@ main(int argc, char **argv) {
-       /* Initialize client globals. */
-       memset(&default_duid, 0, sizeof(default_duid));
-+      char *dhcp_client_identifier_arg = NULL;
-+      char *dhcp_host_name_arg = NULL;
+ static void
+@@ -249,6 +263,16 @@ main(int argc, char **argv) {
+ #else
+       progname = argv[0];
+ #endif
++        char *dhcp_client_identifier_arg = NULL;
++        char *dhcp_host_name_arg = NULL;
 +      char *dhcp_fqdn_arg = NULL;
 +      char *dhcp_vendor_class_identifier_arg = NULL;
 +      char *dhclient_request_options = NULL;
@@ -193,14 +142,13 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
 +      char *arg_conf = NULL;
 +      int arg_conf_len = 0;
 +
-+
-       /* Make sure that file descriptors 0 (stdin), 1, (stdout), and
-          2 (stderr) are open. To do this, we assume that when we
-          open a file the lowest available file descriptor is used. */
-@@ -305,6 +330,89 @@ main(int argc, char **argv) {
-                                        strlen(DHCLIENT_USAGEH)));
-                       IGNORE_RET(write(STDERR_FILENO, "\n", 1));
-                       exit(0);
+       /* Initialize client globals. */
+       memset(&default_duid, 0, sizeof(default_duid));
+@@ -564,6 +588,89 @@ main(int argc, char **argv) {
+                       std_dhcid = 1;
+               } else if (!strcmp(argv[i], "-v")) {
+                       quiet = 0;
 +              } else if (!strcmp(argv[i], "-C")) {
 +                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
 +                              usage(use_noarg, argv[i-1]);
@@ -284,10 +232,10 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
 +
 +                      dhclient_request_options = argv[i];
 +
-               }
-       }
-       /* When not forbidden prepare to become a daemon */
-@@ -831,6 +939,156 @@ main(int argc, char **argv) {
+               } else if (argv[i][0] == '-') {
+                       usage("Unknown command: %s", argv[i]);
+               } else if (interfaces_requested < 0) {
+@@ -760,6 +867,156 @@ main(int argc, char **argv) {
        /* Parse the dhclient.conf file. */
        read_client_conf();
  
@@ -444,46 +392,7 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
        /* Parse the lease database. */
        read_client_leases();
  
-@@ -991,7 +1249,7 @@ main(int argc, char **argv) {
-                                                *whole seconds
-                                                */
-                                               add_timeout(&tv, state_reboot,
--                                                          client, 0, 0);
-+                                                          client, 0, 0);
-                                       } else {
-                                               state_reboot(client);
-                                       }
-@@ -1771,11 +2029,11 @@ void bootp (packet)
-            ap; ap = ap -> next) {
-               if (addr_match(&packet->client_addr, &ap->match)) {
--                      /* piaddr() returns its result in a static
-+                      /* piaddr() returns its result in a static
-                          buffer sized 4*16 (see common/inet.c). */
--                      strcpy(addrbuf, piaddr(ap->match.addr));
--                      strcpy(maskbuf, piaddr(ap->match.mask));
-+                      strcpy(addrbuf, piaddr(ap->match.addr));
-+                      strcpy(maskbuf, piaddr(ap->match.mask));
-                       log_info("BOOTREPLY from %s rejected by rule %s "
-                                "mask %s.", piaddr(packet->client_addr),
-@@ -1823,11 +2081,11 @@ void dhcp (packet)
-            ap; ap = ap -> next) {
-               if (addr_match(&packet->client_addr, &ap->match)) {
--                      /* piaddr() returns its result in a static
-+                      /* piaddr() returns its result in a static
-                          buffer sized 4*16 (see common/inet.c). */
--                      strcpy(addrbuf, piaddr(ap->match.addr));
--                      strcpy(maskbuf, piaddr(ap->match.mask));
-+                      strcpy(addrbuf, piaddr(ap->match.addr));
-+                      strcpy(maskbuf, piaddr(ap->match.mask));
-                       log_info("%s from %s rejected by rule %s mask %s.",
-                                type, piaddr(packet->client_addr),
-@@ -3403,7 +3661,8 @@ void make_discover (client, lease)
+@@ -3472,7 +3729,8 @@ void make_discover (client, lease)
        client -> packet.xid = random ();
        client -> packet.secs = 0; /* filled in by send_discover. */
  
@@ -493,7 +402,7 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
                client -> packet.flags = 0;
        else
                client -> packet.flags = htons (BOOTP_BROADCAST);
-@@ -3488,7 +3747,9 @@ void make_request (client, lease)
+@@ -3557,7 +3815,9 @@ void make_request (client, lease)
        } else {
                memset (&client -> packet.ciaddr, 0,
                        sizeof client -> packet.ciaddr);
@@ -504,7 +413,7 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
                        client -> packet.flags = 0;
                else
                        client -> packet.flags = htons (BOOTP_BROADCAST);
-@@ -3551,7 +3812,8 @@ void make_decline (client, lease)
+@@ -3620,7 +3880,8 @@ void make_decline (client, lease)
        client -> packet.hops = 0;
        client -> packet.xid = client -> xid;
        client -> packet.secs = 0; /* Filled in by send_request. */
@@ -514,10 +423,11 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/client/dhclient.c dhcp-4.4.2/client/dhclie
                client -> packet.flags = 0;
        else
                client -> packet.flags = htons (BOOTP_BROADCAST);
-diff -urNp -x '*.orig' dhcp-4.4.2.org/common/conflex.c dhcp-4.4.2/common/conflex.c
---- dhcp-4.4.2.org/common/conflex.c    2020-01-21 20:21:48.000000000 +0100
-+++ dhcp-4.4.2/common/conflex.c        2021-05-15 22:10:03.054906758 +0200
-@@ -832,6 +832,8 @@ intern(char *atom, enum dhcp_token dfv)
+diff --git a/common/conflex.c b/common/conflex.c
+index 8b01dfb..1fa2be3 100644
+--- a/common/conflex.c
++++ b/common/conflex.c
+@@ -832,6 +832,8 @@ intern(char *atom, enum dhcp_token dfv) {
                if (!strcasecmp(atom+1, "ig-endian")) {
                        return TOKEN_BIG_ENDIAN;
                }
@@ -526,10 +436,11 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/common/conflex.c dhcp-4.4.2/common/conflex
                break;
              case 'c':
                if (!strcasecmp(atom + 1, "ase"))
-diff -urNp -x '*.orig' dhcp-4.4.2.org/includes/dhcpd.h dhcp-4.4.2/includes/dhcpd.h
---- dhcp-4.4.2.org/includes/dhcpd.h    2021-05-15 22:10:02.951572212 +0200
-+++ dhcp-4.4.2/includes/dhcpd.h        2021-05-15 22:10:03.054906758 +0200
-@@ -1279,6 +1279,9 @@ struct client_config {
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index f68b228..3b2e2ca 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -1284,6 +1284,9 @@ struct client_config {
  
        int lease_id_format;            /* format for IDs in lease file,
                                           TOKEN_OCTAL or TOKEN_HEX */
@@ -539,16 +450,20 @@ diff -urNp -x '*.orig' dhcp-4.4.2.org/includes/dhcpd.h dhcp-4.4.2/includes/dhcpd
  };
  
  /* Per-interface state used in the dhcp client... */
-diff -urNp -x '*.orig' dhcp-4.4.2.org/includes/dhctoken.h dhcp-4.4.2/includes/dhctoken.h
---- dhcp-4.4.2.org/includes/dhctoken.h 2020-01-21 20:21:48.000000000 +0100
-+++ dhcp-4.4.2/includes/dhctoken.h     2021-05-15 22:10:03.054906758 +0200
-@@ -376,7 +376,8 @@ enum dhcp_token {
-       LEASE_ID_FORMAT = 676,
+diff --git a/includes/dhctoken.h b/includes/dhctoken.h
+index e6d125f..6daa422 100644
+--- a/includes/dhctoken.h
++++ b/includes/dhctoken.h
+@@ -377,7 +377,8 @@ enum dhcp_token {
        TOKEN_HEX = 677,
        TOKEN_OCTAL = 678,
--      KEY_ALGORITHM = 679
-+      KEY_ALGORITHM = 679,
-+      BOOTP_BROADCAST_ALWAYS = 680
+       KEY_ALGORITHM = 679,
+-      DISCONNECT = 680
++      BOOTP_BROADCAST_ALWAYS = 680,
++      DISCONNECT = 681
  };
  
  #define is_identifier(x)      ((x) >= FIRST_TOKEN &&  \
+-- 
+2.35.1
+
index a4b0fef8f301a62b4a4e1d15862f2c62c23d2643..7a7c38efe71b2b75ebd817d4cb36bf10507a1ae1 100644 (file)
@@ -1,7 +1,28 @@
-diff -up dhcp-4.0.0/includes/dhcpd.h.paths dhcp-4.0.0/includes/dhcpd.h
---- dhcp-4.0.0/includes/dhcpd.h.paths  2008-01-01 15:09:21.000000000 -1000
-+++ dhcp-4.0.0/includes/dhcpd.h        2008-01-01 15:10:55.000000000 -1000
-@@ -1306,11 +1306,11 @@ typedef unsigned char option_mask [16];
+diff -urNpa dhcp-4.4.1.orig/doc/examples/dhclient-dhcpv6.conf dhcp-4.4.1/doc/examples/dhclient-dhcpv6.conf
+--- dhcp-4.4.1.orig/doc/examples/dhclient-dhcpv6.conf  2019-04-17 12:37:47.821000000 +0200
++++ dhcp-4.4.1/doc/examples/dhclient-dhcpv6.conf       2019-04-17 12:39:20.104000000 +0200
+@@ -8,4 +8,4 @@
+ also request dhcp6.sip-servers-addresses;
+ # Likely to be useful: the script path
+-script "/usr/local/etc/dhclient-script";
++script "/sbin/dhclient-script";
+diff -urNpa dhcp-4.4.1.orig/doc/examples/dhcpd-dhcpv6.conf dhcp-4.4.1/doc/examples/dhcpd-dhcpv6.conf
+--- dhcp-4.4.1.orig/doc/examples/dhcpd-dhcpv6.conf     2019-04-17 12:37:47.821000000 +0200
++++ dhcp-4.4.1/doc/examples/dhcpd-dhcpv6.conf  2019-04-17 12:39:20.104000000 +0200
+@@ -43,7 +43,7 @@ option dhcp6.domain-search "test.example
+ option dhcp6.info-refresh-time 21600;
+ # The path of the lease file
+-dhcpv6-lease-file-name "/usr/local/var/db/dhcpd6.leases";
++dhcpv6-lease-file-name "/var/lib/dhcpd/dhcpd6.leases";
+ # Static definition (must be global)
+ host myclient {
+diff -urNpa dhcp-4.4.1.orig/includes/dhcpd.h dhcp-4.4.1/includes/dhcpd.h
+--- dhcp-4.4.1.orig/includes/dhcpd.h   2019-04-17 12:37:47.829000000 +0200
++++ dhcp-4.4.1/includes/dhcpd.h        2019-04-17 12:39:20.105000000 +0200
+@@ -1549,11 +1549,11 @@ typedef unsigned char option_mask [16];
  #endif /* DEBUG */
  
  #ifndef _PATH_DHCPD_DB
@@ -15,17 +36,17 @@ diff -up dhcp-4.0.0/includes/dhcpd.h.paths dhcp-4.0.0/includes/dhcpd.h
  #endif
  
  #ifndef _PATH_DHCPD_PID
-@@ -1340,11 +1340,11 @@ typedef unsigned char option_mask [16];
+@@ -1583,11 +1583,11 @@ typedef unsigned char option_mask [16];
  #endif
  
  #ifndef _PATH_DHCLIENT_DB
 -#define _PATH_DHCLIENT_DB     LOCALSTATEDIR"/db/dhclient.leases"
-+#define _PATH_DHCLIENT_DB     LOCALSTATEDIR"/lib/dhclient/dhclient.leases"
++#define _PATH_DHCLIENT_DB     LOCALSTATEDIR"/lib/dhcpd/dhclient.leases"
  #endif
  
  #ifndef _PATH_DHCLIENT6_DB
 -#define _PATH_DHCLIENT6_DB    LOCALSTATEDIR"/db/dhclient6.leases"
-+#define _PATH_DHCLIENT6_DB    LOCALSTATEDIR"/lib/dhclient/dhclient6.leases"
++#define _PATH_DHCLIENT6_DB    LOCALSTATEDIR"/lib/dhcpd/dhclient6.leases"
  #endif
  
  #ifndef _PATH_RESOLV_CONF
diff --git a/dhcp-ppp.patch b/dhcp-ppp.patch
new file mode 100644 (file)
index 0000000..a5d03f4
--- /dev/null
@@ -0,0 +1,175 @@
+From fe89d58ea8627c66feffa81997daa024834eeb15 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:33:06 +0100
+Subject: [PATCH 13/28] DHCPv6 over PPP support (#626514)
+
+---
+ client/dhc6.c     |  3 ++-
+ client/dhclient.c | 17 ++++++++++++++---
+ common/bpf.c      | 16 ++++++++++++++++
+ common/lpf.c      | 16 ++++++++++++++++
+ includes/dhcp.h   |  2 ++
+ includes/dhcpd.h  |  2 +-
+ server/dhcpv6.c   |  3 +++
+ 7 files changed, 54 insertions(+), 5 deletions(-)
+
+diff --git a/client/dhc6.c b/client/dhc6.c
+index 35cf3d0..88fd07d 100644
+--- a/client/dhc6.c
++++ b/client/dhc6.c
+@@ -5737,7 +5737,8 @@ make_client6_options(struct client_state *client, struct option_state **op,
+        */
+       if ((oc = lookup_option(&dhcpv6_universe, *op,
+                               D6O_CLIENTID)) == NULL) {
+-              if (!option_cache(&oc, &default_duid, NULL, clientid_option,
++              if (default_duid.len == 0 ||
++                  !option_cache(&oc, &default_duid, NULL, clientid_option,
+                                 MDL))
+                       log_fatal("Failure assembling a DUID.");
+diff --git a/client/dhclient.c b/client/dhclient.c
+index b49fcb3..a99e21f 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -1223,8 +1223,8 @@ main(int argc, char **argv) {
+                       if (default_duid.buffer != NULL)
+                               data_string_forget(&default_duid, MDL);
+-                      form_duid(&default_duid, MDL);
+-                      write_duid(&default_duid);
++                      if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS)
++                              write_duid(&default_duid);
+               }
+       }
+@@ -4202,7 +4202,7 @@ write_options(struct client_state *client, struct option_state *options,
+  * is not how it is intended.  Upcoming rearchitecting the client should
+  * address this "one daemon model."
+  */
+-void
++isc_result_t
+ form_duid(struct data_string *duid, const char *file, int line)
+ {
+       struct interface_info *ip;
+@@ -4215,6 +4215,15 @@ form_duid(struct data_string *duid, const char *file, int line)
+       if (ip == NULL)
+               log_fatal("Impossible condition at %s:%d.", MDL);
++      while (ip && ip->hw_address.hbuf[0] == HTYPE_RESERVED) {
++              /* Try the other interfaces */
++              log_debug("Cannot form default DUID from interface %s.", ip->name);
++              ip = ip->next;
++      }
++      if (ip == NULL) {
++              return ISC_R_UNEXPECTED;
++      }
++
+       if ((ip->hw_address.hlen == 0) ||
+           (ip->hw_address.hlen > sizeof(ip->hw_address.hbuf)))
+               log_fatal("Impossible hardware address length at %s:%d.", MDL);
+@@ -4260,6 +4269,8 @@ form_duid(struct data_string *duid, const char *file, int line)
+               log_info("Created duid %s.", str);
+               dfree(str, MDL);
+       }
++      
++      return ISC_R_SUCCESS;
+ }
+ /* Write the default DUID to the lease store. */
+diff --git a/common/bpf.c b/common/bpf.c
+index d2a0549..aede242 100644
+--- a/common/bpf.c
++++ b/common/bpf.c
+@@ -650,6 +650,22 @@ get_hw_addr(const char *name, struct hardware *hw) {
+                         memcpy(&hw->hbuf[1], LLADDR(sa), sa->sdl_alen);
+                         break;
+ #endif /* IFT_FDDI */
++#if defined(IFT_PPP)
++                case IFT_PPP:
++                        if (local_family != AF_INET6)
++                             log_fatal("Unsupported device type %d for \"%s\"",
++                                        sa->sdl_type, name);
++                        hw->hlen = 0;
++                        hw->hbuf[0] = HTYPE_RESERVED;
++                        /* 0xdeadbeef should never occur on the wire,
++                         *  and is a signature that something went wrong.
++                         */
++                        hw->hbuf[1] = 0xde;
++                        hw->hbuf[2] = 0xad;
++                        hw->hbuf[3] = 0xbe;
++                        hw->hbuf[4] = 0xef;
++                        break;
++#endif
+                 default:
+                         log_fatal("Unsupported device type %d for \"%s\"",
+                                   sa->sdl_type, name);
+diff --git a/common/lpf.c b/common/lpf.c
+index bd20b3f..bb8822a 100644
+--- a/common/lpf.c
++++ b/common/lpf.c
+@@ -563,6 +563,22 @@ get_hw_addr(const char *name, struct hardware *hw) {
+                       hw->hbuf[0] = HTYPE_FDDI;
+                       memcpy(&hw->hbuf[1], sa->sa_data, 6);
+                       break;
++#if defined(ARPHRD_PPP)
++              case ARPHRD_PPP:
++                      if (local_family != AF_INET6)
++                              log_fatal("Unsupported device type %d for \"%s\"",
++                                         sa->sa_family, name);
++                      hw->hlen = 0;
++                      hw->hbuf[0] = HTYPE_RESERVED;
++                      /* 0xdeadbeef should never occur on the wire,
++                       * and is a signature that something went wrong.
++                       */
++                      hw->hbuf[1] = 0xde;
++                      hw->hbuf[2] = 0xad;
++                      hw->hbuf[3] = 0xbe;
++                      hw->hbuf[4] = 0xef;
++                      break;
++#endif
+               default:
+                       log_fatal("Unsupported device type %ld for \"%s\"",
+                                 (long int)sa->sa_family, name);
+diff --git a/includes/dhcp.h b/includes/dhcp.h
+index 5a73129..7202f1d 100644
+--- a/includes/dhcp.h
++++ b/includes/dhcp.h
+@@ -80,6 +80,8 @@ struct dhcp_packet {
+                                        * is no standard for this so we
+                                        * just steal a type            */
++#define HTYPE_RESERVED        0               /* RFC 5494 */
++
+ /* Magic cookie validating dhcp options field (and bootp vendor
+    extensions field). */
+ #define DHCP_OPTIONS_COOKIE   "\143\202\123\143"
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 25e1c72..4c5e877 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -3071,7 +3071,7 @@ void client_dns_remove(struct client_state *client, struct iaddr *addr);
+ void dhcpv4_client_assignments(void);
+ void dhcpv6_client_assignments(void);
+-void form_duid(struct data_string *duid, const char *file, int line);
++isc_result_t form_duid(struct data_string *duid, const char *file, int line);
+ void dhcp4o6_start(void);
+diff --git a/server/dhcpv6.c b/server/dhcpv6.c
+index 0ea0532..7d61dc5 100644
+--- a/server/dhcpv6.c
++++ b/server/dhcpv6.c
+@@ -482,6 +482,9 @@ generate_new_server_duid(void) {
+               if (p->hw_address.hlen > 0) {
+                       break;
+               }
++              if (p->next == NULL && p->hw_address.hbuf[0] == HTYPE_RESERVED) {
++                      log_error("Can not generate DUID from interfaces which do not have hardware addresses, please configure server-duid!");
++              }
+       }
+       if (p == NULL) {
+               return ISC_R_UNEXPECTED;
+-- 
+2.35.1
+
index 655c04fbb2024a99c5450c9cbd166d451cb0e15e..c6e9376f248881b539f00fb2404c887f36602c32 100644 (file)
@@ -1,13 +1,23 @@
-diff -urNp -x '*.orig' dhcp-4.3.5.org/client/dhclient.c dhcp-4.3.5/client/dhclient.c
---- dhcp-4.3.5.org/client/dhclient.c   2016-09-27 21:16:50.000000000 +0200
-+++ dhcp-4.3.5/client/dhclient.c       2021-04-01 22:09:11.002580226 +0200
-@@ -556,9 +556,81 @@ main(int argc, char **argv) {
+From be8f73c399c0f89192e57453db153aaa48fcbb2e Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:21:14 +0100
+Subject: [PATCH 03/28] Handle releasing interfaces requested by /sbin/ifup
+
+---
+ client/dhclient.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 72 insertions(+)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index 6c1c09a..07679a7 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -793,9 +793,81 @@ main(int argc, char **argv) {
                                }
                        }
                        fclose(pidfd);
 +              } else {
 +                      /* handle release for interfaces requested with Red Hat
-+                       * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid 
++                       * /sbin/ifup - pidfile will be /var/run/dhclient-$interface.pid
 +                       */
 +
 +                      if ((path_dhclient_pid == NULL) || (*path_dhclient_pid == '\0'))
@@ -28,10 +38,10 @@ diff -urNp -x '*.orig' dhcp-4.3.5.org/client/dhclient.c dhcp-4.3.5/client/dhclie
 +
 +                      for (dpfx=pfx; (dpfx >= 0) && (path_dhclient_pid[dpfx] != '-') && (path_dhclient_pid[dpfx] != '/'); dpfx--);
 +                              if ((dpfx > -1) && (path_dhclient_pid[dpfx] != '/'))
-+                                      pfx = dpfx;                 
++                                      pfx = dpfx;
 +
 +                      for (ip = interfaces; ip; ip = ip->next) {
-+                              if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED)) && (ip->name != NULL)) {
++                              if (interfaces_requested && (ip->flags & (INTERFACE_REQUESTED))) {
 +                                      int n_len = strlen(ip->name);
 +
 +                                      new_path_dhclient_pid = (char*) malloc(pfx + n_len + 6);
@@ -66,7 +76,7 @@ diff -urNp -x '*.orig' dhcp-4.3.5.org/client/dhclient.c dhcp-4.3.5/client/dhclie
 +              if ((pidfp = fopen(path_dhclient_pid, "r")) != NULL) {
 +                      if ((fscanf(pidfp, "%ld", &temp)==1) && ((dhcpid=(pid_t)temp) > 0)) {
 +                              snprintf(procfn,256,"/proc/%u",dhcpid);
-+                              dhc_running = (access(procfn, F_OK) == 0);          
++                              dhc_running = (access(procfn, F_OK) == 0);
 +                      }
 +
 +                      fclose(pidfp);
@@ -83,3 +93,6 @@ diff -urNp -x '*.orig' dhcp-4.3.5.org/client/dhclient.c dhcp-4.3.5/client/dhclie
        if (!quiet) {
                log_info("%s %s", message, PACKAGE_VERSION);
                log_info(copyright);
+-- 
+2.35.1
+
diff --git a/dhcp-rfc3442-classless-static-routes.patch b/dhcp-rfc3442-classless-static-routes.patch
new file mode 100644 (file)
index 0000000..2ab5a5e
--- /dev/null
@@ -0,0 +1,436 @@
+From 7e6299e72feaaf7e8bd499614999ba8a07dd1a8a Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:32:35 +0100
+Subject: [PATCH 12/28] RFC 3442 - Classless Static Route Option for DHCPv4
+ (#516325)
+
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #24572])
+---
+ client/clparse.c      | 13 ++++++++--
+ common/dhcp-options.5 | 43 +++++++++++++++++++++++++++++++++
+ common/inet.c         | 54 +++++++++++++++++++++++++++++++++++++++++
+ common/options.c      | 49 ++++++++++++++++++++++++++++++++++++-
+ common/parse.c        | 56 ++++++++++++++++++++++++++++++++++++++++++-
+ common/tables.c       |  2 ++
+ includes/dhcp.h       |  1 +
+ includes/dhcpd.h      |  2 ++
+ includes/dhctoken.h   |  3 ++-
+ 9 files changed, 218 insertions(+), 5 deletions(-)
+
+diff --git a/client/clparse.c b/client/clparse.c
+index 902b523..57f6456 100644
+--- a/client/clparse.c
++++ b/client/clparse.c
+@@ -31,7 +31,7 @@
+ struct client_config top_level_config;
+-#define NUM_DEFAULT_REQUESTED_OPTS    14
++#define NUM_DEFAULT_REQUESTED_OPTS    15
+ /* There can be 2 extra requested options for DHCPv4-over-DHCPv6. */
+ struct option *default_requested_options[NUM_DEFAULT_REQUESTED_OPTS + 2 + 1];
+@@ -90,7 +90,11 @@ isc_result_t read_client_conf ()
+                               dhcp_universe.code_hash, &code, 0, MDL);
+       /* 4 */
+-      code = DHO_ROUTERS;
++      /* The Classless Static Routes option code MUST appear in the parameter
++     * request list prior to both the Router option code and the Static
++     * Routes option code, if present. (RFC3442)
++       */
++      code = DHO_CLASSLESS_STATIC_ROUTES;
+       option_code_hash_lookup(&default_requested_options[3],
+                               dhcp_universe.code_hash, &code, 0, MDL);
+@@ -144,6 +148,11 @@ isc_result_t read_client_conf ()
+       option_code_hash_lookup(&default_requested_options[13],
+                               dhcp_universe.code_hash, &code, 0, MDL);
++      /* 15 */
++      code = DHO_ROUTERS;
++      option_code_hash_lookup(&default_requested_options[14],
++                              dhcp_universe.code_hash, &code, 0, MDL);
++
+       for (code = 0 ; code < NUM_DEFAULT_REQUESTED_OPTS ; code++) {
+               if (default_requested_options[code] == NULL)
+                       log_fatal("Unable to find option definition for "
+diff --git a/common/dhcp-options.5 b/common/dhcp-options.5
+index a784b32..86f04ed 100644
+--- a/common/dhcp-options.5
++++ b/common/dhcp-options.5
+@@ -117,6 +117,26 @@ hexadecimal, separated by colons.  For example:
+ or
+   option dhcp-client-identifier 43:4c:49:45:54:2d:46:4f:4f;
+ .fi
++.PP
++The
++.B destination-descriptor
++describe the IP subnet number and subnet mask
++of a particular destination using a compact encoding. This encoding
++consists of one octet describing the width of the subnet mask,
++followed by all the significant octets of the subnet number.
++The following table contains some examples of how various subnet
++number/mask combinations can be encoded:
++.nf
++.sp 1
++Subnet number   Subnet mask      Destination descriptor
++0               0                0
++10.0.0.0        255.0.0.0        8.10
++10.0.0.0        255.255.255.0    24.10.0.0
++10.17.0.0       255.255.0.0      16.10.17
++10.27.129.0     255.255.255.0    24.10.27.129
++10.229.0.128    255.255.255.128  25.10.229.0.128
++10.198.122.47   255.255.255.255  32.10.198.122.47
++.fi
+ .SH SETTING OPTION VALUES USING EXPRESSIONS
+ Sometimes it's helpful to be able to set the value of a DHCP option
+ based on some value that the client has sent.  To do this, you can
+@@ -1093,6 +1113,29 @@ dhclient-script will create routes:
+ .RE
+ .PP
+ .nf
++.B option \fBclassless-static-routes\fR \fIdestination-descriptor ip-address\fR
++                            [\fB,\fR \fIdestination-descriptor ip-address\fR...]\fB;\fR
++.fi
++.RS 0.25i
++.PP
++This option (see RFC3442) specifies a list of classless static routes
++that the client should install in its routing cache.
++.PP
++This option can contain one or more static routes, each of which
++consists of a destination descriptor and the IP address of the router
++that should be used to reach that destination.
++.PP
++Many clients may not implement the Classless Static Routes option.
++DHCP server administrators should therefore configure their DHCP
++servers to send both a Router option and a Classless Static Routes
++option, and should specify the default router(s) both in the Router
++option and in the Classless Static Routes option.
++.PP
++If the DHCP server returns both a Classless Static Routes option and
++a Router option, the DHCP client ignores the Router option.
++.RE
++.PP
++.nf
+ .B option \fBstreettalk-directory-assistance-server\fR \fIip-address\fR
+                                            [\fB,\fR \fIip-address\fR...]\fB;\fR
+ .fi
+diff --git a/common/inet.c b/common/inet.c
+index 0f7f168..7c446d4 100644
+--- a/common/inet.c
++++ b/common/inet.c
+@@ -519,6 +519,60 @@ free_iaddrcidrnetlist(struct iaddrcidrnetlist **result) {
+       return ISC_R_SUCCESS;
+ }
++static const char *
++inet_ntopdd(const unsigned char *src, unsigned srclen, char *dst, size_t size)
++{
++      char tmp[sizeof("32.255.255.255.255")];
++      int len;
++
++      switch (srclen) {
++              case 2:
++                      len = sprintf (tmp, "%u.%u", src[0], src[1]);
++                      break;
++              case 3:
++                      len = sprintf (tmp, "%u.%u.%u", src[0], src[1], src[2]);
++                      break;
++              case 4:
++                      len = sprintf (tmp, "%u.%u.%u.%u", src[0], src[1], src[2], src[3]);
++                      break;
++              case 5:
++                      len = sprintf (tmp, "%u.%u.%u.%u.%u", src[0], src[1], src[2], src[3], src[4]);
++                      break;
++              default:
++                      return NULL;
++      }
++      if (len < 0)
++              return NULL;
++
++      if (len > size) {
++              errno = ENOSPC;
++              return NULL;
++      }
++
++      return strcpy (dst, tmp);
++}
++
++/* pdestdesc() turns an iaddr structure into a printable dest. descriptor */
++const char *
++pdestdesc(const struct iaddr addr) {
++      static char pbuf[sizeof("255.255.255.255.255")];
++
++      if (addr.len == 0) {
++              return "<null destination descriptor>";
++      }
++      if (addr.len == 1) {
++              return "0";
++      }
++      if ((addr.len >= 2) && (addr.len <= 5)) {
++              return inet_ntopdd(addr.iabuf, addr.len, pbuf, sizeof(pbuf));
++      }
++
++      log_fatal("pdestdesc():%s:%d: Invalid destination descriptor length %d.",
++                MDL, addr.len);
++      /* quell compiler warnings */
++      return NULL;
++}
++
+ /* piaddr() turns an iaddr structure into a printable address. */
+ /* XXX: should use a const pointer rather than passing the structure */
+ const char *
+diff --git a/common/options.c b/common/options.c
+index 92c8fee..66433c4 100644
+--- a/common/options.c
++++ b/common/options.c
+@@ -734,7 +734,11 @@ cons_options(struct packet *inpacket, struct dhcp_packet *outpacket,
+                * packet.
+                */
+               priority_list[priority_len++] = DHO_SUBNET_MASK;
+-              priority_list[priority_len++] = DHO_ROUTERS;
++              if (lookup_option(&dhcp_universe, cfg_options,
++                                                      DHO_CLASSLESS_STATIC_ROUTES))
++                      priority_list[priority_len++] = DHO_CLASSLESS_STATIC_ROUTES;
++              else
++                      priority_list[priority_len++] = DHO_ROUTERS;
+               priority_list[priority_len++] = DHO_DOMAIN_NAME_SERVERS;
+               priority_list[priority_len++] = DHO_HOST_NAME;
+               priority_list[priority_len++] = DHO_FQDN;
+@@ -1812,6 +1816,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+       unsigned long tval;
+       isc_boolean_t a_array = ISC_FALSE;
+       int len_used;
++      unsigned int octets = 0;
+       if (emit_commas)
+               comma = ',';
+@@ -1820,6 +1825,7 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+       memset (enumbuf, 0, sizeof enumbuf);
++      if (option->format[0] != 'R') { /* see explanation lower */
+       /* Figure out the size of the data. */
+       for (l = i = 0; option -> format [i]; i++, l++) {
+               if (l >= sizeof(fmtbuf) - 1)
+@@ -2029,6 +2035,33 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+       if (numhunk < 0)
+               numhunk = 1;
++      } else { /* option->format[i] == 'R') */
++              /* R (destination descriptor) has variable length.
++               * We can find it only in classless static route option,
++               * so we are for sure parsing classless static route option now.
++               * We go through whole the option to check whether there are no
++               * missing/extra bytes.
++               * I didn't find out how to improve the existing code and that's the
++               * reason for this separate 'else' where I do my own checkings.
++               * I know it's little bit unsystematic, but it works.
++               */
++              numhunk = 0;
++              numelem = 2; /* RI */
++              fmtbuf[0]='R'; fmtbuf[1]='I'; fmtbuf[2]=0;
++              for (i =0; i < len; i = i + octets + 5) {
++                      if (data[i] > 32) { /* subnet mask width */
++                              log_error ("wrong subnet mask width in destination descriptor");
++                              break;
++                      }
++                      numhunk++;
++                      octets = ((data[i]+7) / 8);
++              }
++              if (i != len) {
++                      log_error ("classless static routes option has wrong size or "
++                                         "there's some garbage in format");
++              }
++      }
++
+       /* Cycle through the array (or hunk) printing the data. */
+       for (i = 0; i < numhunk; i++) {
+               if ((a_array == ISC_TRUE) && (i != 0) && (numelem > 0)) {
+@@ -2197,6 +2230,20 @@ const char *pretty_print_option (option, data, len, emit_commas, emit_quotes)
+                               strcpy(op, piaddr(iaddr));
+                               dp += 4;
+                               break;
++
++                            case 'R':
++                              if (dp[0] <= 32)
++                                      iaddr.len = (((dp[0]+7)/8)+1);
++                              else {
++                                      log_error ("wrong subnet mask width in destination descriptor");
++                                      return "<error>";
++                              }
++
++                              memcpy(iaddr.iabuf, dp, iaddr.len);
++                              strcpy(op, pdestdesc(iaddr));
++                              dp += iaddr.len;
++                              break;
++
+                             case '6':
+                               iaddr.len = 16;
+                               memcpy(iaddr.iabuf, dp, 16);
+diff --git a/common/parse.c b/common/parse.c
+index b123a6c..7cf4f2a 100644
+--- a/common/parse.c
++++ b/common/parse.c
+@@ -344,6 +344,39 @@ int parse_ip_addr (cfile, addr)
+       return 0;
+ }
++/*
++ * destination-descriptor :== NUMBER DOT NUMBER |
++ *                            NUMBER DOT NUMBER DOT NUMBER |
++ *                            NUMBER DOT NUMBER DOT NUMBER DOT NUMBER |
++ *                            NUMBER DOT NUMBER DOT NUMBER DOT NUMBER DOT NUMBER
++ */
++
++int parse_destination_descriptor (cfile, addr)
++      struct parse *cfile;
++      struct iaddr *addr;
++{
++              unsigned int mask_width, dest_dest_len;
++              addr -> len = 0;
++              if (parse_numeric_aggregate (cfile, addr -> iabuf,
++                                                                       &addr -> len, DOT, 10, 8)) {
++                      mask_width = (unsigned int)addr->iabuf[0];
++                      dest_dest_len = (((mask_width+7)/8)+1);
++                      if (mask_width > 32) {
++                              parse_warn (cfile,
++                              "subnet mask width (%u) greater than 32.", mask_width);
++                      }
++                      else if (dest_dest_len != addr->len) {
++                              parse_warn (cfile,
++                              "destination descriptor with subnet mask width %u "
++                              "should have %u octets, but has %u octets.",
++                              mask_width, dest_dest_len, addr->len);
++                      }
++
++                      return 1;
++              }
++              return 0;
++}
++
+ /*
+  * Return true if every character in the string is hexadecimal.
+  */
+@@ -724,8 +757,10 @@ unsigned char *parse_numeric_aggregate (cfile, buf,
+               if (count) {
+                       token = peek_token (&val, (unsigned *)0, cfile);
+                       if (token != separator) {
+-                              if (!*max)
++                              if (!*max) {
++                                      *max = count;
+                                       break;
++                              }
+                               if (token != RBRACE && token != LBRACE)
+                                       token = next_token (&val,
+                                                           (unsigned *)0,
+@@ -1672,6 +1707,9 @@ int parse_option_code_definition (cfile, option)
+             case IP_ADDRESS:
+               type = 'I';
+               break;
++            case DESTINATION_DESCRIPTOR:
++              type = 'R';
++              break;
+             case IP6_ADDRESS:
+               type = '6';
+               break;
+@@ -5124,6 +5162,15 @@ int parse_option_token (rv, cfile, fmt, expr, uniform, lookups)
+               }
+               break;
++            case 'R': /* destination descriptor */
++              if (!parse_destination_descriptor (cfile, &addr)) {
++                      return 0;
++              }
++              if (!make_const_data (&t, addr.iabuf, addr.len, 0, 1, MDL)) {
++                      return 0;
++              }
++              break;
++
+             case '6': /* IPv6 address. */
+               if (!parse_ip6_addr(cfile, &addr)) {
+                       return 0;
+@@ -5401,6 +5448,13 @@ int parse_option_decl (oc, cfile)
+                                       goto exit;
+                               len = ip_addr.len;
+                               dp = ip_addr.iabuf;
++                              goto alloc;
++
++                            case 'R': /* destination descriptor */
++                              if (!parse_destination_descriptor (cfile, &ip_addr))
++                                      goto exit;
++                              len = ip_addr.len;
++                              dp = ip_addr.iabuf;
+                             alloc:
+                               if (hunkix + len > sizeof hunkbuf) {
+diff --git a/common/tables.c b/common/tables.c
+index ce12fcd..96521a6 100644
+--- a/common/tables.c
++++ b/common/tables.c
+@@ -45,6 +45,7 @@ HASH_FUNCTIONS (option_code, const unsigned *, struct option,
+    Format codes:
+    I - IPv4 address
++   R - destination descriptor (RFC3442)
+    6 - IPv6 address
+    l - 32-bit signed integer
+    L - 32-bit unsigned integer
+@@ -223,6 +224,7 @@ static struct option dhcp_options[] = {
+ #endif
+       { "subnet-selection", "I",              &dhcp_universe, 118, 1 },
+       { "domain-search", "D",                 &dhcp_universe, 119, 1 },
++      { "classless-static-routes", "RIA",     &dhcp_universe, 121, 1 },
+       { "vivco", "Evendor-class.",            &dhcp_universe, 124, 1 },
+       { "vivso", "Evendor.",                  &dhcp_universe, 125, 1 },
+ #if 0
+diff --git a/includes/dhcp.h b/includes/dhcp.h
+index cafe172..5a73129 100644
+--- a/includes/dhcp.h
++++ b/includes/dhcp.h
+@@ -159,6 +159,7 @@ struct dhcp_packet {
+ #define DHO_V6_ONLY_PREFERRED                 108 /* RFC8925 */
+ #define DHO_SUBNET_SELECTION                  118 /* RFC3011! */
+ #define DHO_DOMAIN_SEARCH                     119 /* RFC3397 */
++#define DHO_CLASSLESS_STATIC_ROUTES           121 /* RFC3442 */
+ #define DHO_VIVCO_SUBOPTIONS                  124
+ #define DHO_VIVSO_SUBOPTIONS                  125
+diff --git a/includes/dhcpd.h b/includes/dhcpd.h
+index 4a57002..25e1c72 100644
+--- a/includes/dhcpd.h
++++ b/includes/dhcpd.h
+@@ -2967,6 +2967,7 @@ isc_result_t range2cidr(struct iaddrcidrnetlist **result,
+                       const struct iaddr *lo, const struct iaddr *hi);
+ isc_result_t free_iaddrcidrnetlist(struct iaddrcidrnetlist **result);
+ const char *piaddr (struct iaddr);
++const char *pdestdesc (struct iaddr);
+ char *piaddrmask(struct iaddr *, struct iaddr *);
+ char *piaddrcidr(const struct iaddr *, unsigned int);
+ u_int16_t validate_port(char *);
+@@ -3189,6 +3190,7 @@ void parse_client_lease_declaration (struct parse *,
+ int parse_option_decl (struct option_cache **, struct parse *);
+ void parse_string_list (struct parse *, struct string_list **, int);
+ int parse_ip_addr (struct parse *, struct iaddr *);
++int parse_destination_descriptor (struct parse *, struct iaddr *);
+ int parse_ip_addr_with_subnet(struct parse *, struct iaddrmatch *);
+ void parse_reject_statement (struct parse *, struct client_config *);
+diff --git a/includes/dhctoken.h b/includes/dhctoken.h
+index 6daa422..3f5334e 100644
+--- a/includes/dhctoken.h
++++ b/includes/dhctoken.h
+@@ -378,7 +378,8 @@ enum dhcp_token {
+       TOKEN_OCTAL = 678,
+       KEY_ALGORITHM = 679,
+       BOOTP_BROADCAST_ALWAYS = 680,
+-      DISCONNECT = 681
++      DESTINATION_DESCRIPTOR = 681,
++      DISCONNECT = 682
+ };
+ #define is_identifier(x)      ((x) >= FIRST_TOKEN &&  \
+-- 
+2.35.1
+
diff --git a/dhcp-stateless-duid-llt.patch b/dhcp-stateless-duid-llt.patch
new file mode 100644 (file)
index 0000000..95a311c
--- /dev/null
@@ -0,0 +1,28 @@
+From eeb2e5bcedd62f21472da165b80741f8072420cf Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:41:14 +0100
+Subject: [PATCH 19/28] dhclient: write DUID_LLT even in stateless mode
+ (#1156356)
+
+(Submitted to dhcp-bugs@isc.org - [ISC-Bugs #38144])
+---
+ client/dhclient.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/client/dhclient.c b/client/dhclient.c
+index d607975..6bbefc7 100644
+--- a/client/dhclient.c
++++ b/client/dhclient.c
+@@ -1462,6 +1462,9 @@ void run_stateless(int exit_mode, u_int16_t port)
+                       data_string_forget(&default_duid, MDL);
+               form_duid(&default_duid, MDL);
++              if (form_duid(&default_duid, MDL) == ISC_R_SUCCESS &&
++                  duid_type == DUID_LLT)
++                      write_duid(&default_duid);
+       }
+ #ifdef DHCP4o6
+-- 
+2.35.1
+
index abf89f2377d9dee1098b2f2c9a83290ab1e280f6..96e0b09730f5454e27ef1edb11f2c2ed8a6636c5 100644 (file)
@@ -1,6 +1,18 @@
-diff -up dhcp-4.3.4/server/bootp.c.unicast dhcp-4.3.4/server/bootp.c
---- dhcp-4.3.4/server/bootp.c.unicast  2016-03-22 14:16:51.000000000 +0100
-+++ dhcp-4.3.4/server/bootp.c  2016-05-02 15:09:40.023243008 +0200
+From 0a640394cb6f4a97fb87e53f049fba23523035c8 Mon Sep 17 00:00:00 2001
+From: Pavel Zhukov <pzhukov@redhat.com>
+Date: Thu, 21 Feb 2019 10:22:41 +0100
+Subject: [PATCH 04/28] Support unicast BOOTP for IBM pSeries systems (and
+ maybe others)
+
+---
+ server/bootp.c | 12 +++++++++++-
+ server/dhcp.c  | 33 ++++++++++++++++++++++++++-------
+ 2 files changed, 37 insertions(+), 8 deletions(-)
+
+diff --git a/server/bootp.c b/server/bootp.c
+index 919d483..338aac0 100644
+--- a/server/bootp.c
++++ b/server/bootp.c
 @@ -52,6 +52,7 @@ void bootp (packet)
        char msgbuf [1024];
        int ignorep;
@@ -34,10 +46,11 @@ diff -up dhcp-4.3.4/server/bootp.c.unicast dhcp-4.3.4/server/bootp.c
  
        /* If it comes from a client that already knows its address
           and is not requesting a broadcast response, and we can
-diff -up dhcp-4.3.4/server/dhcp.c.unicast dhcp-4.3.4/server/dhcp.c
---- dhcp-4.3.4/server/dhcp.c.unicast   2016-03-22 14:16:51.000000000 +0100
-+++ dhcp-4.3.4/server/dhcp.c   2016-05-02 15:10:13.255267511 +0200
-@@ -5132,6 +5132,7 @@ int locate_network (packet)
+diff --git a/server/dhcp.c b/server/dhcp.c
+index 0b261c2..ae805a6 100644
+--- a/server/dhcp.c
++++ b/server/dhcp.c
+@@ -5332,6 +5332,7 @@ int locate_network (packet)
        struct data_string data;
        struct subnet *subnet = (struct subnet *)0;
        struct option_cache *oc;
@@ -45,7 +58,7 @@ diff -up dhcp-4.3.4/server/dhcp.c.unicast dhcp-4.3.4/server/dhcp.c
  
  #if defined(DHCPv6) && defined(DHCP4o6)
        if (dhcpv4_over_dhcpv6 && (packet->dhcp4o6_response != NULL)) {
-@@ -5153,12 +5154,24 @@ int locate_network (packet)
+@@ -5353,12 +5354,24 @@ int locate_network (packet)
           from the interface, if there is one.   If not, fail. */
        if (!oc && !packet -> raw -> giaddr.s_addr) {
                if (packet -> interface -> shared_network) {
@@ -75,7 +88,7 @@ diff -up dhcp-4.3.4/server/dhcp.c.unicast dhcp-4.3.4/server/dhcp.c
        }
  
        /* If there's an option indicating link connection, and it's valid,
-@@ -5185,7 +5198,10 @@ int locate_network (packet)
+@@ -5384,7 +5397,10 @@ int locate_network (packet)
                data_string_forget (&data, MDL);
        } else {
                ia.len = 4;
@@ -87,7 +100,7 @@ diff -up dhcp-4.3.4/server/dhcp.c.unicast dhcp-4.3.4/server/dhcp.c
        }
  
        /* If we know the subnet on which the IP address lives, use it. */
-@@ -5193,7 +5209,10 @@ int locate_network (packet)
+@@ -5392,7 +5408,10 @@ int locate_network (packet)
                shared_network_reference (&packet -> shared_network,
                                          subnet -> shared_network, MDL);
                subnet_dereference (&subnet, MDL);
@@ -99,3 +112,6 @@ diff -up dhcp-4.3.4/server/dhcp.c.unicast dhcp-4.3.4/server/dhcp.c
        }
  
        /* Otherwise, fail. */
+-- 
+2.35.1
+
index e534e60e8b6f8060d38858ea2f4806cfcea2a083..b98bb2085d5d841c09422fbab5a6655a602028bf 100644 (file)
--- a/dhcp.spec
+++ b/dhcp.spec
@@ -4,7 +4,7 @@
 %bcond_without static_libs     # don't build static library
 %bcond_without systemd         # without systemd units
 
-%define         ver     4.4.2
+%define         ver     4.4.3
 %if 0
 %define         pverdot .P1
 %define         pverdir -P1
@@ -26,7 +26,7 @@ Epoch:                4
 License:       MIT
 Group:         Networking/Daemons
 Source0:       ftp://ftp.isc.org/isc/dhcp/%{ver}%{pverdir}/%{name}-%{ver}%{pverdir}.tar.gz
-# Source0-md5: 2afdaf8498dc1edaf3012efdd589b3e1
+# Source0-md5: 9076af4cc1293dde5a7c6cae7de6ab45
 Source1:       %{name}.init
 Source2:       %{name}6.init
 Source3:       %{name}-relay.init
@@ -51,6 +51,25 @@ Patch8:              %{name}-default-requested-options.patch
 Patch9:                %{name}-manpages.patch
 Patch10:       %{name}-extravars.patch
 Patch11:       systemd-notify.patch
+Patch12:       %{name}-CLOEXEC.patch
+Patch13:       %{name}-garbage-in-format-string-error.patch
+Patch14:       %{name}-handle-null-timouet.patch
+Patch15:       %{name}-capabilities.patch
+Patch16:       %{name}-rfc3442-classless-static-routes.patch
+Patch17:       %{name}-ppp.patch
+Patch18:       %{name}-lpf-ib.patch
+Patch19:       %{name}-add-guid-duid-to-logs.patch
+Patch20:       %{name}-duid_uuid.patch
+Patch21:       %{name}-client-request-release-bind-iface.patch
+Patch22:       %{name}-no-subnet-error2info.patch
+Patch23:       %{name}-stateless-duid-llt.patch
+Patch24:       %{name}-hwaddress.patch
+Patch25:       %{name}-confparse.patch
+Patch26:       %{name}-link-local-address.patch
+Patch27:       %{name}-option97-pxe-client-id.patch
+Patch28:       %{name}-detect-time-changes.patch
+Patch29:       bind-detect-time-changes.patch
+Patch30:       bind-system-getaddrinfo.patch
 URL:           https://www.isc.org/dhcp/
 BuildRequires: autoconf
 BuildRequires: automake
@@ -217,6 +236,31 @@ komunikacji z działającym serwerem ISC DHCP i jego kontroli.
 %patch9 -p1
 %patch10 -p1
 %patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
+%patch20 -p1
+%patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+
+cd bind
+tar -xvf bind.tar.gz
+ln -s bind-9* bind
+cd ..
+
+%patch29 -p1
+%patch30 -p1
 
 # Copy in documentation and example scripts for LDAP patch to dhcpd
 cp -a %{SOURCE11} README.ldap
index 4f7407595f751d6c8add62c44e93456a462ecb0b..c52e2739084214f790fc48afa4f321bbe965a105 100644 (file)
@@ -1,8 +1,7 @@
-From 8d974fd1f667e1b957ad4092fe66a8bb94f5f8fd Mon Sep 17 00:00:00 2001
+From d1b1f91a7982be28acdfb580996c93aafcc76cc2 Mon Sep 17 00:00:00 2001
 From: Pavel Zhukov <pzhukov@redhat.com>
 Date: Thu, 7 Nov 2019 14:47:45 +0100
-Subject: [PATCH 1/1] Add missed sd notify patch to manage dhcpd with systemd
-Cc: pzhukov@redhat.com
+Subject: [PATCH 27/28] Add missed sd notify patch to manage dhcpd with systemd
 
 ---
  configure.ac     | 11 +++++++++++
@@ -10,11 +9,10 @@ Cc: pzhukov@redhat.com
  server/dhcpd.c   | 12 ++++++++++++
  3 files changed, 35 insertions(+)
 
-diff --git a/configure.ac b/configure.ac
-index 15fc0d7..0c08000 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1014,6 +1014,17 @@ if test x$ldap = xyes || test x$ldapcrypto = xyes || test x$ldap_gssapi = xyes;
+diff -urNp -x '*.orig' dhcp-4.4.3.org/configure.ac dhcp-4.4.3/configure.ac
+--- dhcp-4.4.3.org/configure.ac        2022-03-08 09:26:03.000000000 +0000
++++ dhcp-4.4.3/configure.ac    2022-04-03 17:02:02.195434917 +0000
+@@ -970,6 +970,17 @@ if test x$ldap = xyes || test x$ldapcryp
      AC_SUBST(LDAP_CFLAGS, [$LDAP_CFLAGS])
  fi
  
@@ -32,11 +30,10 @@ index 15fc0d7..0c08000 100644
  # Append selected warning levels to CFLAGS before substitution (but after
  # AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[],[]) & etc).
  CFLAGS="$CFLAGS $STD_CWARNINGS"
-diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c
-index 7b4f4f1..9eb5bfd 100644
---- a/relay/dhcrelay.c
-+++ b/relay/dhcrelay.c
-@@ -37,6 +37,10 @@
+diff -urNp -x '*.orig' dhcp-4.4.3.org/relay/dhcrelay.c dhcp-4.4.3/relay/dhcrelay.c
+--- dhcp-4.4.3.org/relay/dhcrelay.c    2022-04-03 17:02:02.023434528 +0000
++++ dhcp-4.4.3/relay/dhcrelay.c        2022-04-03 17:02:02.196434919 +0000
+@@ -32,6 +32,10 @@
  #include <sys/time.h>
  #include <isc/file.h>
  
@@ -47,7 +44,7 @@ index 7b4f4f1..9eb5bfd 100644
  TIME default_lease_time = 43200; /* 12 hours... */
  TIME max_lease_time = 86400; /* 24 hours... */
  struct tree_cache *global_options[256];
-@@ -845,6 +849,14 @@ main(int argc, char **argv) {
+@@ -837,6 +841,14 @@ main(int argc, char **argv) {
        signal(SIGTERM, dhcp_signal_handler);  /* kill */
  #endif
  
@@ -62,10 +59,9 @@ index 7b4f4f1..9eb5bfd 100644
        /* Start dispatching packets and timeouts... */
        dispatch();
  
-diff --git a/server/dhcpd.c b/server/dhcpd.c
-index 4aef16b..778ef8d 100644
---- a/server/dhcpd.c
-+++ b/server/dhcpd.c
+diff -urNp -x '*.orig' dhcp-4.4.3.org/server/dhcpd.c dhcp-4.4.3/server/dhcpd.c
+--- dhcp-4.4.3.org/server/dhcpd.c      2022-03-08 09:26:03.000000000 +0000
++++ dhcp-4.4.3/server/dhcpd.c  2022-04-03 17:02:02.196434919 +0000
 @@ -60,6 +60,10 @@ gid_t set_gid = 0;
  struct class unknown_class;
  struct class known_class;
@@ -92,6 +88,3 @@ index 4aef16b..778ef8d 100644
        /*
         * Receive packets and dispatch them...
         * dispatch() will never return.
--- 
-2.14.5
-
This page took 0.390333 seconds and 4 git commands to generate.