]> git.pld-linux.org Git - packages/dhcp.git/commitdiff
- add libdhcp4client
authorPatryk Zawadzki <patrys@room-303.com>
Thu, 13 Dec 2007 23:12:16 +0000 (23:12 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    dhcp-dhcp4client.h -> 1.1
    dhcp-libdhcp4client.make -> 1.1
    dhcp-libdhcp4client.patch -> 1.1
    dhcp-libdhcp4client.pc -> 1.1
    dhcp-libdhcp_control.h -> 1.1
    dhcp-options.patch -> 1.1
    dhcp.spec -> 1.145

dhcp-dhcp4client.h [new file with mode: 0644]
dhcp-libdhcp4client.make [new file with mode: 0644]
dhcp-libdhcp4client.patch [new file with mode: 0644]
dhcp-libdhcp4client.pc [new file with mode: 0644]
dhcp-libdhcp_control.h [new file with mode: 0644]
dhcp-options.patch [new file with mode: 0644]
dhcp.spec

diff --git a/dhcp-dhcp4client.h b/dhcp-dhcp4client.h
new file mode 100644 (file)
index 0000000..80f83a8
--- /dev/null
@@ -0,0 +1,30 @@
+/* dhcp4client.h
+ *
+ * Interface to the ISC dhcp IPv4 client libdhcp4client library.
+ *
+ * Copyright (C) 2006  Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions of
+ * the GNU General Public License v.2, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY expressed or implied, including the implied warranties of
+ * MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details.  You should have received a copy of the
+ * GNU General Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+ * source code or documentation are not subject to the GNU General Public
+ * License and may only be used or replicated with the express permission of
+ * Red Hat, Inc.
+ *
+ * Red Hat Author(s): Jason Vas Dias
+ *                    David Cantrell <dcantrell@redhat.com>
+ */
+
+/* include libdhcp_control.h or libdhcp.h for this */
+extern struct libdhcp_control_s;
+
+/* The ISC IPv4 DHCP client main() function */
+extern int dhcpv4_client(struct libdhcp_control_s *dhc_ctl,
+                         int argc, char **argv, char **envp);
diff --git a/dhcp-libdhcp4client.make b/dhcp-libdhcp4client.make
new file mode 100644 (file)
index 0000000..624d746
--- /dev/null
@@ -0,0 +1,150 @@
+#
+# Makefile.dist for libdhcp4client
+#
+# We get the libdhcp4client library from the patched ISC source code.  We
+# rebuild key C files with -DLIBDHCP to turn on the library features we
+# need.  Normal build results in standard ISC code (i.e., not LIBDHCP
+# stuff enabled).  We then link together a static library and a shared
+# library with the new resulting objects.
+#
+# Copyright (C) 2006, 2007  Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions of
+# the GNU General Public License v.2, or (at your option) any later version.
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY expressed or implied, including the implied warranties of
+# MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE.  See the GNU General
+# Public License for more details.  You should have received a copy of the
+# GNU General Public License along with this program; if not, write to the
+# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+# source code or documentation are not subject to the GNU General Public
+# License and may only be used or replicated with the express permission of
+# Red Hat, Inc.
+#
+# Red Hat Author(s): Jason Vas Dias
+#                    David Cantrell <dcantrell@redhat.com>
+#
+
+# What version of ISC DHCP is this?
+VER   = $(shell grep DHCP_VERSION ../../includes/version.h | head -1 | cut -d '"' -f 2 | cut -d 'V' -f 2 | cut -d '-' -f 1)
+
+PROGS = libdhcp4client.a libdhcp4client-$(VER).so.0
+
+# NOTE: The ordering of these file lists is important!  We are using the
+# whole program optimization features of gcc, so the order matters here.
+
+# Source files shared by all objects
+COMMON_SRCS = client_clparse.c client_dhclient.c common_alloc.c common_bpf.c \
+              common_comapi.c common_conflex.c common_discover.c \
+              common_dispatch.c common_dns.c common_ethernet.c \
+              common_execute.c common_inet.c common_lpf.c common_memory.c \
+              common_options.c common_packet.c common_parse.c common_print.c \
+              common_socket.c common_tables.c common_tr.c common_tree.c \
+              dst_dst_api.c dst_base64.c dst_hmac_link.c dst_md5_dgst.c \
+              omapip_alloc.c omapip_array.c omapip_auth.c omapip_buffer.c \
+              omapip_connection.c omapip_convert.c omapip_dispatch.c \
+              omapip_errwarn.c omapip_handle.c omapip_hash.c \
+              omapip_listener.c omapip_mrtrace.c omapip_result.c \
+              omapip_support.c omapip_toisc.c omapip_trace.c
+
+# Source files for libdhcp4client.o
+CLIENT_SRCS = common_ctrace.c common_dlpi.c common_nit.c common_upf.c \
+              dst_dst_support.c dst_prandom.c omapip_generic.c \
+              omapip_message.c omapip_protocol.c
+
+# Source files for libres.o (minires)
+MINIRES_SRCS = minires_ns_date.c minires_ns_name.c minires_ns_parse.c \
+               minires_ns_samedomain.c minires_ns_sign.c minires_ns_verify.c \
+               minires_res_comp.c minires_res_findzonecut.c \
+               minires_res_init.c minires_res_mkquery.c \
+               minires_res_mkupdate.c minires_res_query.c minires_res_send.c \
+               minires_res_sendsigned.c minires_res_update.c
+
+# ISC dhcp headers we need to copy to /usr/include/dhcp4client
+DHCP_HEADERS = dhcpd.h cdefs.h osdep.h arpa/nameser.h minires/minires.h \
+               site.h cf/linux.h dhcp.h statement.h tree.h inet.h dhctoken.h \
+               omapip/omapip_p.h failover.h ctrace.h minires/resolv.h \
+               minires/res_update.h omapip/convert.h omapip/hash.h \
+               omapip/trace.h
+
+HDRS = dhcp4client.h
+SRCS = $(COMMON_SRCS) $(CLIENT_SRCS)
+OBJS = $(SRCS:.c=.o)
+
+INCLUDES = -I$(TOP) -I$(TOP)/includes -I$(TOP)/dst -I.
+CFLAGS   = $(DEBUG) $(PREDEFINES) $(INCLUDES) $(COPTS) \
+           -DCLIENT_PATH=${CLIENT_PATH} -DLIBDHCP -DUSE_MD5
+
+all: $(PROGS)
+
+install: all
+       install -p -m 0755 -D libdhcp4client-$(VER).so.0 $(DESTDIR)$(LIBDIR)/libdhcp4client-$(VER).so.0
+       ln -sf libdhcp4client-$(VER).so.0 $(DESTDIR)/$(LIBDIR)/libdhcp4client.so
+       install -p -m 0644 -D libdhcp4client.a $(DESTDIR)$(LIBDIR)/libdhcp4client.a
+       install -p -m 0644 -D dhcp4client.h $(DESTDIR)$(INCDIR)/dhcp4client/dhcp4client.h
+       for hdr in $(DHCP_HEADERS) ; do \
+               install -p -m 0644 -D $(TOP)/includes/$${hdr} $(DESTDIR)$(INCDIR)/dhcp4client/$${hdr} ; \
+       done
+
+depend:
+       $(MKDEP) $(INCLUDES) $(PREDEFINES) $(SRCS)
+
+clean:
+       -rm -f $(OBJS)
+
+realclean: clean
+       -rm -f $(PROG) *~ #*
+
+distclean: realclean
+       -rm -f Makefile
+
+# This isn't the cleanest way to set up links, but I prefer this so I don't
+# need object targets for each subdirectory.  The idea is simple.  Since
+# libdhcp4client is a linked together wad of objects from across the source
+# tree, we change / to _ when linking source files here.  Follow this example:
+#
+# We need to use client/dhclient.c, so we make this link:
+#     rm -f client_dhclient.c
+#     ln -s $(TOP)/client/dhclient.c client_dhclient.c
+#
+# Simple.  Given the way the ISC build system works, this is the easiest to
+# maintain and least invasive.
+#
+# David Cantrell <dcantrell@redhat.com>
+links:
+       @for target in $(SRCS); do \
+               source="`echo $$target | sed -e 's|_|/|'`"; \
+               if [ ! -b $$target ]; then \
+                       rm -f $$target; \
+               fi; \
+               ln -s $(TOP)/$$source $$target; \
+       done; \
+       for hdr in $(HDRS); do \
+               if [ ! -b $$hdr ]; then \
+                       rm -f $$hdr; \
+               fi; \
+               ln -s $(TOP)/libdhcp4client/$$hdr $$hdr; \
+       done
+
+# minires is difficult to build because it overrides things in common and dst,
+# so we just link with the already built libres.a since we need it all anyway
+libres.a:
+       if [ ! -f ../minires/$@ ]; then \
+               $(MAKE) -C ../minires; \
+       fi; \
+       ln ../minires/libres.a .; \
+       $(AR) x libres.a
+
+# Create the libraries
+# minires/res_query.o contains an undefined symbol __h_errno_set, is not
+# used by any dhcp code, and is optimized out by the linker when producing
+# the dhclient executable or a shared library
+libdhcp4client.a: $(OBJS) libres.a
+       $(AR) crus $@ $(OBJS) `$(AR) t libres.a | grep -v res_query.o`
+
+libdhcp4client-$(VER).so.0: $(OBJS) libres.a
+       $(CC) -shared -o $@ -Wl,-soname,$@ $(OBJS) `$(AR) t libres.a | grep -v res_query.o`
+
+# Dependencies (semi-automatically-generated)
diff --git a/dhcp-libdhcp4client.patch b/dhcp-libdhcp4client.patch
new file mode 100644 (file)
index 0000000..c2d7f3a
--- /dev/null
@@ -0,0 +1,1092 @@
+diff -up dhcp-3.1.0/omapip/dispatch.c.libdhcp4client dhcp-3.1.0/omapip/dispatch.c
+--- dhcp-3.1.0/omapip/dispatch.c.libdhcp4client        2005-03-17 15:15:21.000000000 -0500
++++ dhcp-3.1.0/omapip/dispatch.c       2007-10-24 14:55:56.000000000 -0400
+@@ -34,7 +34,7 @@
+ #include <omapip/omapip_p.h>
+-static omapi_io_object_t omapi_io_states;
++omapi_io_object_t omapi_io_states;
+ TIME cur_time;
+ OMAPI_OBJECT_ALLOC (omapi_io,
+diff -up dhcp-3.1.0/omapip/errwarn.c.libdhcp4client dhcp-3.1.0/omapip/errwarn.c
+--- dhcp-3.1.0/omapip/errwarn.c.libdhcp4client 2007-10-24 14:55:56.000000000 -0400
++++ dhcp-3.1.0/omapip/errwarn.c        2007-10-24 14:57:16.000000000 -0400
+@@ -39,6 +39,11 @@ static char copyright[] =
+ #include <omapip/omapip_p.h>
+ #include <errno.h>
++#ifdef LIBDHCP
++#include <isc-dhcp/libdhcp_control.h>
++extern LIBDHCP_Control *libdhcp_control;
++#endif
++
+ #ifdef DEBUG
+ int log_perror = -1;
+ #else
+@@ -48,7 +53,9 @@ int log_priority;
+ void (*log_cleanup) (void);
+ #define CVT_BUF_MAX 1023
++#ifndef LIBDHCP
+ static char mbuf [CVT_BUF_MAX + 1];
++#endif
+ static char fbuf [CVT_BUF_MAX + 1];
+ /* Log an error message, then exit... */
+@@ -58,6 +65,16 @@ void log_fatal (const char * fmt, ... )
+   va_list list;
+   do_percentm (fbuf, fmt);
++  
++#ifdef LIBDHCP
++  if (libdhcp_control && (libdhcp_control->eh)) {
++      va_start (list, fmt);
++      libdhcp_control->eh(libdhcp_control, LOG_FATAL, fbuf, list);
++      va_end(list);
++      libdhcp_control->finished = 1;
++      return;
++  }
++#else
+   /* %Audit% This is log output. %2004.06.17,Safe%
+    * If we truncate we hope the user can get a hint from the log.
+@@ -91,6 +108,7 @@ void log_fatal (const char * fmt, ... )
+   if (log_cleanup)
+         (*log_cleanup) ();
+   exit (1);
++#endif
+ }
+ /* Log an error message... */
+@@ -101,6 +119,13 @@ int log_error (const char * fmt, ...)
+   do_percentm (fbuf, fmt);
++#ifdef LIBDHCP
++  if (libdhcp_control && libdhcp_control->eh) {
++      va_start (list, fmt);
++      libdhcp_control->eh(libdhcp_control, LOG_ERR, fbuf, list);
++      va_end(list);
++  }
++#else
+   /* %Audit% This is log output. %2004.06.17,Safe%
+    * If we truncate we hope the user can get a hint from the log.
+    */
+@@ -116,7 +141,7 @@ int log_error (const char * fmt, ...)
+         write (STDERR_FILENO, mbuf, strlen (mbuf));
+         write (STDERR_FILENO, "\n", 1);
+   }
+-
++#endif
+   return 0;
+ }
+@@ -128,6 +153,13 @@ int log_info (const char *fmt, ...)
+   do_percentm (fbuf, fmt);
++#ifdef LIBDHCP
++  if (libdhcp_control && libdhcp_control->eh) {
++      va_start (list, fmt);
++      libdhcp_control->eh(libdhcp_control, LOG_INFO, fbuf, list);
++      va_end(list);
++  }
++#else
+   /* %Audit% This is log output. %2004.06.17,Safe%
+    * If we truncate we hope the user can get a hint from the log.
+    */
+@@ -143,7 +175,7 @@ int log_info (const char *fmt, ...)
+         write (STDERR_FILENO, mbuf, strlen (mbuf));
+         write (STDERR_FILENO, "\n", 1);
+   }
+-
++#endif
+   return 0;
+ }
+@@ -154,7 +186,13 @@ int log_debug (const char *fmt, ...)
+   va_list list;
+   do_percentm (fbuf, fmt);
+-
++#ifdef LIBDHCP
++  if (libdhcp_control && libdhcp_control->eh) {
++      va_start (list, fmt);
++      libdhcp_control->eh(libdhcp_control, LOG_DEBUG, fbuf, list);
++      va_end(list);
++  }
++#else
+   /* %Audit% This is log output. %2004.06.17,Safe%
+    * If we truncate we hope the user can get a hint from the log.
+    */
+@@ -170,7 +208,7 @@ int log_debug (const char *fmt, ...)
+         write (STDERR_FILENO, mbuf, strlen (mbuf));
+         write (STDERR_FILENO, "\n", 1);
+   }
+-
++#endif
+   return 0;
+ }
+diff -up dhcp-3.1.0/omapip/alloc.c.libdhcp4client dhcp-3.1.0/omapip/alloc.c
+--- dhcp-3.1.0/omapip/alloc.c.libdhcp4client   2006-02-24 18:16:30.000000000 -0500
++++ dhcp-3.1.0/omapip/alloc.c  2007-10-24 14:55:56.000000000 -0400
+@@ -40,6 +40,33 @@ static char copyright[] =
+ #include <omapip/omapip_p.h>
++#ifdef LIBDHCP
++/* OK, we need a quick and dirty way of freeing all memory used by libdhcp. 
++   All pointers will be stored in a glibc tree on alloc, and removed on free.
++   This is not too expensive for light single-call library use.
++*/
++#include <search.h>  
++extern void tdestroy (void *root, void (*free_node)(void *nodep));
++static void *all_pointers=0L;
++static int ptr_comparator(const void *p1, const void *p2) {
++    return ((p1 == p2) ? 0 : ((p1 > p2) ? 1 : -1));
++}
++
++static void record_pointer(void *ptr) {
++    tsearch(ptr, &(all_pointers), ptr_comparator);
++}
++
++static void forget_pointer(void *ptr) {
++    tdelete(ptr, &(all_pointers), ptr_comparator);
++}
++
++void omapi_free_all_pointers(void) {
++    if (all_pointers != NULL)
++              tdestroy(all_pointers, free);
++    all_pointers = NULL;
++}
++#endif
++
+ #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+               defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ struct dmalloc_preamble *dmalloc_list;
+@@ -78,7 +105,9 @@ VOIDPTR dmalloc (size, file, line)
+               return (VOIDPTR)0;
+       foo = malloc(len);
+-
++#ifdef LIBDHCP
++      record_pointer(foo);
++#endif
+       if (!foo)
+               return (VOIDPTR)0;
+       bar = (VOIDPTR)(foo + DMDOFFSET);
+@@ -200,6 +229,9 @@ void dfree (ptr, file, line)
+                    0, (unsigned char *)ptr + DMDOFFSET, 0, 1, RC_MALLOC);
+ #endif
+       free (ptr);
++#ifdef LIBDHCP
++      forget_pointer(ptr);
++#endif
+ }
+ #if defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL) || \
+diff -up dhcp-3.1.0/configure.libdhcp4client dhcp-3.1.0/configure
+--- dhcp-3.1.0/configure.libdhcp4client        2005-03-17 15:14:55.000000000 -0500
++++ dhcp-3.1.0/configure       2007-10-24 14:55:56.000000000 -0400
+@@ -246,7 +246,7 @@ if [ ! -d $workname ]; then
+ fi
+ if [ x"$dirs" = x ]; then
+-  dirs=". client server relay common omapip dhcpctl minires dst"
++  dirs=". client server relay common omapip dhcpctl minires dst libdhcp4client"
+ fi
+ for foo in $dirs; do
+diff -up dhcp-3.1.0/dst/hmac_link.c.libdhcp4client dhcp-3.1.0/dst/hmac_link.c
+--- dhcp-3.1.0/dst/hmac_link.c.libdhcp4client  2001-02-22 02:22:08.000000000 -0500
++++ dhcp-3.1.0/dst/hmac_link.c 2007-10-24 14:55:56.000000000 -0400
+@@ -38,6 +38,10 @@ static const char rcsid[] = "$Header: /p
+ #include "dst_internal.h"
++#ifdef LIBDHCP
++extern void* dmalloc(size_t,char *,int);
++#endif
++
+ #ifdef USE_MD5
+ # include "md5.h"
+ # ifndef _MD5_H_
+@@ -86,7 +90,11 @@ dst_hmac_md5_sign(const int mode, DST_KE
+       MD5_CTX *ctx = NULL;
+       if (mode & SIG_MODE_INIT) 
++#ifdef LIBDHCP
++              ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__);
++#else
+               ctx = (MD5_CTX *) malloc(sizeof(*ctx));
++#endif
+       else if (context)
+               ctx = (MD5_CTX *) *context;
+       if (ctx == NULL) 
+@@ -153,7 +161,11 @@ dst_hmac_md5_verify(const int mode, DST_
+       MD5_CTX *ctx = NULL;
+       if (mode & SIG_MODE_INIT) 
++#ifdef LIBDHCP
++              ctx = (MD5_CTX *) dmalloc(sizeof(*ctx),__FILE__,__LINE__);
++#else
+               ctx = (MD5_CTX *) malloc(sizeof(*ctx));
++#endif
+       else if (context)
+               ctx = (MD5_CTX *) *context;
+       if (ctx == NULL) 
+@@ -217,8 +229,11 @@ dst_buffer_to_hmac_md5(DST_KEY *dkey, co
+       if (dkey == NULL || key == NULL || keylen < 0)
+               return (-1);
+-
++#ifdef  LIBDHCP
++      if ((hkey = (HMAC_Key *) dmalloc(sizeof(HMAC_Key),__FILE__,__LINE__)) == NULL)
++#else
+       if ((hkey = (HMAC_Key *) malloc(sizeof(HMAC_Key))) == NULL)
++#endif
+                 return (-2);
+       memset(hkey->hk_ipad, 0, sizeof(hkey->hk_ipad));
+@@ -347,7 +362,11 @@ dst_hmac_md5_key_from_file_format(DST_KE
+       if (eol == NULL)
+               return (-4);
+       len = eol - p;
++#ifdef LIBDHCP
++      tmp = dmalloc(len + 2,__FILE__,__LINE__);
++#else
+       tmp = malloc(len + 2);
++#endif
+       memcpy(tmp, p, len);
+       *(tmp + len) = 0x0;
+       key_len = b64_pton((char *)tmp, key, HMAC_LEN+1);       /* see above */
+@@ -439,8 +458,11 @@ dst_hmac_md5_generate_key(DST_KEY *key, 
+               return(0);
+       
+       len = size > 64 ? 64 : size;
++#ifdef LIBDHCP
++      buff = dmalloc(len+8,__FILE__,__LINE__);
++#else
+       buff = malloc(len+8);
+-
++#endif
+       n = dst_random(DST_RAND_SEMI, len, buff);
+       n += dst_random(DST_RAND_KEY, len, buff);
+       if (n <= len) { /* failed getting anything */
+@@ -463,7 +485,11 @@ dst_hmac_md5_init()
+ {
+       if (dst_t_func[KEY_HMAC_MD5] != NULL)
+               return (1);
++#ifdef LIBDHCP
++      dst_t_func[KEY_HMAC_MD5] = dmalloc(sizeof(struct dst_func),__FILE__,__LINE__);
++#else
+       dst_t_func[KEY_HMAC_MD5] = malloc(sizeof(struct dst_func));
++#endif
+       if (dst_t_func[KEY_HMAC_MD5] == NULL)
+               return (0);
+       memset(dst_t_func[KEY_HMAC_MD5], 0, sizeof(struct dst_func));
+diff -up dhcp-3.1.0/common/discover.c.libdhcp4client dhcp-3.1.0/common/discover.c
+--- dhcp-3.1.0/common/discover.c.libdhcp4client        2006-11-07 18:41:39.000000000 -0500
++++ dhcp-3.1.0/common/discover.c       2007-10-24 14:55:56.000000000 -0400
+@@ -121,6 +121,10 @@ isc_result_t interface_initialize (omapi
+    register that interface with the network I/O software, figure out what
+    subnet it's on, and add it to the list of interfaces. */
++#ifdef LIBDHCP
++int have_setup_fallback = 0;
++#endif
++
+ void discover_interfaces (state)
+       int state;
+ {
+@@ -141,7 +145,9 @@ void discover_interfaces (state)
+       char *s;
+ #endif
+       isc_result_t status;
++#ifndef LIBDHCP
+       static int setup_fallback = 0;
++#endif
+       int wifcount = 0;
+       /* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
+@@ -695,10 +701,17 @@ void discover_interfaces (state)
+               log_fatal ("Not configured to listen on any interfaces!");
+       }
++#ifdef LIBDHCP
++      if (!have_setup_fallback) {
++              have_setup_fallback = 1;
++              maybe_setup_fallback ();
++      }
++#else
+       if (!setup_fallback) {
+               setup_fallback = 1;
+               maybe_setup_fallback ();
+       }
++#endif
+ #if defined (HAVE_SETFD)
+       if (fallback_interface) {
+diff -up dhcp-3.1.0/common/tree.c.libdhcp4client dhcp-3.1.0/common/tree.c
+--- dhcp-3.1.0/common/tree.c.libdhcp4client    2007-02-14 17:41:22.000000000 -0500
++++ dhcp-3.1.0/common/tree.c   2007-10-24 14:55:56.000000000 -0400
+@@ -41,7 +41,7 @@ static char copyright[] =
+ #include <omapip/omapip_p.h>
+ #include <ctype.h>
+-struct binding_scope *global_scope;
++struct binding_scope __attribute__ ((visibility ("default"))) *global_scope;
+ static int do_host_lookup PROTO ((struct data_string *,
+                                 struct dns_host_entry *));
+@@ -2761,6 +2761,7 @@ int evaluate_numeric_expression (result,
+    result of that evaluation.   There should never be both an expression
+    and a valid data_string. */
++__attribute__ ((visibility ("default")))
+ int evaluate_option_cache (result, packet, lease, client_state,
+                          in_options, cfg_options, scope, oc, file, line)
+       struct data_string *result;
+diff -up dhcp-3.1.0/common/options.c.libdhcp4client dhcp-3.1.0/common/options.c
+--- dhcp-3.1.0/common/options.c.libdhcp4client 2007-05-23 15:26:22.000000000 -0400
++++ dhcp-3.1.0/common/options.c        2007-10-24 14:55:56.000000000 -0400
+@@ -2501,6 +2501,7 @@ int fqdn_option_space_encapsulate (resul
+       return 1;
+ }
++__attribute__ ((visibility ("default")))
+ void option_space_foreach (struct packet *packet, struct lease *lease,
+                          struct client_state *client_state,
+                          struct option_state *in_options,
+diff -up dhcp-3.1.0/common/dispatch.c.libdhcp4client dhcp-3.1.0/common/dispatch.c
+--- dhcp-3.1.0/common/dispatch.c.libdhcp4client        2007-10-24 14:55:56.000000000 -0400
++++ dhcp-3.1.0/common/dispatch.c       2007-10-24 14:55:56.000000000 -0400
+@@ -39,8 +39,24 @@ static char copyright[] =
+ #include "dhcpd.h"
+-struct timeout *timeouts;
+-static struct timeout *free_timeouts;
++struct timeout {
++#ifndef LIBDHCP
++      struct timeout *next;
++#endif
++      TIME when;
++      void (*func) PROTO ((void *));
++      void *what;
++      tvref_t ref;
++      tvunref_t unref;
++};
++
++#ifdef LIBDHCP
++static struct timeout *timeouts = NULL;
++static int ntimeouts = 0;
++#else
++static struct timeout *timeouts = NULL;
++static struct timeout *free_timeouts = NULL;
++#endif
+ void set_time(TIME t)
+ {
+@@ -53,9 +69,41 @@ void set_time(TIME t)
+ struct timeval *process_outstanding_timeouts (struct timeval *tvp)
+ {
++#ifdef LIBDHCP
++      int i;
++      struct timeout t = { 0 };
++#endif
+       /* Call any expired timeouts, and then if there's
+          still a timeout registered, time out the select
+          call then. */
++#ifdef LIBDHCP
++      if (!ntimeouts)
++              return NULL;
++
++      for (i = 0; i < ntimeouts && timeouts[i].when <= cur_time;) {
++              struct timeout *new_timeouts;
++              size_t n;
++
++              memmove(&t, &timeouts[i], sizeof (t));
++
++              n = (ntimeouts - i - 1) * sizeof (t);
++              memmove(&timeouts[i+1], &timeouts[i], n);
++
++              n = --ntimeouts * sizeof (t);
++              new_timeouts = realloc(timeouts, n);
++              /* XXX broken API, no way to return error here */
++              if (new_timeouts || !n)
++                      timeouts = new_timeouts;
++
++              if (t.func)
++                      t.func(t.what);
++              if (t.unref)
++                      t.unref(t.what, MDL);
++      }
++      if (tvp && ntimeouts) {
++              tvp->tv_sec = timeouts[0].when;
++              tvp->tv_usec = 0;
++#else
+       another:
+       if (timeouts) {
+               struct timeout *t;
+@@ -73,9 +121,15 @@ struct timeval *process_outstanding_time
+                       tvp -> tv_sec = timeouts -> when;
+                       tvp -> tv_usec = 0;
+               }
++#endif
+               return tvp;
++#ifdef LIBDHCP
++      }
++      return NULL;
++#else
+       } else
+               return (struct timeval *)0;
++#endif
+ }
+ /* Wait for packets to come in using select().   When one does, call
+@@ -104,13 +158,28 @@ void add_timeout (when, where, what, ref
+       tvref_t ref;
+       tvunref_t unref;
+ {
++#ifdef LIBDHCP
++      struct timeout t = {
++              .when = when,
++              .func = where,
++              .what = what,
++              .ref = ref,
++              .unref = unref
++      };
++      struct timeout *new_timeouts;
++      int i, pos = 0;
++#else
+       struct timeout *t, *q;
++#endif
+       /* See if this timeout supersedes an existing timeout. */
++#ifdef LIBDHCP
++      for (i = 0; i < ntimeouts; i++) {
++              struct timeout *q = &timeouts[i];
++#else
+       t = (struct timeout *)0;
+       for (q = timeouts; q; q = q -> next) {
+-              if ((where == NULL || q -> func == where) &&
+-                  q -> what == what) {
++              if ((where == NULL || q -> func == where) && q -> what == what) {
+                       if (t)
+                               t -> next = q -> next;
+                       else
+@@ -119,7 +188,29 @@ void add_timeout (when, where, what, ref
+               }
+               t = q;
+       }
++#endif
++#ifdef LIBDHCP
++              /* If this one is already in the list with a different time,
++               * remove it and re-add */
++              if ((where == NULL || q->func == where) &&
++                              q->what == what) {
++                      size_t n = (--ntimeouts - i) * sizeof (*q);
++                      memmove(&t, q, sizeof (t));
++
++                      if (n)
++                              memmove(&timeouts[i], &timeouts[i+1], n);
++
++                      if (ntimeouts) {
++                              new_timeouts = realloc(timeouts, ntimeouts * sizeof (*q));
++                              /* XXX broken API, no way to return error here */
++                              if (new_timeouts)
++                                      timeouts = new_timeouts;
++                      } else {
++                              timeouts = NULL;
++                      }
++                      add_timeout(when, where, what, ref, unref);
++#else
+       /* If we didn't supersede a timeout, allocate a timeout
+          structure now. */
+       if (!q) {
+@@ -128,7 +219,7 @@ void add_timeout (when, where, what, ref
+                       free_timeouts = q -> next;
+               } else {
+                       q = ((struct timeout *)
+-                           dmalloc (sizeof (struct timeout), MDL));
++                              dmalloc (sizeof (struct timeout), MDL));
+                       if (!q)
+                               log_fatal ("add_timeout: no memory!");
+               }
+@@ -158,22 +249,76 @@ void add_timeout (when, where, what, ref
+               if (t -> next -> when > q -> when) {
+                       q -> next = t -> next;
+                       t -> next = q;
++#endif
+                       return;
++#ifdef LIBDHCP
++              } else if (timeouts[i].when > when) {
++                      pos = i;
++#endif
+               }
+       }
++#ifdef LIBDHCP
++      /* If we didn't supersede an existing timeout, then pos is set
++       * to the timeout which will post after this one.  Insert this
++       * one before it. */
++
++      new_timeouts = realloc(timeouts, sizeof (t) * (ntimeouts+1));
++      /* XXX broken API, no way to return error here */
++      if (new_timeouts) {
++              /* ntimeouts = 10
++               * pos = 3;
++               * n = 10-3 * sizeof (t) = 7 * sizeof (t) 
++               */
++              size_t n = (ntimeouts - pos) * sizeof (t);
++
++              timeouts = new_timeouts;
++              memmove(&timeouts[pos+1], &timeouts[pos], n);
++              memmove(&timeouts[pos], &t, sizeof (t));
++              ntimeouts++;
++      }
++#else
+       /* End of list. */
+       t -> next = q;
+       q -> next = (struct timeout *)0;
++#endif
+ }
+ void cancel_timeout (where, what)
+       void (*where) PROTO ((void *));
+       void *what;
+ {
++#ifdef LIBDHCP
++      struct timeout t;
++      int i = 0;
++#else
+       struct timeout *t, *q;
++#endif
+       /* Look for this timeout on the list, and unlink it if we find it. */
++#ifdef LIBDHCP
++      for (i = 0; i < ntimeouts; i++) {
++              struct timeout *new_timeouts, *q = &timeouts[i];
++
++              if (q->func == where && q->what == what) {
++                      size_t n;
++
++                      memmove(&t, q, sizeof (t));
++
++                      n = (ntimeouts - i - 1) * sizeof (t);
++                      memmove(&timeouts[i+1], &timeouts[i], n);
++
++                      n = --ntimeouts * sizeof (t);
++                      new_timeouts = realloc(timeouts, n);
++                      /* XXX broken API, no way to return error here */
++                      if (new_timeouts || !n)
++                              timeouts = new_timeouts;
++
++                      if (t.unref)
++                              t.unref(t.what, MDL);
++              }
++      }
++#else
+       t = (struct timeout *)0;
+       for (q = timeouts; q; q = q -> next) {
+               if (q -> func == where && q -> what == what) {
+@@ -193,11 +338,16 @@ void cancel_timeout (where, what)
+               q -> next = free_timeouts;
+               free_timeouts = q;
+       }
++#endif
+ }
+ #if defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+ void cancel_all_timeouts ()
+ {
++#ifdef LIBDHCP
++      cur_time = TIME_MAX;
++      process_outstanding_timeouts(NULL);
++#else
+       struct timeout *t, *n;
+       for (t = timeouts; t; t = n) {
+               n = t -> next;
+@@ -205,13 +355,20 @@ void cancel_all_timeouts ()
+               t -> next = free_timeouts;
+               free_timeouts = t;
+       }
++#endif
+ }
++__attribute__ ((visibility ("default")))
+ void relinquish_timeouts ()
+ {
++#ifdef LIBDHCP
++      while (ntimeouts)
++              cancel_timeout(timeouts[0].func, timeouts[0].what);
++#else
+       struct timeout *t, *n;
+       for (t = free_timeouts; t; t = n) {
+               n = t -> next;
+               dfree (t, MDL);
+       }
++#endif
+ }
+diff -up dhcp-3.1.0/common/alloc.c.libdhcp4client dhcp-3.1.0/common/alloc.c
+--- dhcp-3.1.0/common/alloc.c.libdhcp4client   2006-06-01 16:23:17.000000000 -0400
++++ dhcp-3.1.0/common/alloc.c  2007-10-24 14:55:56.000000000 -0400
+@@ -1013,7 +1013,11 @@ int executable_statement_reference (ptr,
+       return 1;
+ }
++#ifdef LIBDHCP
++struct packet *free_packets;
++#else
+ static struct packet *free_packets;
++#endif
+ #if defined (DEBUG_MEMORY_LEAKAGE) || \
+               defined (DEBUG_MEMORY_LEAKAGE_ON_EXIT)
+diff -up dhcp-3.1.0/includes/dhcpd.h.libdhcp4client dhcp-3.1.0/includes/dhcpd.h
+--- dhcp-3.1.0/includes/dhcpd.h.libdhcp4client 2007-10-24 14:55:56.000000000 -0400
++++ dhcp-3.1.0/includes/dhcpd.h        2007-10-24 14:55:56.000000000 -0400
+@@ -1000,14 +1000,6 @@ struct hardware_link {
+ typedef void (*tvref_t)(void *, void *, const char *, int);
+ typedef void (*tvunref_t)(void *, const char *, int);
+-struct timeout {
+-      struct timeout *next;
+-      TIME when;
+-      void (*func) PROTO ((void *));
+-      void *what;
+-      tvref_t ref;
+-      tvunref_t unref;
+-};
+ struct protocol {
+       struct protocol *next;
+@@ -1960,7 +1952,6 @@ extern void (*bootp_packet_handler) PROT
+                                           struct dhcp_packet *, unsigned,
+                                           unsigned int,
+                                           struct iaddr, struct hardware *));
+-extern struct timeout *timeouts;
+ extern omapi_object_type_t *dhcp_type_interface;
+ #if defined (TRACING)
+ trace_type_t *interface_trace;
+diff -up dhcp-3.1.0/client/dhclient.c.libdhcp4client dhcp-3.1.0/client/dhclient.c
+--- dhcp-3.1.0/client/dhclient.c.libdhcp4client        2007-10-24 14:55:56.000000000 -0400
++++ dhcp-3.1.0/client/dhclient.c       2007-10-24 14:56:20.000000000 -0400
+@@ -82,16 +82,52 @@ int quiet=0;
+ int nowait=0;
+ int bootp_broadcast_always = 0;
++#ifdef LIBDHCP
++FILE *leaseFile = NULL;
++#endif
++
+ extern u_int32_t default_requested_options[];
+ #ifdef EXTENDED_NEW_OPTION_INFO
+ int extended_option_environment = 0;
+ #endif
+ static void usage PROTO ((void));
++#ifdef LIBDHCP
++#include "isc-dhcp/libdhcp_control.h"
++LIBDHCP_Control *libdhcp_control;
++static void libdhcp_dispatch(void)
++{
++      struct timeval tv = { 0, 0 }, *tvp;
++      isc_result_t status;
++
++      /* Wait for a packet, or a timeout, or libdhcp being finished */
++      do {
++              tvp = process_outstanding_timeouts(&tv);
++              status = omapi_one_dispatch(0, tvp);
++
++              if (libdhcp_control && ((status == ISC_R_TIMEDOUT) || (libdhcp_control->timeout && (time(NULL) >= (libdhcp_control->timeout + libdhcp_control->now))))) {
++                      if (libdhcp_control->callback)
++                              libdhcp_control->callback(libdhcp_control, DHC_TIMEDOUT, NULL);
++
++                      break;
++              }
++      } while ((status != ISC_R_TIMEDOUT) && ((!libdhcp_control) || (!(libdhcp_control->finished))));
++}
++
++extern void omapi_free_all_pointers(void);
++
++__attribute__ ((visibility ("default")))
++int dhcpv4_client (libdhcp_ctl, argc, argv, envp)
++      LIBDHCP_Control *libdhcp_ctl;
++#else
+ int main (argc, argv, envp)
++#endif
+       int argc;
+       char **argv, **envp;
+ {
++#ifdef LIBDHCP
++      libdhcp_control = libdhcp_ctl;
++#endif
+       int fd;
+       int i;
+       struct servent *ent;
+@@ -120,6 +156,7 @@ int main (argc, argv, envp)
+       char *arg_conf = NULL;
+       int arg_conf_len = 0;
++#ifndef LIBDHCP
+         /* 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 decriptor is used. */
+@@ -143,6 +180,7 @@ int main (argc, argv, envp)
+ #if !(defined (DEBUG) || defined (SYSLOG_4_2) || defined (__CYGWIN32__))
+       setlogmask (LOG_UPTO (LOG_INFO));
+ #endif        
++#endif
+       /* Set up the OMAPI. */
+       status = omapi_init ();
+@@ -439,6 +477,10 @@ int main (argc, argv, envp)
+               }
+       }
++#ifdef LIBDHCP
++      if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE))
++#endif
++#ifndef LIBDHCP
+       if (!quiet) {
+               log_info ("%s %s", message, DHCP_VERSION);
+               log_info (copyright);
+@@ -449,6 +491,7 @@ int main (argc, argv, envp)
+               log_info ("%s", "");
+       } else
+               log_perror = 0;
++#endif
+       /* If we're given a relay agent address to insert, for testing
+          purposes, figure out what it is. */
+@@ -680,11 +723,17 @@ int main (argc, argv, envp)
+               arg_conf_len = 0;
+       }
++#ifdef LIBDHCP
++      if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)) {
++#endif
+       /* Parse the lease database. */
+       read_client_leases ();
+       /* Rewrite the lease database... */
+       rewrite_client_leases ();
++#ifdef LIBDHCP
++      }
++#endif
+       /* XXX */
+ /*    config_counter(&snd_counter, &rcv_counter); */
+@@ -703,7 +752,7 @@ int main (argc, argv, envp)
+               if (!persist) {
+                       /* Nothing more to do. */
+                       log_info ("No broadcast interfaces found - exiting.");
+-                      exit (0);
++                      return (0);
+               }
+       } else if (!release_mode && !exit_mode) {
+               /* Call the script with the list of interfaces. */
+@@ -799,6 +848,7 @@ int main (argc, argv, envp)
+       dmalloc_outstanding = 0;
+ #endif
++#ifndef LIBDHCP
+       /* If we're not supposed to wait before getting the address,
+          don't. */
+       if (nowait)
+@@ -811,6 +861,126 @@ int main (argc, argv, envp)
+       /* Start dispatching packets and timeouts... */
+       dispatch ();
++#else
++      if (libdhcp_control) {
++              if (libdhcp_control->timeout)
++                      libdhcp_control->now = time(NULL);
++              else
++                      libdhcp_control->now = 0;
++      }
++
++      libdhcp_dispatch();
++
++      /* libdhcp is finished with us. */
++
++      /* close all file descriptors:  */
++      for (ip = interfaces; ip; ip = ip->next) {
++              shutdown(ip->wfdesc, SHUT_RDWR);
++              close(ip->wfdesc);
++
++              if (ip->rfdesc != ip->wfdesc)
++                      close(ip->rfdesc);
++      }
++
++      if (fallback_interface != 0) {
++              ip = fallback_interface;
++              shutdown(ip->wfdesc, SHUT_RDWR);
++              close(ip->wfdesc);
++
++              if (ip->rfdesc != ip->wfdesc)
++                      close(ip->rfdesc);
++      }
++
++      if (leaseFile)
++              fclose (leaseFile);
++
++      closelog();
++
++      char *current_pid_file = _PATH_DHCLIENT_PID;
++
++      /* Free ALL allocated memory: */
++      omapi_free_all_pointers();
++
++      /* Re-Initialize globals: */
++      client_env = 0;
++      client_env_count = 0;
++      default_lease_time = 43200;
++
++      dhcp_max_agent_option_packet_length = 0;
++      iaddr_any.len = 4;
++      memset(&(iaddr_any.iabuf[0]), '\0', 4);
++      iaddr_broadcast.len = 4;
++      memset(&(iaddr_broadcast.iabuf[0]), 0xff, 4);
++      interfaces_requested = 0;
++      leaseFile = 0;
++
++      libdhcp_control = 0;
++
++      local_port = 0;
++      no_daemon = 0;
++      nowait = 0;
++      onetry = 0;
++      quiet = 0;
++      max_lease_time = 86400;
++      path_dhclient_conf = _PATH_DHCLIENT_CONF;
++      path_dhclient_db = _PATH_DHCLIENT_DB;
++      path_dhclient_pid = _PATH_DHCLIENT_PID;
++      strcpy(&(path_dhclient_script_array[0]), _PATH_DHCLIENT_SCRIPT);
++      path_dhclient_script = path_dhclient_script_array;
++      remote_port = 0;
++      resolver_inited = 0;
++      log_perror = 1;
++      global_scope = NULL;
++      root_group = NULL;
++      group_name_hash = NULL;
++      interfaces = NULL;
++      dummy_interfaces = NULL;
++      fallback_interface = NULL;
++      extern int have_setup_fallback;
++      have_setup_fallback = 0;
++      quiet_interface_discovery = 1;
++#ifndef LIBDHCP
++      timeouts = NULL;
++#endif
++      dhcp_type_interface = NULL;
++      interface_vector = NULL;
++      interface_count = 0;
++      interface_max = 0;
++      name_servers = 0;
++      domains = 0;
++      dhcp_type_interface = NULL;
++      dhcp_type_group = NULL;
++      dhcp_type_shared_network = NULL;
++      dhcp_type_control = NULL;
++      memset(&dhcp_universe, '\0', sizeof(struct universe));
++      memset(&nwip_universe, '\0', sizeof(struct universe));
++      memset(&fqdn_universe, '\0', sizeof(struct universe));
++      universe_hash = 0;
++      universes = 0;
++      universe_count = 0;
++      universe_max = 0;
++      config_universe = 0; 
++      extern struct hash_bucket *free_hash_buckets;
++      free_hash_buckets = NULL;
++      extern struct dhcp_packet *dhcp_free_list;
++      dhcp_free_list = NULL;
++      extern struct packet *packet_free_list;
++      packet_free_list = NULL;
++      extern struct binding_value *free_binding_values;
++      free_binding_values = NULL;
++      extern struct expression *free_expressions;
++      free_expressions = NULL;
++      extern struct option_cache *free_option_caches;
++      free_option_caches = NULL;
++      extern  struct packet *free_packets;
++      free_packets = NULL;
++      extern  pair free_pairs;
++      free_pairs = NULL;
++      extern omapi_io_object_t omapi_io_states;
++      memset(&omapi_io_states, '\0', sizeof(omapi_io_states));
++      dhcp_control_object = NULL;
++      unlink(current_pid_file);
++#endif
+       /*NOTREACHED*/
+       return 0;
+@@ -1203,7 +1373,20 @@ void dhcpack (packet)
+       if (client -> new -> rebind < cur_time)
+               client -> new -> rebind = TIME_MAX;
++#ifdef LIBDHCP
++      /* We need the server's siaddr for the 'bootServer'
++       * pump option
++       */
++      u_int32_t set_siaddr = 0;
++      set_siaddr = client->packet.siaddr.s_addr;
++      client->packet.siaddr.s_addr = packet->raw->siaddr.s_addr;
++#endif
++
+       bind_lease (client);
++
++#ifdef LIBDHCP
++      client->packet.siaddr.s_addr = set_siaddr;
++#endif
+ }
+ void bind_lease (client)
+@@ -1241,6 +1424,9 @@ void bind_lease (client)
+               return;
+       }
++#ifdef LIBDHCP
++      if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
++#endif
+       /* Write out the new lease. */
+       write_client_lease (client, client -> new, 0, 0);
+@@ -1343,11 +1529,13 @@ int commit_leases ()
+       return 0;
+ }
++#ifndef LIBDHCP
+ int write_lease (lease)
+       struct lease *lease;
+ {
+       return 0;
+ }
++#endif
+ int write_host (host)
+       struct host_decl *host;
+@@ -1957,6 +2145,10 @@ void state_panic (cpp)
+          tell the shell script that we failed to allocate an address,
+          and try again later. */
+       if (onetry) {
++#ifdef LIBDHCP
++              script_init (client, "FAIL", (struct string_list *)0);
++              return;
++#endif
+               if (!quiet)
+                       log_info ("Unable to obtain a lease on first try.%s",
+                                 "  Exiting.");
+@@ -2579,7 +2771,9 @@ void destroy_client_lease (lease)
+       free_client_lease (lease, MDL);
+ }
++#ifndef LIBDHCP
+ FILE *leaseFile;
++#endif
+ void rewrite_client_leases ()
+ {
+@@ -2960,6 +3154,54 @@ void script_write_params (client, prefix
+ int script_go (client)
+       struct client_state *client;
+ {
++#ifdef LIBDHCP
++      struct string_list *sp;
++
++      if (libdhcp_control && libdhcp_control->callback) {
++              int dhcmsg;
++              char *reason="";
++
++              for (sp = client->env; sp; sp = sp->next)
++                      if (strncmp(sp->string, "reason=", 7) == 0) {
++                              reason = sp->string + 7;
++                              break;
++                      }
++
++              if (strcmp(reason,"NBI") == 0)
++                      dhcmsg = DHC4_NBI;
++              else if (strcmp(reason,"PREINIT") == 0)
++                      dhcmsg = DHC4_PREINIT;
++              else if (strcmp(reason,"BOUND") == 0)
++                      dhcmsg = DHC4_BOUND;
++              else if (strcmp(reason,"RENEW") == 0)
++                      dhcmsg = DHC4_RENEW;
++              else if (strcmp(reason,"REBOOT") == 0)
++                      dhcmsg = DHC4_REBOOT;
++              else if (strcmp(reason,"REBIND") == 0)
++                      dhcmsg = DHC4_REBIND;
++              else if (strcmp(reason,"STOP") == 0)
++                      dhcmsg = DHC4_STOP;
++              else if (strcmp(reason,"MEDIUM") == 0)
++                      dhcmsg = DHC4_MEDIUM;
++              else if (strcmp(reason,"TIMEOUT") == 0)
++                      dhcmsg = DHC4_TIMEOUT;
++              else if (strcmp(reason,"FAIL") == 0)
++                      dhcmsg = DHC4_FAIL;
++              else if (strcmp(reason,"EXPIRE") == 0)
++                      dhcmsg = DHC4_EXPIRE;
++              else if (strcmp(reason,"RELEASE") == 0)
++                      dhcmsg = DHC4_RELEASE;
++              else
++                      dhcmsg = DHC4_NBI;
++
++              (*libdhcp_control->callback) (libdhcp_control, dhcmsg, client);
++
++              if (libdhcp_control->decline)
++                      return 1;
++      }
++
++      return 0;
++#else
+       int rval;
+       char *scriptName;
+       char *argv [2];
+@@ -3038,6 +3280,7 @@ int script_go (client)
+       GET_TIME (&cur_time);
+       return (WIFEXITED (wstatus) ?
+               WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
++#endif
+ }
+ void client_envadd (struct client_state *client,
+@@ -3120,6 +3363,9 @@ void go_daemon ()
+       /* Don't become a daemon if the user requested otherwise. */
+       if (no_daemon) {
++#ifdef LIBDHCP
++              if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_PID_FILE ))
++#endif
+               write_client_pid_file ();
+               return;
+       }
+@@ -3129,6 +3375,10 @@ void go_daemon ()
+               return;
+       state = 1;
++#ifdef LIBDHCP
++      return;
++#endif
++
+       /* Stop logging to stderr... */
+       log_perror = 0;
+diff -up dhcp-3.1.0/Makefile.dist.libdhcp4client dhcp-3.1.0/Makefile.dist
+--- dhcp-3.1.0/Makefile.dist.libdhcp4client    2005-03-17 15:14:54.000000000 -0500
++++ dhcp-3.1.0/Makefile.dist   2007-10-24 14:55:56.000000000 -0400
+@@ -22,7 +22,7 @@
+ #   http://www.isc.org/
+-SUBDIRS=      common $(MINIRES) dst omapip server client relay dhcpctl
++SUBDIRS=      common $(MINIRES) dst omapip server client relay dhcpctl libdhcp4client
+ all:
+       @for dir in ${SUBDIRS}; do \
diff --git a/dhcp-libdhcp4client.pc b/dhcp-libdhcp4client.pc
new file mode 100644 (file)
index 0000000..8be7273
--- /dev/null
@@ -0,0 +1,5 @@
+Name: libdhcp4client
+Description: ISC DHCP IPv4 client library
+Version: @DHCP_VERSION@
+Libs: -ldhcp4client
+Cflags: -I/usr/include/dhcp4client
diff --git a/dhcp-libdhcp_control.h b/dhcp-libdhcp_control.h
new file mode 100644 (file)
index 0000000..7eacc22
--- /dev/null
@@ -0,0 +1,132 @@
+/* libdhcp_control.h
+ *
+ * DHCP client control API for libdhcp, a minimal interface to the
+ * ISC dhcp IPv4 client libdhcp4client library,
+ * and to the dhcpv6 DHCPv6 client libdhcp6client library.
+ *
+ * Each DHCP client library must include this file to be controlled
+ * by libdhcp.
+ *
+ * Copyright (C) 2006  Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions of
+ * the GNU General Public License v.2, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY expressed or implied, including the implied warranties of
+ * MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE.  See the GNU General
+ * Public License for more details.  You should have received a copy of the
+ * GNU General Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.  Any Red Hat trademarks that are incorporated in the
+ * source code or documentation are not subject to the GNU General Public
+ * License and may only be used or replicated with the express permission of
+ * Red Hat, Inc.
+ *
+ * Red Hat Author(s): Jason Vas Dias
+ *                    David Cantrell <dcantrell@redhat.com>
+ */
+
+#ifndef LIBDHCP_CONTROL_H
+#define LIBDHCP_CONTROL_H
+
+#include <stdarg.h>
+#include <stdint.h>
+
+#define  LOG_FATAL 8
+
+typedef enum dhcp_state_e {
+    /* DHCPv4 client states
+     * third callback arg will be a 'struct client_state *'
+     */
+    DHC4_NBI,     /* failed: no broadcast interfaces found              */
+    DHC4_PREINIT, /* configuration started - bring the interface "UP"   */
+    DHC4_BOUND,   /* lease obtained                                     */
+    DHC4_RENEW,   /* lease renewed                                      */
+    DHC4_REBOOT,  /* have valid lease, but now obtained a different one */
+    DHC4_REBIND,  /* new, different lease                               */
+    DHC4_STOP,    /* remove old lease                                   */
+    DHC4_MEDIUM,  /* media selection begun                              */
+    DHC4_TIMEOUT, /* timed out contacting DHCP server                   */
+    DHC4_FAIL,    /* all attempts to contact server timed out, sleeping */
+    DHC4_EXPIRE,  /* lease has expired, renewing                        */
+    DHC4_RELEASE, /* releasing lease                                    */
+
+    /* This state raised by both clients: */
+    DHC_TIMEDOUT, /* libdhcp_control timeout has been exceeded          */
+
+    /* DHCPv6 client states:    */
+    DHC6_BOUND,   /* new lease obtained             - arg is optinfo *  */
+    DHC6_REBIND,  /* existing expired lease rebound - arg is optinfo *  */
+    DHC6_RELEASE  /* existing lease expired         - arg is dhcp6_iaidaddr*/
+} DHCP_State;
+
+struct libdhcp_control_s;
+
+/* ala syslog(3): LOG_EMERG=0 - LOG_DEBUG=7 (+ LOG_FATAL=8 : finished -> 1) */
+typedef int (*LIBDHCP_Error_Handler) (struct libdhcp_control_s *ctl,
+                                      int priority, const char *fmt,
+                                      va_list ap);
+
+/* The DHCP clients will call the users' callback on important state change
+ * events, with the second arg set to the client DHCP_State, and the third
+ * arg set to a client specific pointer as described below. */
+typedef int (*LIBDHCP_Callback) (struct libdhcp_control_s *control,
+                                 enum dhcp_state_e, void*);
+
+typedef struct libdhcp_control_s {
+    /* the DHCP clients' main loop calls this on state changes */
+    LIBDHCP_Callback callback;
+
+    /* LIBDHCP_Capability bits to enable */
+    uint16_t capability;
+
+    /* set to one to make clients exit their main loop */
+    uint8_t finished;
+
+    /* set to one to decline the lease (DHCPv4 only) */
+    uint8_t decline;
+
+    /* (timeout+now) == time after which clients MUST return */
+    time_t timeout;
+
+    /* clients set this to time(0) on entering main loop */
+    time_t now;
+
+    /* user data pointer */
+    void *arg;
+    LIBDHCP_Error_Handler eh;
+} LIBDHCP_Control;
+
+/* DHCP client "capabilities" */
+typedef enum libdhcp_capability_e {
+    /* use / do not use persistent lease database files */
+    DHCP_USE_LEASE_DATABASE = 1,
+
+    /* use / do not use pid file */
+    DHCP_USE_PID_FILE = 2,
+
+    /*
+     * DHCPv6 supports these capabilities in process, 
+     * while the DHCPv4 client will fork and exec the dhclient-script to
+     * implement them if these bits are set - otherwise, if no bits are set,
+     * the callback is called and the script is not run.
+     */
+    /* configure interfaces UP/DOWN as required */
+    DHCP_CONFIGURE_INTERFACES = 4,
+
+    /* configure interface addresses as required */
+    DHCP_CONFIGURE_ADDRESSES = 8,
+
+    /* configure routes as required */
+    DHCP_CONFIGURE_ROUTES = 16,
+
+    /* configure resolv.conf as required */
+    DHCP_CONFIGURE_RESOLVER = 32,
+
+    /* DHCPv6 only: */
+    /* configure radvd.conf & restart radvd as required */
+    DHCP_CONFIGURE_RADVD = 64,
+} LIBDHCP_Capability;
+
+#endif
diff --git a/dhcp-options.patch b/dhcp-options.patch
new file mode 100644 (file)
index 0000000..505b2a1
--- /dev/null
@@ -0,0 +1,402 @@
+diff -up dhcp-3.1.0/common/conflex.c.options dhcp-3.1.0/common/conflex.c
+--- dhcp-3.1.0/common/conflex.c.options        2007-10-22 15:46:24.000000000 -0400
++++ dhcp-3.1.0/common/conflex.c        2007-10-22 15:48:07.000000000 -0400
+@@ -599,6 +599,8 @@ static enum dhcp_token intern (atom, dfv
+                       return BALANCE;
+               if (!strcasecmp (atom + 1, "ound"))
+                       return BOUND;
++              if (!strcasecmp (atom + 1, "ootp-broadcast-always"))
++                      return BOOTP_BROADCAST_ALWAYS;
+               break;
+             case 'c':
+               if (!strcasecmp (atom + 1, "ase"))
+diff -up dhcp-3.1.0/includes/dhcpd.h.options dhcp-3.1.0/includes/dhcpd.h
+--- dhcp-3.1.0/includes/dhcpd.h.options        2007-10-22 15:46:24.000000000 -0400
++++ dhcp-3.1.0/includes/dhcpd.h        2007-10-22 15:48:21.000000000 -0400
+@@ -912,6 +912,9 @@ struct client_config {
+       int do_forward_update;          /* If nonzero, and if we have the
+                                          information we need, update the
+                                          A record for the address we get. */
++
++      int bootp_broadcast_always;     /* If nonzero, always set the BOOTP_BROADCAST
++                                         flag in requests */
+ };
+ /* Per-interface state used in the dhcp client... */
+diff -up dhcp-3.1.0/includes/dhctoken.h.options dhcp-3.1.0/includes/dhctoken.h
+--- dhcp-3.1.0/includes/dhctoken.h.options     2006-07-31 18:19:51.000000000 -0400
++++ dhcp-3.1.0/includes/dhctoken.h     2007-10-22 15:49:24.000000000 -0400
+@@ -325,7 +325,8 @@ enum dhcp_token {
+       MIN_BALANCE = 629,
+       DOMAIN_LIST = 630,
+       LEASEQUERY = 631,
+-      EXECUTE = 632
++      EXECUTE = 632,
++      BOOTP_BROADCAST_ALWAYS = 633
+ };
+ #define is_identifier(x)      ((x) >= FIRST_TOKEN &&  \
+diff -up dhcp-3.1.0/client/dhclient.c.options dhcp-3.1.0/client/dhclient.c
+--- dhcp-3.1.0/client/dhclient.c.options       2007-05-22 16:37:04.000000000 -0400
++++ dhcp-3.1.0/client/dhclient.c       2007-10-22 15:47:51.000000000 -0400
+@@ -38,6 +38,12 @@ static char ocopyright[] =
+ #include "dhcpd.h"
+ #include "version.h"
++/*
++ * Defined in stdio.h when _GNU_SOURCE is set, but we don't want to define
++ * that when building ISC code.
++ */
++extern int asprintf(char **strp, const char *fmt, ...);
++
+ TIME default_lease_time = 43200; /* 12 hours... */
+ TIME max_lease_time = 86400; /* 24 hours... */
+@@ -74,6 +80,9 @@ int client_env_count=0;
+ int onetry=0;
+ int quiet=0;
+ int nowait=0;
++int bootp_broadcast_always = 0;
++
++extern u_int32_t default_requested_options[];
+ #ifdef EXTENDED_NEW_OPTION_INFO
+ int extended_option_environment = 0;
+ #endif
+@@ -101,6 +110,15 @@ int main (argc, argv, envp)
+       int no_dhclient_pid = 0;
+       int no_dhclient_script = 0;
+       char *s;
++      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;
++
++      int timeout_arg = 0;
++      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
+@@ -211,6 +229,88 @@ int main (argc, argv, envp)
+               } else if (!strcmp (argv [i], "--version")) {
+                       log_info ("isc-dhclient-%s", DHCP_VERSION);
+                       exit (0);
++              } else if (!strcmp (argv [i], "-I")) {
++                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++                              usage ();
++                              return EXIT_FAILURE;
++                      }
++
++                      if (strlen(argv[i]) >= DHCP_OPTION_LEN) {
++                              log_error("-I option dhcp-client-identifier string \"%s\" is too long - maximum length is: %d",  argv[i], DHCP_OPTION_LEN-1);
++                              exit(1);
++                      }
++
++                      dhcp_client_identifier_arg = argv[i];
++              } else if (!strcmp (argv [i], "-B")) {
++                      bootp_broadcast_always = 1;
++              } else if (!strcmp (argv [i], "-H")) {
++                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++                              usage ();
++                              return EXIT_FAILURE;
++                      }
++
++                      if (strlen(argv[i]) >= DHCP_OPTION_LEN) {
++                              log_error("-H option host-name string \"%s\" is too long - maximum length is: %d",  argv[i], DHCP_OPTION_LEN-1);
++                              exit(1);
++                      }
++
++                      if (dhcp_host_name_arg != NULL) {
++                              log_error("The -H <host-name> and -F <fqdn> arguments are mutually exclusive");
++                              exit(1);
++                      }
++
++                      dhcp_host_name_arg = argv[i];
++              } else if (!strcmp (argv [i], "-F")) {
++                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++                              usage ();
++                              return EXIT_FAILURE;
++                      }
++
++                      if (strlen(argv[i]) >= DHCP_OPTION_LEN) {
++                              log_error("-F option fqdn.fqdn string \"%s\" is too long - maximum length is: %d",  argv[i], DHCP_OPTION_LEN-1);
++                              exit(1);
++                      }
++
++                      if (dhcp_fqdn_arg != NULL) {
++                              log_error("Only one -F <fqdn> argument can be specified");
++                              exit(1);
++                      }
++
++                      if (dhcp_host_name_arg != NULL) {
++                              log_error("The -F <fqdn> and -H <host-name> arguments are mutually exclusive");
++                              exit(1);
++                      }
++
++                      dhcp_fqdn_arg = argv[i];
++              } else if (!strcmp (argv [i], "-T")) {
++                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++                              usage ();
++                              return EXIT_FAILURE;
++                      }
++
++                      if ((timeout_arg = atoi(argv[i])) <= 0) {
++                              log_error("-T timeout option must be > 0 - bad value: %s",argv[i]);
++                              exit(1);
++                      }
++              } else if (!strcmp (argv [i], "-V")) {
++                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++                              usage ();
++                              return EXIT_FAILURE;
++                      }
++
++                      if (strlen(argv[i]) >= DHCP_OPTION_LEN) {
++                              log_error("-V option vendor-class-identifier string \"%s\" is too long - maximum length is: %d",  argv[i], DHCP_OPTION_LEN-1);
++                              exit(1);
++                      }
++
++                      dhcp_vendor_class_identifier_arg = argv[i];
++              } else if (!strcmp (argv [i], "-R")) {
++                      if ((++i == argc) || (argv[i] == NULL) || (*(argv[i])=='\0')) {
++                              usage ();
++                              return EXIT_FAILURE;
++                      }
++
++                      dhclient_request_options=argv[i];
+ #ifdef EXTENDED_NEW_OPTION_INFO
+               } else if (!strcmp (argv [i], "-y")) {
+                   extended_option_environment = 1;
+@@ -347,6 +447,167 @@ int main (argc, argv, envp)
+       /* 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);
++
++              if ((arg_conf == 0) || (arg_conf_len <= 0))
++                      log_fatal("Unable to send -I option dhcp-client-identifier");
++      }
++
++      if ((dhcp_host_name_arg != NULL) && (*dhcp_host_name_arg != '\0')) {
++              if (arg_conf == 0) {
++                      arg_conf_len = asprintf(&arg_conf, "send host-name \"%s\";", dhcp_host_name_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to send -H option host-name");
++              } else {
++                      char *last_arg_conf = arg_conf;
++                      arg_conf = NULL;
++                      arg_conf_len = asprintf( &arg_conf, "%s\nsend host-name \"%s\";", last_arg_conf, dhcp_host_name_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to send -H option host-name");
++
++                      free(last_arg_conf);
++              }
++      }
++
++      if ((dhcp_fqdn_arg != NULL) && (*dhcp_fqdn_arg != '\0')) {
++              if (arg_conf == 0) {
++                      arg_conf_len = asprintf(&arg_conf,  "send fqdn.fqdn \"%s\";", dhcp_fqdn_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to send -F option fqdn.fqdn");
++              } else {
++                      char *last_arg_conf = arg_conf;
++                      arg_conf = NULL;
++                      arg_conf_len = asprintf( &arg_conf, "%s\nsend fqdn.fqdn \"%s\";", last_arg_conf, dhcp_fqdn_arg);
++
++                      if ((arg_conf == 0)  || (arg_conf_len <= 0))
++                              log_fatal("Unable to send -F option fqdn.fqdn");
++
++                      free(last_arg_conf);
++              }
++      }
++
++      if (timeout_arg) {
++              if (arg_conf == 0) {
++                      arg_conf_len = asprintf(&arg_conf,  "timeout %d;", timeout_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to process -T timeout argument");
++              } else {
++                      char *last_arg_conf = arg_conf;
++                      arg_conf = NULL;
++                      arg_conf_len = asprintf( &arg_conf, "%s\ntimeout %d;", last_arg_conf, timeout_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len == 0))
++                              log_fatal("Unable to process -T timeout argument");
++
++                      free(last_arg_conf);
++              }
++      }
++
++      if ((dhcp_vendor_class_identifier_arg != NULL) && (*dhcp_vendor_class_identifier_arg != '\0')) {
++              if (arg_conf == 0) {
++                      arg_conf_len = asprintf(&arg_conf,  "send vendor-class-identifier \"%s\";", dhcp_vendor_class_identifier_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to send -V option vendor-class-identifier");
++              } else {
++                      char *last_arg_conf = arg_conf;
++                      arg_conf = NULL;
++                      arg_conf_len = asprintf(&arg_conf, "%s\nsend vendor-class-identifier \"%s\";", last_arg_conf, dhcp_vendor_class_identifier_arg);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to send -V option vendor-class-identifier");
++
++                      free(last_arg_conf);
++              }
++      }
++
++      if (dhclient_request_options != NULL) {
++              if (arg_conf == 0) {
++                      arg_conf_len = asprintf(&arg_conf,  "request %s;", dhclient_request_options);
++
++                      if ((arg_conf == 0) || (arg_conf_len <= 0))
++                              log_fatal("Unable to parse -R <request options list> argument");
++              } else {
++                      char *last_arg_conf = arg_conf;
++                      arg_conf = NULL;
++                      arg_conf_len = asprintf(&arg_conf, "%s\nrequest %s;", last_arg_conf, dhclient_request_options);
++
++                      if ((arg_conf == 0)  || (arg_conf_len <= 0))
++                              log_fatal("Unable to parse -R <request options list> argument");
++
++                      free(last_arg_conf);
++              }
++      }
++
++      if (arg_conf) {
++              if (arg_conf_len == 0)
++                      if ((arg_conf_len = strlen(arg_conf)) == 0)
++                              /* huh ? cannot happen ! */
++                              log_fatal("Unable to process -I/-H/-F/-T/-V/-R configuration arguments");
++
++              /* parse the extra dhclient.conf configuration arguments
++               * into top level config: */
++              struct parse *cfile = (struct parse *)0;
++              const char *val = NULL;
++              int token;
++
++              status = new_parse (&cfile, -1, arg_conf, arg_conf_len, "extra dhclient -I/-H/-F/-T/-V/-R configuration arguments", 0);
++
++              if ((status != ISC_R_SUCCESS) || (cfile -> warnings_occurred))
++                      log_fatal("Cannot parse -I/-H/-F/-T/-V/-R configuration arguments !");
++              /* more detailed parse failures will be logged */
++
++              do {
++                      token = peek_token (&val, (unsigned *)0, cfile);
++                      if (token == END_OF_FILE)
++                              break;
++
++                      parse_client_statement (cfile, (struct interface_info *)0, &top_level_config);
++              } while (1);
++
++              if (cfile -> warnings_occurred)
++                      log_fatal ("Cannot parse -I/-H/-F/-T/-V/-R configuration arguments !");
++              end_parse (&cfile);
++
++              if (timeout_arg) {
++                      /* we just set the toplevel timeout, but per-client
++                       * timeouts may still be at defaults. Also, it makes no
++                       * sense having the reboot_timeout or backoff_cutoff
++                       * greater than the timeout:
++                       */
++                      if ((top_level_config.backoff_cutoff == 15) && (top_level_config.backoff_cutoff > (timeout_arg / 2)))
++                              top_level_config.backoff_cutoff = (((unsigned long)(timeout_arg / 2)) == 0) ? timeout_arg : (unsigned long)(timeout_arg / 2);
++
++                      for (ip = interfaces; ip; ip = ip -> next) {
++                              if (ip->client->config->timeout == 60)
++                                      ip->client->config->timeout = timeout_arg;
++
++                              if ((ip->client->config->reboot_timeout == 10) && (ip->client->config->reboot_timeout > ip->client->config->timeout))
++                                      ip->client->config->reboot_timeout = ip->client->config->timeout;
++
++                              if ((ip->client->config->backoff_cutoff == 15) && (ip->client->config->backoff_cutoff > top_level_config.backoff_cutoff))
++                                      ip->client->config->backoff_cutoff = top_level_config.backoff_cutoff;
++                      }
++              }
++
++              if ((dhclient_request_options != 0) && (top_level_config.requested_options != default_requested_options)) {
++                      for (ip = interfaces; ip; ip = ip -> next) {
++                              if (ip->client->config->requested_options == default_requested_options)
++                                      ip->client->config->requested_options = top_level_config.requested_options;
++                      }
++              }
++
++              free(arg_conf);
++              arg_conf = NULL;
++              arg_conf_len = 0;
++      }
++
+       /* Parse the lease database. */
+       read_client_leases ();
+@@ -1978,7 +2239,8 @@ void make_discover (client, lease)
+       client -> packet.xid = random ();
+       client -> packet.secs = 0; /* filled in by send_discover. */
+-      if (can_receive_unicast_unconfigured (client -> interface))
++      if ((!(bootp_broadcast_always || client->config->bootp_broadcast_always))
++          && can_receive_unicast_unconfigured(client->interface))
+               client -> packet.flags = 0;
+       else
+               client -> packet.flags = htons (BOOTP_BROADCAST);
+@@ -2065,7 +2327,9 @@ void make_request (client, lease)
+       } else {
+               memset (&client -> packet.ciaddr, 0,
+                       sizeof client -> packet.ciaddr);
+-              if (can_receive_unicast_unconfigured (client -> interface))
++              if ((!(bootp_broadcast_always ||
++                  client ->config->bootp_broadcast_always)) &&
++                  can_receive_unicast_unconfigured (client -> interface))
+                       client -> packet.flags = 0;
+               else
+                       client -> packet.flags = htons (BOOTP_BROADCAST);
+@@ -2125,7 +2389,8 @@ void make_decline (client, lease)
+       client -> packet.hops = 0;
+       client -> packet.xid = client -> xid;
+       client -> packet.secs = 0; /* Filled in by send_request. */
+-      if (can_receive_unicast_unconfigured (client -> interface))
++      if ((!(bootp_broadcast_always || client->config-> bootp_broadcast_always))
++          && can_receive_unicast_unconfigured (client->interface))
+               client -> packet.flags = 0;
+       else
+               client -> packet.flags = htons (BOOTP_BROADCAST);
+diff -up dhcp-3.1.0/client/clparse.c.options dhcp-3.1.0/client/clparse.c
+--- dhcp-3.1.0/client/clparse.c.options        2007-02-14 17:41:22.000000000 -0500
++++ dhcp-3.1.0/client/clparse.c        2007-10-22 15:47:12.000000000 -0400
+@@ -84,6 +84,7 @@ isc_result_t read_client_conf ()
+       top_level_config.requested_options = default_requested_options;
+       top_level_config.omapi_port = -1;
+       top_level_config.do_forward_update = 1;
++      top_level_config.bootp_broadcast_always = 0;
+       group_allocate (&top_level_config.on_receipt, MDL);
+       if (!top_level_config.on_receipt)
+@@ -230,7 +231,8 @@ void read_client_leases ()
+       interface-declaration |
+       LEASE client-lease-statement |
+       ALIAS client-lease-statement |
+-      KEY key-definition */
++      KEY key-definition |
++      BOOTP_BROADCAST_ALWAYS */
+ void parse_client_statement (cfile, ip, config)
+       struct parse *cfile;
+@@ -554,6 +556,12 @@ void parse_client_statement (cfile, ip, 
+               parse_reject_statement (cfile, config);
+               return;
++            case BOOTP_BROADCAST_ALWAYS:
++              token = next_token(&val, (unsigned*)0, cfile);
++              config -> bootp_broadcast_always = 1;
++              parse_semi (cfile);
++              return;
++
+             default:
+               lose = 0;
+               stmt = (struct executable_statement *)0;
index e3eea1e322cd5a50c28ed3fc872c64d6f450d053..2c9b036378910eac7290607a2341ac53a529e513 100644 (file)
--- a/dhcp.spec
+++ b/dhcp.spec
@@ -8,7 +8,7 @@ Summary(pl.UTF-8):      Serwer DHCP
 Summary(pt_BR.UTF-8):  Servidor DHCP (Protocolo de configuração dinâmica de hosts)
 Name:          dhcp
 Version:       3.1.0
-Release:       2
+Release:       3
 Epoch:         4
 License:       distributable
 Group:         Networking/Daemons
@@ -18,6 +18,10 @@ Source1:     %{name}.init
 Source2:       %{name}-relay.init
 Source3:       %{name}.sysconfig
 Source4:       %{name}-relay.sysconfig
+Source5:       %{name}-libdhcp4client.pc
+Source6:       %{name}-dhcp4client.h
+Source7:       %{name}-libdhcp4client.make
+Source8:       %{name}-libdhcp_control.h
 Patch0:                %{name}-dhclient.script.patch
 Patch1:                %{name}-if_buffer_size.patch
 # http://home.ntelos.net/~masneyb/dhcp-3.0.5-ldap-patch
@@ -27,6 +31,8 @@ Patch4:               %{name}-3.0.3-x-option.patch
 Patch5:                %{name}-typo.patch
 Patch6:                %{name}-arg-concat.patch
 Patch7:                %{name}-split-VARDB.patch
+Patch8:                %{name}-options.patch
+Patch9:                %{name}-libdhcp4client.patch
 URL:           http://www.isc.org/sw/dhcp/
 BuildRequires: groff
 %{?with_ldap:BuildRequires:    openldap-devel >= 2.4.6}
@@ -143,6 +149,41 @@ odpytywania o ich stan. Aktualnie jest używana przez serwer ISC DHCP.
 dhcpctl to zbiór funkcji tworzących API, które może być używane do
 komunikacji z działającym serwerem ISC DHCP i jego kontroli.
 
+%package -n libdhcp4client
+Summary:       The DHCP client in a library for invocation by other programs
+Summary(pl.UTF-8):     Klient DHCP w postaci biblioteki do wykorzystania w innych programach
+Group:         Development/Libraries
+
+%description -n libdhcp4client
+Provides the client for the DHCP protocol.
+
+%description -n libdhcp4client -l pl.UTF-8
+Ten pakiet zawiera klienta protokołu DHCP.
+
+%package -n libdhcp4client-devel
+Summary:       Header files for development with the DHCP client library
+Summary(pl.UTF-8):     Pliki nagłówkowe do programowania z użyciem biblioteki klienckiej DHCP
+Group:         Development/Libraries
+Requires:      libdhcp4client = %{epoch}:%{version}-%{release}
+
+%description -n libdhcp4client-devel
+Header files for development with the DHCP client library.
+
+%description -n libdhcp4client-devel -l pl.UTF-8
+Pliki nagłówkowe do programowania z użyciem biblioteki klienckiej DHCP.
+
+%package -n libdhcp4client-static
+Summary:       Static DHCP client library
+Summary(pl.UTF-8):     Statyczna biblioteka kliencka DHCP
+Group:         Development/Libraries
+Requires:      libdhcp4client-devel = %{epoch}:%{version}-%{release}
+
+%description -n libdhcp4client-static
+Static DHCP client library.
+
+%description -n libdhcp4client-static -l pl.UTF-8
+Statyczna biblioteka kliencka DHCP.
+
 %prep
 %setup -q
 %patch0 -p1
@@ -155,6 +196,14 @@ komunikacji z działającym serwerem ISC DHCP i jego kontroli.
 %patch5 -p1
 %patch6 -p1
 %patch7 -p1
+%patch8 -p1
+%patch9 -p1
+
+sed 's/@DHCP_VERSION@/'%{version}'/' < %{SOURCE5} > libdhcp4client.pc
+mkdir -p libdhcp4client
+cp %{SOURCE6} libdhcp4client/dhcp4client.h
+cp %{SOURCE7} libdhcp4client/Makefile.dist
+cp %{SOURCE8} includes/isc-dhcp/libdhcp_control.h
 
 %build
 # NOTE: this is not autoconf configure - do not change it to %%configure
@@ -174,7 +223,7 @@ komunikacji z działającym serwerem ISC DHCP i jego kontroli.
 
 %install
 rm -rf $RPM_BUILD_ROOT
-install -d $RPM_BUILD_ROOT{%{_sysconfdir}/{rc.d/init.d,sysconfig},%{schemadir}}
+install -d $RPM_BUILD_ROOT{%{_sysconfdir}/{rc.d/init.d,sysconfig},%{schemadir},%{_pkgconfigdir}}
 
 %{__make} install \
        DESTDIR=$RPM_BUILD_ROOT \
@@ -210,6 +259,8 @@ touch $RPM_BUILD_ROOT%{_sysconfdir}/dhclient.conf
 touch $RPM_BUILD_ROOT/var/lib/%{name}/dhcpd.leases
 touch $RPM_BUILD_ROOT/var/lib/dhclient/dhclient.leases
 
+install libdhcp4client.pc $RPM_BUILD_ROOT%{_libdir}/pkgconfig/libdhcp4client.pc
+
 %clean
 rm -rf $RPM_BUILD_ROOT
 
@@ -306,3 +357,17 @@ fi
 %{_mandir}/man3/*
 %{_libdir}/*.a
 %{_includedir}/*
+
+%files -n libdhcp4client
+%defattr(644,root,root,755)
+%attr(755,root,root) %{_libdir}/libdhcp4client-%{version}.so.*
+
+%files -n libdhcp4client-devel
+%defattr(644,root,root,755)
+%attr(755,root,root) %{_libdir}/libdhcp4client.so
+%{_includedir}/*
+%{_pkgconfigdir}/libdhcp4client.pc
+
+%files -n libdhcp4client-static
+%defattr(644,root,root,755)
+%{_libdir}/libdhcp4client.a
This page took 0.177007 seconds and 4 git commands to generate.