summaryrefslogblamecommitdiffstats
path: root/workspace/networkDiscovery/networkdiscovery.cpp
blob: f2cb2bbacb574f40a91cdbfadfdf8dababc2ec27 (plain) (tree)






















































































































































































































































































































                                                                                                                     
#include "networkdiscovery.h"
#include <QNetworkInterface>

#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <paths.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#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<QNetworkInterface> interfaces = getListOfNetworkInterfaces();

	/**
	 * test if i get some dhcp values for the dummy0 interface
	 */
	doDHCP(interfaces);
}

NetworkDiscovery::~NetworkDiscovery()
{

}

QList<QNetworkInterface> NetworkDiscovery::getListOfNetworkInterfaces() {
	QList<QNetworkInterface> nIList = QNetworkInterface::allInterfaces();
	QList<QNetworkInterface> 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<QNetworkInterface> 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 */
}