#include "networkdiscovery.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "client.h" #include "dhcpcd/dhcpcd.h" #include "dhcp.h" #include "interface.h" #include "logger.h" #include "socket.h" #include "version.h" NetworkDiscovery::NetworkDiscovery(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QList interfaces = getListOfNetworkInterfaces(); /** * test if i get some dhcp values for the dummy0 interface */ doDHCP(interfaces); } NetworkDiscovery::~NetworkDiscovery() { } QList NetworkDiscovery::getListOfNetworkInterfaces() { QList nIList = QNetworkInterface::allInterfaces(); QList result; foreach(QNetworkInterface nI, nIList) { if (((!(nI.flags() & QNetworkInterface::CanBroadcast)|| nI.flags() & QNetworkInterface::IsLoopBack) || nI.flags() & QNetworkInterface::IsPointToPoint)) { continue; } qDebug() << nI.humanReadableName(); result.append(nI); } return result; } int NetworkDiscovery::doDHCP(QList interfaces) { } static int atoint (const char *s) { char *t; long n; errno = 0; n = strtol (s, &t, 0); if ((errno != 0 && n == 0) || s == t || (errno == ERANGE && (n == LONG_MAX || n == LONG_MIN))) { logger (LOG_ERR, "`%s' out of range", s); return (-1); } return ((int) n); } static pid_t read_pid (const char *pidfile) { FILE *fp; pid_t pid = 0; if ((fp = fopen (pidfile, "r")) == NULL) { errno = ENOENT; return 0; } fscanf (fp, "%d", &pid); fclose (fp); return (pid); } int NetworkDiscovery::doDhcp(QNetworkInterface interface) { options_t *options; int userclasses = 0; int opt; int option_index = 0; char *prefix; pid_t pid; int debug = 0; int i; int pidfd = -1; int sig = 0; int retval = EXIT_FAILURE; /* Close any un-needed fd's */ for (i = getdtablesize() - 1; i >= 3; --i) close(i); openlog(PACKAGE, LOG_PID, LOG_LOCAL0); options = xzalloc(sizeof(*options)); options->script = (char *) DEFAULT_SCRIPT; snprintf(options->classid, CLASS_ID_MAX_LEN, "%s %s", PACKAGE, VERSION); options->doarp = true; options->dodns = true; options->domtu = true; options->donis = true; options->dontp = true; options->dogateway = true; options->daemonise = true; options->doinform = false; options->doipv4ll = true; options->doduid = true; options->timeout = DEFAULT_TIMEOUT; gethostname(options->hostname, sizeof(options->hostname)); if (strcmp(options->hostname, "(none)") == 0 || strcmp(options->hostname, "localhost") == 0) memset(options->hostname, 0, sizeof(options->hostname)); /* * kann vermutlich gelöscht werden. #ifdef THERE_IS_NO_FORK dhcpcd_argv = argv; dhcpcd_argc = argc; if (! realpath (argv[0], dhcpcd)) { logger (LOG_ERR, "unable to resolve the path `%s': %s", argv[0], strerror (errno)); goto abort; } #endif */ //TODO:: do something with the .toStdString()!! may cause errors cause char is expected if (interface.humanReadableName().length() > IF_NAMESIZE) { logger(LOG_ERR, "`%s' too long for an interface name (max=%d)", interface.humanReadableName().toStdString(), IF_NAMESIZE); goto abort; } else { strlcpy(options->interface, interface.humanReadableName().toStdString(), sizeof(options->interface)); } if (strchr(options->hostname, '.')) { if (options->fqdn == FQDN_DISABLE) options->fqdn = FQDN_BOTH; } else options->fqdn = FQDN_DISABLE; if (options->request_address.s_addr == 0 && options->doinform) { if ((options->request_address.s_addr = get_address(options->interface)) != 0) options->keep_address = true; } if (IN_LINKLOCAL (ntohl (options->request_address.s_addr))) { logger(LOG_ERR, "you are not allowed to request a link local address"); goto abort; } if (geteuid()) logger(LOG_WARNING, PACKAGE " will not work correctly unless" " run as root"); prefix = xmalloc(sizeof(char) * (IF_NAMESIZE + 3)); snprintf(prefix, IF_NAMESIZE, "%s: ", options->interface); setlogprefix(prefix); snprintf(options->pidfile, sizeof(options->pidfile), PIDFILE, options->interface); free(prefix); chdir("/"); umask(022); if (mkdir(INFODIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST) { logger(LOG_ERR, "mkdir(\"%s\",0): %s\n", INFODIR, strerror(errno)); goto abort; } if (mkdir(ETCDIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) && errno != EEXIST) { logger(LOG_ERR, "mkdir(\"%s\",0): %s\n", ETCDIR, strerror(errno)); goto abort; } if (options->test) { if (options->dorequest || options->doinform) { logger(LOG_ERR, "cannot test with --inform or --request"); goto abort; } if (options->dolastlease) { logger(LOG_ERR, "cannot test with --lastlease"); goto abort; } if (sig != 0) { logger(LOG_ERR, "cannot test with --release or --renew"); goto abort; } } if (sig != 0) { int killed = -1; pid = read_pid(options->pidfile); if (pid != 0) logger(LOG_INFO, "sending signal %d to pid %d", sig, pid); if (!pid || (killed = kill(pid, sig))) logger(sig == SIGALRM ? LOG_INFO : LOG_ERR, ""PACKAGE" not running"); if (pid != 0 && (sig != SIGALRM || killed != 0)) unlink(options->pidfile); if (killed == 0) { retval = EXIT_SUCCESS; goto abort; } if (sig != SIGALRM) goto abort; } if (!options->test && !options->daemonised) { if ((pid = read_pid(options->pidfile)) > 0 && kill(pid, 0) == 0) { logger(LOG_ERR, ""PACKAGE " already running on pid %d (%s)", pid, options->pidfile); goto abort; } pidfd = open(options->pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0664); if (pidfd == -1) { logger(LOG_ERR, "open `%s': %s", options->pidfile, strerror(errno)); goto abort; } /* Lock the file so that only one instance of dhcpcd runs * on an interface */ if (flock(pidfd, LOCK_EX | LOCK_NB) == -1) { logger(LOG_ERR, "flock `%s': %s", options->pidfile, strerror(errno)); goto abort; } /* dhcpcd.sh should not interhit this fd */ if ((i = fcntl(pidfd, F_GETFD, 0)) == -1 || fcntl(pidfd, F_SETFD, i | FD_CLOEXEC) == -1) logger(LOG_ERR, "fcntl: %s", strerror(errno)); writepid(pidfd, getpid()); logger(LOG_INFO, PACKAGE " " VERSION " starting"); } /* Seed random */ srandomdev(); /* Massage our filters per platform */ setup_packet_filters(); /** * here the dhcp magic begins. * the dhcp protocol is started here */ if (dhcp_run(options, &pidfd) == 0) retval = EXIT_SUCCESS; abort: /* If we didn't daemonise then we need to punt the pidfile now */ if (pidfd > -1) { close(pidfd); unlink(options->pidfile); } free(options); #ifdef THERE_IS_NO_FORK /* There may have been an error before the dhcp_run function * clears this, so just do it here to be safe */ free (dhcpcd_skiproutes); #endif logger(LOG_INFO, "exiting"); exit(retval); /* NOTREACHED */ }