+++ /dev/null
---- dhcp-0.10/common.c.gethwid 2007-02-16 15:26:02.000000000 -0500
-+++ dhcp-0.10/common.c 2007-02-16 15:26:02.000000000 -0500
-@@ -819,11 +819,15 @@
- close(skfd);
- return -1;
- }
-- close(skfd);
-
- strcpy(if_hwaddr.ifr_name, ifname);
-- if (ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr) < 0)
-+ 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:
+++ /dev/null
---- dhcp-0.10/client6_addr.c.libdhcp6client 2007-02-09 01:02:08.000000000 -0500
-+++ dhcp-0.10/client6_addr.c 2007-02-09 01:02:08.000000000 -0500
-@@ -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 *,
-@@ -231,14 +235,23 @@
- 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)
-- dhcp6_remove_timer(sp->timer);
-- free(sp);
-- return (-1);
-+#ifdef LIBDHCP
-+ } else if (libdhcp_control && (libdhcp_control->capability & DHCP_CONFIGURE_ADDRESSES)) {
-+#else
-+ } else
-+#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);
-+ }
-+#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 ||
-@@ -285,6 +298,9 @@
- dprintf(LOG_DEBUG, "%s" "removing address %s", FNAME,
- in6addr2str(&sp->lease_addr.addr, 0));
- sp->state = INVALID;
-+#ifdef LIBDHCP
-+ if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
-+#endif
- if (write_lease(sp, client6_lease_file) != 0) {
- dprintf(LOG_INFO, "%s"
- "failed to write removed lease address %s to lease file",
-@@ -296,10 +312,13 @@
- dprintf(LOG_INFO, "request prefix is %s/%d",
- 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) {
-- dprintf(LOG_INFO, "%s" "removing address %s failed",
-- FNAME, in6addr2str(&sp->lease_addr.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)
-@@ -453,6 +472,9 @@
- memcpy(&sp->lease_addr, addr, sizeof(sp->lease_addr));
- sp->state = ACTIVE;
- time(&sp->start_date);
-+#ifdef LIBDHCP
-+ if (libdhcp_control && (libdhcp_control->capability & DHCP_USE_LEASE_DATABASE))
-+#endif
- if (write_lease(sp, client6_lease_file) != 0) {
- dprintf(LOG_ERR, "%s"
- "failed to write an updated lease address %s to lease file",
---- dhcp-0.10/dhcp6c.c.libdhcp6client 2007-02-09 01:02:08.000000000 -0500
-+++ dhcp-0.10/dhcp6c.c 2007-02-09 01:02:08.000000000 -0500
-@@ -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;
-@@ -136,7 +139,9 @@
- ssize_t, struct dhcp6_optinfo *));
- static int client6_recvreply __P((struct dhcp6_if *, struct dhcp6 *,
- ssize_t, struct dhcp6_optinfo *));
-+#ifndef LIBDHCP
- static void client6_signal __P((int));
-+#endif
- static struct dhcp6_event *find_event_withid __P((struct dhcp6_if *,
- u_int32_t));
- static struct dhcp6_timer *check_lease_file_timo __P((void *));
-@@ -155,20 +160,36 @@
- #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;
-
-+#ifndef LIBDHCP
- int
--main(argc, argv)
-+main(argc, argv, envp)
-+#else
-+#define exit return
-+LIBDHCP_Control *libdhcp_control;
-+__attribute__ ((visibility ("default")))
-+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);
-@@ -286,12 +307,18 @@
- }
- setloglevel(debug);
-
-+#ifdef 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);
- fclose(pidfp);
- }
-
-+#ifdef LIBDHCP
-+ sa6_allagent = (const struct sockaddr_in6 *) &sa6_allagent_storage;
-+#endif
- ifinit(device);
- setup_interface(device);
-
-@@ -303,7 +330,57 @@
- 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 = NULL;
-+ dadlist = NULL;
-+ 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));
-+ sa6_allagent = (const struct sockaddr_in6 *) &sa6_allagent_storage;
-+ memset(&client_duid, '\0', sizeof(client_duid));
-+ memset(&iaidtab, '\0', sizeof(iaidtab));
-+ client6_request_flag = 0;
-+ memset(&leasename, '\0', sizeof(leasename));
-+ debug = 0;
-+ device = NULL;
-+ num_device = 0;
-+ sig_flags = 0;
-+ extern struct host_conf *host_conflist;
-+ host_conflist = 0;
-+ client6_lease_file = server6_lease_file = sync_file = NULL;
-+ cf_dns_list = NULL;
-+ extern int cfdebug;
-+ cfdebug = 0;
-+ hash_anchors = 0;
-+ configfilename = NULL;
-+ 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
-@@ -322,7 +399,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;
-@@ -335,19 +414,19 @@
- ifidx = if_nametoindex(device);
- if (ifidx == 0) {
- dprintf(LOG_ERR, "if_nametoindex(%s)", device);
-- exit(1);
-+ return;
- }
-
- /* get our DUID */
- if (get_duid(DUID_FILE, device, &client_duid)) {
- dprintf(LOG_ERR, "%s" "failed to get a DUID", FNAME);
-- exit(1);
-+ return;
- }
- if (get_linklocal(device, &lladdr) < 0) {
-- exit(1);
-+ return;
- }
- if (inet_ntop(AF_INET6, &lladdr, linklocal, sizeof(linklocal)) < 0) {
-- exit(1);
-+ return;
- }
- dprintf(LOG_DEBUG, "link local addr is %s", linklocal);
-
-@@ -360,12 +439,12 @@
- if (error) {
- dprintf(LOG_ERR, "%s" "getaddrinfo: %s",
- FNAME, strerror(error));
-- exit(1);
-+ return;
- }
- insock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (insock < 0) {
- dprintf(LOG_ERR, "%s" "socket(inbound)", FNAME);
-- exit(1);
-+ return;
- }
- #ifdef IPV6_RECVPKTINFO
- if (setsockopt(insock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
-@@ -373,7 +452,7 @@
- dprintf(LOG_ERR, "%s"
- "setsockopt(inbound, IPV6_RECVPKTINFO): %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- #else
- if (setsockopt(insock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
-@@ -381,7 +460,7 @@
- dprintf(LOG_ERR, "%s"
- "setsockopt(inbound, IPV6_PKTINFO): %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- #endif
- ((struct sockaddr_in6 *)(res->ai_addr))->sin6_scope_id = ifidx;
-@@ -410,7 +489,7 @@
-
- if (bound < 0) {
- dprintf(LOG_ERR, "%s" "bind(inbound): %s", FNAME, strerror(-bound));
-- exit(bound);
-+ return;
- }
-
- freeaddrinfo(res);
-@@ -420,26 +499,26 @@
- if (error) {
- dprintf(LOG_ERR, "%s" "getaddrinfo: %s",
- FNAME, gai_strerror(error));
-- exit(1);
-+ return;
- }
- outsock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
- if (outsock < 0) {
- dprintf(LOG_ERR, "%s" "socket(outbound): %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- if (setsockopt(outsock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
- &ifidx, sizeof(ifidx)) < 0) {
- dprintf(LOG_ERR, "%s"
- "setsockopt(outbound, IPV6_MULTICAST_IF): %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- ((struct sockaddr_in6 *)(res->ai_addr))->sin6_scope_id = ifidx;
- if (bind(outsock, res->ai_addr, res->ai_addrlen) < 0) {
- dprintf(LOG_ERR, "%s" "bind(outbound): %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- freeaddrinfo(res);
- memset(&hints, 0, sizeof(hints));
-@@ -450,7 +529,7 @@
- if (error) {
- dprintf(LOG_ERR, "%s" "getaddrinfo: %s",
- FNAME, gai_strerror(error));
-- exit(1);
-+ return;
- }
- memcpy(&sa6_allagent_storage, res->ai_addr, res->ai_addrlen);
- sa6_allagent = (const struct sockaddr_in6 *)&sa6_allagent_storage;
-@@ -461,25 +540,27 @@
- if ((ifp = find_ifconfbyname(device)) == NULL) {
- dprintf(LOG_ERR, "%s" "interface %s not configured",
- FNAME, device);
-- exit(1);
-+ return;
- }
- ifp->outsock = outsock;
-
-+#ifndef LIBDHCP
- if (signal(SIGHUP, client6_signal) == SIG_ERR) {
- dprintf(LOG_WARNING, "%s" "failed to set signal: %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- if (signal(SIGTERM|SIGKILL, client6_signal) == SIG_ERR) {
- dprintf(LOG_WARNING, "%s" "failed to set signal: %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- if (signal(SIGINT, client6_signal) == SIG_ERR) {
- dprintf(LOG_WARNING, "%s" "failed to set signal: %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
-+#endif
- }
-
- static void
-@@ -493,13 +574,13 @@
- /* get iaid for each interface */
- if (num_device == 0) {
- if ((num_device = create_iaid(&iaidtab[0], num_device)) < 0)
-- exit(1);
-+ return;
- ifp->iaidinfo.iaid = get_iaid(ifp->ifname, &iaidtab[0], num_device);
- if (ifp->iaidinfo.iaid == 0) {
- dprintf(LOG_DEBUG, "%s"
- "interface %s iaid failed to be created",
- FNAME, ifp->ifname);
-- exit(1);
-+ return;
- }
- dprintf(LOG_DEBUG, "%s" "interface %s iaid is %u",
- FNAME, ifp->ifname, ifp->iaidinfo.iaid);
-@@ -508,6 +589,9 @@
- 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);
-@@ -515,14 +599,17 @@
- if ((client6_lease_file =
- init_leases(leasename)) == NULL) {
- dprintf(LOG_ERR, "%s" "failed to parse lease file", FNAME);
-- exit(1);
-+ return;
- }
- strcpy(client6_lease_temp, leasename);
- strcat(client6_lease_temp, "XXXXXX");
- client6_lease_file =
- sync_leases(client6_lease_file, leasename, client6_lease_temp);
- if (client6_lease_file == NULL)
-- exit(1);
-+ return;
-+#ifdef LIBDHCP
-+ }
-+#endif
- if (!TAILQ_EMPTY(&client6_iaidaddr.lease_list)) {
- // struct dhcp6_lease *cl;
- struct dhcp6_listval *lv;
-@@ -531,7 +618,7 @@
- client6_request_flag |= CLIENT6_CONFIRM_ADDR;
- if (TAILQ_EMPTY(&request_list)) {
- if (create_request_list(1) < 0)
-- exit(1);
-+ return;
- } else if (client6_request_flag & CLIENT6_RELEASE_ADDR) {
- for (lv = TAILQ_FIRST(&request_list); lv;
- lv = TAILQ_NEXT(lv, link)) {
-@@ -540,13 +627,13 @@
- dprintf(LOG_INFO, "this address %s is not"
- " leased by this client",
- in6addr2str(&lv->val_dhcp6addr.addr,0));
-- exit(0);
-+ return;
- }
- }
- }
- } else if (client6_request_flag & CLIENT6_RELEASE_ADDR) {
- dprintf(LOG_INFO, "no ipv6 addresses are leased by client");
-- exit(0);
-+ return;
- }
- ifp->link_flag |= IFF_RUNNING;
-
-@@ -557,11 +644,11 @@
- if ((ifp->link_timer =
- dhcp6_add_timer(check_link_timo, ifp)) < 0) {
- dprintf(LOG_ERR, "%s" "failed to create a timer", FNAME);
-- exit(1);
-+ return;
- }
- if ((ifp->sync_timer = dhcp6_add_timer(check_lease_file_timo, ifp)) < 0) {
- dprintf(LOG_ERR, "%s" "failed to create a timer", FNAME);
-- exit(1);
-+ return;
- }
- /* DAD timer set up after getting the address */
- ifp->dad_timer = NULL;
-@@ -569,7 +656,7 @@
- if ((ev = dhcp6_create_event(ifp, DHCP6S_INIT)) == NULL) {
- dprintf(LOG_ERR, "%s" "failed to create an event",
- FNAME);
-- exit(1);
-+ return;
- }
- ifp->servers = NULL;
- ev->ifp->current_server = NULL;
-@@ -577,7 +664,7 @@
- if ((ev->timer = dhcp6_add_timer(client6_timo, ev)) == NULL) {
- dprintf(LOG_ERR, "%s" "failed to add a timer for %s",
- FNAME, ifp->ifname);
-- exit(1);
-+ return;
- }
- dhcp6_reset_timer(ev);
- }
-@@ -594,6 +681,9 @@
- 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));
-@@ -605,6 +695,9 @@
- 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 */
-@@ -627,7 +720,7 @@
- dprintf(LOG_INFO, FNAME "exiting");
- free_resources(dhcp6_if);
- unlink(DHCP6C_PIDFILE);
-- exit(0);
-+ return;
- }
- if ((sig_flags & SIGF_HUP)) {
- dprintf(LOG_INFO, FNAME "restarting");
-@@ -636,7 +729,7 @@
- }
- if ((sig_flags & SIGF_CLEAN)) {
- free_resources(dhcp6_if);
-- exit(0);
-+ return;
- }
- sig_flags = 0;
- }
-@@ -648,11 +741,39 @@
- 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();
-
-+#ifdef LIBDHCP
-+ if (libdhcp_control && libdhcp_control->timeout) {
-+ time_t now = time(0);
-+ double a = (double) w->tv_sec + now;
-+ double b = (double) w->tv_usec / 1000000.0;
-+ double c = (double) libdhcp_control->now;
-+ double d = (double) libdhcp_control->timeout;
-+ if ((w == NULL) || ((a + b) >= (c + d))) {
-+ 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);
-
-@@ -662,7 +783,7 @@
- if (errno != EINTR) {
- dprintf(LOG_ERR, "%s" "select: %s",
- FNAME, strerror(errno));
-- exit(1);
-+ return;
- }
- break;
- case 0: /* timeout */
-@@ -670,6 +791,19 @@
- default: /* received a packet */
- client6_recv();
- }
-+
-+#ifdef LIBDHCP
-+ if (libdhcp_control) {
-+ if (libdhcp_control->finished)
-+ return;
-+
-+ if (libdhcp_control->timeout && (time(NULL) >= (libdhcp_control->timeout + libdhcp_control->now))) {
-+ if (libdhcp_control->callback)
-+ (*(libdhcp_control->callback)) (libdhcp_control, DHC_TIMEDOUT, &client6_iaidaddr);
-+ return;
-+ }
-+ }
-+#endif
- }
- }
-
-@@ -741,7 +875,7 @@
- /* this should not happen! */
- dprintf(LOG_ERR, "%s" "can't find a server",
- FNAME);
-- exit(1); /* XXX */
-+ return (NULL);
- }
- /* if get the address assginment break */
- if (!TAILQ_EMPTY(&client6_iaidaddr.lease_list)) {
-@@ -800,6 +934,7 @@
- return (NULL);
- }
-
-+#ifndef LIBDHCP
- static void
- client6_signal(sig)
- int sig;
-@@ -822,6 +957,7 @@
- break;
- }
- }
-+#endif
-
- void
- client6_send(ev)
-@@ -848,21 +984,21 @@
- case DHCP6S_REQUEST:
- if (ifp->current_server == NULL) {
- dprintf(LOG_ERR, "%s" "assumption failure", FNAME);
-- exit(1); /* XXX */
-+ return;
- }
- dh6->dh6_msgtype = DH6_REQUEST;
- break;
- case DHCP6S_RENEW:
- if (ifp->current_server == NULL) {
- dprintf(LOG_ERR, "%s" "assumption failure", FNAME);
-- exit(1); /* XXX */
-+ return;
- }
- dh6->dh6_msgtype = DH6_RENEW;
- break;
- case DHCP6S_DECLINE:
- if (ifp->current_server == NULL) {
- dprintf(LOG_ERR, "%s" "assumption failure", FNAME);
-- exit(1); /* XXX */
-+ return;
- }
- dh6->dh6_msgtype = DH6_DECLINE;
- break;
-@@ -880,7 +1016,7 @@
- break;
- default:
- dprintf(LOG_ERR, "%s" "unexpected state %d", FNAME, ev->state);
-- exit(1); /* XXX */
-+ return;
- }
- /*
- * construct options
-@@ -922,7 +1058,7 @@
- case DHCP6S_RENEW:
- case DHCP6S_DECLINE:
- if (&ifp->current_server->optinfo == NULL)
-- exit(1);
-+ return;
- dprintf(LOG_DEBUG, "current server ID %s",
- duidstr(&ifp->current_server->optinfo.serverID));
- if (duidcpy(&optinfo.serverID,
-@@ -1012,17 +1148,28 @@
- } else {
- if (ev->state == DHCP6S_RELEASE) {
- dprintf(LOG_INFO, "release empty address list");
-- exit(1);
-+ return;
- }
- /* 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);
-+ return;
- }
-+#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:
-@@ -1061,7 +1208,7 @@
- if (error) {
- dprintf(LOG_ERR, "%s" "getaddrinfo: %s",
- FNAME, gai_strerror(error));
-- exit(1);
-+ return;
- }
- memcpy(&dst, res->ai_addr, res->ai_addrlen);
- salen = res->ai_addrlen;
-@@ -1283,8 +1430,16 @@
- }
- /* 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))
-+ 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;
- }
-
-@@ -1427,6 +1582,9 @@
-
- if (!TAILQ_EMPTY(&optinfo->dns_list.addrlist) ||
- optinfo->dns_list.domainlist != NULL) {
-+#ifdef LIBDHCP
-+ if (libdhcp_control && (libdhcp_control->capability & DHCP_CONFIGURE_RESOLVER))
-+#endif
- resolv_parse(&optinfo->dns_list);
- }
- /*
-@@ -1500,14 +1658,21 @@
- if (!TAILQ_EMPTY(&optinfo->addr_list)) {
- (void)get_if_rainfo(ifp);
- dhcp6_add_iaidaddr(optinfo);
-- if (optinfo->type == IAPD)
-+ 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;
- }
-@@ -1523,6 +1688,10 @@
- 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:
-@@ -1533,7 +1702,14 @@
- 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;
-@@ -1680,6 +1856,9 @@
- /* 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));
-@@ -1690,6 +1869,9 @@
- /* 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);
- }
-@@ -1830,7 +2012,7 @@
- /* 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);
-+ return;
- }
-
- memset(&ifr,'\0', sizeof(struct ifreq));
-@@ -1838,13 +2020,13 @@
-
- if (ioctl(nlsock, SIOCGIFFLAGS, &ifr) < 0) {
- dprintf(LOG_ERR, "ioctl SIOCGIFFLAGS failed");
-- exit(1);
-+ return;
- }
-
- 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.");
-- exit(1);
-+ return;
- }
-
- memset(&ifr, '\0', sizeof(struct ifreq));
-@@ -1852,7 +2034,7 @@
- ifr.ifr_flags |= (IFF_UP | IFF_RUNNING) ;
- if (ioctl(nlsock, SIOCSIFFLAGS, &ifr) < 0) {
- dprintf(LOG_ERR, "ioctl SIOCSIFFLAGS failed");
-- exit(1);
-+ return;
- }
-
- /*
-@@ -1865,7 +2047,7 @@
- strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
- if (ioctl(nlsock, SIOCGIFFLAGS, &ifr) < 0) {
- dprintf(LOG_ERR, "ioctl SIOCGIFFLAGS failed");
-- exit(1);
-+ return;
- }
- }
-
---- dhcp-0.10/common.c.libdhcp6client 2007-02-09 01:02:08.000000000 -0500
-+++ dhcp-0.10/common.c 2007-02-09 01:02:08.000000000 -0500
-@@ -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((unsigned char *, int, const char *, u_int16_t *));
- static int get_assigned_ipv6addrs __P((unsigned char *, unsigned char *,
-@@ -148,7 +156,7 @@
-
- TAILQ_INIT(&ifp->event_list);
-
-- if ((ifp->ifname = strdup(ifname)) == NULL) {
-+ if ((ifp->ifname = strdup((char *) ifname)) == NULL) {
- dprintf(LOG_ERR, "%s" "failed to copy ifname", FNAME);
- goto die;
- }
-@@ -718,6 +726,9 @@
- struct dhcp6_duid_type1 *dp; /* we only support the type1 DUID */
- unsigned 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);
-@@ -772,6 +783,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"
-@@ -2027,8 +2041,16 @@
- va_list ap;
- char logbuf[LINE_MAX];
-
-+#ifdef 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/dhcp6.h.libdhcp6client 2007-02-09 01:02:08.000000000 -0500
-+++ dhcp-0.10/dhcp6.h 2007-02-09 01:02:08.000000000 -0500
-@@ -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 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/libdhcp6client/libdhcp_control.h 2007-02-09 01:02:08.000000000 -0500
-@@ -0,0 +1,128 @@
-+/* 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@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
-+
-+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;
-+
-+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
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/libdhcp6client/dhc6_alloc.h 2007-02-09 01:02:08.000000000 -0500
-@@ -0,0 +1,16 @@
-+extern void *dhc6_alloc(size_t);
-+extern void *dhc6_realloc(void *, size_t);
-+extern void *dhc6_calloc(size_t, size_t);
-+extern char *dhc6_strdup(char *str);
-+extern void dhc6_free(void *);
-+extern void dhc6_free_all_pointers(void);
-+#undef malloc
-+#define malloc(size) dhc6_alloc(size)
-+#undef realloc
-+#define realloc(ptr, size) dhc6_realloc(ptr, size)
-+#undef calloc
-+#define calloc(n, size) dhc6_calloc(n, size)
-+#undef free
-+#define free(ptr) dhc6_free(ptr)
-+#undef strdup
-+#define strdup(str) dhc6_strdup(str)
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/libdhcp6client/dhc6_alloc.c 2007-02-09 01:02:08.000000000 -0500
-@@ -0,0 +1,54 @@
-+#include <malloc.h>
-+#include <search.h>
-+#include <string.h>
-+
-+extern void tdestroy (void *root, void (*free_node)(void *nodep));
-+void *ifp_ptr;
-+
-+static void *ptr_tree = NULL;
-+
-+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;
-+}
-+
-+char *dhc6_strdup(char *str) {
-+ char *ptr = strdup(str);
-+ 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 != NULL)
-+ tdestroy(ptr_tree, free);
-+ ptr_tree = NULL;
-+}
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/libdhcp6client/dhcp6client.h 2007-02-09 01:02:08.000000000 -0500
-@@ -0,0 +1,25 @@
-+/* dhcp6client.h
-+ *
-+ * Interface to the DHCPv6 client libdhcp6client library.
-+ *
-+ *
-+ * Copyright(C) Jason Vas Dias <jvdias@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.
-+ */
-+
-+/* include libdhcp_control.h or libdhcp.h for this */
-+struct libdhcp_control_s;
-+
-+/* the DHCPv6 client main() function */
-+extern int dhcpv6_client(struct libdhcp_control_s *dhc_ctl,
-+ int argc, char **argv, char **envp);
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/libdhcp6client/Makefile 2007-02-09 01:02:19.000000000 -0500
-@@ -0,0 +1,68 @@
-+#
-+# Makefile for libdhcp6client
-+# dcantrell@redhat.com
-+#
-+
-+include ../Makefile.inc
-+
-+# Version of dhcpv6
-+VER = 0.10
-+
-+PROGS = libdhcp6client.a libdhcp6client-$(VER).so.0
-+
-+# Source files
-+SRCS = dhcp6c.c common.c config.c timer.c client6_addr.c hash.c \
-+ lease.c netlink.c lease_token.c client6_parse.c client6_token.c \
-+ dad_token.c ra_token.c resolv_token.c radvd_token.c strlcpy.c \
-+ dhc6_alloc.c
-+OBJS = $(SRCS:.c=.o)
-+
-+# Files to link so that debuginfo is generated correctly
-+LINKS = client6_parse.y client6_token.l dad_token.l lease_token.l lex.cpyy.c \
-+ lex.ifyy.c lex.lyy.c lex.rayy.c lex.rdyy.c lex.rvyy.c ra_token.l \
-+ radvd_token.l resolv_token.l y.tab.c y.tab.h
-+
-+CFLAGS += -I. -I.. -DLIBDHCP
-+
-+all: links $(PROGS)
-+
-+links:
-+ @for f in $(LINKS) ; do \
-+ if [ ! -r $$f ]; then \
-+ ln ../$$f $$f ; \
-+ fi ; \
-+ done
-+
-+$(SRCS):
-+ @if [ ! -r $@ ]; then \
-+ if [ -r ../$@ ]; then \
-+ ln ../$@ $@ ; \
-+ fi ; \
-+ fi
-+
-+%.o: %.c
-+ $(CC) $(CFLAGS) -c -o $@ $<
-+
-+libdhcp6client.a: $(OBJS)
-+ $(AR) crus $@ $(OBJS)
-+
-+libdhcp6client-$(VER).so.0: $(OBJS)
-+ $(CC) -shared -o $@ -Wl,-soname,$@ $(OBJS) $(LIBS)
-+
-+install: $(PROGS)
-+ $(INSTALL) -m 0755 -D -o $(INSTALL_USER) -g $(INSTALL_GROUP) libdhcp6client-$(VER).so.0 $(DESTDIR)$(LIBDIR)/libdhcp6client-$(VER).so.0
-+ $(INSTALL) -m 0644 -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) dhcp6client.h $(DESTDIR)$(INCLUDEDIR)/dhcp6client/dhcp6client.h
-+ $(INSTALL) -m 644 -o $(INSTALL_USER) -g $(INSTALL_GROUP) libdhcp_control.h $(DESTDIR)$(INCLUDEDIR)/dhcp6client/libdhcp_control.h
-+ $(INSTALL) -m 644 -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhc6_alloc.h $(DESTDIR)$(INCLUDEDIR)/dhcp6client/dhcpv6/dhc6_alloc.h
-+ for header in common.h config.h cp.tab.h dhcp6.h hash.h lease.h timer.h ; do \
-+ $(INSTALL) -m 644 -o $(INSTALL_USER) -g $(INSTALL_GROUP) ../$$header $(DESTDIR)$(INCLUDEDIR)/dhcp6client/dhcpv6/$$header ; \
-+ done
-+ $(INSTALL) -m 644 -D -o $(INSTALL_USER) -g $(INSTALL_GROUP) ../libdhcp6client.pc $(DESTDIR)$(PKGCFGDIR)/libdhcp6client.pc
-+ ( cd $(DESTDIR)$(LIBDIR) ; rm -f libdhcp6client.so )
-+ ( cd $(DESTDIR)$(LIBDIR) ; ln -sf libdhcp6client-$(VER).so.0 libdhcp6client.so )
-+
-+clean:
-+ -rm -f libdhcp6client.a libdhcp6client-$(VER).so.0
-+ -rm -f $(OBJS)
+++ /dev/null
---- dhcp-0.10/dhcp6c.conf.5.man 2003-03-28 15:16:36.000000000 -0500
-+++ dhcp-0.10/dhcp6c.conf.5 2007-02-08 15:44:07.000000000 -0500
-@@ -1,202 +1,218 @@
--.\" $Id$\r
--.\"\r
--.\" Copyright (C) International Business Machines Corp., 2003\r
--.\" All rights reserved.\r
--.\"\r
--.\" Redistribution and use in source and binary forms, with or without\r
--.\" modification, are permitted provided that the following conditions\r
--.\" are met:\r
--.\" 1. Redistributions of source code must retain the above copyright\r
--.\" notice, this list of conditions and the following disclaimer.\r
--.\" 2. Redistributions in binary form must reproduce the above copyright\r
--.\" notice, this list of conditions and the following disclaimer in the\r
--.\" documentation and/or other materials provided with the distribution.\r
--.\" 3. Neither the name of the project nor the names of its contributors\r
--.\" may be used to endorse or promote products derived from this software\r
--.\" without specific prior written permission.\r
--.\"\r
--.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\r
--.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
--.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
--.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\r
--.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
--.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
--.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
--.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
--.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
--.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
--.\" SUCH DAMAGE.\r
--.\"\r
--.TH dhcp6c.conf 5 "17 March 2003" "dhcp6c.conf" "Linux System Manager's Manual"\r
--\r
--.SH NAME\r
--dhcp6c.conf \- configuration file of the DHCPv6 client daemon, dhcp6c\r
--\r
--.SH DESCRIPTION\r
--.B dhcp6c.conf\r
--is a configuration file for dhcp6c (DHCPv6 client).\r
--\r
--dhcp6c is configured by the configuration information (such as rapid-commit,\r
--requesting temp-address, or prefix-delegation) in this file.\r
--dhcp6c.conf is an ASCII text file and lines that start with # are comments.\r
--\r
--.PP\r
--.BI STATEMENTS\r
--.PP\r
--.nf\r
--.B interface\ <interface\ name>\r
--.B {\r
--.B \t[declarations]\r
--.B };\r
--.fi\r
--Write configurations for this interface in this statement.\r
--In [declarations], options can be specified.\r
--\r
--.PP\r
--.BI DECLARATIONS\r
--.PP\r
--.nf\r
--.B send\ [dhcpoptions];\r
--.fi\r
--With this declaration, dhcp6c sends specified options.\r
--Currently rapid\-commit is defined.\r
--\r
--.nf\r
--\fIsend rapid\-commit;\fR\r
--.fi\r
--This declaration enables dhcp6c to request the dhcp6s server to perform a\r
--Rapid Commit.\r
--\r
--.nf\r
--.B request\ [dhcpoptions];\r
--.fi\r
--This declaration enables dhcp6c to request specified options.\r
--Currently temp\-address, domain\-name\-servers, and prefix\-delegation\r
--are defined.\r
--\r
--.nf\r
--\fIrequest domain\-name\-servers;\fR\r
--.fi\r
--The DHCPv6 mechanism provides a way to obtain configuration information\r
--such as a list of available DNS servers or NTP servers. This declaration\r
--enables dhcp6c to request a DNS server address from the DHCPv6 server. \r
--\r
--.nf\r
--\fIrequest prefix\-delegation;\fR\r
--.fi\r
--This declaration enables dhcp6c to request a Prefix Delegation to the \r
--DHCPv6 server. dhcp6c gets a prefix assignment from the DHCPv6 server.\r
--\r
--.nf\r
--\fIrequest temp\-address;\fR\r
--.fi\r
--This declaration enables dhcp6c to request temporary addresses.\r
--dhcp6c requests Non-temporary Addresses as default. This option makes\r
--dhcp6c request Temporary Addresses.\r
--\r
--.nf\r
--.B information-only;\r
--.fi\r
--This declaration enables dhcp6c to request host configuration information\r
--from the DHCPv6 server. If dhcp6c doesn't need to be assigned any addresses,\r
--this option should be specified.\r
--\r
--.nf\r
--.B address\ {\r
--.B \t[<ipv6\ address>/<prefix\ length>];\r
--.B \t[prefer-life-time\ <preferred\-lifetime>];\r
--.B \t[valid-life-time\ <valid\-lifetime>];\r
--.B };\r
--.fi\r
--This declaration defines the dhcp6c client preferred IPv6 address,\r
--the preferred lifetime of the address, and the valid lifetime for this\r
--interface.\r
--\r
--.nf\r
--.B prefix\ {\r
--.B \t[<ipv6\ prefix>/<prefix\ length>];\r
--.B \t[prefer-life-time\ <preferred\-lifetime>];\r
--.B \t[valid-life-time\ <valid\-lifetime>];\r
--.B };\r
--.fi\r
--This declaration defines the dhcp6c client acting as a requesting\r
--router for the preferred prefix, the prefix length, and the prefix's\r
--preferred lifetime, and valid lifetime for this interface.\r
--\r
--.nf\r
--.B prefer-life-time\ <preferred\-lifetime>;\r
--.fi\r
--This declaration sets the preferred lifetime (in seconds) of the address\r
--or prefix. This declaration is valid only in address or prefix declarations.\r
--\r
--.nf\r
--.B valid-life-time\ <valid\-lifetime>;\r
--.fi\r
--This declaration sets the valid lifetime (in seconds) of the address or\r
--prefix.\r
--This declaration is valid only in address or prefix declarations.\r
--\r
--.nf\r
--.B renew-time\ <renew-time>;\r
--.fi\r
--This declaration specifies the Renew Time (in seconds) for this Identity\r
--Association (IA). Renew Time is a T1 value in an IA option. dhcp6c sets the\r
--Renew Time in IA options to the specified value.\r
--\r
--.nf\r
--.B rebind-time\ <rebind-time>;\r
--.fi\r
--This declaration specifies the Rebind Time (in seconds) for this IA. Rebind\r
--Time is T2 value in an IA option. dhcp6c sets the Rebind Time in IA options\r
--to the specified value.\r
--\r
--.PP
--.BI DHCPOPTIONS\r
--.PP\r
--.nf\r
--.B rapid\-commit\r
--.fi\r
--If this option is used in a "send [dhcpoptions];" declaration, \r
--dhcp6c sends DHCPv6 messages with a Rapid Commit option.\r
--\r
--.nf\r
--.B domain\-name\-servers\r
--.fi\r
--If this option is used in a "request [dhcpoptions];" declaration, \r
--dhcp6c requests the DNS server address via the DHCPv6 mechanism.\r
--\r
--.nf\r
--.B prefix\-delegation\r
--.fi\r
--If this option is used in a "request [dhcpoptions];" declaration, \r
--dhcp6c requests a Prefix Delegation to the DHCPv6 servers.\r
--\r
--.SH EXAMPLES\r
--.PP\r
--This is a sample of the dhcp6c.conf file.\r
--.nf\r
--.B interface eth0 {\r
--.B \tsend rapid-commit;\r
--.B \trequest prefix-delegation;\r
--.B \trequest domain-name-servers;\r
--.B \trequest temp-address;\r
--.B \tiaid 11111;\r
--.B \taddress {\r
--.B \t\t3ffe:10::10/64;\r
--.B \t\tprefer-life-time 6000;\r
--.B \t\tvalid-life-time 8000;\r
--.B \t};\r
--.B \trenew-time 11000;\r
--.B \trebind-time 21000;\r
--.B };\r
--.fi\r
--\r
--.SH SEE ALSO\r
--Dynamic Host Configuration Protocol for IPv6 (DHCPv6), IPv6 Prefix Options\r
--for DHCPv6, dhcp6c(5)\r
--\r
--.SH AUTHORS\r
--.LP\r
--Kazuo Hiekata <hiekata@yamato.ibm.com>\r
--\r
--\r
-+.\" $Id$
-+.\"
-+.\" Copyright (C) International Business Machines Corp., 2003
-+.\" All rights reserved.
-+.\"
-+.\" Redistribution and use in source and binary forms, with or without
-+.\" modification, are permitted provided that the following conditions
-+.\" are met:
-+.\" 1. Redistributions of source code must retain the above copyright
-+.\" notice, this list of conditions and the following disclaimer.
-+.\" 2. Redistributions in binary form must reproduce the above copyright
-+.\" notice, this list of conditions and the following disclaimer in the
-+.\" documentation and/or other materials provided with the distribution.
-+.\" 3. Neither the name of the project nor the names of its contributors
-+.\" may be used to endorse or promote products derived from this software
-+.\" without specific prior written permission.
-+.\"
-+.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+.\" SUCH DAMAGE.
-+.\"
-+.TH dhcp6c.conf 5 "17 March 2003" "dhcp6c.conf" "Linux System Manager's Manual"
-+
-+.SH NAME
-+dhcp6c.conf \- configuration file of the DHCPv6 client daemon, dhcp6c
-+
-+.SH DESCRIPTION
-+.B dhcp6c.conf
-+is a configuration file for dhcp6c (DHCPv6 client).
-+
-+dhcp6c is configured by the configuration information (such as rapid-commit,
-+requesting temp-address, or prefix-delegation) in this file.
-+dhcp6c.conf is an ASCII text file and lines that start with # are comments.
-+
-+.PP
-+.BI STATEMENTS
-+.PP
-+.nf
-+.B interface\ <interface\ name>
-+.B {
-+.B \t[declarations]
-+.B };
-+.fi
-+Write configurations for this interface in this statement.
-+In [declarations], options can be specified.
-+
-+.PP
-+.BI DECLARATIONS
-+.PP
-+.nf
-+.B send\ [dhcpoptions];
-+.fi
-+With this declaration, dhcp6c sends specified options.
-+Currently rapid\-commit is defined.
-+
-+.nf
-+\fIsend rapid\-commit;\fR
-+.fi
-+This declaration enables dhcp6c to request the dhcp6s server to perform a
-+Rapid Commit.
-+
-+.nf
-+.B request\ [dhcpoptions];
-+.fi
-+This declaration enables dhcp6c to request specified options.
-+Currently temp\-address, domain\-name\-servers, and prefix\-delegation
-+are defined.
-+
-+.nf
-+\fIrequest domain\-name\-servers;\fR
-+.fi
-+The DHCPv6 mechanism provides a way to obtain configuration information
-+such as a list of available DNS servers or NTP servers. This declaration
-+enables dhcp6c to request a DNS server address from the DHCPv6 server.
-+
-+.nf
-+\fIrequest prefix\-delegation;\fR
-+.fi
-+This declaration enables dhcp6c to request a Prefix Delegation to the
-+DHCPv6 server. dhcp6c gets a prefix assignment from the DHCPv6 server.
-+
-+.nf
-+\fIrequest temp\-address;\fR
-+.fi
-+This declaration enables dhcp6c to request temporary addresses.
-+dhcp6c requests Non-temporary Addresses as default. This option makes
-+dhcp6c request Temporary Addresses.
-+
-+.nf
-+.B information-only;
-+.fi
-+This declaration enables dhcp6c to request host configuration information
-+from the DHCPv6 server. If dhcp6c doesn't need to be assigned any addresses,
-+this option should be specified.
-+
-+.nf
-+.B address\ {
-+.B \t[<ipv6\ address>/<prefix\ length>];
-+.B \t[prefer-life-time\ <preferred\-lifetime>];
-+.B \t[valid-life-time\ <valid\-lifetime>];
-+.B };
-+.fi
-+This declaration defines the dhcp6c client preferred IPv6 address,
-+the preferred lifetime of the address, and the valid lifetime for this
-+interface.
-+
-+.nf
-+.B prefix\ {
-+.B \t[<ipv6\ prefix>/<prefix\ length>];
-+.B \t[prefer-life-time\ <preferred\-lifetime>];
-+.B \t[valid-life-time\ <valid\-lifetime>];
-+.B };
-+.fi
-+This declaration defines the dhcp6c client acting as a requesting
-+router for the preferred prefix, the prefix length, and the prefix's
-+preferred lifetime, and valid lifetime for this interface.
-+
-+.nf
-+.B prefer-life-time\ <preferred\-lifetime>;
-+.fi
-+This declaration sets the preferred lifetime (in seconds) of the address
-+or prefix. This declaration is valid only in address or prefix declarations.
-+
-+.nf
-+.B valid-life-time\ <valid\-lifetime>;
-+.fi
-+This declaration sets the valid lifetime (in seconds) of the address or
-+prefix.
-+This declaration is valid only in address or prefix declarations.
-+
-+.nf
-+.B renew-time\ <renew-time>;
-+.fi
-+This declaration specifies the Renew Time (in seconds) for this Identity
-+Association (IA). Renew Time is a T1 value in an IA option. dhcp6c sets the
-+Renew Time in IA options to the specified value.
-+
-+.nf
-+.B rebind-time\ <rebind-time>;
-+.fi
-+This declaration specifies the Rebind Time (in seconds) for this IA. Rebind
-+Time is T2 value in an IA option. dhcp6c sets the Rebind Time in IA options
-+to the specified value.
-+
-+.PP
-+.BI DHCPOPTIONS
-+.PP
-+.nf
-+.B rapid\-commit
-+.fi
-+If this option is used in a "send [dhcpoptions];" declaration,
-+dhcp6c sends DHCPv6 messages with a Rapid Commit option.
-+
-+.nf
-+.B domain\-name\-servers
-+.fi
-+If this option is used in a "request [dhcpoptions];" declaration,
-+dhcp6c requests the DNS server address via the DHCPv6 mechanism.
-+
-+.nf
-+.B prefix\-delegation
-+.fi
-+If this option is used in a "request [dhcpoptions];" declaration,
-+dhcp6c requests a Prefix Delegation to the DHCPv6 servers.
-+
-+.nf
-+.B prefix\-delegation\-interface <interface name>
-+Specifies the name of the interface definition in radvd.conf
-+that dhcp6c will write the 'prefix' declaration for. By default,
-+dhcp6c will write a radvd.conf prefix declaration for the interface
-+on which it receives the prefix delegation lease.
-+
-+.nf
-+\fIuse-ra-prefix;\fR
-+.fi
-+This declaration tells the client not to request the address prefix configured
-+in the server's address or range statements. With this option, client address
-+prefixes can be set only by router advertisements, and the prefix configured in
-+server address or range statements will be ignored. This is a Red Hat extension;
-+previously, the only way to set client address prefixes was by router advertisement.
-+
-+.SH EXAMPLES
-+.PP
-+This is a sample of the dhcp6c.conf file.
-+.nf
-+.B interface eth0 {
-+.B \tsend rapid-commit;
-+.B \trequest prefix-delegation;
-+.B \trequest domain-name-servers;
-+.B \trequest temp-address;
-+.B \tiaid 11111;
-+.B \taddress {
-+.B \t\t3ffe:10::10/64;
-+.B \t\tprefer-life-time 6000;
-+.B \t\tvalid-life-time 8000;
-+.B \t};
-+.B \trenew-time 11000;
-+.B \trebind-time 21000;
-+.B };
-+.fi
-+
-+.SH SEE ALSO
-+Dynamic Host Configuration Protocol for IPv6 (DHCPv6), IPv6 Prefix Options
-+for DHCPv6, dhcp6c(5)
-+
-+.SH AUTHORS
-+.LP
-+Kazuo Hiekata <hiekata@yamato.ibm.com>
-+
-+
---- dhcp-0.10/dhcp6s.conf.5.man 2003-05-28 18:56:23.000000000 -0400
-+++ dhcp-0.10/dhcp6s.conf.5 2007-02-08 15:44:07.000000000 -0500
-@@ -1,322 +1,340 @@
--.\" $Id$\r
--.\"\r
--.\" Copyright (C) International Business Machines Corp., 2003\r
--.\" All rights reserved.\r
--.\"\r
--.\" Redistribution and use in source and binary forms, with or without\r
--.\" modification, are permitted provided that the following conditions\r
--.\" are met:\r
--.\" 1. Redistributions of source code must retain the above copyright\r
--.\" notice, this list of conditions and the following disclaimer.\r
--.\" 2. Redistributions in binary form must reproduce the above copyright\r
--.\" notice, this list of conditions and the following disclaimer in the\r
--.\" documentation and/or other materials provided with the distribution.\r
--.\" 3. Neither the name of the project nor the names of its contributors\r
--.\" may be used to endorse or promote products derived from this software\r
--.\" without specific prior written permission.\r
--.\"\r
--.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND\r
--.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
--.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
--.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE\r
--.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
--.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
--.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
--.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
--.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
--.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
--.\" SUCH DAMAGE.\r
--.\"\r
--.TH dhcp6s.conf 5 "17 March 2003" "dhcp6s.conf" "Linux System Manager's Manual"\r
--\r
--.SH NAME\r
--dhcp6s.conf \- configuration file of the DHCPv6 server daemon, dhcp6s\r
--\r
--.SH DESCRIPTION\r
-+.\" $Id$
-+.\"
-+.\" Copyright (C) International Business Machines Corp., 2003
-+.\" All rights reserved.
-+.\"
-+.\" Redistribution and use in source and binary forms, with or without
-+.\" modification, are permitted provided that the following conditions
-+.\" are met:
-+.\" 1. Redistributions of source code must retain the above copyright
-+.\" notice, this list of conditions and the following disclaimer.
-+.\" 2. Redistributions in binary form must reproduce the above copyright
-+.\" notice, this list of conditions and the following disclaimer in the
-+.\" documentation and/or other materials provided with the distribution.
-+.\" 3. Neither the name of the project nor the names of its contributors
-+.\" may be used to endorse or promote products derived from this software
-+.\" without specific prior written permission.
-+.\"
-+.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+.\" SUCH DAMAGE.
-+.\"
-+.TH dhcp6s.conf 5 "17 March 2003" "dhcp6s.conf" "Linux System Manager's Manual"
-+
-+.SH NAME
-+dhcp6s.conf \- configuration file of the DHCPv6 server daemon, dhcp6s
-+
-+.SH DESCRIPTION
- .B dhcp6s.conf
--contains the configuration information of addresses, prefixes, or\r
--various network configuration parameters for each of the interfaces. \r
--The network configuration parameters can be described globally for all of \r
--the interfaces. The default address preferred life time is 36000 seconds; \r
--the default address valid life time is 72000 seconds if they are not defined\r
--in any declaration. The specific declaration order is interface, link, host;\r
--within link the more specific declaration is pool.\r
--\r
-- The interface definitions are described in the following form:\r
--.PP\r
--.nf\r
--.B \tinterface\ <interface\ name>\r
--.B \t{\r
--.B \t\t[declarations];\r
--.B \t};\r
--.fi\r
-- where each of the declarations could be of type link, group, or host. \r
--Each declaration and the statements within each of these declarations \r
--must be terminated by a semicolon. Additional details of the declarations \r
--are specified below.\r
--\r
--.PP\r
--.BI DECLARATIONS\r
--.PP\r
--.nf\r
--.B interface\ <interface\ name>\r
--.B {\r
--.B \t[declarations];\r
--.B };\r
--.fi\r
--An interface declaration is used to inform the DHCPv6 server that the links and\r
--hosts declared within it are connected to the same network segment. Common\r
--network parameters for this network segment can be defined within the interface\r
--declaration.\r
--\r
--.nf\r
--.B link\ <link\ name>\r
--.B {\r
--.B \t[declarations];\r
--.B };\r
--.fi\r
--A link declaration is used to provide the DHCPv6 server the IPv6 assgined\r
--address ranges, prefixes, and hosts. Common network parameters for this link \r
--can be defined within the link declaration.\r
--\r
--.nf\r
--.B group\r
--.B {\r
--.B \t[declarations];\r
--.B };\r
--.fi\r
--A group declaration is used to group a list of declarations together to define\r
--the common network parameters. These network parameters are valid within this\r
--declaration only. Declarations can be one of the following types: interface, link,\r
--pool, or host.\r
--\r
--.nf\r
--.B pool\r
--.B {\r
--.B \t[declarations];\r
--.B };\r
--.fi\r
--The pool declaration is used to declare an address pool from which IPv6\r
--address can be allocated, with its own permit to control client access\r
--and its own declaration in which you can declare pool-specific network parameters.\r
--\r
--.nf\r
--.B host\ <host\ name>\r
--.B {\r
--.B \t[duid\ <DUID\n>];\r
--.B \t[iaidinfo\ {}];\r
--.B \t[address\ {}];\r
--.B \t[prefix\ <prefix>/<prefix\ length>];\r
--.B \t[declarations];\r
--.B };\r
--.fi\r
--This declaration allows administrators to describe the addresses, prefixes, and\r
--network configuration parameters for this host. As for this declaration, the\r
--DHCP Unique Identifier (DUID), Identity Association Identifier (IAID), and\r
--addresses must be specified. The host declaration is used to do Static\r
--Address Assginment for a particular DHCPv6 client. \r
--\r
--.nf\r
--.B address\r
--.B {\r
--.B \t[<ipv6 address>/<prefix length>];\r
--.B \t[prefer-life-time\ <preferred\ lifetime>];\r
--.B \t[valid-life-time\ <valid\ lifetime>];\r
--.B };\r
--.fi\r
--This statement allows administrators to specify the address for the \r
--host. Preferred Lifetime and Valid Lifetime also can be set in this\r
--statement. This statement is valid only in host {} declarations.\r
--\r
--.nf\r
--.B prefix\ <prefix>/<prefix\ length>;\r
--.fi\r
--This statement allows administrators to specify the prefix.\r
--This parameter is needed when configuring dhcp6s as the Delegation Router for\r
--the Prefix Delegation. dhcp6s assigns the specified prefixes \r
--to the requesting routers.\r
--\r
--.nf\r
--.B iaidinfo\r
--.B {\r
--.B \t[iaid\ <IAID\ number>];\r
--.B \t[renew-time\ <renew\ time>];\r
--.B \t[rebind-time\ <rebind\ time>];\r
--.B };\r
--.fi\r
--This statement allows administrators to describe the information for \r
--this IAID. This statement is only valid in host {} declarations.\r
--iaid is required; renew-time and rebind time are optional in this statement.\r
--\r
--.nf\r
--.B range\ <ipv6\ address>\ to\ <ipv6\ address>/<prefix\ length>;\r
--.fi\r
--This statement allows adminstrators to use "range" and "to" keywords and\r
--prefix length to specify an address range.\r
--For each range not more than one of the unassigned addresses will be\r
--assgined to the requested client.\r
--\r
--.nf\r
--.B duid\ <DUID\>;\r
--.fi\r
--DUID is a DHCP Unique Identifier for a DHCP participant. Using this option,\r
--the administrator can specify the DUID of this DHCPv6 client.\r
--The duid statement is valid only in host {} declarations.\r
--\r
--.nf\r
--.BI iaid\ <IAID\ number>;\r
--.fi\r
--IAID is a Identity Association Identifier. IA is a collection of addresses\r
--assigned to a client. Using this option, the administrator can specify the IAID\r
--in iaidinfo for a host declaration.\r
--\r
--.nf\r
--.BI renew-time\ <renew\ time>;\r
--.fi\r
--This statement allows administrators to specify the RenewTime (T1).\r
--The recommended value for RenewTime is .5 times the shortest preferred\r
--lifetime of the address in the IA, if the value is not defined.\r
--\r
--.nf\r
--.BI rebind-time\ <rebind\ time>;\r
--.fi\r
--This statement allows administrators to specify the RebindTime (T2).\r
--The recommended value for RenewTime is .8 times the shortest preferred \r
--lifetime of the address in the IA, if the value is not defined.\r
--\r
--.nf\r
--.BI prefer-life-time\ <preferred\ lifetime>;\r
--.fi\r
--This statement allows administrators to specify the Preferred Life Time for \r
--each address.\r
--\r
--.nf\r
--.BI valid-life-time\ <valid\ lifetime>;\r
--.fi\r
--This statement allows administrators to specify the Valid Life Time for \r
--each address.\r
--\r
--.nf\r
--.BI option\ dns_server\ <ipv6\ addresses\ or\ domain\ name\ list>;\r
--.fi\r
--This statement allows administrators to specify the DNS servers.\r
--\r
--.B send\ <OPTION>;\r
--.fi\r
--This declaration enables dhcp6s to include the specified option in sending \r
--DHCPv6 messages.\r
--\r
--.nf\r
--\fIsend\ unicast;\fR\r
--.fi\r
--This declaration enables dhcp6s to send a Server Unicast option. Usually\r
--DHCPv6 clients must use multicast addresses to contact the DHCPv6 server and\r
--agents. This declaration specifies that dhcp6s will accept unicast messages\r
--from DHCPv6 clients if they include a Server Unicast option.\r
--\r
--.nf\r
--\fIsend\ server-preference\ <server\ preference\ value>;\fR\r
--.fi\r
--This declaration enables dhcp6s to include a Preference option for sending\r
--DHCPv6 messages. DHCPv6 clients will pick up the DHCPv6 server which has\r
--highest preference value. The highest preference value is 255.\r
--\r
--.nf\r
--\fIsend\ temp-address;\fR\r
--.fi\r
--This declaration assigns a temporary address to the requesting client.\r
--\r
--.nf\r
--\fIsend\ information-only;\fR\r
--.fi\r
--This option enables dhcp6s to give only configuration information rather than\r
--assigning client addresses. This could be, for example, DNS server address\r
--configuration information.\r
--\r
--.nf\r
--.B allow\ <OPTION>;\r
--.fi\r
--This declaration allows the DHCPv6 client to specify an option in receiving\r
--DHCPv6 messages.\r
--\r
--.nf\r
--\fIallow rapid\-commit;\fR\r
--.fi\r
--This option enables dhcp6s to allow the Rapid-Commit option from the DHCPv6\r
--client and the Solicit-Reply message exchanges.\r
--\r
--.nf\r
--\fIallow\ unicast;\fR\r
--.fi\r
--This option enables dhcp6s to allow the Server Unicast option for the DHCPv6\r
--client. Usually DHCPv6 clients must use multicast addresses to contact DHCPv6\r
--server and agents. With this declaration, dhcp6s accepts unicast \r
--messages from DHCPv6 clients if they include a Server Unicast option.\r
--\r
--.SH EXAMPLES\r
--.PP\r
--This is a sample of the dhcp6s.conf file.\r
--.nf\r
--.B option dns\_server 2003::6:1 ibm.com;\r
--.B prefer\-life\-time 10000;\r
--.B valid\-life\-time 20000;\r
--.B renew\-time 5000;\r
--.B rebind\-time 8000;\r
--.B interface eth1 {\r
--.B \tlink AAA {\r
--.B \t\tallow unicast;\r
--.B \t\tsend unicast;\r
--.B \t\tallow rapid-commit;\r
--.B \t\tsend server-preference 5;\r
--.B \t\trenew-time 1000;\r
--.B \t\trebind-time 2400;\r
--.B \t\tprefer-life-time 2000;\r
--.B \t\tvalid-life-time 3000;\r
--.B \t\trange 3ffe:ffff:100::10 to 3ffe:ffff:100::110/64;\r
--.B \t\tprefix 3ffe:ffef:104::/64;\r
--.B \t\tpool {\r
--.B \t\t\tprefer\-life\-time 3600;\r
--.B \t\t\tvalid\-life\-time 7200;\r
--.B \t\t\trange fec0:ffff::10 to fec0:ffff::110/64;\r
--.B \t\t\tprefix fec0:fffe::/48;\r
--.B \t\t};\r
--.B \t};\r
--.B \thost host0 {\r
--.B \t\tduid 00:00:00:00:a0:a0;\r
--.B \t\tiaidinfo {\r
--.B \t\t\tiaid 101010;\r
--.B \t\t\trenew-time 1000;\r
--.B \t\t\trebind-time 2000;\r
--.B \t\t};\r
--.B \t\taddress {\r
--.B \t\t\t3ffe:ffff:102::120/64;\r
--.B \t\t\tprefer-life-time 2000;\r
--.B \t\t\tvalid-life-time 3000;\r
--.B \t\t};\r
--.B \t};\r
--.B \tgroup {\r
--.B \t\tprefer\-life\-time 5000;\r
--.B \t\tvalid\-life\-time 6000;\r
--.B \t\thost host1 {\r
--.B \t\t\tduid 00:00:00:00:a1:a1;\r
--.B \t\t\tiaidinfo {\r
--.B \t\t\t\tiaid 101011;\r
--.B \t\t\t\trenew-time 1000;\r
--.B \t\t\t\trebind-time 2000;\r
--.B \t\t\t};\r
--.B \t\t};\r
--.B \t\thost host2 {\r
--.B \t\t\tduid 00:00:00:00:a2:a2;\r
--.B \t\t\tsend information-only;\r
--.B \t\t};\r
--.B \t};\r
--.B };\r
--.fi\r
--\r
--.SH SEE ALSO\r
--Dynamic Host Configuration Protocol for IPv6 (DHCPv6), IPv6 Prefix Options\r
--for DHCPv6, dhcp6s(5)\r
--\r
--.SH AUTHORS\r
--.LP\r
--Kazuo Hiekata <hiekata@yamato.ibm.com>\r
-+contains the configuration information of addresses, prefixes, or
-+various network configuration parameters for each of the interfaces.
-+The network configuration parameters can be described globally for all of
-+the interfaces. The default address preferred life time is 36000 seconds;
-+the default address valid life time is 72000 seconds if they are not defined
-+in any declaration. The specific declaration order is interface, link, host;
-+within link the more specific declaration is pool.
-+
-+ The interface definitions are described in the following form:
-+.PP
-+.nf
-+.B \tinterface\ <interface\ name>
-+.B \t{
-+.B \t\t[declarations];
-+.B \t};
-+.fi
-+ where each of the declarations could be of type link, group, or host.
-+Each declaration and the statements within each of these declarations
-+must be terminated by a semicolon. Additional details of the declarations
-+are specified below.
-+
-+.PP
-+.BI DECLARATIONS
-+.PP
-+.nf
-+.B interface\ <interface\ name>
-+.B {
-+.B \t[declarations];
-+.B };
-+.fi
-+An interface declaration is used to inform the DHCPv6 server that the links and
-+hosts declared within it are connected to the same network segment. Common
-+network parameters for this network segment can be defined within the interface
-+declaration.
-+
-+.nf
-+.B link\ <link\ name>
-+.B {
-+.B \t[declarations];
-+.B };
-+.fi
-+A link declaration is used to provide the DHCPv6 server the IPv6 assgined
-+address ranges, prefixes, and hosts. Common network parameters for this link
-+can be defined within the link declaration.
-+
-+.nf
-+.B group
-+.B {
-+.B \t[declarations];
-+.B };
-+.fi
-+A group declaration is used to group a list of declarations together to define
-+the common network parameters. These network parameters are valid within this
-+declaration only. Declarations can be one of the following types: interface, link,
-+pool, or host.
-+
-+.nf
-+.B pool
-+.B {
-+.B \t[declarations];
-+.B };
-+.fi
-+The pool declaration is used to declare an address pool from which IPv6
-+address can be allocated, with its own permit to control client access
-+and its own declaration in which you can declare pool-specific network parameters.
-+
-+.nf
-+.B host\ <host\ name>
-+.B {
-+.B \t[duid\ <DUID\n>];
-+.B \t[iaidinfo\ {}];
-+.B \t[address\ {}];
-+.B \t[prefix\ <prefix>/<prefix\ length>];
-+.B \t[declarations];
-+.B };
-+.fi
-+This declaration allows administrators to describe the addresses, prefixes, and
-+network configuration parameters for this host. As for this declaration, the
-+DHCP Unique Identifier (DUID), Identity Association Identifier (IAID), and
-+addresses must be specified. The host declaration is used to do Static
-+Address Assginment for a particular DHCPv6 client.
-+
-+.nf
-+.B address
-+.B {
-+.B \t[<ipv6 address>/<prefix length>];
-+.B \t[prefer-life-time\ <preferred\ lifetime>];
-+.B \t[valid-life-time\ <valid\ lifetime>];
-+.B };
-+.fi
-+This statement allows administrators to specify the address for the
-+host. Preferred Lifetime and Valid Lifetime also can be set in this
-+statement. This statement is valid only in host {} declarations.
-+
-+.nf
-+.B prefix\ <prefix>/<prefix\ length>;
-+.fi
-+This statement allows administrators to specify the prefix.
-+This parameter is needed when configuring dhcp6s as the Delegation Router for
-+the Prefix Delegation. dhcp6s assigns the specified prefixes
-+to the requesting routers.
-+
-+.nf
-+.B relay\ <relay>/<prefix\ length>;
-+.fi
-+This statement specifies the prefix that the relay agent will put in the link
-+address field of the RELAY-FORW message to indicate the link the client is
-+attached to. If the link-address matches this prefix, this link declaration
-+will be used. This statement is only valid in the link declaration.
-+
-+.nf
-+.B iaidinfo
-+.B {
-+.B \t[iaid\ <IAID\ number>];
-+.B \t[renew-time\ <renew\ time>];
-+.B \t[rebind-time\ <rebind\ time>];
-+.B };
-+.fi
-+This statement allows administrators to describe the information for
-+this IAID. This statement is only valid in host {} declarations.
-+iaid is required; renew-time and rebind time are optional in this statement.
-+
-+.nf
-+.B range\ <ipv6\ address>\ to\ <ipv6\ address>/<prefix\ length>;
-+.fi
-+This statement allows adminstrators to use "range" and "to" keywords and
-+prefix length to specify an address range.
-+For each range not more than one of the unassigned addresses will be
-+assgined to the requested client.
-+
-+.nf
-+.B duid\ <DUID\>;
-+.fi
-+DUID is a DHCP Unique Identifier for a DHCP participant. Using this option,
-+the administrator can specify the DUID of this DHCPv6 client.
-+The duid statement is valid only in host {} declarations.
-+
-+.nf
-+.BI iaid\ <IAID\ number>;
-+.fi
-+IAID is a Identity Association Identifier. IA is a collection of addresses
-+assigned to a client. Using this option, the administrator can specify the IAID
-+in iaidinfo for a host declaration.
-+
-+.nf
-+.BI renew-time\ <renew\ time>;
-+.fi
-+This statement allows administrators to specify the RenewTime (T1).
-+The recommended value for RenewTime is .5 times the shortest preferred
-+lifetime of the address in the IA, if the value is not defined.
-+
-+.nf
-+.BI rebind-time\ <rebind\ time>;
-+.fi
-+This statement allows administrators to specify the RebindTime (T2).
-+The recommended value for RenewTime is .8 times the shortest preferred
-+lifetime of the address in the IA, if the value is not defined.
-+
-+.nf
-+.BI prefer-life-time\ <preferred\ lifetime>;
-+.fi
-+This statement allows administrators to specify the Preferred Life Time for
-+each address.
-+
-+.nf
-+.BI valid-life-time\ <valid\ lifetime>;
-+.fi
-+This statement allows administrators to specify the Valid Life Time for
-+each address.
-+
-+.nf
-+.BI option\ dns_server\ <ipv6\ addresses\ or\ domain\ name\ list>;
-+.fi
-+This statement allows administrators to specify the DNS servers.
-+
-+.B send\ <OPTION>;
-+.fi
-+This declaration enables dhcp6s to include the specified option in sending
-+DHCPv6 messages.
-+
-+.nf
-+\fIsend\ unicast;\fR
-+.fi
-+This declaration enables dhcp6s to send a Server Unicast option. Usually
-+DHCPv6 clients must use multicast addresses to contact the DHCPv6 server and
-+agents. This declaration specifies that dhcp6s will accept unicast messages
-+from DHCPv6 clients if they include a Server Unicast option.
-+
-+.nf
-+\fIserver-preference\ <server\ preference\ value>;\fR
-+.fi
-+This declaration enables dhcp6s to include a Preference option for sending
-+DHCPv6 messages. DHCPv6 clients will pick up the DHCPv6 server which has
-+highest preference value. The highest preference value is 255.
-+
-+.nf
-+\fIsend\ temp-address;\fR
-+.fi
-+This declaration assigns a temporary address to the requesting client.
-+
-+.nf
-+\fIsend\ information-only;\fR
-+.fi
-+This option enables dhcp6s to give only configuration information rather than
-+assigning client addresses. This could be, for example, DNS server address
-+configuration information.
-+
-+.nf
-+.B allow\ <OPTION>;
-+.fi
-+This declaration allows the DHCPv6 client to specify an option in receiving
-+DHCPv6 messages.
-+
-+.nf
-+\fIallow rapid\-commit;\fR
-+.fi
-+This option enables dhcp6s to allow the Rapid-Commit option from the DHCPv6
-+client and the Solicit-Reply message exchanges.
-+
-+.nf
-+\fIallow\ unicast;\fR
-+.fi
-+This option enables dhcp6s to allow the Server Unicast option for the DHCPv6
-+client. Usually DHCPv6 clients must use multicast addresses to contact DHCPv6
-+server and agents. With this declaration, dhcp6s accepts unicast
-+messages from DHCPv6 clients if they include a Server Unicast option.
-+
-+
-+.nf
-+\fIuse-ra-prefix;\fR
-+.fi
-+This declaration tells the server not to send clients the address prefix configured
-+in address or range statements. With this option, client address prefixes can
-+be set only by router advertisements, and the prefix configured in address or
-+range statements will be ignored. This is a Red Hat extension; previously, the
-+only way to set client address prefixes was by router advertisement.
-+
-+.SH EXAMPLES
-+.PP
-+This is a sample of the dhcp6s.conf file.
-+.nf
-+.B option dns\_server 2003::6:1 ibm.com;
-+.B prefer\-life\-time 10000;
-+.B valid\-life\-time 20000;
-+.B renew\-time 5000;
-+.B rebind\-time 8000;
-+.B interface eth1 {
-+.B \tlink AAA {
-+.B \t\tallow unicast;
-+.B \t\tsend unicast;
-+.B \t\tallow rapid-commit;
-+.B \t\tserver-preference 5;
-+.B \t\trenew-time 1000;
-+.B \t\trebind-time 2400;
-+.B \t\tprefer-life-time 2000;
-+.B \t\tvalid-life-time 3000;
-+.B \t\trange 3ffe:ffff:100::10 to 3ffe:ffff:100::110/64;
-+.B \t\tprefix 3ffe:ffef:104::/64;
-+.B \t\tpool {
-+.B \t\t\tprefer\-life\-time 3600;
-+.B \t\t\tvalid\-life\-time 7200;
-+.B \t\t\trange fec0:ffff::10 to fec0:ffff::110/64;
-+.B \t\t\tprefix fec0:fffe::/48;
-+.B \t\t};
-+.B \t};
-+.B \thost host0 {
-+.B \t\tduid 00:00:00:00:a0:a0;
-+.B \t\tiaidinfo {
-+.B \t\t\tiaid 101010;
-+.B \t\t\trenew-time 1000;
-+.B \t\t\trebind-time 2000;
-+.B \t\t};
-+.B \t\taddress {
-+.B \t\t\t3ffe:ffff:102::120/64;
-+.B \t\t\tprefer-life-time 2000;
-+.B \t\t\tvalid-life-time 3000;
-+.B \t\t};
-+.B \t};
-+.B \tgroup {
-+.B \t\tprefer\-life\-time 5000;
-+.B \t\tvalid\-life\-time 6000;
-+.B \t\thost host1 {
-+.B \t\t\tduid 00:00:00:00:a1:a1;
-+.B \t\t\tiaidinfo {
-+.B \t\t\t\tiaid 101011;
-+.B \t\t\t\trenew-time 1000;
-+.B \t\t\t\trebind-time 2000;
-+.B \t\t\t};
-+.B \t\t};
-+.B \t\thost host2 {
-+.B \t\t\tduid 00:00:00:00:a2:a2;
-+.B \t\t\tsend information-only;
-+.B \t\t};
-+.B \t};
-+.B };
-+.fi
-+
-+.SH SEE ALSO
-+Dynamic Host Configuration Protocol for IPv6 (DHCPv6), IPv6 Prefix Options
-+for DHCPv6, dhcp6s(5)
-+
-+.SH AUTHORS
-+.LP
-+Kazuo Hiekata <hiekata@yamato.ibm.com>
+++ /dev/null
---- dhcp-0.10/common.h.no_strlcat 2007-02-16 15:30:18.000000000 -0500
-+++ dhcp-0.10/common.h 2007-02-16 15:30:46.000000000 -0500
-@@ -107,9 +107,6 @@
- extern struct host_conf *find_hostconf __P((const struct duid *));
-
- /* missing */
--#ifndef HAVE_STRLCAT
--extern size_t strlcat __P((char *, const char *, size_t));
--#endif
- #ifndef HAVE_STRLCPY
- extern size_t strlcpy __P((char *, const char *, size_t));
- #endif
---- dhcp-0.10/configure.in.no_strlcat 2007-02-16 15:30:18.000000000 -0500
-+++ dhcp-0.10/configure.in 2007-02-16 15:30:40.000000000 -0500
-@@ -67,7 +67,7 @@
- *) ;;
- esac
- dnl Checks for header files.
--AC_REPLACE_FUNCS(strlcpy strlcat)
-+AC_REPLACE_FUNCS(strlcpy)
- AC_HEADER_STDC
- AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h syslog.h unistd.h ifaddrs.h)
- AC_MSG_CHECKING(for socklen_t)
+++ /dev/null
---- dhcp-0.10/Makefile.in.rh 2004-03-04 18:31:24.000000000 -0500
-+++ dhcp-0.10/Makefile.in 2007-02-09 01:28:31.000000000 -0500
-@@ -2,34 +2,9 @@
- # $Id$
- #
-
--srcdir= @srcdir@
--CFLAGS= @CFLAGS@ @DEFS@
--LDFLAGS=@LDFLAGS@
--LIBOBJS=@LIBOBJS@
--LIBS= @LIBS@
--CC= @CC@
--YACC= @YACC@
--LEX= @LEX@
--TARGET= dhcp6c dhcp6s
--DESTDIR=
--
--INSTALL=@INSTALL@
--INSTALL_PROGRAM=@INSTALL_PROGRAM@
--INSTALL_DATA=@INSTALL_DATA@
--prefix= @prefix@
--exec_prefix= @exec_prefix@
--bindir= @bindir@
--sbindir=@sbindir@
--mandir= @mandir@
--initdir=/etc/rc.d/init.d
--etc=/etc
--sysconfigdir=/etc/sysconfig
--CHKCONFIG=/sbin/chkconfig
--
--CFLAGS+= -DCONF_DH6OPT_DNS_RESOLVERS=@dhcpopt_dns_resolvers@ \
-- -DCONF_DH6OPT_DOMAIN_LIST=@dhcpopt_domain_list@ \
-- -DCONF_DH6OPT_IA_PD=@dhcpopt_pdel@ \
-- -DCONF_DH6OPT_IAPREFIX=@dhcpopt_pinfo@
-+include Makefile.inc
-+
-+TARGET= dhcp6c dhcp6s dhcp6r
-
- COMMONGENSRCS=lease_token.c
- CLIENTGENSRCS=client6_parse.c client6_token.c dad_token.c ra_token.c \
-@@ -41,67 +16,85 @@
- SERVOBJS= dhcp6s.o common.o timer.o hash.o lease.o \
- server6_conf.o server6_addr.o \
- $(SERVERGENSRCS:%.c=%.o) $(COMMONGENSRCS:%.c=%.o)
-+RELAYOBJS= dhcp6r.o relay6_database.o relay6_parser.o relay6_socket.o
-
- 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 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)
-+
- dad_token.c: dad_token.l
- $(LEX) -Pifyy dad_token.l
-- mv lex.ifyy.c $@
-+ cp lex.ifyy.c $@
-
- ra_token.c: ra_token.l
- $(LEX) -Prayy ra_token.l
-- mv lex.rayy.c $@
-+ cp lex.rayy.c $@
-
- resolv_token.c: resolv_token.l
- $(LEX) -Prvyy resolv_token.l
-- mv lex.rvyy.c $@
-+ cp lex.rvyy.c $@
-
- radvd_token.c: radvd_token.l
- $(LEX) -Prdyy radvd_token.l
-- mv lex.rdyy.c $@
-+ cp lex.rdyy.c $@
-
- client6_parse.c cp.tab.h: client6_parse.y
- $(YACC) -d -p cpyy client6_parse.y
-- mv y.tab.h cp.tab.h
-- mv y.tab.c client6_parse.c
-+ cp y.tab.h cp.tab.h
-+ cp y.tab.c client6_parse.c
-
- client6_token.c: client6_token.l
- $(LEX) -Pcpyy client6_token.l
-- mv lex.cpyy.c $@
-+ cp lex.cpyy.c $@
-
- lease_token.c: lease_token.l
- $(LEX) -Plyy lease_token.l
-- mv lex.lyy.c $@
-+ cp lex.lyy.c $@
-
- server6_parse.c sf.tab.h: server6_parse.y
- $(YACC) -d -p sfyy server6_parse.y
-- mv y.tab.h sf.tab.h
-- mv y.tab.c server6_parse.c
-+ cp y.tab.h sf.tab.h
-+ cp y.tab.c server6_parse.c
-
- server6_token.c: server6_token.l sf.tab.h
- $(LEX) -Psfyy server6_token.l
-- mv lex.sfyy.c $@
-+ cp lex.sfyy.c $@
-
- install::
- $(INSTALL) -d $(DESTDIR)$(sbindir)
-- $(INSTALL_PROGRAM) -s -o bin -g bin $(TARGET) $(DESTDIR)$(sbindir)
-+ $(INSTALL) -d $(DESTDIR)/sbin
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6s $(DESTDIR)$(sbindir)
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6r $(DESTDIR)$(sbindir)
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6c $(DESTDIR)/sbin
- $(INSTALL) -d $(DESTDIR)$(mandir)/man8 $(DESTDIR)$(mandir)/man5
-- $(INSTALL_DATA) -o bin -g bin dhcp6c.8 $(DESTDIR)$(mandir)/man8/
-- $(INSTALL_DATA) -o bin -g bin dhcp6s.8 $(DESTDIR)$(mandir)/man8/
-- $(INSTALL_DATA) -o bin -g bin dhcp6c.conf.5 $(DESTDIR)$(mandir)/man5/
-- $(INSTALL_DATA) -o bin -g bin dhcp6s.conf.5 $(DESTDIR)$(mandir)/man5/
-+ $(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6c.8 $(DESTDIR)$(mandir)/man8/
-+ $(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6s.8 $(DESTDIR)$(mandir)/man8/
-+ $(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6r.8 $(DESTDIR)$(mandir)/man8/
-+ $(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6c.conf.5 $(DESTDIR)$(mandir)/man5/
-+ $(INSTALL_DATA) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6s.conf.5 $(DESTDIR)$(mandir)/man5/
-+ $(INSTALL) -d $(DESTDIR)$(initdir)
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6s.sh $(DESTDIR)$(initdir)/dhcp6s
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6r.sh $(DESTDIR)$(initdir)/dhcp6r
-+ $(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
-
- rh_install:: install
- $(INSTALL) -d $(initdir)
-- $(INSTALL_PROGRAM) -o root -g root dhcp6s.sh $(initdir)/dhcp6s
-- $(INSTALL_PROGRAM) -o root -g root dhcp6c.sh $(initdir)/dhcp6c
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6s.sh $(initdir)/dhcp6s
-+ $(INSTALL_PROGRAM) -o $(INSTALL_USER) -g $(INSTALL_GROUP) dhcp6c.sh $(initdir)/dhcp6c
- $(CHKCONFIG) --add dhcp6s
- $(CHKCONFIG) --add dhcp6c
-
---- dhcp-0.10/ReadMe.rh 2003-05-28 17:18:22.000000000 -0400
-+++ dhcp-0.10/ReadMe 2007-02-09 01:28:31.000000000 -0500
-@@ -18,7 +18,8 @@
-
- This implementation supports IPv6 address assignment to the clients.
- It also has the support for prefix delegation, DNS server updates but those
--features are not validated yet.
-+features are not validated yet. The server also supports messages sent through
-+relay agents, both inbound and outbound.
-
- The Linux implementation is based upon KAME's DHCPv6 implementation
- on BSD which lacked the support for dynamic address assignment feature, now
-@@ -34,7 +35,8 @@
- 3. Client IPv6 address assignment and temporary IPv6 address assignment support
- on the same link.
- 4. Supported Options: Rapid commit, Server Preference, Information Request, Unicast,
-- Elapsed Time, ClientID, ServerID , IA_NA , IA_TA , IA_ADDR , IA_PD, Status support.
-+ Elapsed Time, ClientID, ServerID , IA_NA , IA_TA , IA_ADDR , IA_PD, Status,
-+ Relay Message, Interface Identifier.
- 5. Solicit/Request/Advertise/Reply/Infomation-request messages/Renew/Rebind
- /Release/Confirm/ messages support for IPv6 address binding.
- 8. Client configuration file support for IPv6 address assignment.
-@@ -47,13 +49,13 @@
- B. Support available but not validated yet
-
- 1. Request option support
-+ 2. Relay-Forw/Relay-Repl messages and Relay Message Option
-
- C. ToDo List:
-
- 1. Authentication/User class/Vendor class/Interface-ID option
- support
-- 2. Relay agent support.
-- 3. Reconfig/Relay messages support.
-+ 2. Reconfig message support.
-
- D. INSTALLATTION:
-
---- dhcp-0.10/client6_addr.c.rh 2003-07-01 22:21:25.000000000 -0400
-+++ dhcp-0.10/client6_addr.c 2007-02-09 01:28:31.000000000 -0500
-@@ -47,8 +47,9 @@
- #include <stdlib.h>
- #include <unistd.h>
- #include <net/if_arp.h>
-+#include <ifaddrs.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -70,7 +71,7 @@
- extern struct dhcp6_timer *client6_timo __P((void *));
- extern void client6_send __P((struct dhcp6_event *));
- extern void free_servers __P((struct dhcp6_if *));
--extern ssize_t gethwid __P((char *, int, const char *, u_int16_t *));
-+extern ssize_t gethwid __P((unsigned char *, int, const char *, u_int16_t *));
-
- extern int nlsock;
- extern FILE *client6_lease_file;
-@@ -109,7 +110,11 @@
- /* add new address */
- for (lv = TAILQ_FIRST(&optinfo->addr_list); lv; lv = lv_next) {
- lv_next = TAILQ_NEXT(lv, link);
-- if (lv->val_dhcp6addr.type != IAPD) {
-+
-+ if ( (lv->val_dhcp6addr.type != IAPD)
-+ &&(lv->val_dhcp6addr.plen == 0)
-+ )
-+ {
- lv->val_dhcp6addr.plen =
- dhcp6_get_prefixlen(&lv->val_dhcp6addr.addr, dhcp6_if);
- if (lv->val_dhcp6addr.plen == PREFIX_LEN_NOTINRA) {
-@@ -119,6 +124,7 @@
- in6addr2str(&lv->val_dhcp6addr.addr, 0));
- }
- }
-+
- if ((cl_lease = dhcp6_find_lease(&client6_iaidaddr,
- &lv->val_dhcp6addr)) != NULL) {
- dhcp6_update_lease(&lv->val_dhcp6addr, cl_lease);
-@@ -156,7 +162,7 @@
- if (client6_iaidaddr.client6_info.iaidinfo.renewtime == 0)
- return (0);
- if (client6_iaidaddr.client6_info.iaidinfo.renewtime == DHCP6_DURATITION_INFINITE) {
-- client6_iaidaddr.client6_info.iaidinfo.rebindtime == DHCP6_DURATITION_INFINITE;
-+ client6_iaidaddr.client6_info.iaidinfo.rebindtime = DHCP6_DURATITION_INFINITE;
- return (0);
- }
- /* set up start date, and renew timer */
-@@ -214,7 +220,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_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)
-@@ -334,15 +340,21 @@
- /* flag == ADDR_UPDATE */
- for (lv = TAILQ_FIRST(&optinfo->addr_list); lv; lv = lv_next) {
- lv_next = TAILQ_NEXT(lv, link);
-- if (lv->val_dhcp6addr.type != IAPD) {
-+
-+ if ( (lv->val_dhcp6addr.type != IAPD)
-+ &&(lv->val_dhcp6addr.plen == 0)
-+ )
-+ {
- lv->val_dhcp6addr.plen =
- dhcp6_get_prefixlen(&lv->val_dhcp6addr.addr, dhcp6_if);
- if (lv->val_dhcp6addr.plen == PREFIX_LEN_NOTINRA) {
- dprintf(LOG_WARNING, "assigned address %s is not in any RAs"
- " prefix length using 64 bit instead",
- in6addr2str(&lv->val_dhcp6addr.addr, 0));
-+
- }
- }
-+
- if ((cl = dhcp6_find_lease(&client6_iaidaddr, &lv->val_dhcp6addr)) != NULL) {
- /* update leases */
- dhcp6_update_lease(&lv->val_dhcp6addr, cl);
-@@ -394,7 +406,7 @@
- if (client6_iaidaddr.client6_info.iaidinfo.renewtime == 0)
- return (0);
- if (client6_iaidaddr.client6_info.iaidinfo.renewtime == DHCP6_DURATITION_INFINITE) {
-- client6_iaidaddr.client6_info.iaidinfo.rebindtime == DHCP6_DURATITION_INFINITE;
-+ client6_iaidaddr.client6_info.iaidinfo.rebindtime = DHCP6_DURATITION_INFINITE;
- if (client6_iaidaddr.timer)
- dhcp6_remove_timer(client6_iaidaddr.timer);
- return (0);
-@@ -695,41 +707,41 @@
- create_iaid(struct iaid_table *iaidtab, int num_device)
- {
- struct iaid_table *temp = iaidtab;
-- char buff[1024];
-- struct ifconf ifc;
-- struct ifreq *ifr, if_hwaddr;
-+ struct ifaddrs *ifa=0L, *ifap=0L;
- int i;
-
-- ifc.ifc_len = sizeof(buff);
-- ifc.ifc_buf = buff;
-- if (ioctl(nlsock, SIOCGIFCONF, &ifc) < 0) {
-- dprintf(LOG_ERR, "%s" "ioctl SIOCGIFCONF", FNAME);
-+ if ( getifaddrs( &ifap ) != 0 )
-+ {
-+ dprintf(LOG_ERR, "%s" "getifaddrs", FNAME);
- return -1;
- }
-
-- ifr = ifc.ifc_req;
-- for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0 && num_device < MAX_DEVICE;
-- ifr++) {
-- if (!strcmp(ifr->ifr_name, "lo")) continue;
-- temp->hwaddr.len = gethwid(temp->hwaddr.data, sizeof(temp->hwaddr.data), ifr->ifr_name, &temp->hwaddr.type);
-+ for (i=0, ifa = ifap;
-+ (ifa != 0L) && ( i < MAX_DEVICE );
-+ i++, ifa = ifa->ifa_next
-+ )
-+ {
-+ if (!strcmp(ifa->ifa_name, "lo")) continue;
-+ temp->hwaddr.len = gethwid(temp->hwaddr.data, sizeof(temp->hwaddr.data), ifa->ifa_name, &temp->hwaddr.type);
- switch (temp->hwaddr.type) {
- case ARPHRD_ETHER:
- case ARPHRD_IEEE802:
- memcpy(&temp->iaid, temp->hwaddr.data, sizeof(temp->iaid));
- break;
- case ARPHRD_PPP:
-- temp->iaid = do_hash(ifr->ifr_name,sizeof(ifr->ifr_name))
-- + if_nametoindex(ifr->ifr_name);
-+ temp->iaid = do_hash(ifa->ifa_name,sizeof(ifa->ifa_name))
-+ + if_nametoindex(ifa->ifa_name);
- break;
- default:
- dprintf(LOG_INFO, "doesn't support %s address family %d",
-- ifr->ifr_name, temp->hwaddr.type);
-+ ifa->ifa_name, temp->hwaddr.type);
- continue;
- }
- dprintf(LOG_DEBUG, "%s"" create iaid %u for interface %s",
-- FNAME, temp->iaid, ifr->ifr_name);
-+ FNAME, temp->iaid, ifa->ifa_name);
- num_device++;
- temp++;
- }
-+ freeifaddrs(ifap);
- return num_device;
- }
---- dhcp-0.10/client6_parse.y.rh 2004-02-04 19:13:05.000000000 -0500
-+++ dhcp-0.10/client6_parse.y 2007-02-09 01:28:31.000000000 -0500
-@@ -38,7 +38,9 @@
-
- #include <arpa/inet.h>
-
--#include "queue.h"
-+#include <malloc.h>
-+#include <sys/queue.h>
-+
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -92,8 +94,8 @@
- %token INTERFACE IFNAME IPV6ADDR
- %token REQUEST SEND
- %token RAPID_COMMIT PREFIX_DELEGATION DNS_SERVERS
--%token INFO_ONLY TEMP_ADDR
--%token ADDRESS PREFIX IAID RENEW_TIME REBIND_TIME V_TIME P_TIME
-+%token INFO_ONLY TEMP_ADDR USE_RA_PREFIX
-+%token ADDRESS PREFIX IAID RENEW_TIME REBIND_TIME V_TIME P_TIME PREFIX_DELEGATION_INTERFACE
- %token NUMBER SLASH EOS BCL ECL STRING INFINITY
- %token COMMA OPTION
-
-@@ -234,6 +236,25 @@
-
- $$ = l;
- }
-+ | PREFIX_DELEGATION_INTERFACE STRING EOS
-+ {
-+ struct cf_list *l;
-+ char *pp = (char*)malloc(strlen($2)+1);
-+ strcpy(pp,$2);
-+ MAKE_CFLIST(l, DECL_PREFIX_DELEGATION_INTERFACE, pp, NULL );
-+
-+ $$ = l;
-+ }
-+
-+ | USE_RA_PREFIX EOS
-+ {
-+ struct cf_list *l;
-+
-+ MAKE_CFLIST(l, DECL_USE_RA_PREFIX, NULL, NULL);
-+ /* no value */
-+ $$ = l;
-+ }
-+
- ;
-
- dhcpoption:
-@@ -260,31 +281,36 @@
- MAKE_CFLIST(l, DHCPOPT_DNS, NULL, NULL);
- /* currently no value */
- $$ = l;
-- }
-+ }
- ;
-
- addrdecl:
--
-+
- addrparam addrvtime
- {
-- (struct dhcp6_addr *)$1->validlifetime = (u_int32_t)$2;
-+ struct dhcp6_addr *addr=(struct dhcp6_addr *)$1;
-+
-+ addr->validlifetime = (u_int32_t)$2;
- $$ = $1;
- }
- | addrparam addrptime
- {
-- (struct dhcp6_addr *)$1->preferlifetime = (u_int32_t)$2;
-+ struct dhcp6_addr *addr=(struct dhcp6_addr *)$1;
-+ addr->preferlifetime = (u_int32_t)$2;
- $$ = $1;
- }
- | addrparam addrvtime addrptime
- {
-- (struct dhcp6_addr *)$1->validlifetime = (u_int32_t)$2;
-- (struct dhcp6_addr *)$1->preferlifetime = (u_int32_t)$3;
-+ struct dhcp6_addr *addr=(struct dhcp6_addr *)$1;
-+ addr->validlifetime = (u_int32_t)$2;
-+ addr->preferlifetime = (u_int32_t)$3;
- $$ = $1;
- }
- | addrparam addrptime addrvtime
- {
-- (struct dhcp6_addr *)$1->validlifetime = (u_int32_t)$3;
-- (struct dhcp6_addr *)$1->preferlifetime = (u_int32_t)$2;
-+ struct dhcp6_addr *addr=(struct dhcp6_addr *)$1;
-+ addr->validlifetime = (u_int32_t)$3;
-+ addr->preferlifetime = (u_int32_t)$2;
- $$ = $1;
- }
- | addrparam
---- dhcp-0.10/client6_token.l.rh 2003-04-02 18:31:49.000000000 -0500
-+++ dhcp-0.10/client6_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -48,7 +48,8 @@
- #include <varargs.h>
- #endif
-
--#include "queue.h"
-+#include <sys/queue.h>
-+
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -60,6 +61,10 @@
- static int cpyy_first_time = 1;
- static int cpyyerrorcount = 0;
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-
- #ifndef NOCONFIG_DEBUG
- #define YYDEBUG 1
-@@ -143,6 +148,7 @@
- <S_CNF>prefer-life-time { DECHO; return (P_TIME); }
- <S_CNF>renew-time { DECHO; return (RENEW_TIME); }
- <S_CNF>rebind-time { DECHO; return (REBIND_TIME); }
-+<S_CNF>prefix-delegation-interface { DECHO; return (PREFIX_DELEGATION_INTERFACE); }
- /* request */
- <S_CNF>request { DECHO; return (REQUEST); }
-
-@@ -157,6 +163,7 @@
- /* generic options */
- <S_CNF>information-only { DECHO; return (INFO_ONLY); }
- <S_CNF>temp-address { DECHO; return (TEMP_ADDR); }
-+<S_CNF>use-ra-prefix { DECHO; return (USE_RA_PREFIX); }
- /* duration */
- <S_CNF>infinity { DECHO; return (INFINITY); }
-
---- dhcp-0.10/common.c.rh 2004-02-04 18:30:17.000000000 -0500
-+++ dhcp-0.10/common.c 2007-02-09 01:28:31.000000000 -0500
-@@ -64,6 +64,7 @@
- #include <netdb.h>
- #include <ifaddrs.h>
- #include <resolv.h>
-+#include <sys/queue.h>
-
- #ifdef HAVE_GETIFADDRS
- # ifdef HAVE_IFADDRS_H
-@@ -72,7 +73,6 @@
- # endif
- #endif
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -85,8 +85,8 @@
- struct dns_list dnslist;
- static struct host_conf *host_conflist;
- 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 *,
-+ssize_t gethwid __P((unsigned char *, int, const char *, u_int16_t *));
-+static int get_assigned_ipv6addrs __P((unsigned char *, unsigned char *,
- struct dhcp6_optinfo *));
- struct dhcp6_if *
- find_ifconfbyname(const char *ifname)
-@@ -215,6 +215,25 @@
- return;
- }
-
-+void
-+relayfree(head)
-+ struct relay_list *head;
-+{
-+ struct relay_listval *v;
-+
-+ while ((v = TAILQ_FIRST(head)) != NULL) {
-+ TAILQ_REMOVE(head, v, link);
-+ if (v->intf_id != NULL) {
-+ if (v->intf_id->intf_id != NULL)
-+ free(v->intf_id->intf_id);
-+ free (v->intf_id);
-+ }
-+ free(v);
-+ }
-+
-+ return;
-+}
-+
- int
- dhcp6_count_list(head)
- struct dhcp6_list *head;
-@@ -255,6 +274,8 @@
- return (lv);
- }
- break;
-+ default:
-+ break;
- }
- }
-
-@@ -539,17 +560,19 @@
- }
-
- char *
--addr2str(sa)
-+addr2str(sa, salen)
- struct sockaddr *sa;
-+ socklen_t salen;
- {
-- static char addrbuf[8][NI_MAXHOST];
-+ static char addrbuf[8][NI_MAXHOST+1];
- static int round = 0;
- char *cp;
-
- round = (round + 1) & 7;
- cp = addrbuf[round];
-+ memset(cp, '\0', NI_MAXHOST+1);
-
-- if (getnameinfo(sa, NI_MAXSERV, cp, NI_MAXHOST, NULL,
-+ if (getnameinfo(sa, salen, cp, NI_MAXHOST, NULL,
- 0, NI_NUMERICHOST) != 0)
- dprintf(LOG_ERR, "%s getnameinfo return error", FNAME);
-
-@@ -568,7 +591,7 @@
- sa6.sin6_addr = *in6;
- sa6.sin6_scope_id = scopeid;
-
-- return (addr2str((struct sockaddr *)&sa6));
-+ return (addr2str((struct sockaddr *)&sa6, sizeof (*in6)));
- }
-
- /* return IPv6 address scope type. caller assumes that smaller is narrower. */
-@@ -627,7 +650,7 @@
-
- if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
- warn("in6_matchflags: ioctl(SIOCGIFFLAGS, %s)",
-- addr2str(addr));
-+ addr2str(addr, sizeof (addr->sa_data)));
- close(s);
- return (-1);
- }
-@@ -642,8 +665,8 @@
- struct duid *duid)
- {
- const char *cp;
-- char *bp, *idbuf = NULL;
-- int duidlen, slen;
-+ unsigned char *bp, *idbuf = NULL;
-+ u_int8_t duidlen, slen;
- unsigned int x;
-
- /* calculate DUID len */
-@@ -655,12 +678,8 @@
- if ((slen % 3) != 0)
- goto bad;
- duidlen += (slen / 3);
-- if (duidlen > 256) {
-- dprintf(LOG_ERR, "%s" "too long DUID (%d)", FNAME, duidlen);
-- return (-1);
-- }
-
-- if ((idbuf = (char *)malloc(duidlen)) == NULL) {
-+ if ((idbuf = (unsigned char *)malloc(duidlen)) == NULL) {
- dprintf(LOG_ERR, "%s" "memory allocation failed", FNAME);
- return (-1);
- }
-@@ -697,7 +716,7 @@
- FILE *fp = NULL;
- u_int16_t len = 0, hwtype;
- struct dhcp6_duid_type1 *dp; /* we only support the type1 DUID */
-- char tmpbuf[256]; /* DUID should be no more than 256 bytes */
-+ unsigned char tmpbuf[256]; /* DUID should be no more than 256 bytes */
-
- if ((fp = fopen(idfile, "r")) == NULL && errno != ENOENT)
- dprintf(LOG_NOTICE, "%s" "failed to open DUID file: %s",
-@@ -722,7 +741,7 @@
-
- memset(duid, 0, sizeof(*duid));
- duid->duid_len = len;
-- if ((duid->duid_id = (char *)malloc(len)) == NULL) {
-+ if ((duid->duid_id = (unsigned char *)malloc(len)) == NULL) {
- dprintf(LOG_ERR, "%s" "failed to allocate memory", FNAME);
- goto fail;
- }
-@@ -787,7 +806,7 @@
-
- ssize_t
- gethwid(buf, len, ifname, hwtypep)
-- char *buf;
-+ unsigned char *buf;
- int len;
- const char *ifname;
- u_int16_t *hwtypep;
-@@ -796,8 +815,11 @@
- ssize_t l;
- struct ifreq if_hwaddr;
-
-- if ((skfd = socket(AF_INET6, SOCK_DGRAM, 0 )) < 0)
-+ if ((skfd = socket(AF_INET6, SOCK_DGRAM, 0 )) < 0) {
-+ close(skfd);
- return -1;
-+ }
-+ close(skfd);
-
- strcpy(if_hwaddr.ifr_name, ifname);
- if (ioctl(skfd, SIOCGIFHWADDR, &if_hwaddr) < 0)
-@@ -819,8 +841,8 @@
- return -1; /* XXX */
- }
- memcpy(buf, if_hwaddr.ifr_hwaddr.sa_data, l);
-- dprintf(LOG_DEBUG, "%s" "found an interface %s harware %x",
-- FNAME, ifname, buf);
-+ dprintf(LOG_DEBUG, "%s" "found an interface %s harware %.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
-+ FNAME, ifname, *buf, *(buf+1), *(buf+2), *(buf+3), *(buf+4), *(buf+5));
- return l;
- }
-
-@@ -837,6 +859,7 @@
- TAILQ_INIT(&optinfo->reqopt_list);
- TAILQ_INIT(&optinfo->stcode_list);
- TAILQ_INIT(&optinfo->dns_list.addrlist);
-+ TAILQ_INIT(&optinfo->relay_list);
- optinfo->dns_list.domainlist = NULL;
- }
-
-@@ -852,6 +875,7 @@
- dhcp6_clear_list(&optinfo->reqopt_list);
- dhcp6_clear_list(&optinfo->stcode_list);
- dhcp6_clear_list(&optinfo->dns_list.addrlist);
-+ relayfree(&optinfo->relay_list);
- if (dhcp6_mode == DHCP6_MODE_CLIENT) {
- for (dlist = optinfo->dns_list.domainlist; dlist; dlist = dlist_next) {
- dlist_next = dlist->next;
-@@ -898,7 +922,7 @@
- {
- struct dhcp6opt *np, opth;
- int i, opt, optlen, reqopts, num;
-- char *cp, *val;
-+ unsigned char *cp, *val;
- u_int16_t val16;
-
- for (; p + 1 <= ep; p = np) {
-@@ -912,7 +936,7 @@
- optlen = ntohs(opth.dh6opt_len);
- opt = ntohs(opth.dh6opt_type);
-
-- cp = (char *)(p + 1);
-+ cp = (unsigned char *)(p + 1);
- np = (struct dhcp6opt *)(cp + optlen);
-
- dprintf(LOG_DEBUG, "%s" "get DHCP option %s, len %d",
-@@ -1021,6 +1045,11 @@
- goto malformed;
- optinfo->flags |= DHCIFF_RAPID_COMMIT;
- break;
-+ case DH6OPT_REQUEST_PREFIX:
-+ if (optlen != 0)
-+ goto malformed;
-+ optinfo->flags |= DHCIFF_REQUEST_PREFIX;
-+ break;
- case DH6OPT_UNICAST:
- if (optlen != sizeof(struct in6_addr)
- && dhcp6_mode != DHCP6_MODE_CLIENT)
-@@ -1104,7 +1133,7 @@
- else {
- val += n;
- dprintf(LOG_DEBUG, "expand domain name %s, size %d",
-- dname->name, strlen(dname->name));
-+ dname->name, (int) strlen(dname->name));
- }
- dname->next = NULL;
- if (optinfo->dns_list.domainlist == NULL) {
-@@ -1141,10 +1170,10 @@
-
- static int
- get_assigned_ipv6addrs(p, ep, optinfo)
-- char *p, *ep;
-+ unsigned char *p, *ep;
- struct dhcp6_optinfo *optinfo;
- {
-- char *np, *cp;
-+ unsigned char *np, *cp;
- struct dhcp6opt opth;
- struct dhcp6_addr_info ai;
- struct dhcp6_prefix_info pi;
-@@ -1209,6 +1238,12 @@
- "(%d)", addr6.preferlifetime, addr6.validlifetime);
- goto malformed;
- }
-+ if ( optlen & 1 )
-+ {
-+ addr6.plen = *(p + sizeof(ai));
-+ optlen -= 1;
-+ p++;
-+ }
- if (optlen == sizeof(ai) - sizeof(u_int32_t)) {
- addr6.status_code = DH6OPT_STCODE_UNDEFINE;
- break;
-@@ -1337,7 +1372,7 @@
- struct dhcp6opt *p = bp, opth;
- struct dhcp6_listval *stcode;
- int len = 0, optlen = 0;
-- char *tmpbuf = NULL;
-+ unsigned char *tmpbuf = NULL;
-
- if (optinfo->clientID.duid_len) {
- COPY_OPTION(DH6OPT_CLIENTID, optinfo->clientID.duid_len,
-@@ -1352,7 +1387,10 @@
- COPY_OPTION(DH6OPT_ELAPSED_TIME, 2, &optinfo->elapsed_time, p);
-
- if (optinfo->flags & DHCIFF_RAPID_COMMIT)
-- COPY_OPTION(DH6OPT_RAPID_COMMIT, 0, NULL, p);
-+ COPY_OPTION(DH6OPT_RAPID_COMMIT, 0, "", p);
-+
-+ if (optinfo->flags & DHCIFF_REQUEST_PREFIX)
-+ COPY_OPTION(DH6OPT_REQUEST_PREFIX, 0, "", p);
-
- if ((dhcp6_mode == DHCP6_MODE_SERVER) && (optinfo->flags & DHCIFF_UNICAST)) {
- if (!IN6_IS_ADDR_UNSPECIFIED(&optinfo->server_addr)) {
-@@ -1362,7 +1400,7 @@
- }
- switch(optinfo->type) {
- int buflen;
-- char *tp;
-+ unsigned char *tp;
- u_int32_t iaid;
- struct dhcp6_iaid_info opt_iana;
- struct dhcp6_iaid_info opt_iapd;
-@@ -1406,14 +1444,17 @@
- if (!TAILQ_EMPTY(&optinfo->addr_list)) {
- for (dp = TAILQ_FIRST(&optinfo->addr_list); dp;
- dp = TAILQ_NEXT(dp, link)) {
-- int iaddr_len = 0;
-+ int iaddr_len =
-+ (dp->val_dhcp6addr.plen &&
-+ ( optinfo->flags & DHCIFF_RESPOND_PREFIX )
-+ ) ? 1 : 0;
- memset(&ai, 0, sizeof(ai));
- ai.dh6_ai_type = htons(DH6OPT_IADDR);
- if (dp->val_dhcp6addr.status_code != DH6OPT_STCODE_UNDEFINE)
-- iaddr_len = sizeof(ai) - sizeof(u_int32_t)
-+ iaddr_len += sizeof(ai) - sizeof(u_int32_t)
- + sizeof(status);
- else
-- iaddr_len = sizeof(ai) - sizeof(u_int32_t);
-+ iaddr_len += sizeof(ai) - sizeof(u_int32_t);
- ai.dh6_ai_len = htons(iaddr_len);
- ai.preferlifetime = htonl(dp->val_dhcp6addr.preferlifetime);
- ai.validlifetime = htonl(dp->val_dhcp6addr.validlifetime);
-@@ -1421,11 +1462,22 @@
- sizeof(ai.addr));
- memcpy(tp, &ai, sizeof(ai));
- tp += sizeof(ai);
-+ if( dp->val_dhcp6addr.plen &&
-+ ( optinfo->flags & DHCIFF_RESPOND_PREFIX )
-+ )
-+ {
-+ *tp = dp->val_dhcp6addr.plen;
-+ optlen += 1;
-+ ++tp;
-+ }
- dprintf(LOG_DEBUG, "set IADDR address option len %d: "
-- "%s preferlifetime %d validlifetime %d",
-+ "%s preferlifetime %d validlifetime %d prefix:%d",
- iaddr_len, in6addr2str(&ai.addr, 0),
- ntohl(ai.preferlifetime),
-- ntohl(ai.validlifetime));
-+ ntohl(ai.validlifetime),
-+ ( optinfo->flags & DHCIFF_RESPOND_PREFIX )
-+ ? dp->val_dhcp6addr.plen : 0
-+ );
- /* set up address status code if any */
- if (dp->val_dhcp6addr.status_code != DH6OPT_STCODE_UNDEFINE) {
- status.dh6_status_type = htons(DH6OPT_STATUS_CODE);
-@@ -1438,6 +1490,8 @@
- dhcp6_stcodestr(ntohs(status.dh6_status_code)));
- optlen += sizeof(status);
- tp += sizeof(status);
-+ dprintf(LOG_DEBUG, "set IADDR status len %d optlen: %d",
-+ (int) sizeof(status), optlen);
- /* XXX: copy status message if any */
- }
- }
-@@ -1595,8 +1649,8 @@
- }
- if (optinfo->dns_list.domainlist != NULL) {
- struct domain_list *dlist;
-- u_char *dst;
-- size_t dstsiz;
-+ unsigned char *dst;
-+// size_t dstsiz;
- optlen = 0;
- tmpbuf = NULL;
- if ((tmpbuf = malloc(MAXDNAME * MAXDN)) == NULL) {
-@@ -1833,6 +1887,10 @@
- return "rapid commit";
- case DH6OPT_DNS_RESOLVERS:
- return "DNS_RESOLVERS";
-+ case DH6OPT_RELAY_MSG:
-+ return "relay message";
-+ case DH6OPT_INTERFACE_ID:
-+ return "interface identifier";
- default:
- sprintf(genstr, "opt_%d", type);
- return (genstr);
---- dhcp-0.10/common.h.rh 2003-04-30 15:04:07.000000000 -0400
-+++ dhcp-0.10/common.h 2007-02-09 01:28:31.000000000 -0500
-@@ -67,7 +67,7 @@
- extern long random_between __P((long, long));
- extern int prefix6_mask __P((struct in6_addr *, int));
- extern int sa6_plen2mask __P((struct sockaddr_in6 *, int));
--extern char *addr2str __P((struct sockaddr *));
-+extern char *addr2str __P((struct sockaddr *, socklen_t));
- extern char *in6addr2str __P((struct in6_addr *, int));
- extern const char *getdev __P((struct sockaddr_in6 *));
- extern int in6_addrscopebyif __P((struct in6_addr *, char *));
-@@ -98,6 +98,7 @@
- extern int duidcpy __P((struct duid *, const struct duid *));
- extern int duidcmp __P((const struct duid *, const struct duid *));
- extern void duidfree __P((struct duid *));
-+extern void relayfree __P((struct relay_list *));
- extern void ifinit __P((const char *));
- extern int configure_duid __P((const char *, struct duid *));
- extern struct dhcp6_if *find_ifconfbyname __P((const char *));
---- dhcp-0.10/config.c.rh 2003-04-11 20:25:32.000000000 -0400
-+++ dhcp-0.10/config.c 2007-02-09 01:28:31.000000000 -0500
-@@ -41,8 +41,8 @@
- #include <stdio.h>
- #include <string.h>
- #include <ifaddrs.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -57,9 +57,11 @@
-
- static int add_options __P((int, struct dhcp6_ifconf *, struct cf_list *));
- static int add_address __P((struct dhcp6_list *, struct dhcp6_addr *));
-+static int add_option __P((struct dhcp6_option_list *, struct cf_list *));
-+static int clear_option_list __P((struct dhcp6_option_list *));
-+
- static void clear_ifconf __P((struct dhcp6_ifconf *));
- static void clear_hostconf __P((struct host_conf *));
--static void clear_options __P((struct dhcp6_optconf *));
-
- int
- configure_interface(const struct cf_namelist *iflist)
-@@ -88,6 +90,7 @@
- ifc->server_pref = DH6OPT_PREF_UNDEF;
- TAILQ_INIT(&ifc->reqopt_list);
- TAILQ_INIT(&ifc->addr_list);
-+ TAILQ_INIT(&ifc->option_list);
-
- for (cfl = ifp->params; cfl; cfl = cfl->next) {
- switch(cfl->type) {
-@@ -185,6 +188,16 @@
- break;
- case DECL_PREFIX_INFO:
- break;
-+ case DECL_PREFIX_DELEGATION_INTERFACE:
-+ if (add_option(&ifc->option_list, cfl)){
-+ dprintf(LOG_ERR, "%s failed to configure prefix-delegation-interface for %s",
-+ FNAME, ifc->ifname);
-+ goto bad;
-+ }
-+ break;
-+ case DECL_USE_RA_PREFIX:
-+ ifc->use_ra_prefix = 1;
-+ break;
- default:
- dprintf(LOG_ERR, "%s" "%s:%d "
- "invalid interface configuration",
-@@ -450,11 +463,6 @@
-
- ifp->allow_flags = ifc->allow_flags;
-
-- clear_options(ifp->send_options);
--
-- ifp->send_options = ifc->send_options;
-- ifc->send_options = NULL;
--
- dhcp6_clear_list(&ifp->reqopt_list);
- ifp->reqopt_list = ifc->reqopt_list;
- TAILQ_INIT(&ifc->reqopt_list);
-@@ -467,8 +475,14 @@
- ifp->prefix_list = ifc->prefix_list;
- TAILQ_INIT(&ifc->prefix_list);
-
-+ clear_option_list(&ifp->option_list);
-+ ifp->option_list = ifc->option_list;
-+ TAILQ_INIT(&ifc->option_list);
-+
- ifp->server_pref = ifc->server_pref;
-
-+ ifp->use_ra_prefix = ifc->use_ra_prefix;
-+
- memcpy(&ifp->iaidinfo, &ifc->iaidinfo, sizeof(ifp->iaidinfo));
- }
- }
-@@ -492,7 +506,7 @@
- ifc_next = ifc->next;
-
- free(ifc->ifname);
-- clear_options(ifc->send_options);
-+
- dhcp6_clear_list(&ifc->reqopt_list);
-
- free(ifc);
-@@ -519,19 +533,6 @@
- }
- }
-
--static void
--clear_options(struct dhcp6_optconf *opt0)
--{
-- struct dhcp6_optconf *opt, *opt_next;
--
-- for (opt = opt0; opt; opt = opt_next) {
-- opt_next = opt->next;
--
-- free(opt->val);
-- free(opt);
-- }
--}
--
- static int
- add_options(int opcode, struct dhcp6_ifconf *ifc,
- struct cf_list *cfl0)
-@@ -647,3 +648,54 @@
- return (0);
- }
-
-+int add_option (struct dhcp6_option_list *opts, struct cf_list *cfl)
-+{
-+ struct dhcp6_option *opt ;
-+
-+ if ( get_if_option( opts, cfl->type ) != 0L )
-+ return (-1);
-+
-+ switch (cfl->type)
-+ {
-+ case DECL_PREFIX_DELEGATION_INTERFACE:
-+ opt = (struct dhcp6_option*)malloc(sizeof(struct dhcp6_option));
-+ opt->type = cfl->type;
-+ if ( cfl->ptr != 0L )
-+ {
-+ opt->len = strlen((char*)(cfl->ptr))+1;
-+ opt->val = malloc(opt->len);
-+ memcpy(opt->val, cfl->ptr, opt->len);
-+ }else
-+ {
-+ opt->val = malloc(1);
-+ opt->len = 0;
-+ *((char*)(opt->val))='\0';
-+ }
-+ TAILQ_INSERT_TAIL(opts, opt, link);
-+ break;
-+ default:
-+ break;
-+ }
-+ return (0);
-+}
-+
-+int clear_option_list (struct dhcp6_option_list *opts)
-+{
-+ struct dhcp6_option *opt;
-+ while ((opt = TAILQ_FIRST(opts)) != NULL) {
-+ TAILQ_REMOVE(opts, opt, link);
-+ free(opt);
-+ }
-+ return (0);
-+}
-+
-+void *get_if_option( struct dhcp6_option_list *opts, int type )
-+{
-+ struct dhcp6_option *opt;
-+ TAILQ_FOREACH( opt, opts, link)
-+ {
-+ if ( opt->type == type )
-+ return opt->val;
-+ }
-+ return 0L;
-+}
---- dhcp-0.10/config.h.rh 2004-03-04 18:31:24.000000000 -0500
-+++ dhcp-0.10/config.h 2007-02-09 01:28:31.000000000 -0500
-@@ -51,6 +51,15 @@
- int flags;
- };
-
-+struct dhcp6_option {
-+ TAILQ_ENTRY(dhcp6_option) link;
-+ int type;
-+ int len;
-+ void *val;
-+};
-+
-+TAILQ_HEAD(dhcp6_option_list, dhcp6_option);
-+
- /* per-interface information */
- struct dhcp6_if {
- struct dhcp6_if *next;
-@@ -87,17 +96,21 @@
- #define DHCIFF_TEMP_ADDRS 0x4
- #define DHCIFF_PREFIX_DELEGATION 0x8
- #define DHCIFF_UNICAST 0x10
--
-+#define DHCIFF_REQUEST_PREFIX 0x20
-+#define DHCIFF_RESPOND_PREFIX 0x40
-
- struct in6_addr linklocal;
- int server_pref; /* server preference (server only) */
-- struct dhcp6_optconf *send_options;
-+
-+ int use_ra_prefix;
-+
- struct dhcp6_list reqopt_list;
- /* request specific addresses list from client */
- struct dhcp6_list addr_list;
- struct dhcp6_list prefix_list;
-+ struct dhcp6_option_list option_list;
- struct dhcp6_serverinfo *current_server;
-- struct dhcp6_serverinfo *servers;
-+ struct dhcp6_serverinfo *servers;
- };
-
- struct dhcp6_event {
-@@ -160,12 +173,14 @@
-
- int server_pref; /* server preference (server only) */
- struct dhcp6_iaid_info iaidinfo;
-- struct dhcp6_optconf *send_options;
-- struct dhcp6_optconf *allow_options;
-
- struct dhcp6_list prefix_list;
- struct dhcp6_list addr_list;
- struct dhcp6_list reqopt_list;
-+
-+ struct dhcp6_option_list option_list;
-+
-+ int use_ra_prefix;
- };
-
- struct prefix_ifconf {
-@@ -199,14 +214,6 @@
- struct dhcp6_list addr_binding_list;
- };
-
--/* DHCP option information */
--struct dhcp6_optconf {
-- struct dhcp6_optconf *next;
-- int type;
-- int len;
-- char *val;
--};
--
- /* structures and definitions used in the config file parser */
- struct cf_namelist {
- struct cf_namelist *next;
-@@ -277,10 +284,10 @@
-
- enum {DECL_SEND, DECL_ALLOW, DECL_INFO_ONLY, DECL_TEMP_ADDR, DECL_REQUEST, DECL_DUID,
- DECL_PREFIX, DECL_PREFERENCE, DECL_IAID, DECL_RENEWTIME, DECL_REBINDTIME,
-- DECL_ADDRESS, DECL_LINKLOCAL, DECL_PREFIX_INFO, DECL_PREFIX_REQ,
-+ DECL_ADDRESS, DECL_LINKLOCAL, DECL_PREFIX_INFO, DECL_PREFIX_REQ, DECL_PREFIX_DELEGATION_INTERFACE,
- DHCPOPT_PREFIX_DELEGATION, IFPARAM_SLA_ID, IFPARAM_SLA_LEN,
- DHCPOPT_RAPID_COMMIT,
-- DHCPOPT_DNS, ADDRESS_LIST_ENT };
-+ DHCPOPT_DNS, ADDRESS_LIST_ENT, DECL_USE_RA_PREFIX };
-
- typedef enum {DHCP6_MODE_SERVER, DHCP6_MODE_CLIENT, DHCP6_MODE_RELAY }
- dhcp6_mode_t;
-@@ -303,3 +310,5 @@
- extern int cfparse (const char *);
- extern int resolv_parse (struct dns_list *);
- extern int get_if_rainfo(struct dhcp6_if *ifp);
-+
-+extern void *get_if_option( struct dhcp6_option_list *, int);
---- dhcp-0.10/configure.in.rh 2003-04-11 20:25:33.000000000 -0400
-+++ dhcp-0.10/configure.in 2007-02-09 01:28:31.000000000 -0500
-@@ -66,14 +66,8 @@
- ;;
- *) ;;
- esac
--
--AC_REPLACE_FUNCS(getaddrinfo)
--AC_REPLACE_FUNCS(getnameinfo)
--AC_REPLACE_FUNCS(ifaddrs)
--AC_CHECK_FUNCS(if_nametoindex)
--AC_REPLACE_FUNCS(strlcpy strlcat)
--
- dnl Checks for header files.
-+AC_REPLACE_FUNCS(strlcpy strlcat)
- AC_HEADER_STDC
- AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h syslog.h unistd.h ifaddrs.h)
- AC_MSG_CHECKING(for socklen_t)
-@@ -206,3 +200,4 @@
- AC_CHECK_HEADERS(stdarg.h)
-
- AC_OUTPUT(Makefile)
-+AC_OUTPUT(Makefile.inc)
---- dhcp-0.10/dad_token.l.rh 2003-05-29 18:23:28.000000000 -0400
-+++ dhcp-0.10/dad_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -34,19 +34,25 @@
- #include <stdio.h>
- #include <string.h>
- #include <sys/types.h>
-+#include <unistd.h>
- #include <netinet/in.h>
- #include <net/if.h>
--
-+#include <arpa/inet.h>
- #include <errno.h>
- #include <syslog.h>
- #include <string.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
- #include "lease.h"
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-+
- #define YYABORT(msg) dprintf(LOG_ERR, msg " %s lineno %d.", \
- ifyytext, num_lines)
-
-@@ -194,5 +200,5 @@
- file, strerror(errno));
- return (-1);
- }
-- yylex();
-+ return yylex();
- }
---- dhcp-0.10/dhcp6.h.rh 2004-03-04 18:31:24.000000000 -0500
-+++ dhcp-0.10/dhcp6.h 2007-02-09 01:28:31.000000000 -0500
-@@ -123,7 +123,12 @@
-
- struct duid {
- u_int8_t duid_len; /* length */
-- char *duid_id; /* variable length ID value (must be opaque) */
-+ unsigned char *duid_id; /* variable length ID value (must be opaque) */
-+};
-+
-+struct intf_id {
-+ u_int16_t intf_len; /* length */
-+ char *intf_id; /* variable length ID value (must be opaque) */
- };
-
- /* iaid info for the IA_NA */
-@@ -188,6 +193,28 @@
- struct domain_list *domainlist;
- };
-
-+/* DHCP6 relay agent base packet format */
-+struct dhcp6_relay {
-+ u_int8_t dh6_msg_type;
-+ u_int8_t dh6_hop_count;
-+ struct in6_addr link_addr;
-+ struct in6_addr peer_addr;
-+ /* options follow */
-+} __attribute__ ((__packed__));
-+
-+
-+struct relay_listval {
-+ TAILQ_ENTRY(relay_listval) link;
-+
-+ struct dhcp6_relay relay;
-+ struct intf_id *intf_id;
-+
-+ /* pointer to the Relay Message option in the RELAY-REPL */
-+ struct dhcp6opt *option;
-+};
-+
-+TAILQ_HEAD (relay_list, relay_listval);
-+
- struct dhcp6_optinfo {
- struct duid clientID; /* DUID */
- struct duid serverID; /* DUID */
-@@ -201,6 +228,8 @@
- struct dhcp6_list reqopt_list; /* options in option request */
- struct dhcp6_list stcode_list; /* status code */
- struct dns_list dns_list; /* DNS server list */
-+ struct relay_list relay_list; /* list of the relays the message passed
-+ through on its way to the server */
- };
-
- /* DHCP6 base packet format */
-@@ -226,8 +255,7 @@
- # define DH6OPT_PREF_UNDEF 0
- # define DH6OPT_PREF_MAX 255
- #define DH6OPT_ELAPSED_TIME 8
--#define DH6OPT_CLIENT_MSG 9
--#define DH6OPT_SERVER_MSG 10
-+#define DH6OPT_RELAY_MSG 9
- #define DH6OPT_AUTH 11
- #define DH6OPT_UNICAST 12
- #define DH6OPT_STATUS_CODE 13
-@@ -273,6 +301,7 @@
- */
- #define DH6OPT_IA_PD CONF_DH6OPT_IA_PD
- #define DH6OPT_IAPREFIX CONF_DH6OPT_IAPREFIX
-+#define DH6OPT_REQUEST_PREFIX 28
-
- struct dhcp6opt {
- u_int16_t dh6opt_type;
---- dhcp-0.10/dhcp6c.c.rh 2004-03-04 18:31:24.000000000 -0500
-+++ dhcp-0.10/dhcp6c.c 2007-02-09 01:28:31.000000000 -0500
-@@ -65,8 +65,9 @@
- #include <string.h>
- #include <err.h>
- #include <ifaddrs.h>
-+#include <sys/ioctl.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -93,7 +94,7 @@
- static struct iaid_table iaidtab[100];
- static u_int8_t client6_request_flag = 0;
- static char leasename[100];
--static int rapatch = 0;
-+//static int rapatch = 0;
-
- #define CLIENT6_RELEASE_ADDR 0x1
- #define CLIENT6_CONFIRM_ADDR 0x2
-@@ -102,9 +103,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;
-@@ -113,6 +114,7 @@
- extern struct dhcp6_iaidaddr client6_iaidaddr;
- FILE *dhcp6_resolv_file;
- static const struct sockaddr_in6 *sa6_allagent;
-+static socklen_t sa6_alen;
- static struct duid client_duid;
-
- static void usage __P((void));
-@@ -146,14 +148,15 @@
- extern int client6_ifaddrconf __P((ifaddrconf_cmd_t, struct dhcp6_addr *));
- extern struct dhcp6_timer *syncfile_timo __P((void *));
- extern int radvd_parse (struct dhcp6_iaidaddr *, int);
-+extern int dad_parse(const char *file);
-
- #define DHCP6C_CONF "/etc/dhcp6c.conf"
- #define DHCP6C_PIDFILE "/var/run/dhcpv6/dhcp6c.pid"
- #define DUID_FILE "/var/lib/dhcpv6/dhcp6c_duid"
-
- static int pid;
--static char cmdbuf[1024];
--static char oldlink[256];
-+//static char cmdbuf[1024];
-+//static char oldlink[256];
- char client6_lease_temp[256];
- struct dhcp6_list request_list;
-
-@@ -290,6 +293,7 @@
- }
-
- ifinit(device);
-+ setup_interface(device);
-
- if ((cfparse(conffile)) != 0) {
- dprintf(LOG_ERR, "%s" "failed to parse configuration file",
-@@ -322,9 +326,11 @@
- int error, on = 1;
- struct dhcp6_if *ifp;
- int ifidx;
-- struct ifaddrs *ifa, *ifap;
-+// struct ifaddrs *ifa, *ifap;
- char linklocal[64];
- struct in6_addr lladdr;
-+ time_t retry, now;
-+ int bound;
-
- ifidx = if_nametoindex(device);
- if (ifidx == 0) {
-@@ -379,12 +385,34 @@
- }
- #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);
-- if (bind(insock, res->ai_addr, res->ai_addrlen) < 0) {
-- dprintf(LOG_ERR, "%s" "bind(inbound): %s",
-- FNAME, strerror(errno));
-- exit(1);
-+ dprintf(LOG_DEBUG, "res addr is %s/%d", addr2str(res->ai_addr, res->ai_addrlen), res->ai_addrlen);
-+
-+ /*
-+ * If the interface has JUST been brought up, the kernel may not have
-+ * enough time to allow the bind to the linklocal address - it will
-+ * then return EADDRNOTAVAIL. The bind will succeed if we try again.
-+ */
-+ retry = now = time(0);
-+ bound = 0;
-+ do {
-+ if (bind(insock, res->ai_addr, res->ai_addrlen) < 0) {
-+ bound = -errno;
-+ retry = time(0);
-+ if ((bound != -EADDRNOTAVAIL) || ((retry - now) > 5))
-+ break;
-+ struct timespec tv = { 0, 200000000 };
-+ nanosleep(&tv, 0);
-+ } else {
-+ bound = 1;
-+ break;
-+ }
-+ } while ((retry - now) < 5);
-+
-+ if (bound < 0) {
-+ dprintf(LOG_ERR, "%s" "bind(inbound): %s", FNAME, strerror(-bound));
-+ exit(bound);
- }
-+
- freeaddrinfo(res);
-
- hints.ai_flags = 0;
-@@ -414,12 +442,6 @@
- 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;
-@@ -432,6 +454,7 @@
- }
- memcpy(&sa6_allagent_storage, res->ai_addr, res->ai_addrlen);
- sa6_allagent = (const struct sockaddr_in6 *)&sa6_allagent_storage;
-+ sa6_alen = res->ai_addrlen;
- freeaddrinfo(res);
-
- /* client interface configuration */
-@@ -501,7 +524,7 @@
- if (client6_lease_file == NULL)
- exit(1);
- if (!TAILQ_EMPTY(&client6_iaidaddr.lease_list)) {
-- struct dhcp6_lease *cl;
-+// struct dhcp6_lease *cl;
- struct dhcp6_listval *lv;
- if (!(client6_request_flag & CLIENT6_REQUEST_ADDR) &&
- !(client6_request_flag & CLIENT6_RELEASE_ADDR))
-@@ -525,7 +548,6 @@
- dprintf(LOG_INFO, "no ipv6 addresses are leased by client");
- exit(0);
- }
-- setup_interface(ifp->ifname);
- ifp->link_flag |= IFF_RUNNING;
-
- /* get addrconf prefix from kernel */
-@@ -600,7 +622,7 @@
- static void
- process_signals()
- {
-- struct stat buf;
-+// struct stat buf;
- if ((sig_flags & SIGF_TERM)) {
- dprintf(LOG_INFO, FNAME "exiting");
- free_resources(dhcp6_if);
-@@ -658,7 +680,7 @@
- struct dhcp6_event *ev = (struct dhcp6_event *)arg;
- struct dhcp6_if *ifp;
- struct timeval now;
-- struct ra_info *rainfo;
-+// struct ra_info *rainfo;
-
- ifp = ev->ifp;
- ev->timeouts++;
-@@ -812,6 +834,7 @@
- struct dhcp6_optinfo optinfo;
- ssize_t optlen, len;
- struct timeval duration, now;
-+ socklen_t salen;
-
- ifp = ev->ifp;
-
-@@ -950,8 +973,14 @@
- if (dhcp6_copy_list(&optinfo.addr_list, &request_list))
- goto end;
- }
-+ /* support for server assigned prefix */
-+ if ( ! ifp->use_ra_prefix )
-+ optinfo.flags |= DHCIFF_REQUEST_PREFIX;
- break;
- case DHCP6S_REQUEST:
-+ /* support for server assigned prefix */
-+ if ( ! ifp->use_ra_prefix )
-+ optinfo.flags |= DHCIFF_REQUEST_PREFIX;
- if (!(ifp->send_flags & DHCIFF_INFO_ONLY)) {
- memcpy(&optinfo.iaidinfo, &client6_iaidaddr.client6_info.iaidinfo,
- sizeof(optinfo.iaidinfo));
-@@ -1035,15 +1064,17 @@
- exit(1);
- }
- memcpy(&dst, res->ai_addr, res->ai_addrlen);
-+ salen = res->ai_addrlen;
- break;
- }
- default:
- dst = *sa6_allagent;
-+ salen = sa6_alen;
- break;
- }
- dst.sin6_scope_id = ifp->linkid;
- dprintf(LOG_DEBUG, "send dst if %s addr is %s scope id is %d",
-- ifp->ifname, addr2str((struct sockaddr *)&dst), ifp->linkid);
-+ ifp->ifname, addr2str((struct sockaddr *)&dst, salen), ifp->linkid);
- if (sendto(ifp->outsock, buf, len, MSG_DONTROUTE, (struct sockaddr *)&dst,
- sizeof(dst)) == -1) {
- dprintf(LOG_ERR, FNAME "transmit failed: %s", strerror(errno));
-@@ -1052,7 +1083,7 @@
-
- dprintf(LOG_DEBUG, "%s" "send %s to %s", FNAME,
- dhcp6msgstr(dh6->dh6_msgtype),
-- addr2str((struct sockaddr *)&dst));
-+ addr2str((struct sockaddr *)&dst, salen));
-
- end:
- dhcp6_clear_options(&optinfo);
-@@ -1114,7 +1145,7 @@
-
- dprintf(LOG_DEBUG, "%s" "receive %s from %s scope id %d %s", FNAME,
- dhcp6msgstr(dh6->dh6_msgtype),
-- addr2str((struct sockaddr *)&from),
-+ addr2str((struct sockaddr *)&from, sizeof (((struct sockaddr *)&from)->sa_data)),
- ((struct sockaddr_in6 *)&from)->sin6_scope_id,
- ifp->ifname);
-
-@@ -1139,7 +1170,7 @@
- default:
- dprintf(LOG_INFO, "%s" "received an unexpected message (%s) "
- "from %s", FNAME, dhcp6msgstr(dh6->dh6_msgtype),
-- addr2str((struct sockaddr *)&from));
-+ addr2str((struct sockaddr *)&from, sizeof(((struct sockaddr *)&from)->sa_data)));
- break;
- }
-
-@@ -1714,10 +1745,10 @@
- *check_dad_timo(void *arg)
- {
- struct dhcp6_if *ifp = (struct dhcp6_if *)arg;
-- struct dhcp6_listval *lv;
-- struct dhcp6_lease *cl, *cl_next;
-- struct timeval timo;
-- double d;
-+// struct dhcp6_listval *lv;
-+// struct dhcp6_lease *cl, *cl_next;
-+// struct timeval timo;
-+// double d;
- int newstate;
- if (client6_iaidaddr.client6_info.type == IAPD)
- goto end;
-@@ -1793,30 +1824,51 @@
- setup_interface(char *ifname)
- {
- struct ifreq ifr;
-+ int retries = 0;
- /* check the 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;
-+
-+ 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.");
-+ exit(1);
-+ }
-+
-+ memset(&ifr, '\0', sizeof(struct ifreq));
-+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
-+ ifr.ifr_flags |= (IFF_UP | IFF_RUNNING) ;
- if (ioctl(nlsock, SIOCSIFFLAGS, &ifr) < 0) {
- dprintf(LOG_ERR, "ioctl SIOCSIFFLAGS failed");
- exit(1);
- }
-+
-+ /*
-+ * give kernel time to assign link local address and to find/respond
-+ * to IPv6 routers...
-+ */
-+ sleep(2);
-+
-+ 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);
- }
- }
-- 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;
-- }
-+
- return;
- }
-
---- dhcp-0.10/dhcp6relay.c.rh 2003-02-27 14:43:08.000000000 -0500
-+++ dhcp-0.10/dhcp6relay.c 2007-02-09 01:28:31.000000000 -0500
-@@ -53,8 +53,8 @@
- #include <errno.h>
- #include <err.h>
- #include <string.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "common.h"
-
-@@ -496,7 +496,7 @@
- }
-
- dprintf(LOG_DEBUG, "relay6_recv: from %s, size %d",
-- addr2str((struct sockaddr *)&from), len);
-+ addr2str((struct sockaddr *)&from, sizeof(from.data)), len);
-
- /* get optional information as ancillary data (if available) */
- for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rmh); cm;
-@@ -705,7 +705,7 @@
- if ((sdev = getdev(&sa6_relay)) == NULL) {
- dprintf(LOG_WARNING,
- "relay6_react_advert: can't detect interface from %s",
-- addr2str((struct sockaddr *)&sa6_relay));
-+ in6addr2str(&dh6a->dh6adv_relayaddr, 0));
- return;
- }
-
---- dhcp-0.10/dhcp6s.c.rh 2004-03-15 17:03:21.000000000 -0500
-+++ dhcp-0.10/dhcp6s.c 2007-02-09 01:28:31.000000000 -0500
-@@ -67,8 +67,8 @@
- #include <err.h>
- #include <netdb.h>
- #include <limits.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "timer.h"
- #include "dhcp6.h"
- #include "config.h"
-@@ -88,7 +88,6 @@
- u_int32_t duration;
- struct dhcp6_timer *timer;
- };
--static TAILQ_HEAD(, dhcp6_binding) dhcp6_binding_head;
-
- static char *device[100];
- static int num_device = 0;
-@@ -100,6 +99,7 @@
- char server6_lease_temp[100];
-
- static const struct sockaddr_in6 *sa6_any_downstream;
-+static u_int16_t upstream_port;
- static struct msghdr rmh;
- static char rdatabuf[BUFSIZ];
- static int rmsgctllen;
-@@ -133,6 +133,15 @@
- struct sockaddr *, int,
- struct dhcp6_optinfo *));
- static struct dhcp6_timer *check_lease_file_timo __P((void *arg));
-+static struct dhcp6 *dhcp6_parse_relay __P((struct dhcp6_relay *,
-+ struct dhcp6_relay *,
-+ struct dhcp6_optinfo *,
-+ struct in6_addr *));
-+static int dhcp6_set_relay __P((struct dhcp6_relay *,
-+ struct dhcp6_relay *,
-+ struct dhcp6_optinfo *));
-+static void dhcp6_set_relay_option_len __P((struct dhcp6_optinfo *,
-+ int len));
- extern struct link_decl *dhcp6_allocate_link __P((struct dhcp6_if *, struct rootgroup *,
- struct in6_addr *));
- extern struct host_decl *dhcp6_allocate_host __P((struct dhcp6_if *, struct rootgroup *,
-@@ -164,7 +173,7 @@
- int argc;
- char **argv;
- {
-- int ch, i = 0;
-+ int ch;//, i = 0;
- struct in6_addr a;
- struct dhcp6_listval *dlv;
- char *progname, *conffile = DHCP6S_CONF;
-@@ -316,6 +325,7 @@
- FNAME, strerror(errno));
- exit(1);
- }
-+ upstream_port = ((struct sockaddr_in6 *) res->ai_addr)->sin6_port;
- freeaddrinfo(res);
-
- /* initiallize outbound interface */
-@@ -511,6 +521,7 @@
- struct dhcp6_if *ifp;
- struct dhcp6 *dh6;
- struct dhcp6_optinfo optinfo;
-+ struct in6_addr relay; /* the address of the first relay, if any */
- memset(&iov, 0, sizeof(iov));
- memset(&mhdr, 0, sizeof(mhdr));
-
-@@ -557,12 +568,34 @@
-
- dprintf(LOG_DEBUG, "%s" "received %s from %s", FNAME,
- dhcp6msgstr(dh6->dh6_msgtype),
-- addr2str((struct sockaddr *)&from));
-+ addr2str((struct sockaddr *)&from, sizeof(((struct sockaddr *)&from)->sa_data)));
-
-+ dhcp6_init_options(&optinfo);
-+
-+ /*
-+ * If this is a relayed message, parse all of the relay data, storing
-+ * the link addresses, peer addresses, and interface identifiers for
-+ * later use. Get a pointer to the original client message.
-+ */
-+ if (dh6->dh6_msgtype == DH6_RELAY_FORW) {
-+ dh6 = dhcp6_parse_relay((struct dhcp6_relay *) dh6,
-+ (struct dhcp6_relay *) (rdatabuf + len),
-+ &optinfo, &relay);
-+
-+ /*
-+ * NULL means there was an error in the relay format or no
-+ * client message was found.
-+ */
-+ if (dh6 == NULL) {
-+ dprintf(LOG_INFO, "%s" "failed to parse relay fields "
-+ "or could not find client message", FNAME);
-+ return -1;
-+ }
-+ }
-+
- /*
- * parse and validate options in the request
- */
-- dhcp6_init_options(&optinfo);
- if (dhcp6_get_options((struct dhcp6opt *)(dh6 + 1),
- (struct dhcp6opt *)(rdatabuf + len), &optinfo) < 0) {
- dprintf(LOG_INFO, "%s" "failed to parse options", FNAME);
-@@ -574,7 +607,17 @@
- * now assume client is on the same link as server
- * if the subnet couldn't be found return status code NotOnLink to client
- */
-- subnet = dhcp6_allocate_link(ifp, globalgroup, NULL);
-+ /*
-+ * If the relay list is empty, then this is a message received directly
-+ * from the client, so client is on the same link as the server.
-+ * Otherwise, allocate the client an address based on the first relay
-+ * that forwarded the message.
-+ */
-+ if (TAILQ_EMPTY(&optinfo.relay_list))
-+ subnet = dhcp6_allocate_link(ifp, globalgroup, NULL);
-+ else
-+ subnet = dhcp6_allocate_link(ifp, globalgroup, &relay);
-+
- if (!(DH6_VALID_MESSAGE(dh6->dh6_msgtype)))
- dprintf(LOG_INFO, "%s" "unknown or unsupported msgtype %s",
- FNAME, dhcp6msgstr(dh6->dh6_msgtype));
-@@ -700,15 +743,28 @@
- case DH6_REQUEST:
- case DH6_RENEW:
- case DH6_DECLINE:
-- if (!IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr)) {
-+ /*
-+ * If the message was relayed, then do not check whether the message
-+ * came in via unicast or multicast, since the relay may be configured
-+ * to send messages via unicast.
-+ */
-+ if (TAILQ_EMPTY(&optinfo->relay_list) &&
-+ !IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr)) {
- if (!(roptinfo.flags & DHCIFF_UNICAST)) {
- num = DH6OPT_STCODE_USEMULTICAST;
- goto send;
- } else
- break;
-- }
-+ }
-+ break;
- default:
-- if (!IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr)) {
-+ /*
-+ * If the message was relayed, then do not check whether the message
-+ * came in via unicast or multicast, since the relay may be configured
-+ * to send messages via unicast.
-+ */
-+ if (TAILQ_EMPTY(&optinfo->relay_list) &&
-+ !IN6_IS_ADDR_MULTICAST(&pi->ipi6_addr)) {
- num = DH6OPT_STCODE_USEMULTICAST;
- goto send;
- }
-@@ -945,7 +1001,7 @@
- {
- char replybuf[BUFSIZ];
- struct sockaddr_in6 dst;
-- int len, optlen;
-+ int len, optlen, relaylen = 0;
- struct dhcp6 *dh6;
-
- if (sizeof(struct dhcp6) > sizeof(replybuf)) {
-@@ -953,12 +1009,41 @@
- return (-1);
- }
-
-- dh6 = (struct dhcp6 *)replybuf;
-+ if (!TAILQ_EMPTY(&optinfo->relay_list) &&
-+ (relaylen = dhcp6_set_relay((struct dhcp6_relay *) replybuf,
-+ (struct dhcp6_relay *) (replybuf +
-+ sizeof (replybuf)),
-+ optinfo)) < 0) {
-+ dprintf(LOG_INFO, "%s" "failed to construct relay message", FNAME);
-+ return (-1);
-+ }
-+
-+ dh6 = (struct dhcp6 *) (replybuf + relaylen);
- len = sizeof(*dh6);
- memset(dh6, 0, sizeof(*dh6));
- dh6->dh6_msgtypexid = origmsg->dh6_msgtypexid;
- dh6->dh6_msgtype = (u_int8_t)type;
--
-+
-+ if ( optinfo->flags & DHCIFF_REQUEST_PREFIX )
-+ {
-+ if ( ! ( (subnet && (subnet->linkscope.use_ra_prefix))
-+ ||(host && (host->hostscope.use_ra_prefix))
-+ )
-+ )
-+ {
-+ struct interface *ifnetwork;
-+ int no_use_ra_prefix = 1;
-+ for (ifnetwork = globalgroup->iflist; ifnetwork; ifnetwork = ifnetwork->next)
-+ {
-+ if ( ( ifp->ifname && ( strcmp( &(ifnetwork->name[0]), ifp->ifname ) == 0 ) )
-+ &&(ifnetwork->ifscope.use_ra_prefix)
-+ ) no_use_ra_prefix = 0;
-+ }
-+
-+ if ( no_use_ra_prefix )
-+ roptinfo->flags |= DHCIFF_RESPOND_PREFIX;
-+ }
-+ }
- /* set options in the reply message */
- if ((optlen = dhcp6_set_options((struct dhcp6opt *)(dh6 + 1),
- (struct dhcp6opt *)(replybuf +
-@@ -970,20 +1055,35 @@
- }
- len += optlen;
-
-+ /*
-+ * If there were any Relay Message options, fill in the option-len
-+ * field(s) with the appropriate value(s).
-+ */
-+ if (!TAILQ_EMPTY(&optinfo->relay_list))
-+ dhcp6_set_relay_option_len(optinfo, len);
-+
-+ len += relaylen;
-+
- /* specify the destination and send the reply */
- dst = *sa6_any_downstream;
- dst.sin6_addr = ((struct sockaddr_in6 *)from)->sin6_addr;
-+
-+ /* RELAY-REPL messages need to be directed back to the port the relay
-+ agent is listening on, namely DH6PORT_UPSTREAM */
-+ if (relaylen > 0)
-+ dst.sin6_port = upstream_port;
-+
- dst.sin6_scope_id = ((struct sockaddr_in6 *)from)->sin6_scope_id;
- dprintf(LOG_DEBUG, "send destination address is %s, scope id is %d",
-- addr2str((struct sockaddr *)&dst), dst.sin6_scope_id);
-+ addr2str((struct sockaddr *)&dst, sizeof(dst.sin6_addr)), dst.sin6_scope_id);
- if (transmit_sa(outsock, &dst, replybuf, len) != 0) {
- dprintf(LOG_ERR, "%s" "transmit %s to %s failed", FNAME,
-- dhcp6msgstr(type), addr2str((struct sockaddr *)&dst));
-+ dhcp6msgstr(type), addr2str((struct sockaddr *)&dst, sizeof(dst.sin6_addr)));
- return (-1);
- }
-
- dprintf(LOG_DEBUG, "%s" "transmit %s to %s", FNAME,
-- dhcp6msgstr(type), addr2str((struct sockaddr *)&dst));
-+ dhcp6msgstr(type), addr2str((struct sockaddr *)&dst, sizeof(dst.sin6_addr)));
-
- return 0;
- }
-@@ -1009,3 +1109,288 @@
- dhcp6_set_timer(&timo, sync_lease_timer);
- return sync_lease_timer;
- }
-+
-+/*
-+ * Parse all of the RELAY-FORW messages and interface ID options. Each
-+ * RELAY-FORW messages will have its hop count, link address, peer-address,
-+ * and interface ID (if any) put into a relay_listval structure.
-+ * A pointer to the actual original client message will be returned.
-+ * If this client message cannot be found, NULL is returned to signal an error.
-+ */
-+static struct dhcp6 *
-+dhcp6_parse_relay(relay_msg, endptr, optinfo, relay_addr)
-+ struct dhcp6_relay *relay_msg;
-+ struct dhcp6_relay *endptr;
-+ struct dhcp6_optinfo *optinfo;
-+ struct in6_addr *relay_addr;
-+{
-+ struct relay_listval *relay_val;
-+ struct dhcp6 *relayed_msg; /* the original message that the relay
-+ received */
-+ struct dhcp6opt *option, *option_endptr = (struct dhcp6opt *) endptr;
-+
-+ u_int16_t optlen;
-+ u_int16_t opt;
-+
-+ while ((relay_msg + 1) < endptr) {
-+ relay_val = (struct relay_listval *)
-+ calloc (1, sizeof (struct relay_listval));
-+
-+ if (relay_val == NULL) {
-+ dprintf(LOG_ERR, "%s" "failed to allocate memory", FNAME);
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+
-+ /* copy the msg-type, hop-count, link-address, and peer-address */
-+ memcpy (&relay_val->relay, relay_msg, sizeof (struct dhcp6_relay));
-+
-+ /* set the msg type to relay reply now so that it doesn't need to be
-+ done when formatting the reply */
-+ relay_val->relay.dh6_msg_type = DH6_RELAY_REPL;
-+
-+ TAILQ_INSERT_TAIL(&optinfo->relay_list, relay_val, link);
-+
-+ /*
-+ * need to record the first relay's link address field for later use.
-+ * The first relay is the last one we see, so keep overwriting the
-+ * relay value.
-+ */
-+ memcpy (relay_addr, &relay_val->relay.link_addr,
-+ sizeof (struct in6_addr));
-+
-+ /* now handle the options in the RELAY-FORW message */
-+ /*
-+ * The only options that should appear in a RELAY-FORW message are:
-+ * - Interface identifier
-+ * - Relay message
-+ *
-+ * All other options are ignored.
-+ */
-+ option = (struct dhcp6opt *) (relay_msg + 1);
-+
-+ relayed_msg = NULL; /* if this is NULL at the end of the loop, no
-+ relayed message was found */
-+
-+ /* since the order of options is not specified, all of the options
-+ must be processed */
-+ while ((option + 1) < option_endptr) {
-+ memcpy (&opt, &option->dh6opt_type, sizeof(opt));
-+ opt = ntohs(opt);
-+ memcpy (&optlen, &option->dh6opt_len, sizeof(optlen));
-+ optlen = ntohs(optlen);
-+
-+ if ((char *) (option + 1) + optlen > (char *) option_endptr) {
-+ dprintf(LOG_ERR, "%s" "invalid option length in %s option",
-+ FNAME, dhcp6optstr(opt));
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+
-+ if (opt == DH6OPT_INTERFACE_ID) {
-+ /* if this is not the first interface identifier option,
-+ then the message is incorrectly formed */
-+ if (relay_val->intf_id == NULL) {
-+ if (optlen) {
-+ relay_val->intf_id = (struct intf_id *)
-+ malloc (sizeof (struct intf_id));
-+ if (relay_val->intf_id == NULL) {
-+ dprintf(LOG_ERR, "%s" "failed to allocate memory",
-+ FNAME);
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+ else {
-+ relay_val->intf_id->intf_len = optlen;
-+ relay_val->intf_id->intf_id = (char *)
-+ malloc (optlen);
-+
-+ if (relay_val->intf_id->intf_id == NULL) {
-+ dprintf(LOG_ERR, "%s"
-+ "failed to allocate memory",
-+ FNAME);
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+ else { /* copy the interface identifier so it can
-+ be sent in the reply */
-+ memcpy (relay_val->intf_id->intf_id,
-+ ((char *) (option + 1)), optlen);
-+ }
-+ }
-+ }
-+ else {
-+ dprintf(LOG_ERR, "%s" "Invalid length for interface "
-+ "identifier option", FNAME);
-+ }
-+ }
-+ else {
-+ dprintf(LOG_INFO, "%s" "Multiple interface identifier "
-+ "options in RELAY-FORW Message ",
-+ FNAME);
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+ }
-+ else if (opt == DH6OPT_RELAY_MSG) {
-+ if (relayed_msg == NULL)
-+ relayed_msg = (struct dhcp6 *) (option + 1);
-+ else {
-+ dprintf(LOG_INFO, "%s" "Duplicated Relay Message option",
-+ FNAME);
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+ }
-+ else /* No other options besides interface identifier and relay
-+ message make sense, so ignore them with a warning */
-+ dprintf(LOG_INFO, "%s" "Unsupported option %s found in "
-+ "RELAY-FORW message",
-+ FNAME, dhcp6optstr(opt));
-+
-+ /* advance the option pointer */
-+ option = (struct dhcp6opt *) (((char *) (option + 1)) + optlen);
-+ }
-+
-+ /*
-+ * If the relayed message is non-NULL and is a regular client
-+ * message, then the relay processing is done. If it is another
-+ * RELAY_FORW message, then continue. If the relayed message is
-+ * NULL, signal an error.
-+ */
-+ if (relayed_msg != NULL && (char *) (relayed_msg + 1) <=
-+ (char *) endptr) {
-+ /* done if have found the client message */
-+ if (relayed_msg->dh6_msgtype != DH6_RELAY_FORW)
-+ return relayed_msg;
-+ else
-+ relay_msg = (struct dhcp6_relay *) relayed_msg;
-+ }
-+ else {
-+ dprintf(LOG_ERR, "%s" "invalid relayed message", FNAME);
-+ relayfree(&optinfo->relay_list);
-+ return NULL;
-+ }
-+ }
-+ return NULL;
-+}
-+
-+/*
-+ * Format all of the RELAY-REPL messages and options to send back to the
-+ * client. A RELAY-REPL message and Relay Message option are added for
-+ * each of the relays that were in the RELAY-FORW packet that this is
-+ * in response to.
-+ */
-+static int
-+dhcp6_set_relay (msg, endptr, optinfo)
-+ struct dhcp6_relay *msg;
-+ struct dhcp6_relay *endptr;
-+ struct dhcp6_optinfo *optinfo;
-+{
-+ struct relay_listval *relay;
-+ struct dhcp6opt *option;
-+ int relaylen = 0;
-+ u_int16_t type, len;
-+
-+ for (relay = TAILQ_FIRST(&optinfo->relay_list); relay;
-+ relay = TAILQ_NEXT(relay, link)) {
-+ /* bounds check */
-+ if (((char *) msg) + sizeof (struct dhcp6_relay) >= (char *) endptr) {
-+ dprintf(LOG_ERR, "%s" "insufficient buffer size for RELAY-REPL",
-+ FNAME);
-+ return -1;
-+ }
-+
-+ memcpy (msg, &relay->relay, sizeof(struct dhcp6_relay));
-+
-+ relaylen += sizeof(struct dhcp6_relay);
-+
-+ option = (struct dhcp6opt *) (msg + 1);
-+
-+ /* include an Interface Identifier option if it was present in the
-+ original message */
-+ if (relay->intf_id != NULL) {
-+ /* bounds check */
-+ if ((((char *) option) + sizeof(struct dhcp6opt) +
-+ relay->intf_id->intf_len) >= (char *) endptr) {
-+ dprintf(LOG_ERR, "%s" "insufficient buffer size for RELAY-REPL",
-+ FNAME);
-+ return -1;
-+ }
-+ type = htons(DH6OPT_INTERFACE_ID);
-+ memcpy (&option->dh6opt_type, &type, sizeof(type));
-+ len = htons(relay->intf_id->intf_len);
-+ memcpy (&option->dh6opt_len, &len, sizeof(len));
-+ memcpy (option + 1, relay->intf_id->intf_id,
-+ relay->intf_id->intf_len);
-+
-+ option = (struct dhcp6opt *)(((char *)(option + 1)) +
-+ relay->intf_id->intf_len);
-+ relaylen += sizeof(struct dhcp6opt) + relay->intf_id->intf_len;
-+ }
-+
-+ /* save a pointer to the relay message option so that it is easier
-+ to fill in the length later */
-+ relay->option = option;
-+
-+ /* bounds check */
-+ if ((char *) (option + 1) >= (char *) endptr) {
-+ dprintf(LOG_ERR, "%s" "insufficient buffer size for RELAY-REPL",
-+ FNAME);
-+ return -1;
-+ }
-+
-+ /* lastly include the Relay Message option, which encapsulates the
-+ message being relayed */
-+ type = htons(DH6OPT_RELAY_MSG);
-+ memcpy (&option->dh6opt_type, &type, sizeof(type));
-+ relaylen += sizeof(struct dhcp6opt);
-+ /* dh6opt_len will be set by dhcp6_set_relay_option_len */
-+
-+ msg = (struct dhcp6_relay *) (option + 1);
-+ }
-+
-+ /*
-+ * if there were no relays, this is an error since this function should
-+ * not have even been called in this case
-+ */
-+ if (relaylen == 0)
-+ return -1;
-+ else
-+ return relaylen;
-+}
-+
-+/*
-+ * Fill in all of the opt-len fields for the Relay Message options now that
-+ * the length of the entire message is known.
-+ *
-+ * len - the length of the DHCPv6 message to the client (not including any
-+ * relay options)
-+ *
-+ * Precondition: dhcp6_set_relay has already been called and the relay->option
-+ * fields of all of the elements in optinfo->relay_list are
-+ * non-NULL
-+ */
-+static void
-+dhcp6_set_relay_option_len(optinfo, reply_msg_len)
-+ struct dhcp6_optinfo *optinfo;
-+ int reply_msg_len;
-+{
-+ struct relay_listval *relay, *last = NULL;
-+ u_int16_t len;
-+
-+ for (relay = TAILQ_LAST(&optinfo->relay_list, relay_list);
-+ relay; relay = TAILQ_PREV(relay, relay_list, link)) {
-+ if (last == NULL) {
-+ len = htons(reply_msg_len);
-+ memcpy (&relay->option->dh6opt_len, &len, sizeof(len));
-+ last = relay;
-+ }
-+ else {
-+ len = reply_msg_len + (((void *) (last->option + 1)) -
-+ ((void *) (relay->option + 1)));
-+ len = htons(len);
-+ memcpy (&relay->option->dh6opt_len, &len, sizeof(len));
-+ }
-+ }
-+}
---- dhcp-0.10/dhcp6s.sh.rh 2003-02-18 06:31:49.000000000 -0500
-+++ dhcp-0.10/dhcp6s.sh 2007-02-09 01:28:31.000000000 -0500
-@@ -5,11 +5,10 @@
- # dhcp6s.
- #
- # chkconfig: - 66 36
--# description: dhcp6s supports server side of Dynamic Host Configuration
-+# description: dhcp6s supports server side of Dynamic Host Configuration \
- # Protocol for IPv6.
- # processname: dhcp6s
- # config: /etc/dhcp6s.conf
--# config: /etc/server6_addr.conf
- # config: /etc/sysconfig/dhcp6s
-
- # Source function library.
-@@ -20,13 +19,19 @@
- . /etc/sysconfig/dhcp6s
-
- # Check that networking is up.
--[ ${NETWORKING} = "no" ] && exit 0
-+# networking is not up, return 1 for generic error
-+[ ${NETWORKING} = "no" ] && exit 1
-
- # Check that files exist
--[ -f /usr/local/sbin/dhcp6s ] || exit 0
--[ -f /etc/dhcp6s.conf ] || exit 0
--[ -f /etc/server6_addr.conf ] || exit 0
--[ ${DHCP6SIF} = "" ] && exit 0
-+# return 5 if program is not installed
-+[ -x /usr/sbin/dhcp6s ] || exit 5
-+
-+# return 6 if program is not configured
-+[ -f /etc/dhcp6s.conf ] || exit 6
-+
-+if [ "x$DHCP6SIF" = "x" ]; then
-+ logger -s -t "dhcp6s" -p "daemon.info" "Warning: dhcp6s listening on ALL interfaces - set DHCP6SIF in /etc/sysconfig/dhcp6s"
-+fi
-
- RETVAL=0
- prog="dhcp6s"
-@@ -34,7 +39,7 @@
- start() {
- # Start daemons.
- echo -n $"Starting $prog: "
-- daemon /usr/local/sbin/dhcp6s -c /etc/dhcp6s.conf ${DHCP6SARGS} ${DHCP6SIF}
-+ daemon /usr/sbin/dhcp6s -c /etc/dhcp6s.conf ${DHCP6SARGS} ${DHCP6SIF}
- RETVAL=$?
- echo
- [ $RETVAL -eq 0 ] && touch /var/lock/subsys/dhcp6s
-@@ -55,15 +60,21 @@
- case "$1" in
- start)
- start
-+ RETVAL=$?
- ;;
- stop)
- stop
-+ RETVAL=$?
- ;;
-- restart|reload)
-+ restart|force-reload)
- stop
- start
- RETVAL=$?
- ;;
-+ reload)
-+ # unimplemented
-+ RETVAL=3
-+ ;;
- condrestart)
- if [ -f /var/lock/subsys/dhcp6s ]; then
- stop
-@@ -81,4 +92,3 @@
- esac
-
- exit $RETVAL
--
---- dhcp-0.10/dhcp6s.sysconfig.rh 2003-02-18 06:31:49.000000000 -0500
-+++ dhcp-0.10/dhcp6s.sysconfig 2007-02-09 01:28:31.000000000 -0500
-@@ -1,4 +1,4 @@
- # specify the interface for dhcp6s
--DHCP6SIF=eth0
-+DHCP6SIF=
- # Command line options here
--DHCP6CARGS=
-+DHCP6SARGS=
---- dhcp-0.10/ifaddrs.c.rh 2003-04-22 14:05:33.000000000 -0400
-+++ dhcp-0.10/ifaddrs.c 2007-02-09 01:28:31.000000000 -0500
-@@ -45,6 +45,8 @@
- #include "libc-compat.h"
- #endif
-
-+extern int __close( int );
-+
- /* ====================================================================== */
- struct nlmsg_list
- {
---- dhcp-0.10/netlink.c.rh 2004-03-15 17:02:09.000000000 -0500
-+++ dhcp-0.10/netlink.c 2007-02-09 01:28:31.000000000 -0500
-@@ -28,22 +28,25 @@
- */
-
- /* Author: Shirley Ma, xma@us.ibm.com */
--
-+#include <sys/types.h>
-+#include <unistd.h>
- #include <string.h>
- #include <time.h>
- #include <malloc.h>
- #include <errno.h>
- #include <syslog.h>
--#include <sys/types.h>
- #include <sys/socket.h>
- #include <asm/types.h>
- #include <linux/netlink.h>
- #include <linux/rtnetlink.h>
- #include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
-+#include "common.h"
-+
-
- static void
- get_if_prefix(struct nlmsghdr *nlm, int nlm_len, int request,
-@@ -117,8 +120,8 @@
- dprintf(LOG_DEBUG, "get prefix plen %d",rtm->rtm_dst_len);
- break;
- case RTA_CACHEINFO:
-- dprintf("prefix route life time is %lu\n",
-- ((struct rta_cacheinfo *)rtadata)->rta_expires);
-+ dprintf(LOG_DEBUG,"prefix route life time is %lu\n",
-+ (unsigned long)((struct rta_cacheinfo *)rtadata)->rta_expires);
- break;
- default:
- break;
-@@ -132,10 +135,8 @@
- {
- struct ifinfomsg *ifim = (struct ifinfomsg *)NLMSG_DATA(nlm);
- struct rtattr *rta, *rta1;
-- size_t rtasize, rtasize1, rtapayload;
-+ size_t rtasize, rtapayload, rtasize1;
- void *rtadata;
-- struct ra_info *rainfo;
-- char addr[64];
-
- dprintf(LOG_DEBUG, "get_if_flags called");
-
-@@ -159,7 +160,6 @@
- for (rta1 = (struct rtattr *)rtadata; RTA_OK(rta1, rtasize1);
- rta1 = RTA_NEXT(rta1, rtasize1)) {
- void *rtadata1 = RTA_DATA(rta1);
-- size_t rtapayload1= RTA_PAYLOAD(rta1);
- switch(rta1->rta_type) {
- case IFLA_INET6_CACHEINFO:
- break;
-@@ -275,7 +275,7 @@
- struct nlmsghdr *nlm;
- struct msghdr msgh;
- struct sockaddr_nl nl_addr;
-- char *newbuf, *buf = NULL;
-+ char *buf = NULL;// *newbuf
- size_t newsize = 65536, size = 0;
- int msg_len;
-
-@@ -312,8 +312,11 @@
- nlm = (struct nlmsghdr *)NLMSG_NEXT(nlm, msg_len)) {
- if (nlm->nlmsg_type == NLMSG_DONE ||
- nlm->nlmsg_type == NLMSG_ERROR) {
-- dprintf(LOG_ERR, "netlink_recv_rtgenmsg error");
-- goto out;
-+ if ( nlm->nlmsg_type == NLMSG_ERROR)
-+ dprintf(LOG_ERR, "netlink_recv_rtgenmsg error, %d %d %d",
-+ request, RTM_GETROUTE, RTM_GETLINK
-+ );
-+ goto out;
- }
- if (nlm->nlmsg_pid != getpid() ||
- nlm->nlmsg_seq != seq)
---- dhcp-0.10/ra_token.l.rh 2004-03-04 18:31:24.000000000 -0500
-+++ dhcp-0.10/ra_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -43,12 +43,17 @@
- #include <errno.h>
- #include <syslog.h>
- #include <string.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-+
- #define YYABORT(msg) dprintf(LOG_ERR, msg " %s lineno %d.", \
- rayytext, num_lines)
-
-@@ -119,7 +124,7 @@
- strcat(buff, ":0");
- len += 2;
- }
-- strcat(buff, "\0");
-+ buff[len]='\0';
- if (inet_pton(AF_INET6, buff, &addr) < 1)
- ABORT;
- memcpy(&rainfo->prefix, &addr, sizeof(rainfo->prefix));
-@@ -171,5 +176,5 @@
- raname, strerror(errno));
- return (-1);
- }
-- yylex();
-+ return yylex();
- }
---- dhcp-0.10/radvd_token.l.rh 2003-07-07 14:01:05.000000000 -0400
-+++ dhcp-0.10/radvd_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -47,8 +47,8 @@
- #include <errno.h>
- #include <syslog.h>
- #include <string.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -58,6 +58,11 @@
- #define PATH_RADVD_PID "/var/run/radvd/radvd.pid"
- #endif
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-+
- #define YYABORT(msg) dprintf(LOG_ERR, msg " %s lineno %d.", \
- yytext, num_lines)
-
-@@ -112,14 +117,24 @@
- BEGIN S_INTERFACE;}
-
- <S_INTERFACE>{string} {
-+ char *requested_if;
- fprintf(dhcp6_radvd_file, yytext);
-- if (!strcmp(yytext, dhcp6_if->ifname))
-- BEGIN INITIAL;
-- else {
-+ if ( ( ( (requested_if = get_if_option(&(dhcp6_if->option_list),
-+ DECL_PREFIX_DELEGATION_INTERFACE
-+ )
-+ ) != 0L
-+ )
-+ &&( strcmp(yytext, requested_if) == 0)
-+ )
-+ ||((requested_if == 0L) && (strcmp(yytext, dhcp6_if->ifname)==0))
-+ )
-+ {
- TAILQ_INIT(&ori_prefix_list);
- TAILQ_INIT(&previous_prefix_list);
-- BEGIN S_IFNAME;}
-- }
-+ BEGIN S_IFNAME;
-+ }else
-+ BEGIN INITIAL;
-+}
-
- <S_IFNAME>{comment} {
- if (strstr(yytext, DHCP6_MARK) != NULL) {
-@@ -280,13 +295,13 @@
- }
- client6iaid = client6_iaid;
- update_flag = flag;
-- yylex();
-+ return yylex();
- }
-
- static int
- update_radvd(void)
- {
-- struct dhcp6_listval *d, *d_next;
-+// struct dhcp6_listval *d, *d_next;
- struct stat buf;
- if (fflush(dhcp6_radvd_file) == EOF) {
- dprintf(LOG_ERR, "%s" "write radvd.conf.dhcpv6 file fflush failed %s",
-@@ -341,4 +356,5 @@
- }
- fclose(yyin);
- close(oldfd);
-+ return 1;
- }
---- dhcp-0.10/resolv_token.l.rh 2003-06-23 13:24:48.000000000 -0400
-+++ dhcp-0.10/resolv_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -37,6 +37,7 @@
- #include <sys/file.h>
- #include <sys/stat.h>
- #include <unistd.h>
-+#include <sys/wait.h>
-
- #include <netinet/in.h>
- #include <arpa/inet.h>
-@@ -44,14 +45,19 @@
- #include <errno.h>
- #include <syslog.h>
- #include <string.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-
- #undef yywrap
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-+
- #define YYABORT(msg) dprintf(LOG_ERR, msg " %s lineno %d.", \
- yytext, num_lines)
-
-@@ -139,7 +145,43 @@
- . {fprintf(dhcp6_resolv_file, yytext);}
-
- %%
-+int change_resolv_conf
-+( char *new_rscf
-+)
-+{
-+ char *argv[] = { "/bin/bash", "-c", 0L, 0L };
-+ char *cmd;
-+ int l, pid, status;
-+ extern char **environ;
-+
-+ if( new_rscf == 0L )
-+ return -1;
-+
-+ if( getuid() != 0 )
-+ return 1;
-+
-+ l = strlen(new_rscf) + 73;
-+ cmd = (char*)malloc(l);
-+ strcpy(cmd, ". /etc/sysconfig/network-scripts/network-functions; change_resolv_conf ");
-+ strcpy(cmd+71, new_rscf);
-+ argv[2] = cmd;
-+
-+ if( (pid = fork()) < 0 )
-+ return -1;
-+ else
-+ if( pid > 0 )
-+ {
-+ status = 0;
-+ if(waitpid(pid, &status, 0L) == pid)
-+ return( ((status & 0x7f)==0)
-+ ? ((status >> 8) & 0xff)
-+ : -(status & 0x7f)
-+ );
-+ }else
-+ execve( argv[0], argv, environ );
-
-+ return -1;
-+}
- /* parse resolv.conf
- * create a new resolv.conf.dhcpv6
- * mv /etc/resolv.conf to /etc/resolv.conf.V6BAK
-@@ -203,14 +245,14 @@
- " failed to fdopen resolv.conf.dhcpv6 file", FNAME);
- return (-1);
- }
-- yylex();
-+ return yylex();
- }
-
- static int
- update_resolver(struct dns_list *dns_list)
- {
- struct domain_list *oldlist, *dprev, *dlist, *dlist_next;
-- struct domain_list *dfirst = NULL;
-+// struct domain_list *dfirst = NULL;
- struct dhcp6_listval *d, *d_next;
- struct stat buf;
- int i = 0;
-@@ -311,9 +353,9 @@
- }
- }
- }
-- if (rename(resolv_dhcpv6_file, RESOLV_CONF_FILE)) {
-- dprintf(LOG_ERR, "%s" " rename failed for resolv.conf file", FNAME);
-- return(-1);
-+ if (change_resolv_conf(resolv_dhcpv6_file)!=0) {
-+// dprintf(LOG_ERR, "%s" " rename failed for resolv.conf file", FNAME);
-+// needs initscripts patch! return(-1);
- }
- return (0);
- }
-@@ -321,7 +363,8 @@
- static int
- yywrap()
- {
-- update_resolver(new_dns_list);
-+ update_resolver(new_dns_list);
- fclose(yyin);
- close(oldfd);
-+ return 1;
- }
---- dhcp-0.10/server6_addr.c.rh 2004-03-15 17:02:55.000000000 -0500
-+++ dhcp-0.10/server6_addr.c 2007-02-09 01:28:31.000000000 -0500
-@@ -36,21 +36,19 @@
- #include <time.h>
- //#include <openssl/md5.h>
-
-+#include <netinet/in.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/socket.h>
- #include <sys/ioctl.h>
--
--#include <linux/ipv6.h>
--
- #include <net/if.h>
-
- #include <errno.h>
- #include <syslog.h>
- #include <string.h>
- #include <unistd.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -553,7 +551,7 @@
- struct in6_addr *tempaddr;
- {
- int i, num_bytes;
-- u_int8_t digest[16];
-+// u_int8_t digest[16];
- u_int8_t seed[16];
-
- get_random_bytes(seed, 16);
-@@ -579,8 +577,8 @@
- struct dhcp6_optinfo *optinfo, *roptinfo;
- {
- struct dhcp6_list *reply_list = &roptinfo->addr_list;
-- struct dhcp6_list *req_list = &optinfo->addr_list;
-- struct dhcp6_listval *lv, *lv_next;
-+// struct dhcp6_list *req_list = &optinfo->addr_list;
-+// struct dhcp6_listval *lv, *lv_next;
-
- if (!(host->hostscope.allow_flags & DHCIFF_TEMP_ADDRS)) {
- roptinfo->iaidinfo.renewtime = host->hostscope.renew_time;
-@@ -933,8 +931,8 @@
- continue;
- else {
- for (link = ifnetwork->linklist; link; link = link->next) {
-- /* without relay agent support, so far we assume
-- * that client and server on the same link, no relay
-+ /* if relay is NULL, assume client and server are on the
-+ * same link (which cannot have a relay configuration option)
- */
- struct v6addrlist *temp;
- if (relay == NULL) {
-@@ -944,8 +942,11 @@
- return link;
- } else {
- for (temp = link->relaylist; temp; temp = temp->next) {
-- if (IN6_ARE_ADDR_EQUAL(relay,
-- &temp->v6addr.addr))
-+ /* only compare the prefix configured to the relay
-+ link address */
-+ if (!prefixcmp (relay,
-+ &temp->v6addr.addr,
-+ temp->v6addr.plen))
- return link;
- else
- continue;
---- dhcp-0.10/server6_conf.c.rh 2004-03-15 17:03:52.000000000 -0500
-+++ dhcp-0.10/server6_conf.c 2007-02-09 01:28:31.000000000 -0500
-@@ -40,8 +40,8 @@
- #include <sys/socket.h>
- #include <net/if.h>
- //#include <openssl/md5.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -293,6 +293,8 @@
- dhcp6_copy_list(¤t->dnslist.addrlist, &up->dnslist.addrlist);
- if (current->dnslist.domainlist == NULL)
- current->dnslist.domainlist = up->dnslist.domainlist;
-+ if ( current->use_ra_prefix )
-+ up->use_ra_prefix = 1;
- return;
- }
-
---- dhcp-0.10/server6_conf.h.rh 2003-04-30 15:04:14.000000000 -0400
-+++ dhcp-0.10/server6_conf.h 2007-02-09 01:28:31.000000000 -0500
-@@ -50,6 +50,7 @@
- u_int8_t send_flags;
- u_int8_t allow_flags;
- struct dns_list dnslist;
-+ u_int8_t use_ra_prefix;
- };
-
- struct scopelist {
---- dhcp-0.10/server6_parse.y.rh 2004-02-04 19:10:31.000000000 -0500
-+++ dhcp-0.10/server6_parse.y 2007-02-09 01:28:31.000000000 -0500
-@@ -33,14 +33,17 @@
-
- %{
-
-+#include <sys/types.h>
- #include <stdio.h>
- #include <string.h>
- #include <syslog.h>
- #include <errno.h>
-+#include <netinet/in.h>
- #include <sys/socket.h>
- #include <net/if.h>
--#include <linux/ipv6.h>
--#include "queue.h"
-+#include <malloc.h>
-+#include <sys/queue.h>
-+
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -104,6 +107,7 @@
- %token <str> IAID IAIDINFO
- %token <str> INFO_ONLY
- %token <str> TO
-+%token <str> USE_RA_PREFIX
-
- %token <str> BAD_TOKEN
- %type <str> name
-@@ -267,7 +271,6 @@
- linkbody
- :
- | linkbody linkparams
-- | relaylist
- ;
-
- linkparams
-@@ -277,6 +280,7 @@
- | hostdef
- | groupdef
- | confdecl
-+ | relaylist
- ;
-
- relaylist
-@@ -900,6 +904,15 @@
- dprintf(LOG_ERR, "%s" "bad server preference number", FNAME);
- currentscope->scope->server_pref = $2;
- }
-+ | USE_RA_PREFIX ';'
-+ {
-+ if (!currentscope) {
-+ currentscope = push_double_list(currentscope, &globalgroup->scope);
-+ if (currentscope == NULL)
-+ ABORT;
-+ }
-+ currentscope->scope->use_ra_prefix = 1;
-+ }
- ;
-
- number_or_infinity
---- dhcp-0.10/server6_token.l.rh 2003-07-16 15:09:53.000000000 -0400
-+++ dhcp-0.10/server6_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -42,14 +42,19 @@
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <net/if.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
- #include <server6_conf.h>
- #include "sf.tab.h"
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-+
- int num_lines = 1;
- int sfyyerrorcount = 0;
- int sfparse(char *filename);
-@@ -118,6 +123,7 @@
- valid-life-time { return VALIDLIFETIME; }
- prefer-life-time { return PREFERLIFETIME; }
- server-preference { return PREFERENCE; }
-+use-ra-prefix { return USE_RA_PREFIX; }
-
- to { return TO; }
- infinity { return INFINITY; }
---- dhcp-0.10/timer.c.rh 2003-03-11 18:52:23.000000000 -0500
-+++ dhcp-0.10/timer.c 2007-02-09 01:28:31.000000000 -0500
-@@ -42,8 +42,8 @@
- #if defined(__NetBSD__) || defined(__OpenBSD__)
- #include <search.h>
- #endif
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
---- dhcp-0.10/lease.c.rh 2004-03-03 15:11:16.000000000 -0500
-+++ dhcp-0.10/lease.c 2007-02-09 01:28:31.000000000 -0500
-@@ -47,8 +47,8 @@
- #include <net/if.h>
- #include <linux/sockios.h>
- #include <ifaddrs.h>
-+#include <sys/queue.h>
-
--#include "queue.h"
- #include "dhcp6.h"
- #include "hash.h"
- #include "config.h"
-@@ -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/lease_token.l.rh 2004-02-04 18:29:24.000000000 -0500
-+++ dhcp-0.10/lease_token.l 2007-02-09 01:28:31.000000000 -0500
-@@ -44,10 +44,10 @@
- #include <errno.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
--
- #include <net/if.h>
- #include <linux/sockios.h>
--#include "queue.h"
-+#include <sys/queue.h>
-+
- #include "dhcp6.h"
- #include "config.h"
- #include "common.h"
-@@ -74,6 +74,11 @@
- (a & LEASE_IAID_FLAG) && (a & LEASE_RNTIME_FLAG) && \
- (a & LEASE_RBTIME_FLAG) && (a & LEASE_DUID_FLAG))
-
-+#define YY_NO_UNPUT 1
-+#define ECHO if (fwrite(yytext, yyleng, 1, yyout) != 1) { \
-+ YY_FATAL_ERROR("error performing ECHO on yytext"); \
-+ }
-+
- #define YYABORT(msg) dprintf(LOG_ERR, msg " %s lineno %d.", \
- yytext, num_lines)
-
-@@ -241,6 +246,8 @@
-
- fseek(file, 0, 0);
- yyin = file;
-+ yy_init = 1;
-+ yy_start = 0;
- yylex();
- return;
- }
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/Makefile.inc.in 2007-02-09 01:28:42.000000000 -0500
-@@ -0,0 +1,32 @@
-+srcdir= @srcdir@
-+CFLAGS= -fPIC -fno-strict-aliasing -fvisibility=hidden @CFLAGS@ @DEFS@
-+LDFLAGS=@LDFLAGS@
-+LIBOBJS=@LIBOBJS@
-+LIBS= @LIBS@
-+CC= @CC@
-+YACC= @YACC@
-+LEX= @LEX@
-+DESTDIR ?=
-+
-+INSTALL=@INSTALL@
-+INSTALL_PROGRAM=@INSTALL_PROGRAM@
-+INSTALL_DATA=@INSTALL_DATA@
-+INSTALL_USER ?= root
-+INSTALL_GROUP ?= root
-+prefix= @prefix@
-+exec_prefix= @exec_prefix@
-+bindir= @bindir@
-+sbindir=@sbindir@
-+mandir= @mandir@
-+initdir=/etc/rc.d/init.d
-+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@ \
-+ -DCONF_DH6OPT_IA_PD=@dhcpopt_pdel@ \
-+ -DCONF_DH6OPT_IAPREFIX=@dhcpopt_pinfo@
+++ /dev/null
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/dhcp6r.8 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,213 @@
-+.\"
-+.\" Copyright (C) NEC Europe Ltd., 2003
-+.\" All rights reserved.
-+.\"
-+.\" Redistribution and use in source and binary forms, with or without
-+.\" modification, are permitted provided that the following conditions
-+.\" are met:
-+.\" 1. Redistributions of source code must retain the above copyright
-+.\" notice, this list of conditions and the following disclaimer.
-+.\" 2. Redistributions in binary form must reproduce the above copyright
-+.\" notice, this list of conditions and the following disclaimer in the
-+.\" documentation and/or other materials provided with the distribution.
-+.\" 3. Neither the name of the project nor the names of its contributors
-+.\" may be used to endorse or promote products derived from this software
-+.\" without specific prior written permission.
-+.\"
-+.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+.\" SUCH DAMAGE.
-+.\"
-+.de Id
-+.ds Dt \\$4
-+..
-+.Id $Id$
-+.TH dhcp6r 8 "15 March 2004" "dhcp6r" "Linux System Manager's Manual"
-+.SH NAME
-+dhcp6r \- DHCPv6 relay agent
-+.SH SYNOPSIS
-+.B dhcp6r
-+[
-+.B \-d
-+] [
-+.I client-options
-+] [
-+.I server-options
-+]
-+.SH DESCRIPTION
-+.B dhcp6r
-+acts as DHCPv6 relay agent forwarding DHCPv6 messages from clients
-+to servers and vice versa. DHCPv6 messages from clients are received
-+at UDP port 547, they are forwarded to one or more DHCPv6
-+servers by multicast and/or unicast. DHCPv6 messages from
-+servers to clients are also received at UDP port 547 and
-+forwarded by unicast only.
-+.PP
-+DHCPv6 messages received by multicast at a certain IPv6
-+interface are never forwarded by multicast to the same
-+interface.
-+.PP
-+If no options are present, the relay agent receives messages
-+by unicast and multicast at all IPv6 interfaces, and
-+all messages are forwarded to all IPv6 interfaces by
-+multicast with the exception mentioned in the previous
-+paragraph.
-+.PP
-+If one or more
-+.I client-options
-+are present, then messages are only received as specified by
-+the client options. If one or more
-+.I server-options
-+are present, then messages are only forwarded as specified by
-+the server options.
-+.SH CLIENT-OPTIONS
-+If no
-+.I client-options
-+are present, the relay receives
-+messages by multicast and unicast at all IPv6 interfaces.
-+.PP
-+If one or more client options are present, then messages
-+are only received as specified by the
-+.IR client-options .
-+.PP
-+In any case, the relay receives client messages by
-+unicast.
-+.TP
-+.B \-cu
-+This option can be used to configure the client
-+such that it receives messages from clients or other
-+relay agents by unicast only.
-+It does not have any effect if a
-+.B \-cm
-+option is present.
-+.TP
-+.BI "\-cm " INTERFACE
-+Accept client messages multicasted at IPv6
-+interface
-+.IR INTERFACE .
-+The others are receiving
-+only unicast messages. For specifying a set of
-+interfaces, an instance of this option is
-+required for each interface.
-+.SH SERVER-OPTIONS
-+If no
-+.I server-options
-+are present, the relay forwards
-+messages received from clients by multicast and unicast
-+to all IPv6 interfaces, except the one, which the packet
-+was received on.
-+.PP
-+If one or more
-+.I server-options
-+are present, then messages are forwarded as specified by the
-+.IR server-options .
-+.TP
-+.BI "\-sm " INTERFACE
-+Forward all received client messages by multicast
-+at IPv6 interface
-+.IR INTERFACE .
-+For specifying a set of interfaces, an instance of this
-+option is required for each interface.
-+.TP
-+.BI "\-su " ADDRESS
-+Forward all received client messages by unicast
-+to the IPv6 address
-+.IR ADDRESS .
-+For specifying a set
-+of addresses, an instance of this option is
-+required for each address.
-+.TP
-+.BI "\-sf " INTERFACE+ADDRESS
-+Forward all received client messages by unicast
-+to the IPv6 address
-+.I ADDRESS
-+through the IPv6 interface
-+.IR INTERFACE .
-+For specifying a set of combinations of
-+interfaces and addresses, an instance of this
-+option is required for each combination.
-+.PP
-+The
-+.BR \-sm ,
-+.BR \-su ,
-+and
-+.B \-sf
-+options can be combined in arbitrary ways.
-+.SH OTHER OPTIONS
-+.TP
-+.B \-d
-+If this option is not present, dhcp6r will dump logging
-+information into the file /var/log/dhcp6r.log. If the
-+option is present, logging information will be sent to stderr
-+instead.
-+.SH EXAMPLES
-+The following examples are shown as given to the shell:
-+.TP
-+.SH dhcp6r
-+Receive messages from clients at all IPv6
-+interfaces by multicast and by unicast, and
-+forward them to all (other) IPv6 interfaces
-+by multicast.
-+.TP
-+.SH dhcp6r -cu
-+Receive messages from clients by unicast only,
-+and forward them to all (other) IPv6 interfaces by
-+multicast.
-+.TP
-+.SH dhcp6r -cm eth0 -cm eth2
-+Receive messages from clients at interfaces
-+eth0 and eth2 by multicast and by unicast, and
-+forward them to all IPv6 interfaces by
-+multicast (except the one at which the message
-+was received by multicast).
-+.TP
-+.SH dhcp6r -cm eth0 -cm eth2 -sm eth1
-+Receive messages from clients at interfaces
-+eth0 and eth2 by multicast and by unicast, and
-+forward them to interfaces eth1 by multicast.
-+.TP
-+.nf
-+.SH dhcp6r -su fec0::204:ce33:763f:b34 -su fec0::504:ff33:73f:c557
-+.fi
-+Receive messages from clients at all IPv6
-+interfaces by multicast and by unicast, and
-+forward a copy of them to each of the specified
-+addresses.
-+.TP
-+.SH dhcp6r -sm eth1 -su fec0::204:ce33:763f:b34
-+Receive messages from clients at all IPv6
-+interfaces by multicast and by unicast, and
-+forward them to interface eth1 by multicast
-+and to the specified unicast address.
-+.TP
-+.SH dhcp6r -sm eth1 -sf eth0+fec0::504:ff33:73f:c557
-+Receive messages from clients at all IPv6
-+interfaces by multicast and by unicast, and
-+forward them to interface eth1 by multicast
-+and to the specified unicast address. For the
-+unicast address it is enforced that the message
-+will be sent through interface eth0.
-+.SH NOTES
-+For proper operation of dhcp6r, the host must have at
-+least one global/site scope address assigned to each interface.
-+.SH FILES
-+.B /var/log/dhcv6r.log
-+.br
-+.B /var/run/dhcp6r.pid
-+.br
-+.SH BUGS
-+Email bug reports to <bug@dhcpv6.org>
-+.SH AUTHORS
-+Cristian Cadar, <cadar@ccrle.nec.de>
-+.br
-+Juergen Quittek,
-+.br
-+Martin Stiemerling
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/dhcp6r.c 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,354 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <unistd.h>
-+#include <signal.h>
-+#include <string.h>
-+#if TIME_WITH_SYS_TIME
-+# include <sys/time.h>
-+# include <sys/timeb.h>
-+# include <time.h>
-+#else
-+# if HAVE_SYS_TIME_H
-+# include <sys/time.h>
-+# else
-+# include <time.h>
-+# endif
-+#endif
-+#include <sys/socket.h>
-+#include <arpa/inet.h>
-+
-+#include "relay6_parser.h"
-+#include "relay6_socket.h"
-+#include "relay6_database.h"
-+
-+int
-+main(argc, argv)
-+ int argc;
-+ char **argv;
-+{
-+ int err =0, i;
-+ FILE *fp;
-+ int sw = 0;
-+ int du = 0;
-+ struct interface *iface;
-+ struct sockaddr_in6 sin6;
-+ char *sf, *eth, *addr;
-+ struct cifaces *ci;
-+ struct sifaces *si;
-+ struct IPv6_uniaddr *unia;
-+ struct server *sa;
-+ struct msg_parser *mesg;
-+
-+ fp = fopen(PIDFILE, "w+");
-+ if (fp == NULL) {
-+ printf("COULD NOT WRITE PID FILE\n");
-+ exit(1);
-+ }
-+ fprintf(fp, "%d", getpid());
-+ fclose(fp);
-+
-+ signal(SIGINT, handler);
-+ init_relay();
-+
-+ if (argc > 1) {
-+ for (i = 1; i < argc; ++i) {
-+ if (strcmp(argv[i], "-d") == 0)
-+ du = 1;
-+ }
-+ if (du == 0) {
-+ dump = fopen(DUMPFILE, "w+");
-+ if (dump == NULL) {
-+ printf("COULD NOT WRITE DUMP FILE: %s\n", DUMPFILE);
-+ exit(1);
-+ }
-+ }
-+ else {
-+ dump = stderr;
-+ }
-+
-+ if (get_interface_info() == 0)
-+ goto ERROR;
-+
-+ for(i = 1; i < argc; ++i) {
-+ if (strcmp(argv[i], "-cm") == 0) {
-+ i++;
-+ if (get_interface_s(argv[i]) == NULL) {
-+ err = 5;
-+ goto ERROR;
-+ }
-+
-+ sw = 1;
-+ ci = (struct cifaces *) malloc(sizeof(struct cifaces));
-+ if (ci == NULL) {
-+ TRACE(dump, "%s - %s ", dhcp6r_clock(),
-+ "Main--> ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+ ci->ciface = strdup(argv[i]);
-+ ci->next = cifaces_list.next;
-+ cifaces_list.next = ci;
-+
-+ TRACE(dump, "%s - %s'%s'\n", dhcp6r_clock(),
-+ "SETTING UP CLIENT INTERFACE: ", argv[i]);
-+ continue;
-+ }
-+ else if (strcmp(argv[i], "-cu") == 0) {
-+ multicast_off = 1;
-+ }
-+ else if (strcmp(argv[i], "-sm") == 0) {
-+ i++;
-+ if (get_interface_s(argv[i]) == NULL) {
-+ err = 5;
-+ goto ERROR;
-+ }
-+ si = (struct sifaces *) malloc(sizeof(struct sifaces));
-+ if (si == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Main--> ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+ si->siface = strdup(argv[i]);
-+ si->next = sifaces_list.next;
-+ sifaces_list.next = si;
-+
-+ TRACE(dump, "%s - %s'%s'\n", dhcp6r_clock(),
-+ "SETTING UP SERVER INTERFACE: ", argv[i]);
-+
-+ continue;
-+ }
-+ else if (strcmp(argv[i], "-d") == 0) {
-+ continue;
-+ }
-+ else if (strcmp(argv[i], "-su") == 0) {
-+ i++;
-+ /* destination address */
-+ if (inet_pton(AF_INET6, argv[i] , &sin6.sin6_addr) <= 0) {
-+ err = 3;
-+ goto ERROR;
-+ }
-+
-+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr)) {
-+ err = 3;
-+ goto ERROR;
-+ }
-+
-+ unia = (struct IPv6_uniaddr *)
-+ malloc(sizeof(struct IPv6_uniaddr));
-+ if (unia == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Main--> ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+ unia->uniaddr = strdup(argv[i]);
-+ unia->next = IPv6_uniaddr_list.next;
-+ IPv6_uniaddr_list.next = unia;
-+
-+ TRACE(dump, "%s - %s'%s'\n", dhcp6r_clock(),
-+ "SETTING UP SERVER ADDRESS: ", argv[i]);
-+ nr_of_uni_addr += 1;
-+
-+ continue;
-+ }
-+ else if (strcmp(argv[i], "-sf") == 0) {
-+ i++;
-+ sf = strdup(argv[i]);
-+
-+ eth = strtok(sf, "+");
-+ if (eth == NULL) {
-+ err = 4;
-+ goto ERROR;
-+ }
-+ addr = strtok((sf+strlen(eth)+1), "\0");
-+ if (addr == NULL) {
-+ err = 4;
-+ goto ERROR;
-+ }
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, addr , &sin6.sin6_addr) <= 0) {
-+ err = 3;
-+ goto ERROR;
-+ }
-+
-+ if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr) ) {
-+ err = 3;
-+ goto ERROR;
-+ }
-+
-+ if ((iface = get_interface_s(eth)) != NULL) {
-+ sa = (struct server *) malloc(sizeof(struct server));
-+ if (sa == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Main--> ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+ sa->serv = strdup(addr);
-+ sa->next = NULL;
-+ if (iface->sname != NULL)
-+ sa->next = iface->sname;
-+ iface->sname = sa;
-+ TRACE(dump, "%s - %s%s FOR INTERFACE: %s\n", dhcp6r_clock(),
-+ "SETTING UP SERVER ADDRESS: ", addr, eth);
-+ free(sf);
-+ }
-+ else {
-+ err = 5;
-+ goto ERROR;
-+ }
-+
-+ continue;
-+ }
-+ else if ((strcmp(argv[i], "-h") == 0) ||
-+ (strcmp(argv[i], "--help") == 0)) {
-+ command_text();
-+ }
-+ else {
-+ err = 4;
-+ goto ERROR;
-+ }
-+ }
-+ }
-+ else {
-+ dump = fopen(DUMPFILE, "w+");
-+ if (dump == NULL) {
-+ printf("COULD NOT WRITE DUMP FILE: %s\n", DUMPFILE);
-+ exit(1);
-+ }
-+
-+ if (get_interface_info() == 0)
-+ goto ERROR;
-+ }
-+
-+ if (sw == 1)
-+ multicast_off = 0;
-+
-+ init_socket();
-+
-+ if (set_sock_opt() == 0)
-+ goto ERROR;
-+
-+ if (fill_addr_struct() == 0)
-+ goto ERROR;
-+
-+ if (du == 0) {
-+ switch(fork()) {
-+ case 0:
-+ break;
-+ case -1:
-+ perror("fork");
-+ exit(1);
-+ default:
-+ exit(0);
-+ }
-+ }
-+
-+ while (1) {
-+ if (check_select() == 1) {
-+ if (recv_data() == 1) {
-+ if (get_recv_data() == 1) {
-+ mesg = create_parser_obj();
-+ if (put_msg_in_store (mesg) == 0)
-+ mesg->sent = 1; /* mark it for deletion */
-+ }
-+ }
-+ }
-+
-+ send_message();
-+ delete_messages();
-+ }
-+
-+ERROR:
-+
-+ if (err == 3) {
-+ printf("dhcp6r: malformed address '%s'\n", argv[i]);
-+ exit(1);
-+ }
-+
-+ if (err == 4) {
-+ printf("dhcp6r: option '%s' not recognized\n", argv[i]);
-+ exit(1);
-+ }
-+
-+ if (err == 5) {
-+ printf("dhcp6r: interface '%s' does not exist \n", argv[i]);
-+ exit(1);
-+ }
-+
-+ printf("ERROR OCCURED IN THE RELAY AGENT LOOP, EXITING..........\n");
-+ exit(1);
-+}
-+
-+void
-+command_text()
-+{
-+ printf("Usage:\n");
-+ printf(" dhcp6r [-d] [-cu] [-cm <interface>] [-sm <interface>] "
-+ "[-su <address>] [-sf <interface>+<address>] \n");
-+ exit(1);
-+}
-+
-+char*
-+dhcp6r_clock()
-+{
-+ time_t tim;
-+ char *s, *p;
-+
-+ time(&tim);
-+ s = ctime(&tim);
-+
-+ p = s;
-+ do {
-+ p = strstr(p, " ");
-+ if (p != NULL) {
-+ if (*(p-1) == '/')
-+ *p = '0';
-+ else
-+ *p = '/';
-+ }
-+ } while(p != NULL);
-+
-+ p = strstr(s, "\n");
-+ if (p != NULL)
-+ *p = '\0';
-+
-+ return s;
-+}
-+
-+void handler(int signo) {
-+ close(recvsock->recv_sock_desc);
-+ close(sendsock->send_sock_desc);
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "RELAY AGENT IS STOPPING............\n");
-+ fflush(dump);
-+
-+ exit(0);
-+}
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/dhcp6r.h 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#ifndef __DHCP6R_H_DEFINED
-+#define __DHCP6R_H_DEFINED
-+
-+#include <stdio.h>
-+#include <stdint.h>
-+
-+#define MAX_DHCP_MSG_LENGTH 1400
-+#define MESSAGE_HEADER_LENGTH 4
-+#define ALL_DHCP_SERVERS "FF05::1:3"
-+#define ALL_DHCP_RELAY_AND_SERVERS "FF02::1:2"
-+#define INET6_LEN 16
-+#define OPAQ 5000 //opaq value for interface id
-+#define HEAD_SIZE 400
-+#define HOP_COUNT_LIMIT 30
-+#define DUMPFILE "/var/log/dhcp6r.log"
-+#define INTERFACEINFO "/proc/net/if_inet6"
-+#define PIDFILE "/var/run/dhcp6r.pid"
-+#define MAXHOPCOUNT 32
-+#define SERVER_PORT 547
-+#define CLIENT_PORT 546
-+#define TRACE fprintf
-+
-+#define SOLICIT 1
-+#define ADVERTISE 2
-+#define REQUEST 3
-+#define CONFIRM 4
-+#define RENEW 5
-+#define REBIND 6
-+#define REPLY 7
-+#define RELEASE 8
-+#define DECLINE 9
-+#define RECONFIGURE 10
-+#define INFORMATION_REQUEST 11
-+#define RELAY_FORW 12
-+#define RELAY_REPL 13
-+
-+#define OPTION_RELAY_MSG 9
-+#define OPTION_INTERFACE_ID 18
-+
-+char *dhcp6r_clock __P((void));
-+FILE *dump;
-+void handler __P((int signo));
-+
-+
-+#endif /* __DHCP6R_H_DEFINED */
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/dhcp6r.sh 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,89 @@
-+#!/bin/sh
-+#
-+# dhcp6r dhcp6r is an implementation of DHCPv6 relay agent.
-+# This shell script takes care of starting and stopping
-+# dhcp6r.
-+#
-+# chkconfig: - 66 36
-+# description: dhcp6r supports the DHCPv6 relay agent protocol.
-+#
-+# processname: dhcp6r
-+# config: /etc/sysconfig/dhcp6r
-+
-+# Source function library.
-+. /etc/rc.d/init.d/functions
-+
-+# Source networking configuration.
-+. /etc/sysconfig/network
-+. /etc/sysconfig/dhcp6r
-+
-+# Check that networking is up.
-+# networking is not up, return 1 for generic error
-+[ ${NETWORKING} = "no" ] && exit 1
-+
-+# Check that files exist
-+# return 5 if program is not installed
-+[ -f /usr/sbin/dhcp6r ] || exit 5
-+
-+# return 6 if program is not configured
-+[ -f /etc/sysconfig/dhcp6r ] || exit 6
-+
-+RETVAL=0
-+prog="dhcp6r"
-+
-+start() {
-+ # Start daemons.
-+ echo -n $"Starting $prog: "
-+ daemon /usr/sbin/dhcp6r ${DHCP6RARGS}
-+ RETVAL=$?
-+ echo
-+ [ $RETVAL -eq 0 ] && touch /var/lock/subsys/dhcp6r
-+ return $RETVAL
-+}
-+
-+stop() {
-+ # Stop daemons.
-+ echo -n $"Shutting down $prog: "
-+ killproc dhcp6r
-+ RETVAL=$?
-+ echo
-+ [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/dhcp6r
-+ return $RETVAL
-+}
-+
-+# See how we were called.
-+case "$1" in
-+ start)
-+ start
-+ RETVAL=$?
-+ ;;
-+ stop)
-+ stop
-+ RETVAL=$?
-+ ;;
-+ restart|force-reload)
-+ stop
-+ start
-+ RETVAL=$?
-+ ;;
-+ reload)
-+ # unimplemented
-+ RETVAL=3
-+ ;;
-+ condrestart)
-+ if [ -f /var/lock/subsys/dhcp6s ]; then
-+ stop
-+ start
-+ RETVAL=$?
-+ fi
-+ ;;
-+ status)
-+ status dhcp6r
-+ RETVAL=$?
-+ ;;
-+ *)
-+ echo $"Usage: $0 {start|stop|restart|condrestart|status}"
-+ exit 1
-+esac
-+
-+exit $RETVAL
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/dhcp6r.sysconfig 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,3 @@
-+# Configuration for the DHCPv6 relay agent, dhcp6r
-+# Command line options here
-+DHCP6RARGS=
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/relay6_database.c 2007-02-09 00:47:58.000000000 -0500
-@@ -0,0 +1,569 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <arpa/inet.h>
-+
-+#include "relay6_database.h"
-+
-+void
-+init_relay()
-+{
-+ nr_of_uni_addr = 0;
-+ multicast_off = 0;
-+ nr_of_devices = 0;
-+ max_count = 0;
-+
-+ cifaces_list.next = &cifaces_list;
-+
-+ sifaces_list.next = &sifaces_list;
-+
-+ server_list.next = &server_list;
-+
-+ IPv6_address_list.next = &IPv6_address_list;
-+
-+ IPv6_uniaddr_list.next = &IPv6_uniaddr_list;
-+
-+ interface_list.prev = &interface_list;
-+ interface_list.next = &interface_list;
-+
-+ msg_parser_list.prev = &msg_parser_list;
-+ msg_parser_list.next = &msg_parser_list;
-+}
-+
-+int
-+check_interface_semafor(index)
-+ int index;
-+{
-+ struct interface *device = NULL;
-+ struct cifaces *iface;
-+
-+ device = get_interface(index);
-+ if (device == NULL) {
-+ printf("FATAL ERROR IN CheckInterfaceSemafor()\n");
-+ exit(1);
-+ }
-+
-+ if (cifaces_list.next == &cifaces_list)
-+ return 1;
-+
-+ for (iface = cifaces_list.next; iface != &cifaces_list;
-+ iface = iface->next) {
-+ if (strcmp(device->ifname, iface->ciface) == 0)
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+struct interface *
-+get_interface(if_index)
-+ int if_index;
-+{
-+ struct interface *deviface;
-+
-+ for (deviface = interface_list.next; deviface != &interface_list;
-+ deviface = deviface->next) {
-+ if (deviface->devindex == if_index)
-+ return deviface;
-+ }
-+
-+ return NULL;
-+}
-+
-+struct interface *
-+get_interface_s(s)
-+ char *s;
-+{
-+ struct interface *deviface;
-+
-+ for (deviface = interface_list.next; deviface != &interface_list;
-+ deviface = deviface->next) {
-+ if (strcmp(s, deviface->ifname)== 0)
-+ return deviface;
-+ }
-+
-+ return NULL;
-+}
-+
-+struct msg_parser *
-+get_send_messages_out()
-+{
-+ struct msg_parser *msg;
-+
-+ for (msg = msg_parser_list.next; msg != &msg_parser_list; msg = msg->next) {
-+ if (msg->sent == 0)
-+ return msg;
-+ }
-+
-+ return NULL;
-+}
-+
-+
-+void
-+delete_messages()
-+{
-+ struct msg_parser *msg;
-+
-+ for (msg = msg_parser_list.next; msg != &msg_parser_list; msg = msg->next) {
-+ if (msg->sent == 1) {
-+ msg->prev->next = msg->next;
-+ msg->next->prev = msg->prev;
-+ msg->next = NULL;
-+ msg->prev = NULL;
-+ free(msg->buffer);
-+ free(msg);
-+ msg = msg_parser_list.next;
-+ }
-+ }
-+}
-+
-+
-+int
-+process_RELAY_FORW(msg)
-+ struct msg_parser *msg;
-+{
-+ uint8_t *head = (uint8_t *) malloc(HEAD_SIZE*sizeof(uint8_t));
-+ uint8_t *newbuff = (uint8_t *) malloc(MAX_DHCP_MSG_LENGTH*sizeof(uint8_t));
-+ uint8_t *pointer;
-+ struct interface *device = NULL;
-+ struct sockaddr_in6 sap;
-+ int check = 0;
-+ uint16_t *p16, *optl;
-+ uint32_t *p32;
-+ int len, hop;
-+
-+ if ((head == NULL) || (newbuff == NULL)) {
-+ printf("ProcessRELAYFORW--> ERROR, NO MORE MEMRY AVAILABLE \n");
-+ exit(1);
-+ }
-+
-+ memset(head, 0, HEAD_SIZE);
-+
-+ pointer = head;
-+
-+
-+ if (msg->isRF == 1) { /* got message from a relay agent to be relayed */
-+ (*pointer) = RELAY_FORW;
-+ pointer += 1;
-+ (*pointer) = msg->hop_count + 1; /* increased hop-count */
-+ msg->hc_pointer = pointer;
-+
-+ if (max_count == 1) {
-+ (*pointer) = MAXHOPCOUNT;
-+ hop = (int) (*pointer);
-+ TRACE(dump, "%s - %s%d\n", dhcp6r_clock(), "HOPCOUNT: ", hop);
-+ }
-+
-+ pointer += 1;
-+
-+ }
-+ else { /*got message from a client to be relayed */
-+ (*pointer) = RELAY_FORW;
-+ pointer += 1;
-+ (*pointer) = 0; /* hop-count */
-+ msg->hc_pointer = pointer;
-+
-+ if (max_count == 1) {
-+ (*pointer) = MAXHOPCOUNT;
-+ hop = (int) (*pointer);
-+ TRACE(dump, "%s - %s%d\n", dhcp6r_clock(), "HOPCOUNT: ", hop);
-+ }
-+ pointer += 1;
-+ }
-+
-+ msg->msg_type = RELAY_FORW;
-+
-+ device = get_interface(msg->interface_in);
-+ if (device == NULL) {
-+ printf("ProcessRELAYFORW--->ERROR NO INTERFACE FOUND!\n");
-+ exit(1);
-+ }
-+
-+ /* fill in link-address */
-+
-+ if (inet_pton(AF_INET6, msg->src_addr , &sap.sin6_addr) <= 0) {
-+ printf("ProcessRELAYFORW1--->ERROR IN inet_pton !\n");
-+ exit(1);
-+ }
-+
-+ if ((!IN6_IS_ADDR_LINKLOCAL(&sap.sin6_addr)) && (nr_of_devices == 1 )) {
-+ memset(&sap.sin6_addr, 0, sizeof(sap.sin6_addr));
-+ memcpy(pointer, &sap.sin6_addr, INET6_LEN);
-+ pointer += INET6_LEN;
-+ }
-+ else {
-+ check = 0;
-+
-+ memset(&sap.sin6_addr, 0, sizeof(sap.sin6_addr));
-+
-+ if (inet_pton(AF_INET6, device->ipv6addr->gaddr, &sap.sin6_addr) <= 0) {
-+ printf("ProcessRELAYFORW1--->ERROR IN inet_pton !\n");
-+ exit(1);
-+ }
-+
-+ memcpy(pointer, &sap.sin6_addr, INET6_LEN);
-+ pointer += INET6_LEN;
-+ }
-+
-+
-+ /* fill in peer-addrees */
-+ memset(&sap.sin6_addr, 0, sizeof(sap.sin6_addr));
-+
-+ if (inet_pton(AF_INET6, msg->src_addr , &sap.sin6_addr) <= 0) {
-+ printf("ProcessRELAYFORW--->ERROR2 IN inet_pton !\n");
-+ exit(1);
-+ }
-+
-+ memcpy(pointer, &sap.sin6_addr, INET6_LEN);
-+ pointer += INET6_LEN;
-+
-+ /* Insert Interface_ID option to identify the interface */
-+ p16 = (uint16_t *) pointer;
-+ *p16 = htons(OPTION_INTERFACE_ID);
-+ pointer += 2;
-+ p16 = (uint16_t *) pointer;
-+ *p16 = htons(4); /* 4 octeti length */
-+ pointer += 2;
-+ p32 = (uint32_t *) pointer;
-+ *p32 = htonl(device->opaq);
-+ pointer += 4;
-+
-+ p16 = (uint16_t *) pointer;
-+ *p16 = htons(OPTION_RELAY_MSG);
-+ pointer += 2;
-+ optl = (uint16_t *) pointer;
-+ pointer += 2;
-+ *optl = htons(msg->datalength);
-+
-+ len = (pointer - head);
-+ TRACE(dump, "%s - %s%d\n", dhcp6r_clock(), "RELAY_FORW HEADERLENGTH: ",
-+ len);
-+ TRACE(dump, "%s - %s%d\n", dhcp6r_clock(), "ORIGINAL MESSAGE LENGTH: ",
-+ msg->datalength );
-+
-+ if ((len+ msg->datalength) > MAX_DHCP_MSG_LENGTH) {
-+ printf(" ERROR FRAGMENTATION WILL OCCUR IF SENT, DROP THE PACKET"
-+ "......\n");
-+ return 0;
-+ }
-+
-+ pointer = newbuff;
-+ memset(pointer, 0, MAX_DHCP_MSG_LENGTH);
-+ memcpy(pointer, head, len);
-+ pointer += len;
-+ memcpy(pointer, msg->buffer, msg->datalength);
-+ msg->datalength += len; /* final length for sending */
-+ free(msg->buffer);
-+ free(head);
-+ msg->buffer = newbuff;
-+
-+ return 1;
-+}
-+
-+int
-+process_RELAY_REPL(msg)
-+ struct msg_parser *msg;
-+{
-+ uint8_t *newbuff = (uint8_t *) malloc(MAX_DHCP_MSG_LENGTH*sizeof(uint8_t));
-+ uint8_t *pointer, *pstart, *psp;
-+ struct interface *device = NULL;
-+ struct sockaddr_in6 sap;
-+ int check = 0;
-+ uint16_t *p16, option, opaqlen, msglen;
-+ uint32_t *p32;
-+ int len, opaq;
-+ struct IPv6_address *ipv6a;
-+ char *s;
-+
-+ if (newbuff == NULL) {
-+ printf("ProcessRELAYREPL--> ERROR, NO MORE MEMRY AVAILABLE \n");
-+ exit(1);
-+ }
-+
-+ pointer = msg->buffer;
-+ pstart = pointer;
-+
-+ if ((*msg->buffer - (*pointer - *pstart)) < MESSAGE_HEADER_LENGTH) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "MESSAGE_HEADER_LENGTH, DROPING... \n");
-+ return 0;
-+ }
-+
-+ if (*pointer != RELAY_REPL)
-+ return 0;
-+
-+ pointer += 1; /* RELAY_FORW */
-+ msg->hop = *pointer;
-+ pointer += 1; /* hop-count */
-+ msg->msg_type = RELAY_REPL;
-+
-+ if ((*msg->buffer - (*pointer - *pstart)) < (2*INET6_LEN) ) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "INET6_LEN, DROPING... \n");
-+ return 0;
-+ }
-+
-+ /* extract link_address */
-+ memset(msg->link_addr, 0, INET6_ADDRSTRLEN);
-+ memset(&sap.sin6_addr, 0, sizeof(sap.sin6_addr));
-+ memcpy(&sap.sin6_addr, pointer, INET6_LEN);
-+ pointer += INET6_LEN;
-+
-+ if (inet_ntop(AF_INET6, &sap.sin6_addr, msg->link_addr,
-+ INET6_ADDRSTRLEN ) <=0 ) {
-+ printf("ProcessRELAYREPL1--->ERROR IN inet_ntop !\n");
-+ exit(1);
-+ }
-+
-+ /* extract peer address */
-+ memset(msg->peer_addr, 0, INET6_ADDRSTRLEN);
-+ memset(&sap.sin6_addr, 0, sizeof(sap.sin6_addr));
-+ memcpy(&sap.sin6_addr, pointer, INET6_LEN);
-+ pointer += INET6_LEN;
-+
-+ if (inet_ntop(AF_INET6, &sap.sin6_addr, msg->peer_addr,
-+ INET6_ADDRSTRLEN ) <=0 ) {
-+ printf("ProcessRELAYREPL1--->ERROR IN inet_ntop !\n");
-+ exit(1);
-+ }
-+
-+ if ((*msg->buffer - (*pointer - *pstart)) < MESSAGE_HEADER_LENGTH ) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "MESSAGE_HEADER_LENGTH, DROPING... \n");
-+ return 0;
-+ }
-+
-+ p16 = (uint16_t *) pointer;
-+ option = ntohs(*p16);
-+
-+ if (option == OPTION_INTERFACE_ID) {
-+ pointer += 2;
-+ p16 = (uint16_t *) pointer;
-+ opaqlen = ntohs(*p16);
-+ pointer += 2;
-+
-+ if ((*msg->buffer - (*pointer - *pstart)) < opaqlen) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "opaqlen, DROPING... \n");
-+ return 0;
-+ }
-+
-+ p32 = (uint32_t *) pointer;
-+ opaq = ntohl(*p32);
-+ pointer += opaqlen;
-+
-+ if ((*msg->buffer - (*pointer - *pstart)) < MESSAGE_HEADER_LENGTH ) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "MESSAGE_HEADER_LENGTH, DROPING... \n");
-+ return 0;
-+ }
-+
-+ p16 = (uint16_t *) pointer;
-+ option = ntohs(*p16);
-+
-+ if (option == OPTION_RELAY_MSG) {
-+ pointer += 2;
-+ p16 = (uint16_t *) pointer;
-+ msglen = ntohs(*p16);
-+ pointer += 2;
-+ if ((*msg->buffer - (*pointer - *pstart)) < msglen) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "msglen, DROPING... \n");
-+ return 0;
-+ }
-+
-+ /*--------------------------*/
-+ if (*pointer == RELAY_FORW)
-+ *pointer = RELAY_REPL; /* is the job of the server to set to
-+ RELAY_REPL? */
-+ /*--------------------------*/
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ if (device->opaq == opaq)
-+ break;
-+ }
-+
-+ if (device != &interface_list ) {
-+ msg->if_index = device->devindex;
-+ memset(newbuff, 0, MAX_DHCP_MSG_LENGTH);
-+ len = (pointer - msg->buffer);
-+ len = (msg->datalength - len);
-+ memcpy(newbuff, pointer, len);
-+ msg->datalength = len;
-+ free(msg->buffer);
-+ msg->buffer = newbuff;
-+ return 1;
-+
-+ }
-+ else {
-+ s = msg->link_addr;
-+
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ ipv6a = device->ipv6addr;
-+
-+ while(ipv6a!= NULL) {
-+ if (strcmp(s, ipv6a->gaddr) == 0) {
-+ msg->if_index = device->devindex;
-+ check = 1;
-+ break;
-+ }
-+ ipv6a = ipv6a->next;
-+ }
-+
-+ if (check == 1)
-+ break;
-+ }
-+
-+ if (check == 0) {
-+ printf("ProcessRELAYREPL--->ERROR NO INTERFACE FOUND!\n");
-+ return 0;
-+ }
-+
-+ memset(newbuff, 0, MAX_DHCP_MSG_LENGTH);
-+ len = (pointer - msg->buffer);
-+ len = (msg->datalength - len);
-+ memcpy(newbuff, pointer, len);
-+ msg->datalength = len;
-+ free(msg->buffer);
-+ msg->buffer = newbuff;
-+ return 1;
-+ }
-+ }
-+ else { /* OPTION_RELAY_MSG */
-+ printf("ProcessRELAYREPL--->ERROR MESSAGE IS MALFORMED NO "
-+ "OPTION_RELAY_MSG FOUND, DROPING...!\n");
-+ return 0;
-+ }
-+ } /* OPTION_INTERFACE_ID */
-+
-+ if (option == OPTION_RELAY_MSG) {
-+ pointer += 2;
-+ p16 = (uint16_t *) pointer;
-+ msglen = ntohs(*p16);
-+ pointer += 2;
-+
-+ if ((*msg->buffer - (*pointer - *pstart)) < msglen ) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value for "
-+ "msglen, DROPING... \n");
-+ return 0;
-+ }
-+
-+ opaq = 0;
-+ psp = (pointer + msglen); /* jump over message, seek for
-+ OPTION_INTERFACE_ID */
-+
-+ if ((*msg->buffer - (*psp - *pstart)) >= MESSAGE_HEADER_LENGTH ) {
-+ if (option == OPTION_INTERFACE_ID) {
-+ psp += 2;
-+ p16 = (uint16_t *) psp;
-+ opaqlen = ntohs(*p16);
-+ psp += 2;
-+
-+ if ((*msg->buffer - (*psp - *pstart)) < opaqlen) {
-+ printf("ProcessRELAYREPL()--> opt_length has 0 value "
-+ "for opaqlen, DROPING... \n");
-+ return 0;
-+ }
-+
-+ p32 = (uint32_t *) psp;
-+ opaq = ntohl(*p32);
-+ psp += opaqlen;
-+ }
-+ }
-+
-+ /*--------------------------*/
-+ if (*pointer == RELAY_FORW)
-+ *pointer = RELAY_REPL; /* is the job of the server to set to
-+ RELAY_REPL? */
-+ /*--------------------------*/
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ if (device->opaq == opaq)
-+ break;
-+ }
-+
-+ if (device != &interface_list) {
-+ msg->if_index = device->devindex;
-+ memset(newbuff, 0, MAX_DHCP_MSG_LENGTH);
-+ len = (pointer - msg->buffer);
-+ len = (msg->datalength - len);
-+ memcpy(newbuff, pointer, len);
-+ msg->datalength = len;
-+ free(msg->buffer);
-+ msg->buffer = newbuff;
-+ return 1;
-+ }
-+ else {
-+ s = msg->link_addr;
-+
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ ipv6a = device->ipv6addr;
-+
-+ while(ipv6a != NULL) {
-+ if (strcmp(s, ipv6a->gaddr) == 0) {
-+ msg->if_index = device->devindex;
-+ check = 1;
-+ break;
-+ }
-+ ipv6a = ipv6a->next;
-+ }
-+
-+ if (check == 1)
-+ break;
-+ }
-+
-+ if (check == 0) {
-+ printf("ProcessRELAYREPL--->ERROR NO INTERFACE FOUND!\n");
-+ return 0;
-+ }
-+
-+ memset(newbuff, 0, MAX_DHCP_MSG_LENGTH);
-+ len = (pointer - msg->buffer);
-+ len = (msg->datalength - len);
-+ memcpy(newbuff, pointer, len);
-+ msg->datalength = len;
-+ free(msg->buffer);
-+ msg->buffer = newbuff;
-+ return 1;
-+ }
-+ }
-+ else { /* OPTION_RELAY_MSG */
-+ printf("ProcessRELAYREPL--->ERROR MESSAGE IS MALFORMED NO "
-+ "OPTION_RELAY_MSG FOUND, DROPING...!\n");
-+ return 0;
-+ }
-+
-+ return 1;
-+}
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/relay6_database.h 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,98 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#ifndef __RELAY6_DATABASE_H_DEFINED
-+#define __RELAY6_DATABASE_H_DEFINED
-+
-+#include "dhcp6r.h"
-+#include "relay6_parser.h"
-+
-+struct cifaces {
-+ struct cifaces *next;
-+ char *ciface;
-+};
-+
-+struct sifaces {
-+ struct sifaces *next;
-+ char *siface;
-+};
-+
-+struct server {
-+ struct server *next;
-+ char *serv;
-+};
-+
-+struct IPv6_address {
-+ struct IPv6_address *next;
-+ char *gaddr;
-+};
-+
-+struct IPv6_uniaddr { /* STORAGE OF UNICAST DEST. SERVER ADRESSES */
-+ struct IPv6_uniaddr *next;
-+ char *uniaddr;
-+};
-+
-+struct interface {
-+ struct interface *next;
-+ struct interface *prev;
-+
-+ struct server *sname;
-+ struct IPv6_address *ipv6addr;
-+
-+ int got_addr;
-+ char *ifname;
-+ uint32_t devindex;
-+ char *link_local;
-+ int opaq;
-+};
-+
-+struct cifaces cifaces_list;
-+struct sifaces sifaces_list;
-+struct server server_list;
-+struct IPv6_address IPv6_address_list;
-+struct IPv6_uniaddr IPv6_uniaddr_list;
-+struct interface interface_list ;
-+
-+int process_RELAY_FORW __P((struct msg_parser *msg));
-+int process_RELAY_REPL __P((struct msg_parser *msg));
-+struct msg_parser *get_send_messages_out __P((void));
-+void delete_messages __P((void));
-+int check_interface_semafor __P((int index));
-+struct interface *get_interface __P((int if_index));
-+struct interface *get_interface_s __P((char *s));
-+
-+int nr_of_devices;
-+int nr_of_uni_addr;
-+int max_count;
-+int multicast_off;
-+
-+void init_relay __P((void));
-+void command_text __P((void));
-+
-+#endif /* __RELAY6_DATABASE_H_DEFINED */
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/relay6_parser.c 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,278 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "relay6_parser.h"
-+#include "relay6_database.h"
-+
-+struct msg_parser *create_parser_obj()
-+{
-+ struct msg_parser *msg;
-+
-+ msg = (struct msg_parser *) malloc (sizeof(struct msg_parser));
-+ if (msg == NULL) {
-+ printf("create_parser_obj()--> NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+
-+ msg->buffer = (uint8_t *) malloc(MAX_DHCP_MSG_LENGTH*sizeof(uint8_t));
-+ if (msg->buffer == NULL) {
-+ printf("create_parser_obj()--> NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+
-+ memcpy(msg->buffer, recvsock->databuf, MAX_DHCP_MSG_LENGTH);
-+
-+ msg->sent = 0;
-+ msg->if_index = 0;
-+
-+ msg->interface_in = recvsock->pkt_interface;
-+ memcpy(msg->src_addr, recvsock->src_addr, sizeof(recvsock->src_addr));
-+ msg->datalength = recvsock->buflength;
-+ msg->pointer_start = msg->buffer;
-+ msg->dst_addr_type = recvsock->dst_addr_type;
-+
-+ msg->prev = &msg_parser_list;
-+ msg->next = msg_parser_list.next;
-+ msg->prev->next = msg;
-+ msg->next->prev = msg;
-+
-+ TRACE(dump, "\n%s - RECEIVED NEW MESSAGE ON INTERFACE: %d, SOURCE: %s\n",
-+ dhcp6r_clock(), msg->interface_in, msg->src_addr);
-+
-+ return msg;
-+}
-+
-+int
-+check_buffer(ref, mesg)
-+ int ref;
-+ struct msg_parser *mesg;
-+{
-+ int diff;
-+ diff =(int) (mesg->pstart - mesg->pointer_start);
-+
-+ if ((((int) mesg->datalength) - diff) >= ref)
-+ return 1;
-+ else
-+ return 0;
-+}
-+
-+int
-+put_msg_in_store(mesg)
-+ struct msg_parser *mesg;
-+{
-+ uint32_t msg_type;
-+ uint8_t *hop, msg;
-+
-+ /* --------------------------- */
-+ mesg->pstart = mesg->buffer;
-+
-+ if (check_buffer(MESSAGE_HEADER_LENGTH, mesg) == 0) {
-+ printf("put_msg_in_store()--> opt_length has 0 value for "
-+ "MESSAGE_HEADER_LENGTH, DROPING... \n");
-+ return 0;
-+ }
-+ msg_type = *((uint32_t *) mesg->pstart);
-+ msg_type = (ntohl(msg_type) & 0xFF000000)>>24;
-+
-+ if (msg_type == SOLICIT) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'SOLICIT' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == REBIND) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'REBIND' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == INFORMATION_REQUEST) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'INFORMATION_REQUEST' FROM CLIENT---> "
-+ "IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == REQUEST) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'REQUEST' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == REPLY) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'REPLY' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == RENEW) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'RENEW' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == RECONFIGURE) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'RECONFIGURE' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == CONFIRM) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'CONFIRM' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == ADVERTISE) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'ADVERTISE' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == DECLINE) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'DECLINE' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ else if (msg_type == RELEASE) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'RELEASE' FROM CLIENT---> IS TO BE RELAYED\n");
-+ mesg->isRF = 0;
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+ msg = *mesg->pstart;
-+
-+ if (msg == RELAY_FORW) {
-+ if (check_interface_semafor(mesg->interface_in) == 0)
-+ return 0;
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'RELAY_FORW' FROM RELAY AGENT---> "
-+ "IS TO BE FURTHER RELAYED\n");
-+ hop = (mesg->pstart + 1);
-+ if (*hop >= HOP_COUNT_LIMIT) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "HOP COUNT EXCEEDED, PACKET WILL BE DROPED...\n");
-+ return 0;
-+ }
-+
-+ mesg->hop_count = *hop;
-+ mesg->isRF = 1;
-+
-+ if (process_RELAY_FORW(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+
-+ if (msg == RELAY_REPL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "GOT MESSAGE 'RELAY_REPL' FROM RELAY AGENT OR SERVER---> "
-+ "IS TO BE FURTHER RELAYED\n");
-+
-+ if (process_RELAY_REPL(mesg) == 0)
-+ return 0;
-+
-+ return 1;
-+ }
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "put_msg_in_store()--> ERROR GOT UNKNOWN MESSAGE DROPING IT......\n");
-+
-+ return 0;
-+}
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/relay6_parser.h 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,62 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#ifndef __RELAY6_PARSER_H_DEFINED
-+#define __RELAY6_PARSER_H_DEFINED
-+
-+#include "dhcp6r.h"
-+#include "relay6_socket.h"
-+
-+struct msg_parser {
-+ struct msg_parser *next;
-+ struct msg_parser *prev;
-+
-+ int if_index;
-+ uint8_t msg_type;
-+ uint8_t hop;
-+ uint8_t *buffer;
-+ uint8_t *ptomsg;
-+ uint8_t *pstart, *pointer_start, *hc_pointer;
-+ uint32_t datalength; /* the length of the DHCPv6 message */
-+ int dst_addr_type;
-+ char src_addr[INET6_ADDRSTRLEN]; /* source address from the UDP packet */
-+ char peer_addr[INET6_ADDRSTRLEN];
-+ char link_addr[INET6_ADDRSTRLEN];
-+ int interface_in, hop_count;
-+ int sent;
-+ int isRF;
-+};
-+
-+struct msg_parser msg_parser_list;
-+
-+struct msg_parser *create_parser_obj __P((void));
-+int put_msg_in_store __P((struct msg_parser *mesg));
-+int check_buffer __P((int ref, struct msg_parser *mesg));
-+
-+#endif /* __RELAY6_PARSER_H_DEFINED */
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/relay6_socket.c 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,802 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <arpa/inet.h>
-+#include <net/if.h>
-+
-+#include "relay6_socket.h"
-+#include "relay6_database.h"
-+
-+void
-+init_socket()
-+{
-+ recvsock = (struct receive *) malloc(sizeof(struct receive));
-+ sendsock = (struct send *) malloc(sizeof(struct send));
-+
-+ if ((recvsock == NULL) || (sendsock == NULL)) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "init_socket--> ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+
-+ memset(recvsock, 0, sizeof(struct receive));
-+ memset(sendsock, 0, sizeof(struct send));
-+
-+ recvsock->databuf = (char *) malloc(MAX_DHCP_MSG_LENGTH*sizeof(char));
-+ if (recvsock->databuf == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "init_socket--> ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+
-+ if ((recvsock->recv_sock_desc = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-+ printf("Failed to get new socket with socket()\n");
-+ exit(0);
-+ }
-+
-+ if ((sendsock->send_sock_desc = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
-+ printf("Failed to get new socket with socket()\n");
-+ exit(0);
-+ }
-+}
-+
-+int
-+get_recv_data()
-+{
-+ struct cmsghdr *cm;
-+ struct in6_pktinfo *pi;
-+ struct sockaddr_in6 dst;
-+
-+ memset(recvsock->src_addr, 0, sizeof(recvsock->src_addr));
-+
-+ for(cm = (struct cmsghdr *) CMSG_FIRSTHDR(&recvsock->msg); cm;
-+ cm = (struct cmsghdr *) CMSG_NXTHDR(&recvsock->msg, cm)) {
-+ if ((cm->cmsg_level == IPPROTO_IPV6) && (cm->cmsg_type == IPV6_PKTINFO)
-+ && (cm->cmsg_len == CMSG_LEN(sizeof(struct in6_pktinfo)))) {
-+ pi = (struct in6_pktinfo *)(CMSG_DATA(cm));
-+ dst.sin6_addr = pi->ipi6_addr;
-+ recvsock->pkt_interface = pi->ipi6_ifindex; /* the interface index
-+ the packet got in */
-+
-+ if (IN6_IS_ADDR_LOOPBACK(&recvsock->from.sin6_addr)) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "get_recv_data()-->SOURCE ADDRESS IS LOOPBACK!\n");
-+ return 0;
-+ }
-+
-+ if (inet_ntop(AF_INET6, &recvsock->from.sin6_addr,
-+ recvsock->src_addr, INET6_ADDRSTRLEN) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_ntop failed in get_recv_data()\n");
-+ return 0;
-+ }
-+
-+ if (IN6_IS_ADDR_LOOPBACK(&dst.sin6_addr)) {
-+ recvsock->dst_addr_type = 1;
-+ }
-+ else if (IN6_IS_ADDR_MULTICAST(&dst.sin6_addr)) {
-+ recvsock->dst_addr_type = 2;
-+ if (multicast_off == 1) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "RECEIVED MULTICAST PACKET IS DROPPED, ONLY UNICAST "
-+ "IS ALLOWED!\n");
-+ return 0;
-+ }
-+ }
-+ else if (IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr)) {
-+ recvsock->dst_addr_type = 3;
-+ }
-+ else if (IN6_IS_ADDR_SITELOCAL(&dst.sin6_addr))
-+ recvsock->dst_addr_type = 4;
-+
-+ return 1;
-+ }
-+ } /* for */
-+
-+ return 0;
-+}
-+
-+int
-+check_select(void)
-+{
-+ int i = 0;
-+ int flag = 0;
-+ struct timeval tv;
-+
-+ tv.tv_sec = 0;
-+ tv.tv_usec = 0;
-+
-+ FD_ZERO(&readfd);
-+ fdmax = recvsock->recv_sock_desc; /* check the max of them if many
-+ desc used */
-+ FD_SET(fdmax, &readfd);
-+
-+ if ((i = select(fdmax+1, &readfd, NULL, NULL, &tv)) == -1) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(), "Failure in select()\n");
-+ return 0;
-+ }
-+
-+ if (FD_ISSET(fdmax, &readfd)) {
-+ flag = 1;
-+ }
-+ else{
-+ flag = 0;
-+ }
-+
-+ return flag;
-+}
-+
-+int
-+set_sock_opt()
-+{
-+ int on = 1;
-+ struct interface *device;
-+ int flag;
-+ struct cifaces *iface;
-+ struct ipv6_mreq sock_opt;
-+
-+ if (setsockopt(recvsock->recv_sock_desc, IPPROTO_IPV6, IPV6_PKTINFO,
-+ &on, sizeof(on) ) < 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Failed to set socket for IPV6_PKTINFO\n");
-+ return 0;
-+ }
-+
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ if (cifaces_list.next != &cifaces_list) {
-+ flag = 0;
-+ for (iface = cifaces_list.next; iface != &cifaces_list;
-+ iface = iface->next) {
-+ if (strcmp(device->ifname, iface->ciface) == 0) {
-+ flag = 1;
-+ break;
-+ }
-+ }
-+ if (flag == 0)
-+ continue;
-+ }
-+
-+ sock_opt.ipv6mr_interface = device->devindex;
-+
-+ if (inet_pton(AF_INET6, ALL_DHCP_RELAY_AND_SERVERS,
-+ &sock_opt.ipv6mr_multiaddr) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Failed to set struct for MULTICAST receive\n");
-+ return 0;
-+ }
-+
-+ if (setsockopt(recvsock->recv_sock_desc, IPPROTO_IPV6, IPV6_JOIN_GROUP,
-+ (char *) &sock_opt, sizeof(sock_opt)) < 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Failed to set socket option for IPV6_JOIN_GROUP \n");
-+ return 0;
-+ }
-+ }
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "SOCKET OPTIONS ARE SET............\n");
-+ fflush(dump);
-+ return 1;
-+}
-+
-+
-+int
-+fill_addr_struct()
-+{
-+ bzero((char *)&recvsock->from, sizeof(struct sockaddr_in6));
-+ recvsock->from.sin6_family = AF_INET6;
-+ recvsock->from.sin6_addr = in6addr_any;
-+ recvsock->from.sin6_port = htons(547);
-+
-+ recvsock->iov[0].iov_base = recvsock->databuf;
-+ recvsock->iov[0].iov_len = MAX_DHCP_MSG_LENGTH;
-+ recvsock->msg.msg_name = (void *) &recvsock->from;
-+ recvsock->msg.msg_namelen = sizeof(recvsock->from);
-+ recvsock->msg.msg_iov = &recvsock->iov[0];
-+ recvsock->msg.msg_iovlen = 1;
-+
-+ recvsock->recvmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-+ recvsock->recvp = (char *) malloc(recvsock->recvmsglen*sizeof(char));
-+ recvsock->msg.msg_control = (void *) recvsock->recvp;
-+ recvsock->msg.msg_controllen = recvsock->recvmsglen;
-+
-+ if (bind(recvsock->recv_sock_desc, (struct sockaddr *)&recvsock->from,
-+ sizeof(recvsock->from)) < 0) {
-+ perror("bind");
-+ return 0;
-+ }
-+
-+ return 1;
-+}
-+
-+int
-+recv_data()
-+{
-+ int count = -1;
-+
-+ memset(recvsock->databuf, 0, (MAX_DHCP_MSG_LENGTH*sizeof(char)));
-+
-+ if ((count = recvmsg(recvsock->recv_sock_desc, &recvsock->msg, 0)) < 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "Failed to receive data with recvmsg()-->Receive::recv_data()\n");
-+ return -1;
-+ }
-+
-+ recvsock->buflength = count;
-+
-+ return 1;
-+}
-+
-+int
-+get_interface_info()
-+{
-+ FILE *f;
-+ char addr6[40], devname[20];
-+ struct sockaddr_in6 sap;
-+ int plen, scope, dad_status, if_idx;
-+ char addr6p[8][5];
-+ char src_addr[INET6_ADDRSTRLEN];
-+ struct interface *device = NULL;
-+ int opaq = OPAQ;
-+ int sw = 0;
-+ struct IPv6_address *ipv6addr;
-+
-+ if ((f = fopen(INTERFACEINFO, "r")) == NULL) {
-+ printf("FATAL ERROR-->COULD NOT OPEN FILE: %s\n", INTERFACEINFO);
-+ return 0;
-+ }
-+
-+ while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
-+ addr6p[0], addr6p[1], addr6p[2], addr6p[3],addr6p[4],
-+ addr6p[5], addr6p[6], addr6p[7], &if_idx, &plen, &scope,
-+ &dad_status, devname) != EOF) {
-+ memset(src_addr, 0, INET6_ADDRSTRLEN);
-+ sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s", addr6p[0], addr6p[1],
-+ addr6p[2], addr6p[3],addr6p[4], addr6p[5], addr6p[6],
-+ addr6p[7]);
-+ sap.sin6_family = AF_INET6;
-+ sap.sin6_port = 0;
-+
-+ if (inet_pton(AF_INET6, addr6, sap.sin6_addr.s6_addr) <= 0)
-+ return 0;
-+
-+ if (inet_ntop(AF_INET6, &sap.sin6_addr, src_addr, sizeof(src_addr)) <=
-+ 0)
-+ return 0;
-+
-+ if (IN6_IS_ADDR_LOOPBACK(&sap.sin6_addr))
-+ continue;
-+
-+ sw = 0;
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ if (device->devindex == if_idx) {
-+ sw = 1;
-+ break;
-+ }
-+ }
-+
-+ if (sw == 0) {
-+ opaq += 10;
-+ device = (struct interface *) malloc(sizeof(struct interface));
-+ if (device ==NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "get_interface_info()--> "
-+ "ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+ device->opaq = opaq;
-+ device->ifname = strdup(devname);
-+ device->devindex = if_idx;
-+ device->ipv6addr = NULL;
-+ device->prev = &interface_list;
-+ device->next = interface_list.next;
-+ device->prev->next = device;
-+ device->next->prev = device;
-+ nr_of_devices += 1;
-+ }
-+
-+ if (IN6_IS_ADDR_LINKLOCAL(&sap.sin6_addr)) {
-+ device->link_local = strdup(src_addr);
-+ TRACE(dump,"%s %s %s %d %s %s\n",\
-+ "RELAY INTERFACE INFO-> DEVNAME:", devname, "INDEX:", if_idx,
-+ "LINK_LOCAL_ADDRR:", src_addr);
-+ }
-+ else {
-+ ipv6addr = (struct IPv6_address *)
-+ malloc(sizeof(struct IPv6_address));
-+ if (ipv6addr ==NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "get_interface_info()--> "
-+ "ERROR NO MORE MEMORY AVAILABLE\n");
-+ exit(1);
-+ }
-+ ipv6addr->gaddr = strdup(src_addr);
-+ ipv6addr->next = NULL;
-+ if (device->ipv6addr!= NULL)
-+ ipv6addr->next = device->ipv6addr;
-+
-+ device->ipv6addr = ipv6addr;
-+ }
-+ } /* while */
-+
-+ fflush(dump);
-+ for (device = interface_list.next; device != &interface_list;
-+ device = device->next) {
-+ if ( device->ipv6addr == NULL) {
-+ TRACE(dump,"%s - ERROR--> ONE MUST ASSIGN SITE SCOPED IPv6 "
-+ "ADDRESS FOR INTERFACE: %s\n", dhcp6r_clock(),
-+ device->ifname);
-+ exit(1);
-+ }
-+ }
-+
-+ fclose(f);
-+ return 1;
-+}
-+
-+int
-+send_message()
-+{
-+ struct sockaddr_in6 sin6; /* my address information */
-+ struct msghdr msg;
-+ uint32_t count = 0;
-+ struct msg_parser *mesg;
-+ struct in6_pktinfo *in6_pkt;
-+ struct cmsghdr *cmsgp;
-+ char dest_addr[INET6_ADDRSTRLEN];
-+ struct IPv6_uniaddr *ipv6uni;
-+ struct interface *iface;
-+ int hit = 0;
-+ struct iovec iov[1];
-+ int recvmsglen;
-+ char *recvp;
-+ struct server *uservers;
-+ struct sifaces *si;
-+
-+ if ((mesg = get_send_messages_out()) == NULL)
-+ return 0;
-+
-+ if (mesg->sent == 1)
-+ return 0;
-+
-+ bzero((char *)&sin6, sizeof(struct sockaddr_in6));
-+ sin6.sin6_family = AF_INET6;
-+ sin6.sin6_flowinfo = 0;
-+ sin6.sin6_scope_id = 0;
-+
-+ if (mesg->msg_type == RELAY_REPL) {
-+ memset(dest_addr, 0, INET6_ADDRSTRLEN);
-+ memcpy(dest_addr, mesg->peer_addr , INET6_ADDRSTRLEN);
-+
-+ recvmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-+ recvp = (char *) malloc(recvmsglen*sizeof(char));
-+ if (recvp == NULL) {
-+ printf("ERROR-->recvp NO MORE MEMORY AVAILABLE \n");
-+ exit(1);
-+ }
-+ memset(recvp, 0, recvmsglen);
-+ cmsgp = (struct cmsghdr *) recvp;
-+ cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-+ cmsgp->cmsg_level = IPPROTO_IPV6;
-+ cmsgp->cmsg_type = IPV6_PKTINFO;
-+ in6_pkt = (struct in6_pktinfo *) CMSG_DATA(cmsgp);
-+ msg.msg_control = (void *) recvp;
-+ msg.msg_controllen = recvmsglen;
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr)<=0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "send_message()--> inet_pton FAILED \n");
-+ exit(1);
-+ }
-+ sin6.sin6_scope_id = mesg->if_index;
-+
-+ if (mesg->hop > 0)
-+ sin6.sin6_port = htons(SERVER_PORT);
-+ else
-+ sin6.sin6_port = htons(CLIENT_PORT);
-+
-+ iface = get_interface(mesg->if_index);
-+
-+ if (iface != NULL) {
-+ if (inet_pton(AF_INET6, iface->ipv6addr->gaddr,
-+ &in6_pkt->ipi6_addr) <= 0) { /* source address */
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ exit(1);
-+ }
-+ TRACE(dump, "%s - SOURCE ADDRESS: %s\n", dhcp6r_clock(),
-+ iface->ipv6addr->gaddr);
-+ }
-+ else {
-+ /* the kernel will choose the source address */
-+ memset(&in6_pkt->ipi6_addr, 0, sizeof(in6_pkt->ipi6_addr));
-+ }
-+
-+ /* OUTGOING DEVICE FOR RELAY_REPLY MSG */
-+ in6_pkt->ipi6_ifindex = mesg->if_index;
-+ TRACE(dump, "%s - OUTGOING DEVICE INDEX: %d\n", dhcp6r_clock(),
-+ in6_pkt->ipi6_ifindex);
-+ TRACE(dump, "%s - DESTINATION PORT: %d\n", dhcp6r_clock(),
-+ ntohs(sin6.sin6_port));
-+
-+ iov[0].iov_base = mesg->buffer;
-+ iov[0].iov_len = mesg->datalength;
-+ msg.msg_name = (void *) &sin6;
-+ msg.msg_namelen = sizeof(sin6);
-+ msg.msg_iov = &iov[0];
-+ msg.msg_iovlen = 1;
-+
-+ if ((count = sendmsg(sendsock->send_sock_desc, &msg, 0)) < 0) {
-+ perror("sendmsg");
-+ return 0;
-+ }
-+
-+ if (count > MAX_DHCP_MSG_LENGTH)
-+ perror("bytes in sendmsg");
-+
-+ TRACE(dump, "%s - *********> RELAY_REPL, SENT TO: %s SENT_BYTES: %d\n",
-+ dhcp6r_clock(), dest_addr, count);
-+
-+ free(recvp);
-+
-+ mesg->sent = 1;
-+ return 1;
-+ }
-+
-+ if (mesg->msg_type == RELAY_FORW) {
-+ for (ipv6uni = IPv6_uniaddr_list.next; ipv6uni != &IPv6_uniaddr_list;
-+ ipv6uni = ipv6uni->next) {
-+ bzero((char *)&sin6, sizeof(struct sockaddr_in6));
-+ sin6.sin6_family = AF_INET6;
-+
-+ memset(dest_addr, 0, INET6_ADDRSTRLEN);
-+ memcpy(dest_addr, ipv6uni->uniaddr , INET6_ADDRSTRLEN);
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump,"%s - %s",dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+
-+ recvmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-+ recvp = (char *) malloc(recvmsglen*sizeof(char));
-+ if (recvp == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "ERROR-->recvp NO MORE MEMORY AVAILABLE \n");
-+ exit(1);
-+ }
-+ memset(recvp, 0, recvmsglen);
-+
-+ cmsgp = (struct cmsghdr *) recvp;
-+ cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-+ cmsgp->cmsg_level = IPPROTO_IPV6;
-+ cmsgp->cmsg_type = IPV6_PKTINFO;
-+ in6_pkt = (struct in6_pktinfo *) CMSG_DATA(cmsgp);
-+ msg.msg_control = (void *) recvp;
-+ msg.msg_controllen = recvmsglen;
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr)<=0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+ sin6.sin6_scope_id = 0;
-+ sin6.sin6_port = htons(SERVER_PORT);
-+
-+ /* the kernel will choose the source address */
-+ memset(&in6_pkt->ipi6_addr, 0, sizeof(in6_pkt->ipi6_addr));
-+ /* OUTGOING DEVICE FOR RELAY_REPLY MSG */
-+ in6_pkt->ipi6_ifindex = 0;
-+
-+ iov[0].iov_base = mesg->buffer;
-+ iov[0].iov_len = mesg->datalength;
-+ msg.msg_name = (void *) &sin6;
-+ msg.msg_namelen = sizeof(sin6);
-+ msg.msg_iov = &iov[0];
-+ msg.msg_iovlen = 1;
-+
-+ if ((count = sendmsg(sendsock->send_sock_desc, &msg, 0)) < 0) {
-+ perror("sendmsg");
-+ return 0;
-+ }
-+
-+ if (count > MAX_DHCP_MSG_LENGTH)
-+ perror("bytes sendmsg");
-+
-+ TRACE(dump,
-+ "%s - ========> RELAY_FORW, SENT TO: %s SENT_BYTES: %d\n",
-+ dhcp6r_clock(), dest_addr, count);
-+ free(recvp);
-+ hit = 1;
-+ } /* for */
-+
-+ for (iface = interface_list.next; iface!= &interface_list;
-+ iface = iface->next) {
-+ uservers = iface->sname;
-+ while (uservers != NULL) {
-+ bzero((char *)&sin6, sizeof(struct sockaddr_in6));
-+ sin6.sin6_family = AF_INET6;
-+
-+ memset(dest_addr, 0, INET6_ADDRSTRLEN);
-+ memcpy(dest_addr, uservers->serv , INET6_ADDRSTRLEN);
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ exit(1);
-+ }
-+
-+ recvmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-+ recvp = (char *) malloc(recvmsglen*sizeof(char));
-+ if (recvp == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "ERROR-->recvp NO MORE MEMORY AVAILABLE \n");
-+ exit(1);
-+ }
-+ memset(recvp, 0, recvmsglen);
-+
-+ cmsgp = (struct cmsghdr *) recvp;
-+ cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-+ cmsgp->cmsg_level = IPPROTO_IPV6;
-+ cmsgp->cmsg_type = IPV6_PKTINFO;
-+ in6_pkt = (struct in6_pktinfo *) CMSG_DATA(cmsgp);
-+ msg.msg_control = (void *) recvp;
-+ msg.msg_controllen = recvmsglen;
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+
-+ in6_pkt->ipi6_ifindex = iface->devindex;
-+ sin6.sin6_scope_id = in6_pkt->ipi6_ifindex;
-+
-+ TRACE(dump, "%s - OUTGOING DEVICE INDEX: %d\n", dhcp6r_clock(),
-+ in6_pkt->ipi6_ifindex);
-+ if (inet_pton(AF_INET6, iface->ipv6addr->gaddr,
-+ &in6_pkt->ipi6_addr) <= 0) { /* source address */
-+ TRACE(dump,"%s - %s",dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ exit(1);
-+ }
-+ TRACE(dump, "%s - SOURCE ADDRESS: %s\n", dhcp6r_clock(),
-+ iface->ipv6addr->gaddr);
-+
-+ sin6.sin6_port = htons(SERVER_PORT);
-+
-+ iov[0].iov_base = mesg->buffer;
-+ iov[0].iov_len = mesg->datalength;
-+ msg.msg_name = (void *) &sin6;
-+ msg.msg_namelen = sizeof(sin6);
-+ msg.msg_iov = &iov[0];
-+ msg.msg_iovlen = 1;
-+
-+ if ((count = sendmsg(sendsock->send_sock_desc, &msg, 0)) < 0) {
-+ perror("sendmsg");
-+ return 0;
-+ }
-+
-+ if (count > MAX_DHCP_MSG_LENGTH)
-+ perror("bytes sendmsg");
-+
-+ TRACE(dump,
-+ "%s - ========> RELAY_FORW, SENT TO: %s SENT_BYTES: %d\n",
-+ dhcp6r_clock(), dest_addr, count);
-+ free(recvp);
-+ uservers = uservers->next;
-+ hit = 1;
-+ } /* while */
-+ } /* Interfaces */
-+
-+ for (si = sifaces_list.next; si != &sifaces_list; si = si->next) {
-+ *(mesg->hc_pointer)= MAXHOPCOUNT;
-+ bzero((char *)&sin6, sizeof(struct sockaddr_in6));
-+ sin6.sin6_family = AF_INET6;
-+
-+ memset(dest_addr, 0, INET6_ADDRSTRLEN);
-+ strcpy(dest_addr, ALL_DHCP_SERVERS);
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+
-+ recvmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-+ recvp = (char *) malloc(recvmsglen*sizeof(char));
-+ if (recvp == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "ERROR-->recvp NO MORE MEMORY AVAILABLE \n");
-+ exit(1);
-+ }
-+ memset(recvp, 0, recvmsglen);
-+
-+ cmsgp = (struct cmsghdr *) recvp;
-+ cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-+ cmsgp->cmsg_level = IPPROTO_IPV6;
-+ cmsgp->cmsg_type = IPV6_PKTINFO;
-+ in6_pkt = (struct in6_pktinfo *) CMSG_DATA(cmsgp);
-+ msg.msg_control = (void *) recvp;
-+ msg.msg_controllen = recvmsglen;
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump,"%s - %s",dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+
-+ in6_pkt->ipi6_ifindex = if_nametoindex(si->siface);
-+ sin6.sin6_scope_id = in6_pkt->ipi6_ifindex;
-+
-+ TRACE(dump, "%s - OUTGOING DEVICE INDEX: %d\n", dhcp6r_clock(),
-+ in6_pkt->ipi6_ifindex);
-+ iface = get_interface(in6_pkt->ipi6_ifindex);
-+ if (iface == NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "ERROR--> send_message(), NO INTERFACE INFO FOUND\n");
-+ exit(0);
-+ }
-+ if (inet_pton(AF_INET6, iface->ipv6addr->gaddr,
-+ &in6_pkt->ipi6_addr)<=0) { /* source address */
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ exit(1);
-+ }
-+ TRACE(dump,"%s - SOURCE ADDRESS: %s\n",dhcp6r_clock(),
-+ iface->ipv6addr->gaddr);
-+
-+ sin6.sin6_port = htons(SERVER_PORT);
-+
-+ iov[0].iov_base = mesg->buffer;
-+ iov[0].iov_len = mesg->datalength;
-+ msg.msg_name = (void *) &sin6;
-+ msg.msg_namelen = sizeof(sin6);
-+ msg.msg_iov = &iov[0];
-+ msg.msg_iovlen = 1;
-+
-+ if ((count = sendmsg(sendsock->send_sock_desc, &msg, 0)) < 0) {
-+ perror("sendmsg");
-+ return 0;
-+ }
-+
-+ if (count > MAX_DHCP_MSG_LENGTH)
-+ perror("bytes sendmsg");
-+
-+ TRACE(dump,
-+ "%s - ========> RELAY_FORW, SENT TO: %s SENT_BYTES: %d\n",
-+ dhcp6r_clock(), dest_addr, count);
-+
-+ free(recvp);
-+ hit = 1;
-+ } /* for */
-+
-+ if (hit == 0) {
-+ for (iface = interface_list.next; iface != &interface_list;
-+ iface = iface->next) {
-+ if (mesg->interface_in == iface->devindex)
-+ continue;
-+
-+ *(mesg->hc_pointer)= MAXHOPCOUNT;
-+ bzero((char *)&sin6, sizeof(struct sockaddr_in6));
-+ sin6.sin6_family = AF_INET6;
-+
-+ memset(dest_addr, 0, INET6_ADDRSTRLEN);
-+ strcpy(dest_addr, ALL_DHCP_SERVERS);
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+
-+ recvmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo));
-+ recvp = (char *) malloc(recvmsglen*sizeof(char));
-+ if (recvp ==NULL) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "ERROR-->recvp NO MORE MEMORY AVAILABLE \n");
-+ exit(1);
-+ }
-+ memset(recvp, 0, recvmsglen);
-+
-+ cmsgp = (struct cmsghdr *) recvp;
-+ cmsgp->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
-+ cmsgp->cmsg_level = IPPROTO_IPV6;
-+ cmsgp->cmsg_type = IPV6_PKTINFO;
-+ in6_pkt = (struct in6_pktinfo *) CMSG_DATA(cmsgp);
-+ msg.msg_control = (void *) recvp;
-+ msg.msg_controllen = recvmsglen;
-+
-+ /* destination address */
-+ if (inet_pton(AF_INET6, dest_addr, &sin6.sin6_addr) <= 0) {
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ return 0;
-+ }
-+ sin6.sin6_port = htons(SERVER_PORT);
-+
-+ in6_pkt->ipi6_ifindex = iface->devindex;
-+ sin6.sin6_scope_id = in6_pkt->ipi6_ifindex;
-+
-+ TRACE(dump, "%s - OUTGOING DEVICE INDEX: %d\n", dhcp6r_clock(),
-+ in6_pkt->ipi6_ifindex);
-+ if (inet_pton(AF_INET6, iface->ipv6addr->gaddr,
-+ &in6_pkt->ipi6_addr)<=0) { /* source address */
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "inet_pton failed in send_message()\n");
-+ exit(1);
-+ }
-+
-+ TRACE(dump, "%s - SOURCE ADDRESS: %s\n", dhcp6r_clock(),
-+ iface->ipv6addr->gaddr);
-+
-+ iov[0].iov_base = mesg->buffer;
-+ iov[0].iov_len = mesg->datalength;
-+ msg.msg_name = (void *) &sin6;
-+ msg.msg_namelen = sizeof(sin6);
-+ msg.msg_iov = &iov[0];
-+ msg.msg_iovlen = 1;
-+
-+ if ((count = sendmsg(sendsock->send_sock_desc, &msg, 0))< 0) {
-+ perror("sendmsg");
-+ return 0;
-+ }
-+
-+ if (count > MAX_DHCP_MSG_LENGTH)
-+ perror("sendmsg");
-+
-+ TRACE(dump,
-+ "%s - ========> RELAY_FORW, SENT TO: %s SENT_BYTES: %d\n",
-+ dhcp6r_clock(), dest_addr, count);
-+ free(recvp);
-+ } /* for */
-+ }
-+ }
-+
-+ fflush(dump);
-+ mesg->sent = 1;
-+ return 1;
-+
-+
-+ TRACE(dump, "%s - %s", dhcp6r_clock(),
-+ "FATAL ERROR--> NO MESSAGE TYPE TO BE SENT!\n");
-+ exit(1);
-+}
---- /dev/null 2007-02-06 10:40:24.955607220 -0500
-+++ dhcp-0.10/relay6_socket.h 2007-02-09 00:16:08.000000000 -0500
-@@ -0,0 +1,74 @@
-+/*
-+ * Copyright (C) NEC Europe Ltd., 2003
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ * notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ * notice, this list of conditions and the following disclaimer in the
-+ * documentation and/or other materials provided with the distribution.
-+ * 3. Neither the name of the project nor the names of its contributors
-+ * may be used to endorse or promote products derived from this software
-+ * without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */
-+
-+#ifndef __RELAY6_SOCKET_H_DEFINED
-+#define __RELAY6_SOCKET_H_DEFINED
-+
-+#include <sys/types.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+
-+#include "dhcp6r.h"
-+
-+fd_set readfd;
-+int fdmax;
-+
-+struct receive {
-+ struct msghdr msg;
-+ struct iovec iov[1];
-+ struct cmsghdr *cmsgp;
-+ struct sockaddr_in6 sin6; /* my address information */
-+ struct sockaddr_in6 from;
-+ int recvmsglen;
-+ char *recvp;
-+ char src_addr[INET6_ADDRSTRLEN];
-+ int pkt_interface;
-+ int buflength;
-+ int dst_addr_type ;
-+ char *databuf;
-+ int recv_sock_desc;
-+};
-+
-+struct send {
-+ int send_sock_desc;
-+};
-+
-+struct send *sendsock;
-+struct receive *recvsock;
-+
-+int send_message __P((void));
-+int fill_addr_struct __P((void));
-+int set_sock_opt __P((void));
-+int recv_data __P((void));
-+int check_select __P((void));
-+int get_recv_data __P((void));
-+int get_interface_info __P((void));
-+void init_socket __P((void));
-+
-+#endif /* __RELAY6_SOCKET_H_DEFINED */