aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Christian Hesse <mail@eworm.de>2015-06-04 22:01:53 +0200
committerGravatar Christian Hesse <mail@eworm.de>2015-06-04 22:01:53 +0200
commitd85accad1322e19f85bda707c27c94d5ce24cddb (patch)
tree1490378f2e563297e44b50670c883bdfcf6c9581
parent6c8bcf52d208cb85d8494b928ef0eba02cbfbe91 (diff)
downloaddyndhcpd-d85accad1322e19f85bda707c27c94d5ce24cddb.tar.gz
dyndhcpd-d85accad1322e19f85bda707c27c94d5ce24cddb.tar.zst
divide network into smaller chunks and provide pools
-rw-r--r--config/dhcpd.conf16
-rw-r--r--dyndhcpd.c94
-rw-r--r--dyndhcpd.h9
3 files changed, 70 insertions, 49 deletions
diff --git a/config/dhcpd.conf b/config/dhcpd.conf
index 6444f16..bfddf4d 100644
--- a/config/dhcpd.conf
+++ b/config/dhcpd.conf
@@ -11,12 +11,6 @@ max-lease-time 43200;
option domain-name "__DOMAINNAME__";
-# make sure we do not serve our own address
-host localhost {
- hardware ethernet de:ad:00:be:ef:00;
- fixed-address __ADDRESS__;
-}
-
class "PXEClient" {
match if substring(option vendor-class-identifier, 0, 9) = "PXEClient";
@@ -31,6 +25,8 @@ subnet __NETADDRESS__ netmask __NETMASK__ {
option time-servers __ADDRESS__;
pool {
+ allow members of "PXEClient";
+
next-server __ADDRESS__;
# Disable ProxyDHCP, we're in control of the primary DHCP server.
@@ -69,7 +65,13 @@ subnet __NETADDRESS__ netmask __NETMASK__ {
filename "/ipxe/ipxe.pxe";
}
- range dynamic-bootp __MINHOST__ __MAXHOST__;
+ range dynamic-bootp __MINBOOTP__ __MAXBOOTP__;
+ }
+
+ pool {
+ deny members of "PXEClient";
+
+ range __MINDHCP__ __MAXDHCP__;
}
}
diff --git a/dyndhcpd.c b/dyndhcpd.c
index 79b345d..93dd225 100644
--- a/dyndhcpd.c
+++ b/dyndhcpd.c
@@ -37,9 +37,7 @@ int main(int argc, char ** argv) {
const char * tmp;
struct ifaddrs *ifaddr = NULL, *ifa;
- struct sockaddr_in * s4;
- struct address address, netmask, netaddress,
- broadcast, minhost, maxhost;
+ struct network network, dhcp, bootp;
char * interface = NULL;
char hostname[254];
@@ -138,47 +136,57 @@ int main(int argc, char ** argv) {
if (!(ifa->ifa_flags & IFF_RUNNING))
fprintf(stderr, "Warning: Interface %s is not connected.\n", interface);
- /* get variables in place for address and convert from binary to text */
- s4 = (struct sockaddr_in *)ifa->ifa_addr;
- memcpy(&address.i, &s4->sin_addr, sizeof(struct in_addr));
- if (!inet_ntop(AF_INET, &address.i, address.c, INET_ADDRSTRLEN))
- fprintf(stderr, "%s: inet_ntop failed!\n", ifa->ifa_name);
-
- /* get variables in place for netmask and convert from binary to text */
- s4 = (struct sockaddr_in *)ifa->ifa_netmask;
- memcpy(&netmask.i, &s4->sin_addr, sizeof(struct in_addr));
- if (!inet_ntop(AF_INET, &netmask.i, netmask.c, INET_ADDRSTRLEN))
- fprintf(stderr, "%s: inet_ntop failed!\n", ifa->ifa_name);
-
- /* calculate broadcast and netaddress */
- broadcast.i.s_addr = address.i.s_addr |~ netmask.i.s_addr;
- netaddress.i.s_addr = address.i.s_addr & netmask.i.s_addr;
+ /* get variables in place for address and netmask */
+ memcpy(&network.address.i, &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr, sizeof(struct in_addr));
+ memcpy(&network.netmask.i, &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr, sizeof(struct in_addr));
/* check if subnet has enough addresses */
- if (ntohl(broadcast.i.s_addr) - ntohl(netaddress.i.s_addr) < 2) {
- fprintf(stderr, "We do not have addresses to serve, need a netmask with 30 bit minimum.\n");
+ if ((network.netmask.i.s_addr & 0x0f000000) > 0) {
+ fprintf(stderr, "We do not have addresses to serve, need a netmask with 28 bit minimum.\n");
goto out;
}
- /* calculate min and max host */
- minhost.i.s_addr = htonl(ntohl(netaddress.i.s_addr) + 1);
- maxhost.i.s_addr = htonl(ntohl(broadcast.i.s_addr) - 1);
-
- /* convert missing addresses from binary to text form */
- if (inet_ntop(AF_INET, &broadcast.i, broadcast.c, INET_ADDRSTRLEN) != NULL &&
- inet_ntop(AF_INET, &netaddress.i, netaddress.c, INET_ADDRSTRLEN) != NULL &&
- inet_ntop(AF_INET, &minhost.i, minhost.c, INET_ADDRSTRLEN) != NULL &&
- inet_ntop(AF_INET, &maxhost.i, maxhost.c, INET_ADDRSTRLEN) != NULL) {
+ /* calculate broadcast and netaddress */
+ network.broadcast.i.s_addr = network.address.i.s_addr | ~network.netmask.i.s_addr;
+ network.netaddress.i.s_addr = network.address.i.s_addr & network.netmask.i.s_addr;
+
+ /* calculate for dhcp subnet */
+ dhcp.netmask.i.s_addr = htonl(ntohl(network.netmask.i.s_addr) >> 1 | (1 << 31));
+ dhcp.address.i.s_addr = network.address.i.s_addr ^ (dhcp.netmask.i.s_addr ^ network.netmask.i.s_addr);
+ dhcp.broadcast.i.s_addr = dhcp.address.i.s_addr | ~dhcp.netmask.i.s_addr;
+ dhcp.netaddress.i.s_addr = dhcp.address.i.s_addr & dhcp.netmask.i.s_addr;
+ dhcp.minhost.i.s_addr = htonl(ntohl(dhcp.netaddress.i.s_addr) + 1);
+ dhcp.maxhost.i.s_addr = htonl(ntohl(dhcp.broadcast.i.s_addr) - 1);
+
+ /* calculate for pxe subnet */
+ bootp.netmask.i.s_addr = htonl(ntohl(dhcp.netmask.i.s_addr) >> 1 | (1 << 31));
+ bootp.address.i.s_addr = network.address.i.s_addr ^ (bootp.netmask.i.s_addr ^ dhcp.netmask.i.s_addr);
+ bootp.broadcast.i.s_addr = bootp.address.i.s_addr | ~bootp.netmask.i.s_addr;
+ bootp.netaddress.i.s_addr = bootp.address.i.s_addr & bootp.netmask.i.s_addr;
+ bootp.minhost.i.s_addr = htonl(ntohl(bootp.netaddress.i.s_addr) + 1);
+ bootp.maxhost.i.s_addr = htonl(ntohl(bootp.broadcast.i.s_addr) - 1);
+
+ /* convert addresses from binary to text form */
+ if (inet_ntop(AF_INET, &network.address.i, network.address.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &network.netmask.i, network.netmask.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &network.broadcast.i, network.broadcast.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &network.netaddress.i, network.netaddress.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &dhcp.minhost.i, dhcp.minhost.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &dhcp.maxhost.i, dhcp.maxhost.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &bootp.minhost.i, bootp.minhost.c, INET_ADDRSTRLEN) != NULL &&
+ inet_ntop(AF_INET, &bootp.maxhost.i, bootp.maxhost.c, INET_ADDRSTRLEN) != NULL) {
/* print information */
if (verbose)
- printf("Interface: %s\n"
- "Domain: %s\n"
+ printf("Interface: %s\n"
+ "Domain: %s\n"
"Host Address: %s\n"
- "Network Address: %s\n"
- "Broadcast: %s\n"
- "Netmask: %s\n"
- "Hosts: %s - %s\n", interface, domainname, address.c, netaddress.c,
- broadcast.c, netmask.c, minhost.c, maxhost.c);
+ "Network: %s\n"
+ "Broadcast: %s\n"
+ "Netmask: %s\n"
+ "Hosts DHCP: %s - %s\n"
+ "Hosts BOOTP: %s - %s\n",
+ interface, domainname, network.address.c, network.netaddress.c, network.broadcast.c, network.netmask.c,
+ dhcp.minhost.c, dhcp.maxhost.c, bootp.minhost.c, bootp.maxhost.c);
/* open the template for reading */
if (templatefilename == NULL)
@@ -208,12 +216,14 @@ int main(int argc, char ** argv) {
if (replace(&config, &length, &tmp, "__INTERFACE__", interface) ||
replace(&config, &length, &tmp, "__VERSION__", VERSION) ||
replace(&config, &length, &tmp, "__DOMAINNAME__", domainname) ||
- replace(&config, &length, &tmp, "__ADDRESS__", address.c) ||
- replace(&config, &length, &tmp, "__NETADDRESS__", netaddress.c) ||
- replace(&config, &length, &tmp, "__BROADCAST__", broadcast.c) ||
- replace(&config, &length, &tmp, "__NETMASK__", netmask.c) ||
- replace(&config, &length, &tmp, "__MINHOST__", minhost.c) ||
- replace(&config, &length, &tmp, "__MAXHOST__", maxhost.c)) {
+ replace(&config, &length, &tmp, "__ADDRESS__", network.address.c) ||
+ replace(&config, &length, &tmp, "__NETADDRESS__", network.netaddress.c) ||
+ replace(&config, &length, &tmp, "__BROADCAST__", network.broadcast.c) ||
+ replace(&config, &length, &tmp, "__NETMASK__", network.netmask.c) ||
+ replace(&config, &length, &tmp, "__MINDHCP__", dhcp.minhost.c) ||
+ replace(&config, &length, &tmp, "__MAXDHCP__", dhcp.maxhost.c) ||
+ replace(&config, &length, &tmp, "__MINBOOTP__", bootp.minhost.c) ||
+ replace(&config, &length, &tmp, "__MAXBOOTP__", bootp.maxhost.c)) {
/* do nothing, work has been done */
} else {
config = realloc(config, length + 1);
diff --git a/dyndhcpd.h b/dyndhcpd.h
index 96a7cf3..1f01abf 100644
--- a/dyndhcpd.h
+++ b/dyndhcpd.h
@@ -29,6 +29,15 @@ struct address {
char c[INET_ADDRSTRLEN];
};
+struct network {
+ struct address address;
+ struct address netaddress;
+ struct address netmask;
+ struct address broadcast;
+ struct address minhost;
+ struct address maxhost;
+};
+
/*** replace ***/
int replace(char ** config, size_t *length, const char ** tmp,
const char * template, const char * value);