Compare commits
10 Commits
f7db9fd5e7
...
3ff8685fc6
Author | SHA1 | Date | |
---|---|---|---|
|
3ff8685fc6 | ||
|
d9e0afdc7c | ||
|
aa684baad7 | ||
|
841c8663e9 | ||
|
44511e6789 | ||
|
1b8dc7f05e | ||
|
1c1ea86604 | ||
|
95c70ba2a7 | ||
|
26f81272ee | ||
|
5eccd4893a |
2
Makefile
2
Makefile
@ -23,7 +23,7 @@ ifchd-parse.c:
|
||||
ragel -G2 -o ifchd-parse.c ifchd-parse.rl
|
||||
|
||||
cfg.c:
|
||||
ragel -G2 -o cfg.c cfg.rl
|
||||
ragel -T0 -o cfg.c cfg.rl
|
||||
|
||||
ragel: ifchd-parse.c cfg.c
|
||||
|
||||
|
38
cfg.rl
38
cfg.rl
@ -9,6 +9,7 @@
|
||||
#include <limits.h>
|
||||
#include "ndhc-defines.h"
|
||||
#include "cfg.h"
|
||||
#include "sys.h"
|
||||
#include "arp.h"
|
||||
#include "ndhc.h"
|
||||
#include "ifchd.h"
|
||||
@ -17,6 +18,43 @@
|
||||
#include "nk/privs.h"
|
||||
#include "nk/io.h"
|
||||
|
||||
static bool xisxdigit(int c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
|
||||
}
|
||||
|
||||
static bool is_string_hwaddr(const char *str, size_t slen)
|
||||
{
|
||||
return slen == 17 && str[2] == ':' && str[5] == ':' && str[8] == ':' &&
|
||||
str[11] == ':' && str[14] == ':' &&
|
||||
xisxdigit(str[0]) && xisxdigit(str[1]) && xisxdigit(str[3]) &&
|
||||
xisxdigit(str[4]) && xisxdigit(str[6]) && xisxdigit(str[7]) &&
|
||||
xisxdigit(str[9]) && xisxdigit(str[10]) && xisxdigit(str[12]) &&
|
||||
xisxdigit(str[13]) && xisxdigit(str[15]) && xisxdigit(str[16]);
|
||||
}
|
||||
|
||||
static int get_clientid_string(const char *str, size_t slen)
|
||||
{
|
||||
if (!slen)
|
||||
return -1;
|
||||
if (!is_string_hwaddr(str, slen)) {
|
||||
client_config.clientid[0] = 0;
|
||||
memcpy(client_config.clientid + 1, str,
|
||||
min_size_t(slen, sizeof client_config.clientid - 1));
|
||||
client_config.clientid_len = slen + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mac[6];
|
||||
for (size_t i = 0; i < sizeof mac; ++i)
|
||||
mac[i] = strtol(str+i*3, (char **)0, 16);
|
||||
client_config.clientid[0] = 1; // Ethernet MAC type
|
||||
memcpy(client_config.clientid + 1, mac,
|
||||
min_size_t(sizeof mac, sizeof client_config.clientid - 1));
|
||||
client_config.clientid_len = 7;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void copy_cmdarg(char *dest, const char *src,
|
||||
size_t destlen, const char *argname)
|
||||
{
|
||||
|
@ -1,6 +1,8 @@
|
||||
#!/bin/execlineb -P
|
||||
fdmove -c 2 1
|
||||
backtick OLDEXTIP { cat /etc/firewall/tmp/OLDEXTIP }
|
||||
backtick OLDEXTIP { cat /etc/ndhc/LEASE-wan0 }
|
||||
importas OLDEXTIP OLDEXTIP
|
||||
/sbin/ndhc -c /etc/ndhc/wan0.conf -r $OLDEXTIP
|
||||
ifelse { eltest -n $OLDEXTIP }
|
||||
{ /sbin/ndhc -c /etc/ndhc/wan0.conf -r $OLDEXTIP }
|
||||
/sbin/ndhc -c /etc/ndhc/wan0.conf
|
||||
|
||||
|
13
ifset.c
13
ifset.c
@ -29,15 +29,14 @@
|
||||
|
||||
static uint32_t ifset_nl_seq = 1;
|
||||
|
||||
// 32-bit position values are relatively prime to 37, so the residue mod37
|
||||
// gives a unique mapping for each value. Gives correct result for v=0.
|
||||
static int trailz(uint32_t v)
|
||||
// Portable ctz() that gives a defined result for x == 0.
|
||||
static int trailz(uint32_t x)
|
||||
{
|
||||
static const int bpm37[] = {
|
||||
32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17,
|
||||
0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18
|
||||
static const int ctzt[32] = {
|
||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10,
|
||||
};
|
||||
return bpm37[(-v & v) % 37];
|
||||
return x ? ctzt[((x & -x) * 0x077cb531u) >> 27] : 32;
|
||||
}
|
||||
|
||||
// sn must be in network order
|
||||
|
@ -33,7 +33,7 @@ void open_leasefile(void)
|
||||
{
|
||||
char leasefile[PATH_MAX];
|
||||
get_leasefile_path(leasefile, sizeof leasefile, client_config.interface);
|
||||
leasefilefd = open(leasefile, O_WRONLY|O_TRUNC|O_CREAT|O_CLOEXEC, 0644);
|
||||
leasefilefd = open(leasefile, O_WRONLY|O_CREAT|O_CLOEXEC, 0644);
|
||||
if (leasefilefd < 0)
|
||||
suicide("%s: (%s) Failed to create lease file '%s': %s",
|
||||
client_config.interface, __func__, leasefile, strerror(errno));
|
||||
@ -59,6 +59,10 @@ static void do_write_leasefile(struct in_addr ipnum)
|
||||
log_line("%s: (%s) memccpy failed", client_config.interface, __func__);
|
||||
return;
|
||||
}
|
||||
size_t outlen = strlen(out);
|
||||
// Make sure that we're not overwriting the leasefile with an invalid
|
||||
// IP address. This is a very minimal check.
|
||||
if (outlen < 7) return;
|
||||
if (safe_ftruncate(leasefilefd, 0)) {
|
||||
log_line("%s: (%s) Failed to truncate lease file: %s",
|
||||
client_config.interface, __func__, strerror(errno));
|
||||
@ -69,7 +73,6 @@ static void do_write_leasefile(struct in_addr ipnum)
|
||||
client_config.interface, __func__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
size_t outlen = strlen(out);
|
||||
ssize_t ret = safe_write(leasefilefd, out, outlen);
|
||||
if (ret < 0 || (size_t)ret != outlen)
|
||||
log_line("%s: (%s) Failed to write ip to lease file.",
|
||||
|
66
ndhc.c
66
ndhc.c
@ -10,7 +10,6 @@
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
@ -198,41 +197,6 @@ static void setup_signals_ndhc(void)
|
||||
suicide("sigaction failed");
|
||||
}
|
||||
|
||||
static int is_string_hwaddr(const char *str, size_t slen)
|
||||
{
|
||||
if (slen == 17 && str[2] == ':' && str[5] == ':' && str[8] == ':' &&
|
||||
str[11] == ':' && str[14] == ':' &&
|
||||
isxdigit(str[0]) && isxdigit(str[1]) && isxdigit(str[3]) &&
|
||||
isxdigit(str[4]) && isxdigit(str[6]) && isxdigit(str[7]) &&
|
||||
isxdigit(str[9]) && isxdigit(str[10]) && isxdigit(str[12]) &&
|
||||
isxdigit(str[13]) && isxdigit(str[15]) && isxdigit(str[16])
|
||||
)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_clientid_string(const char *str, size_t slen)
|
||||
{
|
||||
if (!slen)
|
||||
return -1;
|
||||
if (!is_string_hwaddr(str, slen)) {
|
||||
client_config.clientid[0] = 0;
|
||||
memcpy(client_config.clientid + 1, str,
|
||||
min_size_t(slen, sizeof client_config.clientid - 1));
|
||||
client_config.clientid_len = slen + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mac[6];
|
||||
for (size_t i = 0; i < sizeof mac; ++i)
|
||||
mac[i] = strtol(str+i*3, (char **)0, 16);
|
||||
client_config.clientid[0] = 1; // Ethernet MAC type
|
||||
memcpy(client_config.clientid + 1, mac,
|
||||
min_size_t(sizeof mac, sizeof client_config.clientid - 1));
|
||||
client_config.clientid_len = 7;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void fail_if_state_dir_dne(void)
|
||||
{
|
||||
if (strlen(state_dir) == 0)
|
||||
@ -257,24 +221,21 @@ static void do_ndhc_work(void)
|
||||
setup_signals_ndhc();
|
||||
start_dhcp_listen(&cs);
|
||||
|
||||
struct pollfd pfds[6] = {0};
|
||||
pfds[0].fd = cs.nlFd;
|
||||
pfds[0].events = POLLIN|POLLHUP|POLLERR|POLLRDHUP;
|
||||
pfds[1].fd = ifchStream[0];
|
||||
pfds[1].events = POLLHUP|POLLERR|POLLRDHUP;
|
||||
pfds[2].fd = sockdStream[0];
|
||||
pfds[2].events = POLLHUP|POLLERR|POLLRDHUP;
|
||||
pfds[3].fd = cs.rfkillFd;
|
||||
pfds[3].events = POLLIN|POLLHUP|POLLERR|POLLRDHUP;
|
||||
// These can change on the fly.
|
||||
pfds[4].events = POLLIN|POLLHUP|POLLERR|POLLRDHUP;
|
||||
pfds[5].events = POLLIN|POLLHUP|POLLERR|POLLRDHUP;
|
||||
|
||||
struct pollfd pfds[] = {
|
||||
[0] = { .fd = cs.nlFd, .events = POLLIN|POLLHUP|POLLERR|POLLRDHUP },
|
||||
[1] = { .fd = ifchStream[0], .events = POLLHUP|POLLERR|POLLRDHUP },
|
||||
[2] = { .fd = sockdStream[0], .events = POLLHUP|POLLERR|POLLRDHUP },
|
||||
[6] = { .fd = scriptdStream[0], .events = POLLHUP|POLLERR|POLLRDHUP },
|
||||
[3] = { .fd = cs.rfkillFd, .events = POLLIN|POLLHUP|POLLERR|POLLRDHUP },
|
||||
// These can change on the fly.
|
||||
[4] = { .events = POLLIN|POLLHUP|POLLERR|POLLRDHUP },
|
||||
[5] = { .events = POLLIN|POLLHUP|POLLERR|POLLRDHUP },
|
||||
};
|
||||
for (;;) {
|
||||
pfds[4].fd = cs.arpFd;
|
||||
pfds[5].fd = cs.listenFd;
|
||||
had_event = false;
|
||||
if (poll(pfds, 6, timeout) < 0) {
|
||||
if (poll(pfds, 7, timeout) < 0) {
|
||||
if (errno != EINTR) suicide("poll failed");
|
||||
}
|
||||
|
||||
@ -300,6 +261,9 @@ static void do_ndhc_work(void)
|
||||
if (pfds[2].revents & (POLLHUP|POLLERR|POLLRDHUP)) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (pfds[6].revents & (POLLHUP|POLLERR|POLLRDHUP)) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (pfds[3].revents & POLLIN) {
|
||||
had_event = true;
|
||||
sev_rfk = rfkill_get(&cs, 1, client_config.rfkillIdx);
|
||||
@ -411,7 +375,7 @@ int ifchStream[2];
|
||||
int sockdSock[2];
|
||||
int sockdStream[2];
|
||||
int scriptdSock[2];
|
||||
int scriptdStream[2];
|
||||
int scriptdStream[2] = { -1, -1 };
|
||||
|
||||
static void create_ifch_ipc_sockets(void) {
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, ifchSock) < 0)
|
||||
|
1
ndhc.h
1
ndhc.h
@ -83,7 +83,6 @@ bool carrier_isup(void);
|
||||
void set_client_addr(const char *v);
|
||||
void show_usage(void);
|
||||
void signal_exit(int status);
|
||||
int get_clientid_string(const char *str, size_t slen);
|
||||
void print_version(void);
|
||||
|
||||
static inline void advance_xid(struct client_state_t *cs) {
|
||||
|
29
nk/random.c
29
nk/random.c
@ -1,17 +1,16 @@
|
||||
// Copyright 2013-2018 Nicholas J. Kain <njkain at gmail dot com>
|
||||
// Copyright 2013-2022 Nicholas J. Kain <njkain at gmail dot com>
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include <stdint.h>
|
||||
#include "nk/hwrng.h"
|
||||
#include "nk/random.h"
|
||||
|
||||
// GJrand64: https://gjrand.sourceforge.net
|
||||
// SFC64 modified to use a Weyl counter.
|
||||
|
||||
void nk_random_init(struct nk_random_state *s)
|
||||
{
|
||||
nk_hwrng_bytes(s->seed, sizeof(uint64_t) * 2);
|
||||
s->seed[2] = 2000001;
|
||||
s->seed[3] = 0;
|
||||
for (size_t i = 0; i < 14; ++i) nk_random_u64(s);
|
||||
nk_hwrng_bytes(s->seed, sizeof(uint64_t) * 3);
|
||||
s->seed[3] = 1;
|
||||
for (size_t i = 0; i < 12; ++i) nk_random_u64(s);
|
||||
}
|
||||
|
||||
static inline uint64_t rotl64(const uint64_t x, int k) {
|
||||
@ -20,17 +19,11 @@ static inline uint64_t rotl64(const uint64_t x, int k) {
|
||||
|
||||
uint64_t nk_random_u64(struct nk_random_state *s)
|
||||
{
|
||||
s->seed[1] += s->seed[2];
|
||||
s->seed[0] = rotl64(s->seed[0], 32);
|
||||
s->seed[2] ^= s->seed[1];
|
||||
s->seed[3] += 0x55aa96a5;
|
||||
s->seed[0] += s->seed[1];
|
||||
s->seed[2] = rotl64(s->seed[2], 23);
|
||||
s->seed[1] ^= s->seed[0];
|
||||
s->seed[0] += s->seed[2];
|
||||
s->seed[1] = rotl64(s->seed[1], 19);
|
||||
s->seed[2] += s->seed[0];
|
||||
s->seed[1] += s->seed[3];
|
||||
return s->seed[0];
|
||||
const uint64_t t = (s->seed[0] + s->seed[1]) ^ s->seed[3];
|
||||
s->seed[3] += 0x6a09e667a7541669ull;
|
||||
s->seed[0] = s->seed[1] ^ (s->seed[1] >> 11);
|
||||
s->seed[1] = s->seed[2] + (s->seed[2] << 3);
|
||||
s->seed[2] = rotl64(s->seed[2], 24) + t;
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "nk/log.h"
|
||||
#include "nk/io.h"
|
||||
#include "nk/pspawn.h"
|
||||
@ -138,7 +139,7 @@ static void setup_signals_scriptd(void)
|
||||
|
||||
struct sigaction sa = {
|
||||
.sa_handler = signal_handler,
|
||||
.sa_flags = SA_RESTART|SA_NOCLDWAIT,
|
||||
.sa_flags = SA_RESTART,
|
||||
};
|
||||
if (sigemptyset(&sa.sa_mask))
|
||||
suicide("sigemptyset failed");
|
||||
@ -153,6 +154,8 @@ void scriptd_main(void)
|
||||
prctl(PR_SET_NAME, "ndhc: scriptd");
|
||||
umask(077);
|
||||
setup_signals_scriptd();
|
||||
fcntl(scriptdSock[1], F_SETFD, FD_CLOEXEC);
|
||||
fcntl(scriptdStream[1], F_SETFD, FD_CLOEXEC);
|
||||
do_scriptd_work();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user