static void setup_iface_foo(struct Interface *iface, void *data) { int sock = *(int *)data; if (setup_iface(sock, iface) < 0) { if (iface->IgnoreIfMissing) { dlog(LOG_DEBUG, 4, "interface %s does not exist or is not set up properly, ignoring the interface", iface->props.name); return; } else { flog(LOG_ERR, "interface %s does not exist or is not set up properly", iface->props.name); exit(1); } } config_interface(iface); kickoff_adverts(sock, iface); }
void process_netlink_msg(int sock) { int len; char buf[4096]; struct iovec iov = { buf, sizeof(buf) }; struct sockaddr_nl sa; struct msghdr msg = { (void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; struct nlmsghdr *nh; struct ifinfomsg * ifinfo; char ifname[IF_NAMESIZE] = {""}; char * rc = 0; len = recvmsg (sock, &msg, 0); if (len == -1) { flog(LOG_ERR, "recvmsg failed: %s", strerror(errno)); } for (nh = (struct nlmsghdr *) buf; NLMSG_OK (nh, len); nh = NLMSG_NEXT (nh, len)) { /* The end of multipart message. */ if (nh->nlmsg_type == NLMSG_DONE) return; if (nh->nlmsg_type == NLMSG_ERROR) { flog(LOG_ERR, "%s:%d Some type of netlink error.\n", __FILE__, __LINE__); abort(); } /* Continue with parsing payload. */ ifinfo = NLMSG_DATA(nh); rc = if_indextoname(ifinfo->ifi_index, ifname); if (ifinfo->ifi_flags & IFF_RUNNING) { dlog(LOG_DEBUG, 3, "%s, ifindex %d, flags is running", ifname, ifinfo->ifi_index); } else { dlog(LOG_DEBUG, 3, "%s, ifindex %d, flags is *NOT* running", ifname, ifinfo->ifi_index); } config_interface(); kickoff_adverts(); } }
/* END: Added by z67728, 2009/12/26 */ void reload_config(void) { struct Interface *iface; flog(LOG_INFO, "attempting to reread config file"); dlog(LOG_DEBUG, 4, "reopening log"); if (log_reopen() < 0) exit(1); /* disable timers, free interface and prefix structures */ for(iface=IfaceList; iface; iface=iface->next) { /* check that iface->tm was set in the first place */ if (iface->tm.next && iface->tm.prev) { dlog(LOG_DEBUG, 4, "disabling timer for %s", iface->Name); clear_timer(&iface->tm); } } iface=IfaceList; while(iface) { struct Interface *next_iface = iface->next; struct AdvPrefix *prefix; struct AdvRoute *route; struct AdvRDNSS *rdnss; dlog(LOG_DEBUG, 4, "freeing interface %s", iface->Name); prefix = iface->AdvPrefixList; while (prefix) { struct AdvPrefix *next_prefix = prefix->next; free(prefix); prefix = next_prefix; } route = iface->AdvRouteList; while (route) { struct AdvRoute *next_route = route->next; free(route); route = next_route; } rdnss = iface->AdvRDNSSList; while (rdnss) { struct AdvRDNSS *next_rdnss = rdnss->next; free(rdnss); rdnss = next_rdnss; } free(iface); iface = next_iface; } IfaceList = NULL; /* reread config file */ if (readin_config(conf_file) < 0) exit(1); /* XXX: fails due to lack of permissions with non-root user */ config_interface(); kickoff_adverts(); flog(LOG_INFO, "resuming normal operation"); }
int main(int argc, char *argv[]) { unsigned char msg[MSG_SIZE]; char pidstr[16]; ssize_t ret; int c, log_method; char *logfile, *pidfile; sigset_t oset, nset; int facility, fd; char *username = NULL; char *chrootdir = NULL; int singleprocess = 0; #ifdef HAVE_GETOPT_LONG int opt_idx; #endif /* BEGIN: Added by z67728, 2009/10/19 */ FILE * pidfp = NULL; int pid = 0; /* END: Added by z67728, 2009/10/19 */ /*start: 用于查询组件版本号(dns atpv),请不要修改或删除*/ /*if ((argc == 2) && (NULL != argv[1]) && (0 == strcmp(argv[1],ATP_VERSION_CMD_KEY))) { printf("\r\n%s.\n", RADVD_MODULE_VERSION); exit(0); }*/ /*end */ pname = ((pname=strrchr(argv[0],'/')) != NULL)?pname+1:argv[0]; srand((unsigned int)time(NULL)); log_method = L_STDERR_SYSLOG; /*BEGIN PN:2071008409 l00170266 for var problem modify 20120725 */ #define RADVD_LOG (ROUTER_VARPATH_PREFIX "/radvd/radvd.log") #define RADVD_CONF (ROUTER_VARPATH_PREFIX "/radvd/radvd.conf") #define RADVD_PID (ROUTER_VARPATH_PREFIX "/radvd/radvd.pid") logfile = RADVD_LOG; conf_file = RADVD_CONF; facility = LOG_FACILITY; pidfile = RADVD_PID; /*END PN:2071008409 l00170266 for var problem modify 20120725 */ /* parse args */ #ifdef HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, "d:C:l:m:p:t:u:vhs", prog_opt, &opt_idx)) > 0) #else while ((c = getopt(argc, argv, "d:C:l:m:p:t:u:vhs")) > 0) #endif { switch (c) { case 'C': conf_file = optarg; break; case 'd': set_debuglevel(atoi(optarg)); break; case 'f': facility = atoi(optarg); break; case 'l': logfile = optarg; break; case 'p': pidfile = optarg; break; case 'm': if (!strcmp(optarg, "syslog")) { log_method = L_SYSLOG; } else if (!strcmp(optarg, "stderr_syslog")) { log_method = L_STDERR_SYSLOG; } else if (!strcmp(optarg, "stderr")) { log_method = L_STDERR; } else if (!strcmp(optarg, "logfile")) { log_method = L_LOGFILE; } else if (!strcmp(optarg, "none")) { log_method = L_NONE; } else { fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg); exit(1); } break; case 't': chrootdir = strdup(optarg); break; case 'u': username = strdup(optarg); break; case 'v': /* BEGIN 3061302357 y00188255 2013-6-28 Modified */ //version(); printf("%s\n", RADVD_MODULE_VERSION); printf("BUILTTIME is: %s %s\n",__DATE__,__TIME__); exit(1); /* END 3061302357 y00188255 2013-6-28 Modified */ break; case 's': singleprocess = 1; break; case 'h': usage(); #ifdef HAVE_GETOPT_LONG case ':': fprintf(stderr, "%s: option %s: parameter expected\n", pname, prog_opt[opt_idx].name); exit(1); #endif case '?': exit(1); } } if (chrootdir) { if (!username) { fprintf(stderr, "Chroot as root is not safe, exiting\n"); exit(1); } if (chroot(chrootdir) == -1) { perror("chroot"); exit (1); } if (chdir("/") == -1) { perror("chdir"); exit (1); } /* username will be switched later */ } if (log_open(log_method, pname, logfile, facility) < 0) exit(1); flog(LOG_INFO, "version %s started", VERSION); /* get a raw socket for sending and receiving ICMPv6 messages */ sock = open_icmpv6_socket(); if (sock < 0) exit(1); #if 0 /* check that 'other' cannot write the file * for non-root, also that self/own group can't either */ if (check_conffile_perm(username, conf_file) < 0) { if (get_debuglevel() == 0) exit(1); else flog(LOG_WARNING, "Insecure file permissions, but continuing anyway"); } /* if we know how to do it, check whether forwarding is enabled */ if (check_ip6_forwarding()) { if (get_debuglevel() == 0) { flog(LOG_ERR, "IPv6 forwarding seems to be disabled, exiting"); exit(1); } else flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway."); } #endif /* parse config file */ if (readin_config(conf_file) < 0){ if ( 0 != unlink(pidfile) ){ printf("\r\n Delete %s meet error. error : %s .",pidfile,strerror(errno)); } exit(1); } /* drop root privileges if requested. */ if (username) { if (!singleprocess) { dlog(LOG_DEBUG, 3, "Initializing privsep"); if (privsep_init() < 0) flog(LOG_WARNING, "Failed to initialize privsep."); } if (drop_root_privileges(username) < 0) exit(1); } #if 0 if ((fd = open(pidfile, O_RDONLY, 0)) > 0) { ret = read(fd, pidstr, sizeof(pidstr) - 1); if (ret < 0) { flog(LOG_ERR, "cannot read radvd pid file, terminating: %s", strerror(errno)); exit(1); } pidstr[ret] = '\0'; if (!kill((pid_t)atol(pidstr), 0)) { flog(LOG_ERR, "radvd already running, terminating."); exit(1); } close(fd); fd = open(pidfile, O_CREAT|O_TRUNC|O_WRONLY, 0644); } else /* FIXME: not atomic if pidfile is on an NFS mounted volume */ fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644); if (fd < 0) { flog(LOG_ERR, "cannot create radvd pid file, terminating: %s", strerror(errno)); exit(1); } #endif /* * okay, config file is read in, socket and stuff is setup, so * lets fork now... */ #if 0 if (get_debuglevel() == 0) { /* Detach from controlling terminal */ if (daemon(0, 0) < 0) perror("daemon"); /* close old logfiles, including stderr */ log_close(); /* reopen logfiles, but don't log to stderr unless explicitly requested */ if (log_method == L_STDERR_SYSLOG) log_method = L_SYSLOG; if (log_open(log_method, pname, logfile, facility) < 0) exit(1); } #endif /* * config signal handlers, also make sure ALRM isn't blocked and raise a warning if so * (some stupid scripts/pppd appears to do this...) */ sigemptyset(&nset); sigaddset(&nset, SIGALRM); sigprocmask(SIG_UNBLOCK, &nset, &oset); if (sigismember(&oset, SIGALRM)) flog(LOG_WARNING, "SIGALRM has been unblocked. Your startup environment might be wrong."); signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGINT, sigint_handler); /* BEGIN: Added by z67728, 2009/11/3 */ signal(SIGUSR1, sigdebug_handler); signal(SIGUSR2, sigprefixchg_handler); /* END: Added by z67728, 2009/11/3 */ #if 0 snprintf(pidstr, sizeof(pidstr), "%ld\n", (long)getpid()); write(fd, pidstr, strlen(pidstr)); close(fd); #endif /*BEGIN PN:2071008409 l00170266 for var problem modify 20120725 */ #define RADVD_READTEST (ROUTER_VARPATH_PREFIX "/radvd/readtest") if ( 0 == access(RADVD_READTEST,F_OK) ) /*END PN:2071008409 l00170266 for var problem modify 20120725 */ { /* Ready test */ g_iReadTestFlag = 1; } pid = getpid(); if ((pidfp = fopen(pidfile, "w")) != NULL) { fwrite(&pid,1,4,pidfp); fclose(pidfp); } config_interface(); kickoff_adverts(); /* enter loop */ for (;;) { int len = 0, hoplimit = 0; struct sockaddr_in6 rcv_addr; struct in6_pktinfo *pkt_info = NULL; len = recv_rs_ra(sock, msg, &rcv_addr, &pkt_info, &hoplimit); if (len > 0) { process(sock, IfaceList, msg, len, &rcv_addr, pkt_info, hoplimit); } if (sigterm_received || sigint_received) { stop_adverts(); break; } if (sighup_received) { if ( 1 == g_iPrefixChgeFlag ) { disable_oldprefix(); } reload_config(); sighup_received = 0; g_iPrefixChgeFlag = 0; } } unlink(pidfile); exit(0); }
int main(int argc, char *argv[]) { unsigned char msg[MSG_SIZE]; char pidstr[16]; ssize_t ret; int c, log_method; char *logfile, *pidfile; sigset_t oset, nset; int facility, fd; char *username = NULL; char *chrootdir = NULL; int singleprocess = 0; #ifdef HAVE_GETOPT_LONG int opt_idx; #endif pname = ((pname=strrchr(argv[0],'/')) != NULL)?pname+1:argv[0]; srand((unsigned int)time(NULL)); log_method = L_STDERR_SYSLOG; logfile = PATH_RADVD_LOG; conf_file = PATH_RADVD_CONF; facility = LOG_FACILITY; pidfile = PATH_RADVD_PID; /* parse args */ #ifdef HAVE_GETOPT_LONG /* Add option to show advertise real lifetime */ /* while ((c = getopt_long(argc, argv, "d:C:l:m:p:t:u:vhs", prog_opt, &opt_idx)) > 0) */ while ((c = getopt_long(argc, argv, "d:C:l:m:p:t:u:vhsD", prog_opt, &opt_idx)) > 0) #else /* Add option to show advertise real lifetime */ /* while ((c = getopt(argc, argv, "d:C:l:m:p:t:u:vhs")) > 0) */ while ((c = getopt(argc, argv, "d:C:l:m:p:t:u:vhsD")) > 0) #endif { switch (c) { case 'C': conf_file = optarg; break; case 'd': set_debuglevel(atoi(optarg)); break; case 'f': facility = atoi(optarg); break; case 'l': logfile = optarg; break; case 'p': pidfile = optarg; break; case 'm': if (!strcmp(optarg, "syslog")) { log_method = L_SYSLOG; } else if (!strcmp(optarg, "stderr_syslog")) { log_method = L_STDERR_SYSLOG; } else if (!strcmp(optarg, "stderr")) { log_method = L_STDERR; } else if (!strcmp(optarg, "logfile")) { log_method = L_LOGFILE; } else if (!strcmp(optarg, "none")) { log_method = L_NONE; } else { fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg); exit(1); } break; case 't': chrootdir = strdup(optarg); break; case 'u': username = strdup(optarg); break; case 'v': version(); break; case 's': singleprocess = 1; break; /* Add option to show advertise dynamic lifetime */ case 'D': use_dynamic_lifetime = 1; break; case 'h': usage(); #ifdef HAVE_GETOPT_LONG case ':': fprintf(stderr, "%s: option %s: parameter expected\n", pname, prog_opt[opt_idx].name); exit(1); #endif case '?': exit(1); } } if (chrootdir) { if (!username) { fprintf(stderr, "Chroot as root is not safe, exiting\n"); exit(1); } if (chroot(chrootdir) == -1) { perror("chroot"); exit (1); } if (chdir("/") == -1) { perror("chdir"); exit (1); } /* username will be switched later */ } if (log_open(log_method, pname, logfile, facility) < 0) exit(1); flog(LOG_INFO, "version %s started", VERSION); /* get a raw socket for sending and receiving ICMPv6 messages */ sock = open_icmpv6_socket(); if (sock < 0) exit(1); /* check that 'other' cannot write the file * for non-root, also that self/own group can't either */ if (check_conffile_perm(username, conf_file) < 0) { if (get_debuglevel() == 0) exit(1); else flog(LOG_WARNING, "Insecure file permissions, but continuing anyway"); } /* if we know how to do it, check whether forwarding is enabled */ if (check_ip6_forwarding()) { if (get_debuglevel() == 0) { flog(LOG_ERR, "IPv6 forwarding seems to be disabled, exiting"); exit(1); } else flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway."); } /* parse config file */ if (readin_config(conf_file) < 0) exit(1); /* drop root privileges if requested. */ if (username) { if (!singleprocess) { dlog(LOG_DEBUG, 3, "Initializing privsep"); if (privsep_init() < 0) flog(LOG_WARNING, "Failed to initialize privsep."); } if (drop_root_privileges(username) < 0) exit(1); } if ((fd = open(pidfile, O_RDONLY, 0)) > 0) { ret = read(fd, pidstr, sizeof(pidstr) - 1); if (ret < 0) { flog(LOG_ERR, "cannot read radvd pid file, terminating: %s", strerror(errno)); exit(1); } pidstr[ret] = '\0'; if (!kill((pid_t)atol(pidstr), 0)) { flog(LOG_ERR, "radvd already running, terminating."); exit(1); } close(fd); fd = open(pidfile, O_CREAT|O_TRUNC|O_WRONLY, 0644); } else /* FIXME: not atomic if pidfile is on an NFS mounted volume */ fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644); if (fd < 0) { flog(LOG_ERR, "cannot create radvd pid file, terminating: %s", strerror(errno)); exit(1); } /* * okay, config file is read in, socket and stuff is setup, so * lets fork now... */ if (get_debuglevel() == 0) { /* Detach from controlling terminal */ if (daemon(0, 0) < 0) perror("daemon"); /* close old logfiles, including stderr */ log_close(); /* reopen logfiles, but don't log to stderr unless explicitly requested */ if (log_method == L_STDERR_SYSLOG) log_method = L_SYSLOG; if (log_open(log_method, pname, logfile, facility) < 0) exit(1); } /* * config signal handlers, also make sure ALRM isn't blocked and raise a warning if so * (some stupid scripts/pppd appears to do this...) */ sigemptyset(&nset); sigaddset(&nset, SIGALRM); sigprocmask(SIG_UNBLOCK, &nset, &oset); if (sigismember(&oset, SIGALRM)) flog(LOG_WARNING, "SIGALRM has been unblocked. Your startup environment might be wrong."); signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGINT, sigint_handler); signal(SIGUSR1, sigusr1_handler); snprintf(pidstr, sizeof(pidstr), "%ld\n", (long)getpid()); write(fd, pidstr, strlen(pidstr)); close(fd); config_interface(); /* Record the time for first advertisement */ set_initial_advert_time(); kickoff_adverts(); /* enter loop */ for (;;) { int len, hoplimit; struct sockaddr_in6 rcv_addr; struct in6_pktinfo *pkt_info = NULL; len = recv_rs_ra(sock, msg, &rcv_addr, &pkt_info, &hoplimit); if (len > 0) process(sock, IfaceList, msg, len, &rcv_addr, pkt_info, hoplimit); if (sigterm_received || sigint_received) { stop_adverts(); /* WNR3500L TD192, Per Netgear spec, * need to send RA for 3 times before termination. */ usleep(200000); stop_adverts(); usleep(200000); stop_adverts(); break; } if (sighup_received) { reload_config(); sighup_received = 0; } /* Reset the initial advertisement time to now */ /* This should happen after a successful IADP renew */ if (sigusr1_received) { set_initial_advert_time(); sigusr1_received = 0; } } unlink(pidfile); exit(0); }
int main(int argc, char *argv[]) { char pidstr[16]; ssize_t ret; int c, log_method; char *logfile, *pidfile; int facility, fd; char *username = NULL; char *chrootdir = NULL; int configtest = 0; int singleprocess = 0; #ifdef HAVE_GETOPT_LONG int opt_idx; #endif pname = ((pname=strrchr(argv[0],'/')) != NULL)?pname+1:argv[0]; srand((unsigned int)time(NULL)); log_method = L_STDERR_SYSLOG; logfile = PATH_RADVD_LOG; conf_file = PATH_RADVD_CONF; facility = LOG_FACILITY; pidfile = PATH_RADVD_PID; /* parse args */ #define OPTIONS_STR "d:C:l:m:p:t:u:vhcs" #ifdef HAVE_GETOPT_LONG while ((c = getopt_long(argc, argv, OPTIONS_STR, prog_opt, &opt_idx)) > 0) #else while ((c = getopt(argc, argv, OPTIONS_STR)) > 0) #endif { switch (c) { case 'C': conf_file = optarg; break; case 'd': set_debuglevel(atoi(optarg)); break; case 'f': facility = atoi(optarg); break; case 'l': logfile = optarg; break; case 'p': pidfile = optarg; break; case 'm': if (!strcmp(optarg, "syslog")) { log_method = L_SYSLOG; } else if (!strcmp(optarg, "stderr_syslog")) { log_method = L_STDERR_SYSLOG; } else if (!strcmp(optarg, "stderr")) { log_method = L_STDERR; } else if (!strcmp(optarg, "logfile")) { log_method = L_LOGFILE; } else if (!strcmp(optarg, "none")) { log_method = L_NONE; } else { fprintf(stderr, "%s: unknown log method: %s\n", pname, optarg); exit(1); } break; case 't': chrootdir = strdup(optarg); break; case 'u': username = strdup(optarg); break; case 'v': version(); break; case 'c': configtest = 1; break; case 's': singleprocess = 1; break; case 'h': usage(); #ifdef HAVE_GETOPT_LONG case ':': fprintf(stderr, "%s: option %s: parameter expected\n", pname, prog_opt[opt_idx].name); exit(1); #endif case '?': exit(1); } } if (chrootdir) { if (!username) { fprintf(stderr, "Chroot as root is not safe, exiting\n"); exit(1); } if (chroot(chrootdir) == -1) { perror("chroot"); exit (1); } if (chdir("/") == -1) { perror("chdir"); exit (1); } /* username will be switched later */ } if (configtest) { log_method = L_STDERR; } if (log_open(log_method, pname, logfile, facility) < 0) { perror("log_open"); exit(1); } if (!configtest) { flog(LOG_INFO, "version %s started", VERSION); } /* get a raw socket for sending and receiving ICMPv6 messages */ sock = open_icmpv6_socket(); if (sock < 0) { perror("open_icmpv6_socket"); exit(1); } /* check that 'other' cannot write the file * for non-root, also that self/own group can't either */ if (check_conffile_perm(username, conf_file) < 0) { if (get_debuglevel() == 0) { flog(LOG_ERR, "Exiting, permissions on conf_file invalid.\n"); exit(1); } else flog(LOG_WARNING, "Insecure file permissions, but continuing anyway"); } /* if we know how to do it, check whether forwarding is enabled */ if (check_ip6_forwarding()) { flog(LOG_WARNING, "IPv6 forwarding seems to be disabled, but continuing anyway."); } /* parse config file */ if (readin_config(conf_file) < 0) { flog(LOG_ERR, "Exiting, failed to read config file.\n"); exit(1); } if (configtest) { fprintf(stderr, "Syntax OK\n"); exit(0); } /* drop root privileges if requested. */ if (username) { if (!singleprocess) { dlog(LOG_DEBUG, 3, "Initializing privsep"); if (privsep_init() < 0) flog(LOG_WARNING, "Failed to initialize privsep."); } if (drop_root_privileges(username) < 0) { perror("drop_root_privileges"); exit(1); } } if ((fd = open(pidfile, O_RDONLY, 0)) > 0) { ret = read(fd, pidstr, sizeof(pidstr) - 1); if (ret < 0) { flog(LOG_ERR, "cannot read radvd pid file, terminating: %s", strerror(errno)); exit(1); } pidstr[ret] = '\0'; if (!kill((pid_t)atol(pidstr), 0)) { flog(LOG_ERR, "radvd already running, terminating."); exit(1); } close(fd); fd = open(pidfile, O_CREAT|O_TRUNC|O_WRONLY, 0644); } else /* FIXME: not atomic if pidfile is on an NFS mounted volume */ fd = open(pidfile, O_CREAT|O_EXCL|O_WRONLY, 0644); if (fd < 0) { flog(LOG_ERR, "cannot create radvd pid file, terminating: %s", strerror(errno)); exit(1); } /* * okay, config file is read in, socket and stuff is setup, so * lets fork now... */ if (get_debuglevel() == 0) { /* Detach from controlling terminal */ if (daemon(0, 0) < 0) perror("daemon"); /* close old logfiles, including stderr */ log_close(); /* reopen logfiles, but don't log to stderr unless explicitly requested */ if (log_method == L_STDERR_SYSLOG) log_method = L_SYSLOG; if (log_open(log_method, pname, logfile, facility) < 0) { perror("log_open"); exit(1); } } /* * config signal handlers */ signal(SIGHUP, sighup_handler); signal(SIGTERM, sigterm_handler); signal(SIGINT, sigint_handler); signal(SIGUSR1, sigusr1_handler); snprintf(pidstr, sizeof(pidstr), "%ld\n", (long)getpid()); ret = write(fd, pidstr, strlen(pidstr)); if (ret != strlen(pidstr)) { flog(LOG_ERR, "cannot write radvd pid file, terminating: %s", strerror(errno)); exit(1); } close(fd); config_interface(); kickoff_adverts(); main_loop(); stop_adverts(); unlink(pidfile); return 0; }
void reload_config(void) { struct Interface *iface; flog(LOG_INFO, "attempting to reread config file"); dlog(LOG_DEBUG, 4, "reopening log"); if (log_reopen() < 0) { perror("log_reopen"); exit(1); } iface=IfaceList; while(iface) { struct Interface *next_iface = iface->next; struct AdvPrefix *prefix; struct AdvRoute *route; struct AdvRDNSS *rdnss; struct AdvDNSSL *dnssl; dlog(LOG_DEBUG, 4, "freeing interface %s", iface->Name); prefix = iface->AdvPrefixList; while (prefix) { struct AdvPrefix *next_prefix = prefix->next; free(prefix); prefix = next_prefix; } route = iface->AdvRouteList; while (route) { struct AdvRoute *next_route = route->next; free(route); route = next_route; } rdnss = iface->AdvRDNSSList; while (rdnss) { struct AdvRDNSS *next_rdnss = rdnss->next; free(rdnss); rdnss = next_rdnss; } dnssl = iface->AdvDNSSLList; while (dnssl) { struct AdvDNSSL *next_dnssl = dnssl->next; int i; for (i = 0; i < dnssl->AdvDNSSLNumber; i++) free(dnssl->AdvDNSSLSuffixes[i]); free(dnssl->AdvDNSSLSuffixes); free(dnssl); dnssl = next_dnssl; } free(iface); iface = next_iface; } IfaceList = NULL; /* reread config file */ if (readin_config(conf_file) < 0) { perror("readin_config failed."); exit(1); } /* XXX: fails due to lack of permissions with non-root user */ config_interface(); kickoff_adverts(); flog(LOG_INFO, "resuming normal operation"); }