Change ifchange_*() so that the interface and ip keywords are only sent to
ifchd if it is necessary to do so, just as is the case for other keywords. Make data sending in ifchange_*() collect all keywords into a buffer that is sent in a single sockwrite() rather than performing a sockwrite() for every keyword. Minor documentation updates.
This commit is contained in:
parent
3316505f3c
commit
daf42ccb29
15
README
15
README
@ -36,9 +36,18 @@ the ability to service multiple client requests simultaneously; a single ifchd
|
|||||||
is sufficient for multiple ndhc clients. Only exotic setups should require
|
is sufficient for multiple ndhc clients. Only exotic setups should require
|
||||||
this functionality, but it does exist.
|
this functionality, but it does exist.
|
||||||
|
|
||||||
Note that ndhc does not support the entire DHCP client protocol. Only the
|
Note that ndhc does not support the entire DHCP client protocol. Notably, DHCP
|
||||||
minimum necessary featureset is implemented. This behavior should be familiar
|
options concatenation and IPv4 Link Local Addressing as defined in RFC3927 are
|
||||||
to anyone who has used software that purports to be be secure.
|
not and will not be supported.
|
||||||
|
|
||||||
|
On the other hand, ndhc fully implements RFC5227's address conflict detection
|
||||||
|
and defense. Great care is taken to ensure that address conflicts will be
|
||||||
|
detected, and ndhc also has extensive support for address defense. Care is
|
||||||
|
taken to prevent unintentional ARP flooding under any circumstance.
|
||||||
|
|
||||||
|
ndhc also monitors hardware link status via netlink events and reacts
|
||||||
|
appropriately when interface carrier status changes or an interface is
|
||||||
|
explicitly deconfigured.
|
||||||
|
|
||||||
USAGE
|
USAGE
|
||||||
-----
|
-----
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* ifchange.c - functions to call the interface change daemon
|
/* ifchange.c - functions to call the interface change daemon
|
||||||
* Time-stamp: <2011-07-04 22:03:35 njk>
|
* Time-stamp: <2011-07-05 19:22:50 njk>
|
||||||
*
|
*
|
||||||
* (c) 2004-2011 Nicholas J. Kain <njkain at gmail dot com>
|
* (c) 2004-2011 Nicholas J. Kain <njkain at gmail dot com>
|
||||||
*
|
*
|
||||||
@ -37,6 +37,7 @@
|
|||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "strl.h"
|
||||||
#include "ifchange.h"
|
#include "ifchange.h"
|
||||||
|
|
||||||
static int cfg_deconfig; // Set if the interface has already been deconfigured.
|
static int cfg_deconfig; // Set if the interface has already been deconfigured.
|
||||||
@ -154,8 +155,6 @@ static void sockwrite(int fd, const char *buf, size_t count)
|
|||||||
{
|
{
|
||||||
if (safe_write(fd, buf, count) == -1)
|
if (safe_write(fd, buf, count) == -1)
|
||||||
log_error("sockwrite: write failed: %s", strerror(errno));
|
log_error("sockwrite: write failed: %s", strerror(errno));
|
||||||
else
|
|
||||||
log_line("sent to ifchd: %s", buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ifchange_deconfig(void)
|
void ifchange_deconfig(void)
|
||||||
@ -168,10 +167,9 @@ void ifchange_deconfig(void)
|
|||||||
|
|
||||||
sockfd = open_ifch();
|
sockfd = open_ifch();
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "interface:%s:", client_config.interface);
|
snprintf(buf, sizeof buf, "interface:%s:ip:0.0.0.0:",
|
||||||
sockwrite(sockfd, buf, strlen(buf));
|
client_config.interface);
|
||||||
|
log_line("sent to ifchd: ip:0.0.0.0:");
|
||||||
snprintf(buf, sizeof buf, "ip:0.0.0.0:");
|
|
||||||
sockwrite(sockfd, buf, strlen(buf));
|
sockwrite(sockfd, buf, strlen(buf));
|
||||||
|
|
||||||
cfg_deconfig = 1;
|
cfg_deconfig = 1;
|
||||||
@ -180,56 +178,67 @@ void ifchange_deconfig(void)
|
|||||||
close(sockfd);
|
close(sockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_cmd(int sockfd, struct dhcpmsg *packet, uint8_t code)
|
static size_t send_client_ip(char *out, size_t olen, struct dhcpmsg *packet)
|
||||||
|
{
|
||||||
|
char ip[32], ipb[64];
|
||||||
|
if (!memcmp(&packet->yiaddr, &cfg_packet.yiaddr, sizeof packet->yiaddr))
|
||||||
|
return 0;
|
||||||
|
inet_ntop(AF_INET, &packet->yiaddr, ip, sizeof ip);
|
||||||
|
snprintf(ipb, sizeof ipb, "ip:%s:", ip);
|
||||||
|
strlcat(out, ipb, olen);
|
||||||
|
log_line("sent to ifchd: %s", ipb);
|
||||||
|
return strlen(ipb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t send_cmd(char *out, size_t olen, struct dhcpmsg *packet,
|
||||||
|
uint8_t code)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
uint8_t *optdata, *olddata;
|
uint8_t *optdata, *olddata;
|
||||||
ssize_t optlen, oldlen;
|
ssize_t optlen, oldlen;
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
memset(buf, '\0', sizeof buf);
|
memset(buf, '\0', sizeof buf);
|
||||||
optdata = get_option_data(packet, code, &optlen);
|
optdata = get_option_data(packet, code, &optlen);
|
||||||
if (!optlen)
|
if (!optlen)
|
||||||
return;
|
return 0;
|
||||||
olddata = get_option_data(&cfg_packet, code, &oldlen);
|
olddata = get_option_data(&cfg_packet, code, &oldlen);
|
||||||
if (oldlen == optlen && !memcmp(optdata, olddata, optlen))
|
if (oldlen == optlen && !memcmp(optdata, olddata, optlen))
|
||||||
return;
|
return 0;
|
||||||
if (ifchd_cmd(buf, sizeof buf, optdata, optlen, code) == -1)
|
if (ifchd_cmd(buf, sizeof buf, optdata, optlen, code) == -1)
|
||||||
return;
|
return 0;
|
||||||
sockwrite(sockfd, buf, strlen(buf));
|
strlcat(out, buf, olen);
|
||||||
|
log_line("sent to ifchd: %s", buf);
|
||||||
|
return strlen(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ifchange_bind(struct dhcpmsg *packet)
|
void ifchange_bind(struct dhcpmsg *packet)
|
||||||
{
|
{
|
||||||
|
char buf[2048];
|
||||||
int sockfd;
|
int sockfd;
|
||||||
char buf[256];
|
int tbs = 0;
|
||||||
char ip[32];
|
|
||||||
|
|
||||||
if (!packet)
|
if (!packet)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
sockfd = open_ifch();
|
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "interface:%s:", client_config.interface);
|
snprintf(buf, sizeof buf, "interface:%s:", client_config.interface);
|
||||||
sockwrite(sockfd, buf, strlen(buf));
|
tbs |= send_client_ip(buf, sizeof buf, packet);
|
||||||
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_SUBNET);
|
||||||
inet_ntop(AF_INET, &packet->yiaddr, ip, sizeof ip);
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_ROUTER);
|
||||||
snprintf(buf, sizeof buf, "ip:%s:", ip);
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_DNS_SERVER);
|
||||||
sockwrite(sockfd, buf, strlen(buf));
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_HOST_NAME);
|
||||||
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_DOMAIN_NAME);
|
||||||
send_cmd(sockfd, packet, DHCP_SUBNET);
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_MTU);
|
||||||
send_cmd(sockfd, packet, DHCP_ROUTER);
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_BROADCAST);
|
||||||
send_cmd(sockfd, packet, DHCP_DNS_SERVER);
|
tbs |= send_cmd(buf, sizeof buf, packet, DHCP_WINS_SERVER);
|
||||||
send_cmd(sockfd, packet, DHCP_HOST_NAME);
|
if (tbs) {
|
||||||
send_cmd(sockfd, packet, DHCP_DOMAIN_NAME);
|
sockfd = open_ifch();
|
||||||
send_cmd(sockfd, packet, DHCP_MTU);
|
sockwrite(sockfd, buf, strlen(buf));
|
||||||
send_cmd(sockfd, packet, DHCP_BROADCAST);
|
close(sockfd);
|
||||||
send_cmd(sockfd, packet, DHCP_WINS_SERVER);
|
}
|
||||||
|
|
||||||
cfg_deconfig = 0;
|
cfg_deconfig = 0;
|
||||||
memcpy(&cfg_packet, packet, sizeof cfg_packet);
|
memcpy(&cfg_packet, packet, sizeof cfg_packet);
|
||||||
|
|
||||||
close(sockfd);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user