Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
DISCONTINUED:openSUSE:11.2:Update
dhcpv6
dhcpv6-1.0.22-netconfig.dif
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File dhcpv6-1.0.22-netconfig.dif of Package dhcpv6
Index: src/dhcp6c.c =================================================================== --- src/dhcp6c.c.orig +++ src/dhcp6c.c @@ -91,6 +91,19 @@ #include "libdhcp_control.h" #endif +#ifdef WITH_NETCONFIG +#ifndef _GNU_SOURCE + #define _GNU_SOURCE + #include <getopt.h> + #undef _GNU_SOURCE +#else + #include <getopt.h> +#endif +#include "netconfig.h" + +static int use_netconfig = 0; +#endif + static int debug = 0; static u_long sig_flags = 0; @@ -196,6 +209,12 @@ int dhcpv6_client(LIBDHCP_Control *libdh char *progname, *conffile = DHCP6C_CONF; FILE *pidfp; char *addr; +#ifdef WITH_NETCONFIG + struct option long_options[] = { + {"netconfig", no_argument, NULL, 0x0100}, + { NULL, 0, NULL, 0 } + }; +#endif #ifdef LIBDHCP libdhcp_control = libdhcp_ctl; @@ -212,8 +231,17 @@ int dhcpv6_client(LIBDHCP_Control *libdh progname++; TAILQ_INIT(&request_list); +#ifdef WITH_NETCONFIG + while ((ch = getopt_long(argc, argv, "c:r:R:P:vfIp:", + long_options, NULL)) != -1) { + switch (ch) { + case 0x0100: + use_netconfig = 1; + break; +#else while ((ch = getopt(argc, argv, "c:r:R:P:vfIp:")) != -1) { switch (ch) { +#endif case 'p': if (strlen(optarg) >= MAXPATHLEN) { dhcpv6_dprintf(LOG_ERR, "pid file name is too long"); @@ -931,11 +959,25 @@ static void free_resources(struct dhcp6_ dhcp6_remove_event(ev); } - /* restore /etc/resolv.conf.dhcpv6.bak back to /etc/resolv.conf */ - if (!lstat(RESOLV_CONF_BAK_FILE, &buf)) { - if (rename(RESOLV_CONF_BAK_FILE, RESOLV_CONF_FILE)) - dhcpv6_dprintf(LOG_ERR, "%s" " failed to backup resolv.conf", - FNAME); +#ifdef WITH_NETCONFIG + if(use_netconfig) + { + int ret = netconfig_remove("dhcp6c", debug, ifp->ifname); + dhcpv6_dprintf(LOG_DEBUG, "netconfig remove(%s): status %d", + ifp->ifname, ret); + } + else +#endif +#ifdef LIBDHCP + if (libdhcp_control && (libdhcp_control->capability & DHCP_CONFIGURE_RESOLVER)) +#endif + { + /* restore /etc/resolv.conf.dhcpv6.bak back to /etc/resolv.conf */ + if (!lstat(RESOLV_CONF_BAK_FILE, &buf)) { + if (rename(RESOLV_CONF_BAK_FILE, RESOLV_CONF_FILE)) + dhcpv6_dprintf(LOG_ERR, "%s" " failed to backup resolv.conf", + FNAME); + } } free_servers(ifp); @@ -1857,6 +1899,15 @@ static int client6_recvreply(struct dhcp return -1; } +#ifdef WITH_NETCONFIG + if (use_netconfig) + { + int ret = netconfig_modify("dhcp6c", debug, ifp->ifname, optinfo, ifp); + dhcpv6_dprintf(LOG_DEBUG, "netconfig modify(%s): status %d", + ifp->ifname, ret); + } + else +#endif if (!TAILQ_EMPTY(&optinfo->dns_list.addrlist) || optinfo->dns_list.domainlist != NULL) { #ifdef LIBDHCP @@ -2478,3 +2529,8 @@ static void setup_interface(char *ifname return; } + +#ifdef WITH_NETCONFIG +#include "netconfig.c" +#endif + Index: src/netconfig.c =================================================================== --- /dev/null +++ src/netconfig.c @@ -0,0 +1,242 @@ +#ifdef WITH_NETCONFIG +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/wait.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include "netconfig.h" + +static int do_netconfig_restore = 0; + +int netconfig_modify(const char *service, int verbose, const char *ifname, + struct dhcp6_optinfo *optinfo, struct dhcp6_if *ifp) +{ + if(getuid() != 0 || geteuid() != 0) + { + return -1; + } + + if( !service || !ifname || !optinfo || !ifp) + { + return -1; + } + + int rc; + int fd[2] = {-1, -1}; + rc = socketpair(AF_LOCAL, SOCK_STREAM, PF_LOCAL, fd); + if(rc == -1) + { + return -1; + } + + pid_t pid; + pid = fork(); + if(pid == 0) + { + char *argv[] = { + "/sbin/netconfig", + "modify", + "-s", (char *)service, + "-i", (char *)ifname, + (verbose ? "-v" : NULL), + NULL + }; + extern char **environ; + + close(fd[0]); + if(dup2(fd[1], fileno(stdin)) == fileno(stdin)) + { + close(fd[1]); + if(freopen("/dev/null", "w", stdout) && + freopen("/dev/null", "w", stderr)) + { + execve(argv[0], argv, environ); + } + } else { + close(fd[1]); + } + exit(127); + } + else + if(pid > 0) + { + close(fd[1]); + FILE *out = fdopen(fd[0], "w"); + if( out) + { + fprintf(out, "INTERFACE='%s'\n", ifname); +#if 0 + /* + ** FIXME: the optinfo struct changed between 1.0.11 and 1.0.20 + ** not a problem, since IPADDR is informational only + */ + struct ia_listval *ia = ia_find_listval(&optinfo->ia_list, ...); + + if(!TAILQ_EMPTY(&ia->addr_list)) + { + struct dhcp6_listval *lv; + size_t i = 0; + fprintf(out, "IPADDR='"); + for (lv = TAILQ_FIRST(&ia->addr_list); + lv; + lv = TAILQ_NEXT(lv, link), i++) + { + if (lv->val_dhcp6addr.type != IAPD) { + u_int8_t plen = lv->val_dhcp6addr.plen ? + lv->val_dhcp6addr.plen : + dhcp6_get_prefixlen(&lv->val_dhcp6addr.addr, ifp); + + dhcpv6_dprintf(LOG_DEBUG, + "netconfig modify(%s): " + "IPADDR+='%s/%u'", + ifname, + in6addr2str(&lv->val_dhcp6addr.addr, 0), + plen); + fprintf(out, "%s%s", + (i == 0 ? "" : " "), + in6addr2str(&lv->val_dhcp6addr.addr, 0)); + if( plen) + fprintf(out, "/%u", plen); + } + } + fprintf(out, "'\n"); + } +#endif + fprintf(out, "DNSSERVERS='"); + if (!TAILQ_EMPTY(&optinfo->dns_list.addrlist)) + { + struct dhcp6_listval *d; + size_t i = 0; + for (d = TAILQ_FIRST(&optinfo->dns_list.addrlist); + d; + d = TAILQ_NEXT(d, link), i++) + { + dhcpv6_dprintf(LOG_DEBUG, + "netconfig modify(%s): " + "DNSSERVERS+='%s'", + ifname, + in6addr2str(&d->val_addr6, 0)); + + fprintf(out, "%s%s", + (i == 0 ? "" : " "), + in6addr2str(&d->val_addr6, 0)); + } + } + else + { + dhcpv6_dprintf(LOG_DEBUG, "netconfig modify(%s): " + "no DNS server available", ifname); + } + fprintf(out, "'\n"); + + fprintf(out, "DNSSEARCH='"); + if (optinfo->dns_list.domainlist) + { + struct domain_list *dlist; + size_t i = 0; + for (dlist = optinfo->dns_list.domainlist; + dlist; + dlist = dlist->next, i++) + { + dhcpv6_dprintf(LOG_DEBUG, + "netconfig modify(%s): " + "DNSSEARCH+='%s'", + ifname, + dlist->name); + + fprintf(out, "%s%s", + (i == 0 ? "" : " "), + dlist->name); + } + } + else + { + dhcpv6_dprintf(LOG_DEBUG, "netconfig modify(%s): " + "no DNS search list available", ifname); + } + fprintf(out, "'\n"); + + fclose(out); + } + else + { + close(fd[0]); + } + + /* wait for child even unable to write */ + int err; + int ret = 0; + do + { + err = waitpid(pid, &ret, 0); + } while(err == -1 && errno == EINTR); + + do_netconfig_restore++; + + return (((ret & 0x7f)==0) ? + ((ret >> 8) & 0xff) : + -(ret & 0x7f)); + } + return -1; +} + +int netconfig_remove(const char *service, int verbose, const char *ifname) +{ + if(getuid() != 0 || geteuid() != 0) + { + return -1; + } + + if( !service || !ifname) + { + return -1; + } + + if( do_netconfig_restore == 0) + { + return 0; + } + + pid_t pid; + + pid = fork(); + if(pid == 0) + { + char *argv[] = { + "/sbin/netconfig", + "remove", + "-s", (char *)service, + "-i", (char *)ifname, + (verbose ? "-v" : NULL), + NULL + }; + extern char **environ; + + if(freopen("/dev/null", "r", stdin) && + freopen("/dev/null", "w", stdout) && + freopen("/dev/null", "w", stderr)) + { + execve(argv[0], argv, environ); + } + exit(127); + } + else + if(pid > 0) + { + int err; + int ret = 0; + do + { + err = waitpid(pid, &ret, 0); + } while(err == -1 && errno == EINTR); + + do_netconfig_restore = 0; + + return (((ret & 0x7f)==0) ? + ((ret >> 8) & 0xff) : + -(ret & 0x7f)); + } + return -1; +} +#endif Index: src/netconfig.h =================================================================== --- /dev/null +++ src/netconfig.h @@ -0,0 +1,12 @@ +#ifdef WITH_NETCONFIG +#ifndef NETCONFIG_H +#define NETCONFIG_H +#include "dhcp6.h" + +int netconfig_modify(const char *service, int verbose, const char *ifname, + struct dhcp6_optinfo *optinfo, struct dhcp6_if *ifp); + +int netconfig_remove(const char *service, int verbose, const char *ifname); + +#endif +#endif
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor