rpms/dhcpv6/devel dhcpv6-0.10-libdhcp6client.patch, NONE, 1.1 dhcpv6-0.10-libdhcp6client-Makefile.patch, NONE, 1.1 libdhcp6client.pc, NONE, 1.1

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Mon May 15 14:54:11 UTC 2006


Author: jvdias

Update of /cvs/dist/rpms/dhcpv6/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv10798

Added Files:
	dhcpv6-0.10-libdhcp6client.patch 
	dhcpv6-0.10-libdhcp6client-Makefile.patch libdhcp6client.pc 
Log Message:
Produce the libdhcp6client DHCPv6 client libraries for invoking dhcp6c within other programs

dhcpv6-0.10-libdhcp6client.patch:
 client6_addr.c    |   61 ++++++--
 common.c          |   39 ++++-
 dhc6_alloc.c      |   59 +++++++
 dhc6_alloc.h      |   10 +
 dhcp6.h           |   17 ++
 dhcp6c.c          |  408 +++++++++++++++++++++++++++++++++++++++++++++++-------
 dhcp6client.h     |   22 ++
 lease.c           |   10 -
 lease.h           |    2 
 lease_token.l     |    3 
 libdhcp_control.h |  104 +++++++++++++
 11 files changed, 656 insertions(+), 79 deletions(-)

--- NEW FILE dhcpv6-0.10-libdhcp6client.patch ---
--- dhcp-0.10/libdhcp6client/lease_token.l.libdhcp6client	2004-02-04 18:29:24.000000000 -0500
+++ dhcp-0.10/libdhcp6client/lease_token.l	2006-05-14 09:14:06.000000000 -0400
@@ -241,6 +241,9 @@
 	
 	fseek(file, 0, 0);
 	yyin = file;
+	yy_init=1;
+	yy_start=0;
+	yy_current_buffer=0;
 	yylex(); 
 	return;
 }
--- dhcp-0.10/libdhcp6client/client6_addr.c.libdhcp6client	2006-05-14 08:09:10.000000000 -0400
+++ dhcp-0.10/libdhcp6client/client6_addr.c	2006-05-14 08:09:29.000000000 -0400
@@ -56,6 +56,10 @@
 #include "timer.h"
 #include "lease.h"
 
+#ifdef LIBDHCP
+#include "libdhcp_control.h"
+#endif
+
 static int dhcp6_update_lease __P((struct dhcp6_addr *, struct dhcp6_lease *));
 static int dhcp6_add_lease __P((struct dhcp6_addr *));
 struct dhcp6_lease *dhcp6_find_lease __P((struct dhcp6_iaidaddr *, 
@@ -217,7 +221,7 @@
 	sp->iaidaddr = &client6_iaidaddr;
 	time(&sp->start_date);
 	sp->state = ACTIVE;
-	if (write_lease(sp, client6_lease_file) != 0) {
+	if (client6_lease_file && (write_6_lease(sp, client6_lease_file) != 0)) {
 		dprintf(LOG_ERR, "%s" "failed to write a new lease address %s to lease file", 
 			FNAME, in6addr2str(&sp->lease_addr.addr, 0));
 		if (sp->timer)
@@ -228,14 +232,24 @@
 	if (sp->lease_addr.type == IAPD) {
 		dprintf(LOG_INFO, "request prefix is %s/%d", 
 			in6addr2str(&sp->lease_addr.addr, 0), sp->lease_addr.plen);
-	} else if (client6_ifaddrconf(IFADDRCONF_ADD, addr) != 0) {
-		dprintf(LOG_ERR, "%s" "adding address failed: %s",
-		    FNAME, in6addr2str(&addr->addr, 0));
-		if (sp->timer)
+	} else 
+#ifdef LIBDHCP
+                if (  libdhcp_control
+                   &&(libdhcp_control->capability & DHCP_CONFIGURE_ADDRESSES)
+                   )
+                {
+#endif
+	        if (client6_ifaddrconf(IFADDRCONF_ADD, addr) != 0) {
+		    dprintf(LOG_ERR, "%s" "adding address failed: %s",
+			    FNAME, in6addr2str(&addr->addr, 0));
+		    if (sp->timer)
 			dhcp6_remove_timer(sp->timer);
-		free(sp);
-		return (-1);
-	}
+		    free(sp);
+		    return (-1);
+		}
+#ifdef LIBDHCP
+		}
+#endif
 	TAILQ_INSERT_TAIL(&client6_iaidaddr.lease_list, sp, link);
 	/* for infinite lifetime don't do any timer */
 	if (sp->lease_addr.validlifetime == DHCP6_DURATITION_INFINITE || 
@@ -282,7 +296,12 @@
 	dprintf(LOG_DEBUG, "%s" "removing address %s", FNAME,
 		in6addr2str(&sp->lease_addr.addr, 0));
 	sp->state = INVALID;
-	if (write_lease(sp, client6_lease_file) != 0) {
+#ifdef LIBDHCP
+	if (  libdhcp_control
+	    &&(libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)
+	   )
+#endif
+	if (write_6_lease(sp, client6_lease_file) != 0) {
 		dprintf(LOG_INFO, "%s" 
 			"failed to write removed lease address %s to lease file", 
 			FNAME, in6addr2str(&sp->lease_addr.addr, 0));
@@ -294,10 +313,17 @@
 			in6addr2str(&sp->lease_addr.addr, 0), sp->lease_addr.plen);
 		/* XXX: remove from the update prefix list */
 
-	} else if (client6_ifaddrconf(IFADDRCONF_REMOVE, &sp->lease_addr) != 0) {
+	} else
+#ifdef LIBDHCP
+	if (  libdhcp_control
+	    &&(libdhcp_control->capability & DHCP_CONFIGURE_ADDRESSES)
+	   )
+#endif
+
+	    if (client6_ifaddrconf(IFADDRCONF_REMOVE, &sp->lease_addr) != 0) {
 			dprintf(LOG_INFO, "%s" "removing address %s failed",
 		    		FNAME, in6addr2str(&sp->lease_addr.addr, 0));
-	}
+	    }
 	/* remove expired timer for this lease. */
 	if (sp->timer)
 		dhcp6_remove_timer(sp->timer);
@@ -446,7 +472,12 @@
 	memcpy(&sp->lease_addr, addr, sizeof(sp->lease_addr));
 	sp->state = ACTIVE;
 	time(&sp->start_date);
-	if (write_lease(sp, client6_lease_file) != 0) {
+#ifdef LIBDHCP
+	if (  libdhcp_control
+	    &&(libdhcp_control->capability & DHCP_USE_LEASE_DATABASE)
+	   )
+#endif
+	if (write_6_lease(sp, client6_lease_file) != 0) {
 		dprintf(LOG_ERR, "%s" 
 			"failed to write an updated lease address %s to lease file", 
 			FNAME, in6addr2str(&sp->lease_addr.addr, 0));
@@ -670,7 +701,7 @@
 		return (-1);
 	}
 
-	dprintf(LOG_DEBUG, "%s" "%s an address %s on %s", FNAME, cmdstr,
+	dprintf(LOG_INFO, "%s" "%s an address %s on %s", FNAME, cmdstr,
 	    in6addr2str(&ifaddr->addr, 0), ifp->ifname);
 	close(s); 
 	return (0);
@@ -700,7 +731,7 @@
 create_iaid(struct iaid_table *iaidtab, int num_device)
 {
 	struct iaid_table *temp = iaidtab;
-	struct ifaddrs *ifa=0L, *ifap=0L;
+	struct ifaddrs *ifap=0L,*ifa=0L;
 	int i;
 	
 	if ( getifaddrs( &ifap ) != 0 )
@@ -709,7 +740,7 @@
 		return -1;
 	}
 
-	for (i=0, ifa = ifap; 
+	for (i=0, ifa=ifap; 
 	     (ifa != 0L) && ( i < MAX_DEVICE );
 	     i++, ifa = ifa->ifa_next
 	    )
--- dhcp-0.10/libdhcp6client/dhcp6c.c.libdhcp6client	2006-05-14 08:09:10.000000000 -0400
+++ dhcp-0.10/libdhcp6client/dhcp6c.c	2006-05-14 08:09:29.000000000 -0400
@@ -73,6 +73,9 @@
 #include "common.h"
 #include "timer.h"
 #include "lease.h"
+#ifdef LIBDHCP
+#include "libdhcp_control.h"
+#endif
 
 static int debug = 0;
 static u_long sig_flags = 0;
@@ -103,9 +106,9 @@
 
 #define CLIENT6_INFO_REQ	0x10
 
-int insock;	/* inbound udp port */
-int outsock;	/* outbound udp port */
-int nlsock;	
+int insock = -1;	/* inbound udp port */
+int outsock= -1;	/* outbound udp port */
+int nlsock = -1;	
 
 extern char *raproc_file;
 extern char *ifproc_file;
@@ -154,20 +157,34 @@
 #define DUID_FILE "/var/lib/dhcpv6/dhcp6c_duid"
 
 static int pid;
+#ifdef LIBDHCP
+struct sockaddr_in6 sa6_allagent_storage;
+#endif
 //static char cmdbuf[1024];
 //static char oldlink[256];
 char client6_lease_temp[256];
 struct dhcp6_list request_list;
 
-int
-main(argc, argv)
+#ifndef LIBDHCP
+int main
+(argc, argv, envp)
+#else
+LIBDHCP_Control *libdhcp_control;
+int dhcpv6_client
+(libdhcp_ctl, argc, argv, envp)
+        LIBDHCP_Control *libdhcp_ctl;
+#endif
 	int argc;
 	char **argv;
+	char **envp;
 {
 	int ch;
 	char *progname, *conffile = DHCP6C_CONF;
 	FILE *pidfp;
 	char *addr;
+#ifdef LIBDHCP
+	libdhcp_control = libdhcp_ctl;
+#endif
 
 	pid = getpid();
 	srandom(time(NULL) & pid);
@@ -283,8 +300,12 @@
 			err(1, "daemon");
 		openlog(progname, LOG_NDELAY|LOG_PID, LOG_DAEMON);
 	}
+
 	setloglevel(debug);
 
+#ifndef LIBDHCP	
+	if ( libdhcp_control && ( libdhcp_control->capability & DHCP_USE_PID_FILE ) )
+#endif
 	/* dump current PID */
 	if ((pidfp = fopen(DHCP6C_PIDFILE, "w")) != NULL) {
 		fprintf(pidfp, "%d\n", pid);
@@ -292,7 +313,7 @@
 	}
 
 	ifinit(device);
-
+	setup_interface(device);
 	if ((cfparse(conffile)) != 0) {
 		dprintf(LOG_ERR, "%s" "failed to parse configuration file",
 			FNAME);
@@ -301,7 +322,55 @@
 	client6_init(device);
 	client6_ifinit(device);
 	client6_mainloop();
-	exit(0);
+#ifdef LIBDHCP
+	/* close all file descriptors */
+	close(nlsock);
+	nlsock = -1;
+	close(insock);
+	insock = -1;
+	close(outsock);
+	outsock = -1;
+	closelog();
+	/* release all memory */
+	sleep(1); /* keep valgrind happy :-) */
+	dhc6_free_all_pointers();
+	/* initialize globals */
+	optarg = 0L;
+	optind = 0;
+	opterr = 0;
+	optopt = 0;
+	memset( &client6_iaidaddr, '\0', sizeof(client6_iaidaddr));
+	dhcp6_if = 0L;
+	dadlist = 0L;
+	extern LIST_HEAD(, dhcp6_timer) timer_head;
+	memset( &timer_head, '\0', sizeof(timer_head));
+	memset( &request_list, '\0', sizeof(request_list));
+	memset( &sa6_allagent_storage, '\0', sizeof(sa6_allagent_storage));
+	memset( &client_duid, '\0', sizeof(client_duid));
+	memset( &iaidtab, '\0', sizeof(iaidtab));
+	client6_request_flag =0;
+	memset( &leasename, '\0', sizeof(leasename));
+	sa6_allagent = 0;
+	debug = 0;
+	device = 0L;	
+	num_device=0;
+	sig_flags = 0;
+	extern struct host_conf *host_conflist;
+	host_conflist = 0;
+	client6_lease_file = server6_lease_file = sync_file = 0L;
+	cf_dns_list = 0L;
+	extern int cfdebug;
+	cfdebug = 0;
+	hash_anchors = 0;
+	configfilename = 0L;
+	debug_thresh = 0;
+	memset( &dnslist, '\0', sizeof(dnslist));
+	memset( &radvd_dhcpv6_file, '\0', sizeof(radvd_dhcpv6_file));
+	memset( &resolv_dhcpv6_file, '\0', sizeof(resolv_dhcpv6_file));
+	memset( &client6_lease_temp, '\0', sizeof(client6_lease_temp));
+	foreground = 0;
+#endif
+	return(0);
 }
 
 static void
@@ -320,7 +389,9 @@
 	char *device;
 {
 	struct addrinfo hints, *res;
+#ifndef LIBDHCP
 	static struct sockaddr_in6 sa6_allagent_storage;
+#endif
 	int error, on = 1;
 	struct dhcp6_if *ifp;
 	int ifidx;
@@ -345,7 +416,7 @@
 	if (inet_ntop(AF_INET6, &lladdr, linklocal, sizeof(linklocal)) < 0) {
 		exit(1);
 	}
-	dprintf(LOG_DEBUG, "link local addr is %s", linklocal);
+	dprintf(LOG_INFO, "link local addr is %s", linklocal);
 	
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = PF_INET6;
@@ -381,7 +452,7 @@
 	}
 #endif
 	((struct sockaddr_in6 *)(res->ai_addr))->sin6_scope_id = ifidx;
-	dprintf(LOG_DEBUG, "res addr is %s/%d", addr2str(res->ai_addr), res->ai_addrlen);
+	dprintf(LOG_INFO, "inbound addr is %s/%d", addr2str(res->ai_addr), res->ai_addrlen);
 	if (bind(insock, res->ai_addr, res->ai_addrlen) < 0) {
 		dprintf(LOG_ERR, "%s" "bind(inbound): %s",
 			FNAME, strerror(errno));
@@ -410,18 +481,13 @@
 		exit(1);
 	}
 	((struct sockaddr_in6 *)(res->ai_addr))->sin6_scope_id = ifidx;
+	dprintf(LOG_INFO, "outbound addr is %s/%d", addr2str(res->ai_addr), res->ai_addrlen);
 	if (bind(outsock, res->ai_addr, res->ai_addrlen) < 0) {
 		dprintf(LOG_ERR, "%s" "bind(outbound): %s",
 			FNAME, strerror(errno));
 		exit(1);
 	}
 	freeaddrinfo(res);
-	/* open a socket to watch the off-on link for confirm messages */
-	if ((nlsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-		dprintf(LOG_ERR, "%s" "open a socket: %s",
-			FNAME, strerror(errno));
-		exit(1);
-	}
 	memset(&hints, 0, sizeof(hints));
 	hints.ai_family = PF_INET6;
 	hints.ai_socktype = SOCK_DGRAM;
@@ -443,7 +509,7 @@
 		exit(1);
 	}
 	ifp->outsock = outsock;
-
+#ifndef LIBDHCP
 	if (signal(SIGHUP, client6_signal) == SIG_ERR) {
 		dprintf(LOG_WARNING, "%s" "failed to set signal: %s",
 			FNAME, strerror(errno));
@@ -459,6 +525,7 @@
 			FNAME, strerror(errno));
 		exit(1);
 	}
+#endif
 }
 
 static void
@@ -487,6 +554,10 @@
 	memcpy(&client6_iaidaddr.client6_info.iaidinfo, &ifp->iaidinfo, 
 			sizeof(client6_iaidaddr.client6_info.iaidinfo));
 	duidcpy(&client6_iaidaddr.client6_info.clientid, &client_duid);
+#ifdef LIBDHCP
+	if ( libdhcp_control && ( libdhcp_control->capability & DHCP_USE_LEASE_DATABASE ) )
+	{
+#endif
 	/* parse the lease file */
 	strcpy(leasename, PATH_CLIENT6_LEASE);
 	sprintf(iaidstr, "%u", ifp->iaidinfo.iaid);
@@ -502,6 +573,9 @@
 		sync_leases(client6_lease_file, leasename, client6_lease_temp);
 	if (client6_lease_file == NULL)
 		exit(1);
+#ifdef LIBDHCP
+        }
+#endif
 	if (!TAILQ_EMPTY(&client6_iaidaddr.lease_list)) {
 //		struct dhcp6_lease *cl;
 		struct dhcp6_listval *lv;
@@ -527,7 +601,7 @@
 		dprintf(LOG_INFO, "no ipv6 addresses are leased by client");
 		exit(0);
 	}
-	setup_interface(ifp->ifname);
+/*	setup_interface(ifp->ifname); */
 	ifp->link_flag |= IFF_RUNNING;
 
 	/* get addrconf prefix from kernel */
@@ -574,6 +648,11 @@
 	else {
 		for (sp = TAILQ_FIRST(&client6_iaidaddr.lease_list); sp; sp = sp_next) { 
 			sp_next = TAILQ_NEXT(sp, link);
+#ifdef LIBDHCP
+			if(   libdhcp_control 
+			   && (libdhcp_control->capability & DHCP_CONFIGURE_ADDRESSES )
+			 )
+#endif
 			if (client6_ifaddrconf(IFADDRCONF_REMOVE, &sp->lease_addr) != 0) 
 				dprintf(LOG_INFO, "%s" "deconfiging address %s failed",
 					FNAME, in6addr2str(&sp->lease_addr.addr, 0));
@@ -585,6 +664,11 @@
 		ev_next = TAILQ_NEXT(ev, link);
 		dhcp6_remove_event(ev);
 	}
+#ifdef LIBDHCP
+	if(   libdhcp_control 
+	      && (libdhcp_control->capability & DHCP_CONFIGURE_RADVD )
+	  )
+#endif
 	/* XXX: check the last dhcpv6 client daemon to restore the original file */
 	{
 		/* restore /etc/radv.conf.bak back to /etc/radvd.conf */
@@ -624,19 +708,72 @@
 static void
 client6_mainloop()
 {
-	struct timeval *w;
+        struct timeval *w;
 	int ret;
 	fd_set r;
 
+#ifdef LIBDHCP
+	struct timeval fb /* fallback timeout */;
+
+	if (  libdhcp_control )
+	{
+	    if ( libdhcp_control->timeout )
+		libdhcp_control->now = time(0);
+	    else
+		libdhcp_control->now = 0;
+	}
+#endif
+
 	while(1) {
 		if (sig_flags)
 			process_signals();
-		w = dhcp6_check_timer();
 
+		w = dhcp6_check_timer();
+#ifdef LIBDHCP
+		if (  libdhcp_control && libdhcp_control->timeout )
+		{
+		    time_t now = time(0);
+		    if ( (w == 0L) 
+		       ||( ( ((double)(w->tv_sec + now ))
+			    +(((double)(w->tv_usec))/1000000.0)
+			   ) >=
+			   ( ((double)libdhcp_control->now)
+			    +((double)libdhcp_control->timeout)
+			   )
+			 )
+		       )
+		    {
+			w = &fb;
+			fb.tv_sec = 0;
+			fb.tv_usec = 0;
+			if ( now < ( libdhcp_control->now + libdhcp_control->timeout ) )
+			    fb.tv_sec = (libdhcp_control->now + libdhcp_control->timeout) - now;
+		    }
+                           
+		}
+#endif
 		FD_ZERO(&r);
 		FD_SET(insock, &r);
 
+		dprintf(LOG_DEBUG,"\n\nentering select - client state: %d %s timeout: %p %lu %lu\n",
+			client6_iaidaddr.state,
+			(client6_iaidaddr.state == DHCP6_ACTIVE)
+			? "ACTIVE"
+			:(client6_iaidaddr.state == DHCP6_RENEW)
+			? "RENEW"
+			:(client6_iaidaddr.state == DHCP6_REBIND)
+			? "REBIND"
+			:(client6_iaidaddr.state == DHCP6_EXPIRED)
+			? "EXPIRED"
+			:(client6_iaidaddr.state == DHCP6_INVALID)
+			?"INVALID"
+			:"UNKNOWN", w,
+			w ? w -> tv_sec : 0,
+			w ? w -> tv_usec: 0
+		    );
+
 		ret = select(insock + 1, &r, NULL, NULL, w);
+
 		switch (ret) {
 		case -1:
 			if (errno != EINTR) {
@@ -648,8 +785,36 @@
 		case 0:	/* timeout */
 			break;	/* dhcp6_check_timer() will treat the case */
 		default: /* received a packet */
+		        dprintf(LOG_DEBUG,"client_recv");
 			client6_recv();
+			
+		}
+#ifdef LIBDHCP
+		if ( libdhcp_control )
+		{
+		    dprintf(LOG_INFO,"libdhcp_check");
+		    if( libdhcp_control->finished )
+			return;
+
+		    if( libdhcp_control->timeout 
+		      &&( time(0L) >=
+			  (  libdhcp_control->timeout 
+			   + libdhcp_control->now
+			  )
+		        )
+		      ) 
+		    {
+			if ( libdhcp_control -> callback )
+			    (*( libdhcp_control -> callback ) )
+			    (
+				libdhcp_control,
+				DHC_TIMEDOUT,
+				&client6_iaidaddr
+			    );
+			return;
+		    }
 		}
+#endif
 	}
 }
 
@@ -676,6 +841,7 @@
 
 	switch(ev->state) {
 	case DHCP6S_INIT:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_INIT");
 		/* From INIT state client could
 		 * go to CONFIRM state if the client reboots;
 		 * go to RELEASE state if the client issues a release;
@@ -715,6 +881,7 @@
 			ev->state = DHCP6S_SOLICIT;
 		dhcp6_set_timeoparam(ev);
 	case DHCP6S_SOLICIT:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_SOLICIT");
 		if (ifp->servers) {
 			ifp->current_server = select_server(ifp);
 			if (ifp->current_server == NULL) {
@@ -725,7 +892,7 @@
 			}
 			/* if get the address assginment break */
 			if (!TAILQ_EMPTY(&client6_iaidaddr.lease_list)) {
-				dhcp6_remove_event(ev);
+				dhcp6_remove_event(ev);				
 				return (NULL);
 			}
 			ev->timeouts = 0;
@@ -733,14 +900,21 @@
 			dhcp6_set_timeoparam(ev);
 		}
 	case DHCP6S_INFOREQ:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_INFOREQ");
 	case DHCP6S_REQUEST:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_REQUEST");
 		client6_send(ev);
 		break;
 	case DHCP6S_RELEASE:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_RELEASE");
 	case DHCP6S_DECLINE:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_DECLINE");
 	case DHCP6S_CONFIRM:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_CONFIRM");
 	case DHCP6S_RENEW:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_RENEW");
 	case DHCP6S_REBIND:
+	    dprintf(LOG_DEBUG,"client6_timo - DHCP6_REBIND");
 		if (!TAILQ_EMPTY(&request_list))
 			client6_send(ev);
 		else {
@@ -822,9 +996,11 @@
 
 	switch(ev->state) {
 	case DHCP6S_SOLICIT:
+	    dprintf(LOG_DEBUG,"send state SOLICIT");
 		dh6->dh6_msgtype = DH6_SOLICIT;
 		break;
 	case DHCP6S_REQUEST:
+	    dprintf(LOG_DEBUG,"send state REQUEST");
 		if (ifp->current_server == NULL) {
 			dprintf(LOG_ERR, "%s" "assumption failure", FNAME);
 			exit(1); /* XXX */
@@ -832,6 +1008,7 @@
 		dh6->dh6_msgtype = DH6_REQUEST;
 		break;
 	case DHCP6S_RENEW:
+	    dprintf(LOG_DEBUG,"send state RENEW");
 		if (ifp->current_server == NULL) {
 			dprintf(LOG_ERR, "%s" "assumption failure", FNAME);
 			exit(1); /* XXX */
@@ -839,6 +1016,7 @@
 		dh6->dh6_msgtype = DH6_RENEW;
 		break;
 	case DHCP6S_DECLINE:
+	    dprintf(LOG_DEBUG,"send state DECLINE");
 		if (ifp->current_server == NULL) {
 			dprintf(LOG_ERR, "%s" "assumption failure", FNAME);
 			exit(1); /* XXX */
@@ -846,15 +1024,19 @@
 		dh6->dh6_msgtype = DH6_DECLINE;
 		break;
 	case DHCP6S_INFOREQ:	
+	    dprintf(LOG_DEBUG,"send state INFOREQ");
 		dh6->dh6_msgtype = DH6_INFORM_REQ;
 		break;
 	case DHCP6S_REBIND:
+	    dprintf(LOG_DEBUG,"send state REBIND");
 		dh6->dh6_msgtype = DH6_REBIND;
 		break;
 	case DHCP6S_CONFIRM:
+	    dprintf(LOG_DEBUG,"send state CONFIRM");
 		dh6->dh6_msgtype = DH6_CONFIRM;
 		break;
 	case DHCP6S_RELEASE:
+	    dprintf(LOG_DEBUG,"send state RELEASE");
 		dh6->dh6_msgtype = DH6_RELEASE;
 		break;
 	default:
@@ -990,12 +1172,34 @@
 			/* XXX: allow the other emtpy list ?? */
 		}
 		if (client6_request_flag & CLIENT6_RELEASE_ADDR) {
+#ifdef LIBDHCP
+		    if(   libdhcp_control 
+		       && (libdhcp_control->capability & DHCP_CONFIGURE_ADDRESSES )
+		      )
+			
+#endif
 			if (dhcp6_update_iaidaddr(&optinfo, ADDR_REMOVE)) {
 				dprintf(LOG_INFO, "client release failed");
 				exit(1);
 			}
+#ifdef LIBDHCP
+		     if(   libdhcp_control 
+		       && (libdhcp_control->capability & DHCP_CONFIGURE_RADVD )
+		      )
+			
+#endif
 			if (client6_iaidaddr.client6_info.type == IAPD)
 				radvd_parse(&client6_iaidaddr, ADDR_REMOVE);
+
+#ifdef LIBDHCP
+		     if( libdhcp_control &&  libdhcp_control->callback )
+			 (*(libdhcp_control->callback))
+			 (  libdhcp_control,
+			    DHC6_RELEASE,
+			    &client6_iaidaddr
+			 );
+#endif
+
 		}
 		break;
 	default:
@@ -1044,15 +1248,17 @@
 		break;
 	}
 	dst.sin6_scope_id = ifp->linkid;
-	dprintf(LOG_DEBUG, "send dst if %s addr is %s scope id is %d", 
+	dprintf(LOG_INFO, "send dst if %s addr is %s scope id is %d", 
 		ifp->ifname, addr2str((struct sockaddr *)&dst), ifp->linkid);
+	
+	dprintf(LOG_DEBUG,"\nSEND PACKET\n");
 	if (sendto(ifp->outsock, buf, len, MSG_DONTROUTE, (struct sockaddr *)&dst,
 	    sizeof(dst)) == -1) {
 		dprintf(LOG_ERR, FNAME "transmit failed: %s", strerror(errno));
 		goto end;
 	}
 
-	dprintf(LOG_DEBUG, "%s" "send %s to %s", FNAME,
+	dprintf(LOG_INFO, "%s" "send %s to %s", FNAME,
 		dhcp6msgstr(dh6->dh6_msgtype),
 		addr2str((struct sockaddr *)&dst));
 
@@ -1076,6 +1282,7 @@
 	struct cmsghdr *cm;
 	struct in6_pktinfo *pi = NULL;
 
+	dprintf(LOG_DEBUG,"\nclient6_recv\n");
 	memset(&iov, 0, sizeof(iov));
 	memset(&mhdr, 0, sizeof(mhdr));
 
@@ -1133,9 +1340,11 @@
 
 	switch(dh6->dh6_msgtype) {
 	case DH6_ADVERTISE:
+	        dprintf(LOG_DEBUG,"client6_recv RECVADVERT");
 		(void)client6_recvadvert(ifp, dh6, len, &optinfo);
 		break;
 	case DH6_REPLY:
+	        dprintf(LOG_DEBUG,"client6_recv RECVREPLY");
 		(void)client6_recvreply(ifp, dh6, len, &optinfo);
 		break;
 	default:
@@ -1144,7 +1353,6 @@
 			addr2str((struct sockaddr *)&from));
 		break;
 	}
-
 	dhcp6_clear_options(&optinfo);
 	return;
 }
@@ -1255,7 +1463,22 @@
 	/* if the client send preferred addresses reqeust in SOLICIT */
 	/* XXX: client might have some local policy to select the addresses */
 	if (!TAILQ_EMPTY(&optinfo0->addr_list))
+	{
+#ifdef LIBDHCP
+	    if ( ! TAILQ_EMPTY( &(client6_iaidaddr.lease_list) ) )
+	    /* looks like we did a successful REBIND ? */
+		if( libdhcp_control && libdhcp_control->callback )
+		{
+		    (*(libdhcp_control->callback))
+			(
+			    libdhcp_control,
+			    DHC6_REBIND,
+			    optinfo0
+			);
+		}
+#endif
 		dhcp6_copy_list(&request_list, &optinfo0->addr_list);
+	}
 	return 0;
 }
 
@@ -1343,6 +1566,7 @@
 	int addr_status_code = DH6OPT_STCODE_UNSPECFAIL;
 	struct dhcp6_serverinfo *newserver;
 	int newstate = 0;
+	dprintf(LOG_DEBUG, "RECV REPLY");
 	/* find the corresponding event based on the received xid */
 	dprintf(LOG_DEBUG, "%s" "reply message XID is (%x)",
 		FNAME, ntohl(dh6->dh6_xid) & DH6_XIDMASK);
@@ -1366,13 +1590,16 @@
 		dprintf(LOG_INFO, "%s" "no server ID option", FNAME);
 		return -1;
 	}
-	dprintf(LOG_DEBUG, "%s" "serverID is %s len is %d", FNAME,
+	dprintf(LOG_INFO, "%s" "serverID is %s len is %d", FNAME,
 		duidstr(&optinfo->serverID), optinfo->serverID.duid_len); 
 	/* get current server */
 	switch (ev->state) {
 	case DHCP6S_SOLICIT:
+	    dprintf(LOG_DEBUG, "%s" "state SOLICIT",FNAME);
 	case DHCP6S_CONFIRM:
+	    dprintf(LOG_DEBUG, "%s" "state CONFIRM",FNAME);
 	case DHCP6S_REBIND:
+	    dprintf(LOG_DEBUG, "%s" "state REBIND",FNAME);
 		newserver = allocate_newserver(ifp, optinfo);
 		if (newserver == NULL)
 			return (-1);
@@ -1395,11 +1622,13 @@
 		dprintf(LOG_INFO, "%s" "client DUID mismatch", FNAME);
 		return -1;
 	}
+        if (!TAILQ_EMPTY(&optinfo->dns_list.addrlist) || 
+		optinfo->dns_list.domainlist != NULL)
 
-	if (!TAILQ_EMPTY(&optinfo->dns_list.addrlist) || 
-	    optinfo->dns_list.domainlist != NULL) {
-		resolv_parse(&optinfo->dns_list);
-	}
+#ifdef LIBDHCP
+	    if ( libdhcp_control && (libdhcp_control->capability & DHCP_CONFIGURE_RESOLVER) )
+#endif
+		  resolv_parse(&optinfo->dns_list);	
 	/*
 	 * The client MAY choose to report any status code or message from the
 	 * status code option in the Reply message.
@@ -1426,7 +1655,7 @@
 	switch (addr_status_code) {
 	case DH6OPT_STCODE_UNSPECFAIL:
 	case DH6OPT_STCODE_USEMULTICAST:
-		dprintf(LOG_INFO, "%s" "status code: %s", FNAME, 
+		dprintf(LOG_INFO, "%s" "status code: %s - RETRANSMIT", FNAME, 
 			dhcp6_stcodestr(addr_status_code));
 		/* retransmit the message with multicast address */
 		/* how many time allow the retransmission with error status code? */
@@ -1441,6 +1670,7 @@
 	 */
 	switch (ev->state) {
 	case DHCP6S_SOLICIT:
+	    dprintf(LOG_DEBUG, "%s" "state SOLICIT",FNAME);
 		if (optinfo->iaidinfo.iaid == 0)
 			break;
 		else if (!optinfo->flags & DHCIFF_RAPID_COMMIT) {
@@ -1448,6 +1678,7 @@
 			break;
 		}
 	case DHCP6S_REQUEST:
+	    dprintf(LOG_DEBUG, "%s" "state REQUEST",FNAME);
 		/* NotOnLink: 1. SOLICIT 
 		 * NoAddrAvail: Information Request */
 		switch(addr_status_code) {
@@ -1468,32 +1699,57 @@
 		case DH6OPT_STCODE_SUCCESS:
 		case DH6OPT_STCODE_UNDEFINE:
 		default:
+		    dprintf(LOG_DEBUG, "%s" "addr_status_code SUCCESS/UNDEFINE",FNAME);
 			if (!TAILQ_EMPTY(&optinfo->addr_list)) {
 				(void)get_if_rainfo(ifp);
 				dhcp6_add_iaidaddr(optinfo);
 				if (optinfo->type == IAPD)
+				{
+#ifdef LIBDHCP
+				    if(   libdhcp_control 
+				      && (libdhcp_control->capability & DHCP_CONFIGURE_RADVD )
+				      )
+#endif
 					radvd_parse(&client6_iaidaddr, ADDR_UPDATE);
-				else if (ifp->dad_timer == NULL && (ifp->dad_timer =
+				}else if (ifp->dad_timer == NULL && (ifp->dad_timer =
 					  dhcp6_add_timer(check_dad_timo, ifp)) < 0) {
 					dprintf(LOG_INFO, "%s" "failed to create a timer for "
 						" DAD", FNAME); 
-				}
+				}				
 				setup_check_timer(ifp);
+#ifdef LIBDHCP
+				if( libdhcp_control && libdhcp_control->callback )
+				    (*(libdhcp_control -> callback))
+				    (  libdhcp_control,
+				       DHC6_BOUND,
+				       optinfo
+				    );
+#endif				
 			}
 			break;
 		}
 		break;
 	case DHCP6S_RENEW:
+	    dprintf(LOG_DEBUG, "%s" "state RENEW",FNAME);
 	case DHCP6S_REBIND:
+	    dprintf(LOG_DEBUG, "%s" "state REBIND",FNAME);
 		if (client6_request_flag & CLIENT6_CONFIRM_ADDR) 
 			goto rebind_confirm;
 		/* NoBinding for RENEW, REBIND, send REQUEST */
 		switch(addr_status_code) {
-		case DH6OPT_STCODE_NOBINDING:
+ 		case DH6OPT_STCODE_NOBINDING:
 			newstate = DHCP6S_REQUEST;
 			dprintf(LOG_DEBUG, "%s" 
 			    	  "got a NoBinding reply, sending request.", FNAME);
 			dhcp6_remove_iaidaddr(&client6_iaidaddr);
+#ifdef LIBDHCP
+			if( libdhcp_control && libdhcp_control->callback )
+			    (*(libdhcp_control -> callback))
+			    (  libdhcp_control,
+			       DHC6_RELEASE,
+			       &client6_iaidaddr
+			    );
+#endif				
 			break;
 		case DH6OPT_STCODE_NOADDRAVAIL:
 		case DH6OPT_STCODE_NOPREFIXAVAIL:
@@ -1504,11 +1760,26 @@
 		default:
 			dhcp6_update_iaidaddr(optinfo, ADDR_UPDATE);
 			if (optinfo->type == IAPD)
+#ifdef LIBDHCP
+			    if(   libdhcp_control 
+			      && (libdhcp_control->capability & DHCP_CONFIGURE_RADVD )
+			      )
+#endif
 				radvd_parse(&client6_iaidaddr, ADDR_UPDATE);
+#ifdef LIBDHCP
+			if( libdhcp_control && libdhcp_control->callback )
+			    (*(libdhcp_control -> callback))
+			    (  libdhcp_control,
+			       DHC6_REBIND,
+			       optinfo
+			    );
+#endif				
 			break;
+
 		}
 		break;
 	case DHCP6S_CONFIRM:
+	    dprintf(LOG_DEBUG, "%s" "state CONFIRM - goto SOLICIT",FNAME);
 		/* NOtOnLink for a Confirm, send SOLICIT message */
 rebind_confirm:	client6_request_flag &= ~CLIENT6_CONFIRM_ADDR;
 	switch(addr_status_code) {
@@ -1526,6 +1797,7 @@
 			break;
 		case DH6OPT_STCODE_SUCCESS:
 		case DH6OPT_STCODE_UNDEFINE:
+		    dprintf(LOG_DEBUG, "%s" "CONFIRM: addr_status_code SUCCESS/UNDEFINE",FNAME);
 			/* XXX: set up renew/rebind timer */
 			dprintf(LOG_DEBUG, "%s" "got an expected reply for confirm", FNAME);
 			ftime(&now);
@@ -1548,7 +1820,7 @@
 			if ( offset > client6_iaidaddr.client6_info.iaidinfo.renewtime) 
 				timo.tv_sec = 0;
 			else
-				timo.tv_sec = client6_iaidaddr.client6_info.iaidinfo.renewtime 						- offset; 
+				timo.tv_sec = client6_iaidaddr.client6_info.iaidinfo.renewtime - offset; 
 			timo.tv_usec = 0;
 			dhcp6_set_timer(&timo, client6_iaidaddr.timer);
 			/* check DAD */
@@ -1564,6 +1836,7 @@
 		}
 		break;
 	case DHCP6S_DECLINE:
+	    dprintf(LOG_DEBUG, "%s" "state DECLINE",FNAME);
 		/* send REQUEST message to server with none decline address */
 		dprintf(LOG_DEBUG, "%s" 
 		    "got an expected reply for decline, sending request.", FNAME);
@@ -1572,6 +1845,7 @@
 		newstate = DHCP6S_REQUEST;
 		break;
 	case DHCP6S_RELEASE:
+	    dprintf(LOG_DEBUG, "%s" "state RELEASE",FNAME);
 		dprintf(LOG_INFO, "%s" "got an expected release, exit.", FNAME);
 		dhcp6_remove_event(ev);
 		exit(0);
@@ -1593,6 +1867,8 @@
 	int state;
 {
 	struct dhcp6_event *ev;
+	dprintf(LOG_DEBUG,"send_newstate: %d", state);
+		
 	if ((ev = dhcp6_create_event(ifp, state)) == NULL) {
 		dprintf(LOG_ERR, "%s" "failed to create an event",
 			FNAME);
@@ -1651,6 +1927,11 @@
 		/* config the interface for reboot */
 		if (reboot && client6_iaidaddr.client6_info.type != IAPD && 
 		    (client6_request_flag & CLIENT6_CONFIRM_ADDR)) {
+#ifdef LIBDHCP
+                if (  libdhcp_control
+                   &&(libdhcp_control->capability & DHCP_CONFIGURE_ADDRESSES)
+                   )
+#endif
 			if (client6_ifaddrconf(IFADDRCONF_ADD, &cl->lease_addr) != 0) {
 				dprintf(LOG_INFO, "config address failed: %s",
 					in6addr2str(&cl->lease_addr.addr, 0));
@@ -1661,6 +1942,11 @@
 	/* update radvd.conf for prefix delegation */
 	if (reboot && client6_iaidaddr.client6_info.type == IAPD &&
 	    (client6_request_flag & CLIENT6_CONFIRM_ADDR))
+#ifdef LIBDHCP
+	    if(   libdhcp_control 
+	      && (libdhcp_control->capability & DHCP_CONFIGURE_RADVD )
+	      )
+#endif
 		radvd_parse(&client6_iaidaddr, ADDR_UPDATE);
 	return (0);
 }
@@ -1752,8 +2038,9 @@
 	int newstate;
 	dprintf(LOG_DEBUG, "enter checking link ...");
 	strncpy(ifr.ifr_name, dhcp6_if->ifname, IFNAMSIZ);
+	dprintf(LOG_DEBUG,"check_link_timo: ioctl SIOCIGIFFLAGS");
 	if (ioctl(nlsock, SIOCGIFFLAGS, &ifr) < 0) {
-		dprintf(LOG_DEBUG, "ioctl SIOCGIFFLAGS failed");
+		dprintf(LOG_DEBUG, "check_link_timo: ioctl SIOCGIFFLAGS failed");
 		goto settimer;
 	}
 	if (ifr.ifr_flags & IFF_RUNNING) {
@@ -1795,29 +2082,48 @@
 setup_interface(char *ifname)
 {
 	struct ifreq ifr;
+	int retries = 0;
 	/* check the interface */
+
+	dprintf(LOG_INFO,"setup interface");
+
+	/* open a socket to watch the off-on link for confirm messages */
+	if ((nlsock == -1) && ((nlsock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)) {
+		dprintf(LOG_ERR, "%s" "open a socket: %s",
+			FNAME, strerror(errno));
+		exit(1);
+	}
+	memset(&ifr,'\0',sizeof(struct ifreq));
 	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-again:
 	if (ioctl(nlsock, SIOCGIFFLAGS, &ifr) < 0) {
 		dprintf(LOG_ERR, "ioctl SIOCGIFFLAGS failed");
 		exit(1);
 	}
-	if (!ifr.ifr_flags & IFF_UP) {
-		ifr.ifr_flags |= IFF_UP;
-		if (ioctl(nlsock, SIOCSIFFLAGS, &ifr) < 0) {
-			dprintf(LOG_ERR, "ioctl SIOCSIFFLAGS failed");
-			exit(1);
-		}
-		if (ioctl(nlsock, SIOCGIFFLAGS, &ifr) < 0) {
-			dprintf(LOG_ERR, "ioctl SIOCGIFFLAGS failed");
-			exit(1);
-		}
-	}
-	if (!ifr.ifr_flags & IFF_RUNNING) {
-		dprintf(LOG_INFO, "NIC is not connected to the network, "
-			"please connect it. dhcp6c is sleeping ...");
-		sleep(10);
-		goto again;
+	while( (ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) !=  (IFF_UP | IFF_RUNNING) )
+	{
+	       if( retries++ > 1 )
+	       {
+		   dprintf(LOG_INFO, "NIC is not connected to the network, "
+			    "please connect it. dhcp6c is sleeping ...");
+		   sleep(10);
+	       }
+	       memset(&ifr,'\0',sizeof(struct ifreq));
+	       strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+	       ifr.ifr_flags |= (IFF_UP | IFF_RUNNING) ;
+	       dprintf(LOG_INFO,"ioctl SIOCISIFFLAGS (UP | RUNNING)");
+	       if (ioctl(nlsock, SIOCSIFFLAGS, &ifr) < 0) {
+		   dprintf(LOG_ERR, "ioctl SIOCSIFFLAGS failed");
+		   exit(1);
+	       }
+	       sleep(2); /* give kernel time to assign link local address 
+			  * and to find / respond to IPv6 routers ..
+			  */
+	       memset(&ifr,'\0',sizeof(struct ifreq));
+	       strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+	       if (ioctl(nlsock, SIOCGIFFLAGS, &ifr) < 0) {
+		   dprintf(LOG_ERR, "ioctl SIOCGIFFLAGS failed");
+		   exit(1);
+	       }
 	}
 	return;
 }
--- /dev/null	2006-05-13 13:28:06.911768500 -0400
+++ dhcp-0.10/libdhcp6client/libdhcp_control.h	2006-05-14 08:09:29.000000000 -0400
@@ -0,0 +1,104 @@
+/* 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) Jason Vas Dias <jvdias at redhat.com> Red Hat Inc. May 2006
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation at 
+ *           http://www.fsf.org/licensing/licenses/gpl.txt
+ *  and included in this software distribution as the "LICENSE" file.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+#ifndef LIBDHCP_CONTROL_H
+#define LIBDHCP_CONTROL_H
+
+#include <stdint.h>
+#include <stdarg.h>
+
+#define  LOG_FATAL 8
+
+enum dhcp_state_e;
+struct libdhcp_control_s;
+
+typedef
+int ( *LIBDHCP_Error_Handler )
+    ( struct libdhcp_control_s *ctl,
+      int priority,  /* ala syslog(3): LOG_EMERG=0 - LOG_DEBUG=7 (+ LOG_FATAL=8 : finished -> 1)   */
+      const char *fmt,
+      va_list ap
+    );
+
+typedef 
+int ( *LIBDHCP_Callback ) ( struct libdhcp_control_s *control, enum dhcp_state_e, void* );
+    /* 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 
+struct libdhcp_control_s
+{
+    LIBDHCP_Callback    callback;    	/* the DHCP clients' main loop calls this on state changes */
+    uint16_t            capability;     /* LIBDHCP_Capability bits to enable                       */
+    uint8_t             finished;       /* set to one to make clients exit their main loop         */
+    uint8_t             decline;        /* set to one to decline the lease (DHCPv4 only)           */
+    time_t              timeout;        /* (timeout+now) == time after which clients MUST return   */
+    time_t              now;            /* clients set this to time(0) on entering main loop       */
+    void               *arg;            /* user data pointer                                       */
+    LIBDHCP_Error_Handler eh;
+} LIBDHCP_Control;
+
+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;
+
+typedef enum libdhcp_capability_e
+{/* DHCP client "capabilities" */ 
+    DHCP_USE_LEASE_DATABASE   = 1,  	/* use / do not use persistent lease database files */
+    DHCP_USE_PID_FILE         = 2,  	/* use / do not use pid file                        */
+ /*
+  * 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.
+  */
+    DHCP_CONFIGURE_INTERFACES = 4,  	/* configure interfaces UP/DOWN as required         */
+    DHCP_CONFIGURE_ADDRESSES  = 8,  	/* configure interface addresses as required        */
+    DHCP_CONFIGURE_ROUTES     =16,  	/* configure routes as required                     */
+    DHCP_CONFIGURE_RESOLVER   =32,  	/* configure resolv.conf as required                */
+    /* DHCPv6 only: */
+    DHCP_CONFIGURE_RADVD      =64,  	/* configure radvd.conf & restart radvd as required */
+} LIBDHCP_Capability;
+
+#endif
--- /dev/null	2006-05-13 13:28:06.911768500 -0400
+++ dhcp-0.10/libdhcp6client/dhc6_alloc.h	2006-05-14 08:09:29.000000000 -0400
@@ -0,0 +1,10 @@
+
+extern void *dhc6_alloc( size_t );
+extern void *dhc6_realloc(void *, size_t);
+extern void *dhc6_calloc(size_t, size_t);
+extern void dhc6_free( void *);
+extern void dhc6_free_all_pointers(void);
+#define malloc( size ) dhc6_alloc( size )
+#define realloc(ptr, size) dhc6_realloc(ptr, size)
+#define calloc(n, size) dhc6_calloc(n, size)
+#define free( ptr ) dhc6_free( ptr )
--- dhcp-0.10/libdhcp6client/lease.c.libdhcp6client	2004-03-03 15:11:16.000000000 -0500
+++ dhcp-0.10/libdhcp6client/lease.c	2006-05-14 08:09:29.000000000 -0400
@@ -64,7 +64,7 @@
 static int init_lease_hashes __P((void));
 
 int 
-write_lease(const struct dhcp6_lease *lease_ptr,
+write_6_lease(const struct dhcp6_lease *lease_ptr,
 	    FILE *file)
 {
 	struct tm brokendown_time;
@@ -140,7 +140,7 @@
 		for (i = 0; i < lease_hash_table->hash_size; i++) {
 			element = lease_hash_table->hash_list[i];
 			while (element) {
-				if (write_lease((struct dhcp6_lease *)element->data, 
+				if (write_6_lease((struct dhcp6_lease *)element->data, 
 							sync_file) < 0) {
 					dprintf(LOG_ERR, "%s" "write lease failed", FNAME);
 					return (NULL);
@@ -152,7 +152,7 @@
 		struct dhcp6_lease *lv, *lv_next;
 		for (lv = TAILQ_FIRST(&client6_iaidaddr.lease_list); lv; lv = lv_next) {
 			lv_next = TAILQ_NEXT(lv, link);
-			if (write_lease(lv, sync_file) < 0)  
+			if (write_6_lease(lv, sync_file) < 0)  
 				dprintf(LOG_ERR, "%s" "write lease failed", FNAME);
 		}
 	}
@@ -354,8 +354,8 @@
 get_linklocal(const char *ifname,
 	      struct in6_addr *linklocal)
 {	
-	struct ifaddrs *ifa, *ifap;
-	struct sockaddr *sd;
+	struct ifaddrs *ifa=0, *ifap=0;
+	struct sockaddr *sd=0;
 	if (getifaddrs(&ifap) < 0) {
 		dprintf(LOG_ERR, "getifaddrs error");
 		return -1;
--- dhcp-0.10/libdhcp6client/lease.h.libdhcp6client	2003-07-01 22:21:25.000000000 -0400
+++ dhcp-0.10/libdhcp6client/lease.h	2006-05-14 08:09:29.000000000 -0400
@@ -101,7 +101,7 @@
 extern FILE *init_leases __P((const char *));
 extern void lease_parse __P((FILE *));
 extern int do_iaidaddr_hash __P((struct dhcp6_lease *, struct client6_if *));
-extern int write_lease __P((const struct dhcp6_lease *, FILE *));
+extern int write_6_lease __P((const struct dhcp6_lease *, FILE *));
 extern FILE *sync_leases __P((FILE *, const char *, char *));
 extern struct dhcp6_timer *syncfile_timo __P((void *));
 extern unsigned int addr_hash __P((const void *));
--- /dev/null	2006-05-13 13:28:06.911768500 -0400
+++ dhcp-0.10/libdhcp6client/dhc6_alloc.c	2006-05-14 08:09:29.000000000 -0400
@@ -0,0 +1,59 @@
+#include <malloc.h>
+#include <search.h>
+extern void tdestroy (void *root, void (*free_node)(void *nodep));
+void *ifp_ptr;
+
+static void *ptr_tree=0L;
+
+static int ptr_comparator( const void *p1, const void *p2 )
+{
+    return
+	(  (p1 == p2) 
+	   ? 0
+	   :( (p1 > p2)
+	      ? 1
+	      : -1
+	    )
+	);
+}
+
+void *dhc6_alloc( size_t s )
+{
+    void *ptr = malloc( s );
+    if ( ptr != 0 )
+	tsearch(ptr, &(ptr_tree), ptr_comparator);
+    return ptr;
+}
+
+void *dhc6_realloc( void *ptr, size_t s )
+{
+    void *ptr2 = realloc(ptr, s);
+    if ( ptr2 != 0 )
+    {
+	if ( ptr != 0 )
+	    tdelete(ptr,&(ptr_tree), ptr_comparator);
+	tsearch(ptr2, &(ptr_tree), ptr_comparator);
+    }
+    return ptr2;
+}
+
+void *dhc6_calloc( size_t n, size_t s )
+{
+    void *ptr = calloc( n, s );
+    if ( ptr != 0 )
+	tsearch(ptr, &(ptr_tree), ptr_comparator);
+    return ptr;
+}
+
+void dhc6_free( void *ptr )
+{
+    free(ptr);
+    tdelete(ptr, &(ptr_tree), ptr_comparator);
+}
+
+void dhc6_free_all_pointers(void)
+{
+    if( ptr_tree != 0L )
+	tdestroy(ptr_tree, free);
+    ptr_tree = 0L;
+}
--- dhcp-0.10/libdhcp6client/common.c.libdhcp6client	2006-05-14 08:09:11.000000000 -0400
+++ dhcp-0.10/libdhcp6client/common.c	2006-05-14 08:09:29.000000000 -0400
@@ -79,11 +79,19 @@
 #include "timer.h"
 #include "lease.h"
 
+#ifdef LIBDHCP
+#include "libdhcp_control.h"
+#endif
+
 int foreground;
 int debug_thresh;
 struct dhcp6_if *dhcp6_if;
 struct dns_list dnslist;
+#ifdef LIBDHCP
+struct host_conf *host_conflist;
+#else
 static struct host_conf *host_conflist;
+#endif
 static int in6_matchflags __P((struct sockaddr *, char *, int));
 ssize_t gethwid __P((char *, int, const char *, u_int16_t *));
 static int get_assigned_ipv6addrs __P((char *, char *,
@@ -645,7 +653,7 @@
 	memset(&ifr, 0, sizeof(ifr));
 	strncpy(ifr.ifr_name, ifnam, sizeof(ifr.ifr_name));
 	ifr.ifr_addr = *(struct sockaddr *)addr;
-
+	dprintf(LOG_DEBUG,"in6_matchflags: SIOCGIFFLAGS");
 	if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
 		warn("in6_matchflags: ioctl(SIOCGIFFLAGS, %s)",
 		     addr2str(addr));
@@ -720,6 +728,9 @@
 	struct dhcp6_duid_type1 *dp; /* we only support the type1 DUID */
 	char tmpbuf[256];	/* DUID should be no more than 256 bytes */
 
+#ifdef LIBDHCP
+     if ( libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
+#endif
 	if ((fp = fopen(idfile, "r")) == NULL && errno != ENOENT)
 		dprintf(LOG_NOTICE, "%s" "failed to open DUID file: %s",
 		    FNAME, idfile);
@@ -774,6 +785,9 @@
 	}
 
 	/* save the (new) ID to the file for next time */
+#ifdef LIBDHCP
+     if ( libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
+#endif
 	if (!fp) {
 		if ((fp = fopen(idfile, "w+")) == NULL) {
 			dprintf(LOG_ERR, "%s"
@@ -821,8 +835,13 @@
 		return -1;
 
 	strcpy(if_hwaddr.ifr_name, ifname);
+	dprintf(LOG_DEBUG,"gethwid: ioctl SIOCGIFHWADDR");
 	if (ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr) < 0)
+	{
+	    close(skfd);
 		return -1;
+	}
+	close(skfd);
 	/* only support Ethernet */
 	switch (if_hwaddr.ifr_hwaddr.sa_family) {
 	case ARPHRD_ETHER:
@@ -938,7 +957,7 @@
 		cp = (char *)(p + 1);
 		np = (struct dhcp6opt *)(cp + optlen);
 
-		dprintf(LOG_DEBUG, "%s" "get DHCP option %s, len %d",
+		dprintf(LOG_INFO, "%s" "get DHCP option %s, len %d",
 		    FNAME, dhcp6optstr(opt), optlen);
 
 		/* option length field overrun */
@@ -1078,7 +1097,7 @@
 				ntohl(*(u_int32_t *)(cp + sizeof(u_int32_t)));
 			optinfo->iaidinfo.rebindtime = 
 				ntohl(*(u_int32_t *)(cp + 2 * sizeof(u_int32_t)));
-			dprintf(LOG_DEBUG, "get option iaid is %u, renewtime %u, "
+			dprintf(LOG_INFO, "get option iaid is %u, renewtime %u, "
 				"rebindtime %u", optinfo->iaidinfo.iaid,
 				optinfo->iaidinfo.renewtime, optinfo->iaidinfo.rebindtime);
 			if (get_assigned_ipv6addrs(cp + 3 * sizeof(u_int32_t), 
@@ -1182,7 +1201,7 @@
 		opt = ntohs(opth.dh6opt_type);
 		cp = p + sizeof(opth);
 		np = cp + optlen;
-		dprintf(LOG_DEBUG, "  IA address option: %s, "
+		dprintf(LOG_INFO, "  IA address option: %s, "
 			"len %d", dhcp6optstr(opt), optlen);
 
 		if (np > ep) {
@@ -1212,7 +1231,7 @@
 			}
 			break;
 		case DH6OPT_IADDR:
-			if (optlen < sizeof(ai) - sizeof(u_int32_t))
+			if (optlen < sizeof(ai)- sizeof(u_int32_t))
 				goto malformed;
 			memcpy(&ai, p, sizeof(ai));
 			/* copy the information into internal format */
@@ -1221,7 +1240,7 @@
 			addr6.preferlifetime = ntohl(ai.preferlifetime);
 			addr6.validlifetime = ntohl(ai.validlifetime);
 			addr6.plen = ai.plen;
-			dprintf(LOG_DEBUG, "  get IAADR address information: "
+			dprintf(LOG_INFO, "  get IAADR address information: "
 			    "%s preferlifetime %d validlifetime %d",
 			    in6addr2str(&addr6.addr, 0),
 			    addr6.preferlifetime, addr6.validlifetime);
@@ -1998,8 +2017,16 @@
 	va_list ap;
 	char logbuf[LINE_MAX];
 
+#if LIBDHCP
+	va_start(ap, fmt);
+	if ( libdhcp_control && libdhcp_control->eh )
+	    libdhcp_control->eh(libdhcp_control, level, fmt, ap);
+	va_end(ap);
+	return;
+#endif
 	va_start(ap, fmt);
 	vsnprintf(logbuf, sizeof(logbuf), fmt, ap);
+	va_end(ap);
 
 	if (foreground && debug_thresh >= level) {
 		time_t now;
--- dhcp-0.10/libdhcp6client/dhcp6.h.libdhcp6client	2006-05-14 08:09:11.000000000 -0400
+++ dhcp-0.10/libdhcp6client/dhcp6.h	2006-05-14 08:09:29.000000000 -0400
@@ -116,9 +116,24 @@
 
 typedef enum { IANA, IATA, IAPD} iatype_t;
 
-typedef enum { ACTIVE, RENEW,
+#ifdef LIBDHCP
+typedef enum { DHCP6_ACTIVE=1, DHCP6_RENEW,
+	       DHCP6_REBIND, DHCP6_EXPIRED,
+	       DHCP6_INVALID } state_t;
+
+#define ACTIVE 	DHCP6_ACTIVE
+#define RENEW  	DHCP6_RENEW
+#define REBIND	DHCP6_REBIND
+#define EXPIRED	DHCP6_EXPIRED
+#define INVALID DHCP6_INVALID
+#include <libdhcp_control.h>
+extern LIBDHCP_Control *libdhcp_control;
+#include <dhc6_alloc.h>
+#else
+typedef enum { ACTIVE=1, RENEW,
 	       REBIND, EXPIRED,
 	       INVALID } state_t;
+#endif
 /* Internal data structure */
 
 struct duid {
--- /dev/null	2006-05-13 13:28:06.911768500 -0400
+++ dhcp-0.10/libdhcp6client/dhcp6client.h	2006-05-14 08:09:29.000000000 -0400
@@ -0,0 +1,22 @@
+/* dhcp6client.h
+ *
+ *  Interface to the DHCPv6 client libdhcp6client library.
+ *
+ *
+ *  Copyright(C) Jason Vas Dias <jvdias at redhat.com> Red Hat Inc. May 2006
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation at
+ *           http://www.fsf.org/licensing/licenses/gpl.txt
+ *  and included in this software distribution as the "LICENSE" file.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ */
+struct libdhcp_control_s;  /* include libdhcp_control.h or libdhcp.h for this */
+
+extern int dhcpv6_client( struct libdhcp_control_s *dhc_ctl, int argc, char **argv, char **envp);
+/* the DHCPv6 client main() function */

dhcpv6-0.10-libdhcp6client-Makefile.patch:
 Makefile.in |   34 +++++++++++++++++++++++++++++++---
 1 files changed, 31 insertions(+), 3 deletions(-)

--- NEW FILE dhcpv6-0.10-libdhcp6client-Makefile.patch ---
--- dhcp-0.10/Makefile.in.libdhcp6client-Makefile	2006-05-14 02:46:21.000000000 -0400
+++ dhcp-0.10/Makefile.in	2006-05-14 02:48:20.000000000 -0400
@@ -10,8 +10,8 @@
 CC=	@CC@
 YACC=	@YACC@
 LEX=	@LEX@
-TARGET=	dhcp6c dhcp6s dhcp6r
-DESTDIR=
+TARGET=	dhcp6c dhcp6s dhcp6r libdhcp6client.so libdhcp6client.a
+DESTDIR ?=
 
 INSTALL=@INSTALL@
 INSTALL_PROGRAM=@INSTALL_PROGRAM@
@@ -27,6 +27,9 @@
 etc=/etc
 sysconfigdir=/etc/sysconfig
 CHKCONFIG=/sbin/chkconfig
+LIBDIR ?= /usr/lib
+INCLUDEDIR ?= /usr/include
+PKGCFGDIR ?= /usr/lib/pkgconfig
 
 CFLAGS+= -Wall -DCONF_DH6OPT_DNS_RESOLVERS=@dhcpopt_dns_resolvers@ \
 	-DCONF_DH6OPT_DOMAIN_LIST=@dhcpopt_domain_list@ \
@@ -48,11 +51,16 @@
 CLEANFILES=cf.tab.h cp.tab.h sf.tab.h dad_token.c ra_token.c client6_token.c client6_parse.c \
 		server6_parse.c server6_token.c lease_token.c resolv_token.c radvd_token.c
 
+CLIENTHDRS=common.h  config.h  cp.tab.h dhcp6.h  hash.h  lease.h  queue.h  timer.h
+
 all:	$(TARGET) 
+
 dhcp6c:	$(CLIENTOBJS) $(LIBOBJS)
 	$(CC) $(LDFLAGS) -o dhcp6c $(CLIENTOBJS) $(LIBOBJS) $(LIBS) 
+
 dhcp6s:	$(SERVOBJS) $(LIBOBJS)
 	$(CC) $(LDFLAGS) -o dhcp6s $(SERVOBJS) $(LIBOBJS) $(LIBS) 
+
 dhcp6r: $(RELAYOBJS) $(LIBOBJS)
 	$(CC) $(LDFLAGS) -o dhcp6r $(RELAYOBJS)
 
@@ -94,6 +102,21 @@
 	$(LEX) -Psfyy server6_token.l
 	mv lex.sfyy.c $@
 
+libdhcp6client/.: libdhcp6client.patch
+	mkdir -p libdhcp6client/
+	cp -fp $(CLIENTOBJS:%.o=%.c) $(CLIENTHDRS) $(COMMONGENSRCS:%.c=%.l) $(subst client6_parse.l,client6_parse.y,$(CLIENTGENSRCS:%.c=%.l)) strlcat.c strlcpy.c libdhcp6client/
+	cp -fp Makefile libdhcp6client/
+	patch -p1 -b --suffix=.libdhcp6client < libdhcp6client.patch
+
+libdhcp6client/%.o: $(@:%.o:%.c) $(patsubst %,libdhcp6client/%,$(CLIENTHDRS))
+	$(MAKE) -C libdhcp6client $*.o CFLAGS="$(subst -O2,-Os,$(CFLAGS)) -fPIC -DLIBDHCP"
+
+libdhcp6client.a: libdhcp6client/. $(patsubst %,libdhcp6client/%,$(CLIENTOBJS) strlcpy.o strlcat.o dhc6_alloc.o)
+	$(AR) cruv $@ $(patsubst %,libdhcp6client/%,$(CLIENTOBJS) strlcpy.o strlcat.o dhc6_alloc.o)
+
+libdhcp6client.so: libdhcp6client/. $(patsubst %,libdhcp6client/%,$(CLIENTOBJS) strlcpy.o strlcat.o dhc6_alloc.o)
+	$(CC) -shared -o $@ $(patsubst %,libdhcp6client/%,$(CLIENTOBJS) strlcpy.o strlcat.o dhc6_alloc.o) -lresolv -lcrypto
+
 install::
 	$(INSTALL) -d $(DESTDIR)$(sbindir)
 	$(INSTALL) -d $(DESTDIR)/sbin
@@ -112,7 +135,12 @@
 	$(INSTALL) -d  $(DESTDIR)/etc/sysconfig
 	$(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6s.sysconfig  $(DESTDIR)/etc/sysconfig/dhcp6s
 	$(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6r.sysconfig  $(DESTDIR)/etc/sysconfig/dhcp6r
-
+	$(INSTALL) -m 754 -D  -o $(INSTALL_USER) -g $(INSTALL_GROUP) libdhcp6client.so $(DESTDIR)/$(LIBDIR)/libdhcp6client.so
+	$(INSTALL) -m 644 -D  -o $(INSTALL_USER) -g $(INSTALL_GROUP) libdhcp6client.a  $(DESTDIR)/$(LIBDIR)/libdhcp6client.a
+	mkdir -p $(DESTDIR)/$(INCLUDEDIR)/dhcp6client/dhcpv6
+	$(INSTALL) -m 644 -o $(INSTALL_USER) -g $(INSTALL_GROUP) libdhcp6client/*.h $(DESTDIR)/$(INCLUDEDIR)/dhcp6client/dhcpv6
+	mv $(DESTDIR)/$(INCLUDEDIR)/dhcp6client/dhcpv6/{libdhcp_control.h,dhcp6client.h} $(DESTDIR)/$(INCLUDEDIR)/dhcp6client
+	$(INSTALL) -m 644 -D -o $(INSTALL_USER) -g $(INSTALL_GROUP) libdhcp6client.pc $(DESTDIR)/$(PKGCFGDIR)/libdhcp6client.pc
 
 rh_install:: install
 	$(INSTALL) -d $(initdir)


--- NEW FILE libdhcp6client.pc ---
Name:		libdhcp6client
Description:	The DHCPv6 IPv6 DHCP client library
Version:	@DHCPV6_VERSION@
Libs:		-ldhcp6client
Libs.private:	-lresolv -lcrypto
Cflags:		-I/usr/include/dhcp6client
DHCPv6.Cflags=  -I/usr/include/dhcp6client/dhcpv6




More information about the fedora-cvs-commits mailing list