-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathhook.c
More file actions
93 lines (72 loc) · 1.88 KB
/
hook.c
File metadata and controls
93 lines (72 loc) · 1.88 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include "hook.h"
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include "logger.h"
#include "tools.h"
ATTR_NONNULL_ALL void hook(uint8_t type, struct in_addr* address, uint8_t* chaddr, ddhcp_config* config) {
#if LOG_LEVEL_LIMIT >= LOG_DEBUG
char* hwaddr = hwaddr2c(chaddr);
DEBUG("hook(type:%i,addr:%s,chaddr:%s,config)\n", type, inet_ntoa(*address), hwaddr);
free(hwaddr);
#endif
if (!config->hook_command) {
DEBUG("hook(...): No hook command set\n");
return;
}
int pid;
char* action = NULL;
switch (type) {
case HOOK_LEASE:
action = (char*)"lease";
break;
case HOOK_RELEASE:
action = (char*)"release";
break;
default:
break;
}
if (!action) {
DEBUG("hook(...): unknown hook type: %i\n", type);
return;
}
pid = fork();
if (pid < 0) {
// TODO: Include errno from fork
FATAL("hook(...): Failed to fork() for hook command execution (errno: %i).\n", pid);
return;
}
if (pid != 0) {
//Nothing to do as the parent
return;
}
int err = execl(
// Binary to execute
"/bin/sh",
// Arguments to pass
"/bin/sh", //Be pedantic about executing /bin/sh
"-e", // Terminate on error return
"--", // Terminate argument parsing
config->hook_command, // Our actual command to run
action, // The action we notify about
inet_ntoa(*address), // The affected IP address
hwaddr2c(chaddr), // The affected MAC address
(char*) NULL // End of command line
);
if (err < 0) {
// TODO: Logging from the child should be synchronized
FATAL("hook(...): Command could not be executed (errno: %i).\n", err);
}
exit(1);
}
void cleanup_process_table(int signum)
{
UNUSED(signum);
DEBUG("cleanup_process_table(...): Got signal %i\n", signum);
wait(NULL);
}
void hook_init() {
signal(SIGCHLD, cleanup_process_table);
}