Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 20 additions & 16 deletions examples/dhcpd/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,27 @@ if(CONFIG_EXAMPLES_DHCPD)
STACKSIZE
${CONFIG_DEFAULT_TASK_STACKSIZE})

nuttx_add_application(
NAME
dhcpd_start
SRCS
dhcpd_start.c
dhcpd_daemon.c
STACKSIZE
${CONFIG_DEFAULT_TASK_STACKSIZE})
if(NOT CONFIG_BUILD_KERNEL)
nuttx_add_application(
NAME
dhcpd_start
SRCS
dhcpd_start.c
dhcpd_daemon.c
STACKSIZE
${CONFIG_DEFAULT_TASK_STACKSIZE})
endif()

nuttx_add_application(
NAME
dhcpd_stop
SRCS
dhcpd_stop.c
dhcpd_daemon.c
STACKSIZE
${CONFIG_DEFAULT_TASK_STACKSIZE})
if(CONFIG_SCHED_WAITPID)
nuttx_add_application(
NAME
dhcpd_stop
SRCS
dhcpd_stop.c
dhcpd_daemon.c
STACKSIZE
${CONFIG_DEFAULT_TASK_STACKSIZE})
endif()

add_definitions(-DCONFIG_NETUTILS_DHCPD_HOST=1 -DHAVE_SO_REUSEADDR=1
-DHAVE_SO_BROADCAST=1)
Expand Down
14 changes: 12 additions & 2 deletions examples/dhcpd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,23 @@ include $(APPDIR)/Make.defs

CSRCS = dhcpd_daemon.c

MAINSRC = dhcpd_start.c dhcpd_stop.c target.c
MAINSRC = target.c

# DHCPD built-in application info

PROGNAME = dhcpd_start dhcpd_stop dhcpd
PROGNAME = dhcpd
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_DHCPD)

ifneq ($(CONFIG_BUILD_KERNEL),y)
MAINSRC += dhcpd_start.c
PROGNAME += dhcpd_start
endif

ifeq ($(CONFIG_SCHED_WAITPID),y)
MAINSRC += dhcpd_stop.c
PROGNAME += dhcpd_stop
endif

include $(APPDIR)/Application.mk
8 changes: 5 additions & 3 deletions examples/dhcpd/dhcpd_daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,12 @@ int dhcpd_daemon(int argc, FAR char *argv[], bool daemon)

/* Then start the dhcpd */

if (daemon)
#ifndef CONFIG_BUILD_KERNEL
if (!daemon)
{
return dhcpd_run(devname);
return dhcpd_start(devname);
}
#endif

return dhcpd_start(devname);
return dhcpd_run(devname);
}
150 changes: 96 additions & 54 deletions netutils/dhcpd/dhcpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@

#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/wait.h>

#include <inttypes.h>
#include <sched.h>
Expand Down Expand Up @@ -276,8 +277,6 @@ struct dhcpd_state_s
struct dhcpd_daemon_s
{
uint8_t ds_state; /* See enum dhcpd_daemon_e */
sem_t ds_lock; /* Used to protect the whole structure */
sem_t ds_sync; /* Used to synchronize start and stop events */
pid_t ds_pid; /* Task ID of the DHCPD daemon */
FAR struct dhcpd_state_s *ds_data; /* DHCPD daemon data */
};
Expand Down Expand Up @@ -314,8 +313,6 @@ static const uint8_t g_magiccookie[4] =
static struct dhcpd_daemon_s g_dhcpd_daemon =
{
DHCPD_NOT_RUNNING,
SEM_INITIALIZER(1),
SEM_INITIALIZER(0),
-1,
NULL
};
Expand Down Expand Up @@ -1019,7 +1016,7 @@ static int dhcpd_sendpacket(int sockfd, int bbroadcast)
#endif

/* Create a socket to respond with a packet to the client. We
* cannot re-use the listener socket because it is not bound correctly
* cannot reuse the listener socket because it is not bound correctly
*/

/* Then send the response to the DHCP client port at that address */
Expand Down Expand Up @@ -1407,7 +1404,7 @@ static inline int dhcpd_decline(void)
lease = dhcpd_findbymac(g_state.ds_inpacket.chaddr);
if (lease)
{
/* Disassociate the IP from the MAC, but prevent re-used of this
/* Disassociate the IP from the MAC, but prevent reused of this
* address for a period of time.
*/

Expand Down Expand Up @@ -1497,10 +1494,74 @@ static inline int dhcpd_openlistener(FAR const char *interface)
* Name: dhcpd_task_run
****************************************************************************/

#ifndef CONFIG_BUILD_KERNEL
static int dhcpd_task_run(int argc, char **argv)
{
return dhcpd_run(argv[1]);
}
#endif

/****************************************************************************
* Name: dhcpd_get_pid
*
* Description:
* Use /proc filesystem to get dhcpd process PID
*
* Returned Value:
* PID of dhcpd process on success, -1 on failure
*
****************************************************************************/

#if !defined(CONFIG_BUILD_KERNEL) || defined(CONFIG_SCHED_WAITPID)
static pid_t dhcpd_get_pid(void)
{
pid_t pid = -1;

#if !defined(CONFIG_BUILD_KERNEL)
pid = g_dhcpd_daemon.ds_pid;
#elif defined(CONFIG_SYSTEM_POPEN)
FAR FILE *fp;
char line[32];

fp = popen(("pidof dhcpd"), "r");
if (fp == NULL)
{
return -errno;
}

if (fgets(line, sizeof(line), fp) != NULL)
{
pid = atoi(line);
}

pclose(fp);
#endif

return pid;
}
#endif

/****************************************************************************
* Name: dhcpd_signal_handler
*
* Description:
* Signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP
* This function allows dhcpd_stop to terminate dhcpd daemon
*
* Input Parameters:
* signo - Signal number
* info - Signal information
* ctx - Signal context
*
****************************************************************************/

static void
dhcpd_signal_handler(int signo, FAR siginfo_t *info, FAR void *ctx)
{
/* Set global flag to indicate stop request */

g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED;
}

/****************************************************************************
* Public Functions
Expand All @@ -1512,7 +1573,8 @@ static int dhcpd_task_run(int argc, char **argv)

int dhcpd_run(FAR const char *interface)
{
int sockfd;
struct sigaction act;
int sockfd = -1;
int nbytes;

ninfo("Started\n");
Expand All @@ -1538,15 +1600,19 @@ int dhcpd_run(FAR const char *interface)

g_dhcpd_daemon.ds_pid = getpid();

/* Install signal handler for CONFIG_NETUTILS_DHCPD_SIGWAKEUP */

memset(&act, 0, sizeof(act));
act.sa_sigaction = dhcpd_signal_handler;
act.sa_flags = SA_SIGINFO;
sigaction(CONFIG_NETUTILS_DHCPD_SIGWAKEUP, &act, NULL);

/* Indicate that we have started */

g_dhcpd_daemon.ds_state = DHCPD_RUNNING;

sem_post(&g_dhcpd_daemon.ds_sync);

/* Now loop indefinitely, reading packets from the DHCP server socket */

sockfd = -1;
while (g_dhcpd_daemon.ds_state != DHCPD_STOP_REQUESTED)
{
/* Create a socket to listen for requests from DHCP clients */
Expand Down Expand Up @@ -1631,7 +1697,6 @@ int dhcpd_run(FAR const char *interface)
g_dhcpd_daemon.ds_data = NULL;
g_dhcpd_daemon.ds_pid = -1;
g_dhcpd_daemon.ds_state = DHCPD_STOPPED;
sem_post(&g_dhcpd_daemon.ds_sync);

return OK;
}
Expand All @@ -1648,6 +1713,7 @@ int dhcpd_run(FAR const char *interface)
*
****************************************************************************/

#ifndef CONFIG_BUILD_KERNEL
int dhcpd_start(FAR const char *interface)
{
FAR char *argv[2];
Expand All @@ -1658,42 +1724,28 @@ int dhcpd_start(FAR const char *interface)

/* Is the DHCPD in a non-running state? */

sem_wait(&g_dhcpd_daemon.ds_lock);
if (g_dhcpd_daemon.ds_state == DHCPD_NOT_RUNNING ||
g_dhcpd_daemon.ds_state == DHCPD_STOPPED)
if (dhcpd_get_pid() < 0)
{
/* Start the DHCPD daemon */

g_dhcpd_daemon.ds_state = DHCPD_STARTED;
pid =
task_create("DHCPD daemon", CONFIG_NETUTILS_DHCPD_PRIORITY,
CONFIG_NETUTILS_DHCPD_STACKSIZE, dhcpd_task_run,
argv);
pid = task_create("dhcpd", CONFIG_NETUTILS_DHCPD_PRIORITY,
CONFIG_NETUTILS_DHCPD_STACKSIZE, dhcpd_task_run,
argv);

/* Handle failures to start the DHCPD daemon */

if (pid < 0)
{
int errval = errno;

g_dhcpd_daemon.ds_state = DHCPD_STOPPED;
nerr("ERROR: Failed to start the DHCPD daemon: %d\n", errval);
sem_post(&g_dhcpd_daemon.ds_lock);
return -errval;
}

/* Wait for any daemon state change */

do
{
sem_wait(&g_dhcpd_daemon.ds_sync);
}
while (g_dhcpd_daemon.ds_state == DHCPD_STARTED);
}

sem_post(&g_dhcpd_daemon.ds_lock);
return OK;
}
#endif

/****************************************************************************
* Name: dhcpd_stop
Expand All @@ -1707,46 +1759,36 @@ int dhcpd_start(FAR const char *interface)
*
****************************************************************************/

#ifdef CONFIG_SCHED_WAITPID
int dhcpd_stop(void)
{
int ret;
pid_t pid;

/* Is the DHCPD in a running state? */

sem_wait(&g_dhcpd_daemon.ds_lock);
if (g_dhcpd_daemon.ds_state == DHCPD_STARTED ||
g_dhcpd_daemon.ds_state == DHCPD_RUNNING)
pid = dhcpd_get_pid();
if (pid >= 0)
{
/* Yes.. request that the daemon stop. */

g_dhcpd_daemon.ds_state = DHCPD_STOP_REQUESTED;

/* Wait for any daemon state change */

do
if (kill(pid, CONFIG_NETUTILS_DHCPD_SIGWAKEUP) < 0)
{
/* Signal the DHCPD client */

ret = kill(g_dhcpd_daemon.ds_pid,
CONFIG_NETUTILS_DHCPD_SIGWAKEUP);

if (ret < 0)
{
nerr("ERROR: kill pid %d failed: %d\n",
g_dhcpd_daemon.ds_pid, errno);
break;
}
nerr("ERROR: kill pid %d failed: %d\n", pid, errno);
return -errno;
}

/* Wait for the DHCPD client to respond to the stop request */
/* Wait for the DHCPD client to respond to the stop request */

sem_wait(&g_dhcpd_daemon.ds_sync);
if (waitpid(pid, NULL, 0) < 0)
{
nerr("ERROR: waitpid failed: %d\n", errno);
return -errno;
}
while (g_dhcpd_daemon.ds_state == DHCPD_STOP_REQUESTED);
}

sem_post(&g_dhcpd_daemon.ds_lock);
return OK;
}
#endif

/****************************************************************************
* Name: dhcpd_set_startip
Expand Down
Loading