#include "logger.h"
#include "socket.h"
-static char *cleanmetas (char *cstr)
+static char *cleanmetas (const char *cstr)
{
- register char *c = cstr;
-
- if (! cstr)
- return NULL;
-
+ /* The largest single element we can have is 256 bytes according to the RFC,
+ so this buffer size should be safe even if it's all ' */
+ char buffer[1024] = {0};
+ register char *c = (char *) cstr;
+ register char *b = buffer;
+
+ if (! cstr || strlen (cstr) == 0)
+ return b;
+
do
if (*c == 39)
- *c = ' ';
+ {
+ *b++ = '\'';
+ *b++ = '\\';
+ *b++ = '\'';
+ *b++ = '\'';
+ }
+ else
+ *b++ = *c;
while (*c++);
-
- return cstr;
+
+ *b++ = 0;
+ b = buffer;
+
+ return b;
}
static void exec_script (const char *script, const char *infofile,
pid_t pid;
char *const argc[4] =
{ (char *) script, (char *) infofile, (char *) arg, NULL };
-
+
if (! script || ! infofile || ! arg)
return;
logger (LOG_ERR, "`%s': %s", script, strerror (ENOENT));
return;
}
-
+
logger (LOG_DEBUG, "exec \"%s %s %s\"", script, infofile, arg);
-
+
/* We don't wait for the user script to finish - do we trust it? */
/* Don't use vfork as we lose our memory when dhcpcd exits
causing the script to fail */
logger (LOG_ERR, "fopen `%s': %s", NTPFILE, strerror (errno));
return -1;
}
-
+
fprintf (f, "# Generated by dhcpcd for interface %s\n", ifname);
fprintf (f, "restrict default noquery notrust nomodify\n");
fprintf (f, "restrict 127.0.0.1\n");
fprintf (f, "%s %s\n", prefix, inet_ntoa (address->address));
fclose (f);
-
+
return 0;
}
-static int write_info(const interface_t *iface, const dhcp_t *dhcp)
+static int write_info(const interface_t *iface, const dhcp_t *dhcp,
+ const options_t *options)
{
FILE *f;
route_t *route;
fprintf (f, "BROADCAST='%s'\n", inet_ntoa (dhcp->broadcast));
if (dhcp->mtu > 0)
fprintf (f, "MTU='%d'\n", dhcp->mtu);
-
+
if (dhcp->routes)
{
fprintf (f, "ROUTES='");
}
fprintf (f, "'\n");
}
-
+
if (dhcp->rootpath)
fprintf (f, "ROOTPATH='%s'\n", cleanmetas (dhcp->rootpath));
fprintf (f, "DHCPSID='%s'\n", inet_ntoa (dhcp->serveraddress));
- fprintf (f, "DHCPCHADDR='%s'\n", ether_ntoa (&iface->ethernet_address));
fprintf (f, "DHCPSNAME='%s'\n", cleanmetas (dhcp->servername));
fprintf (f, "LEASETIME='%u'\n", dhcp->leasetime);
fprintf (f, "RENEWALTIME='%u'\n", dhcp->renewaltime);
fprintf (f, "REBINDTIME='%u'\n", dhcp->rebindtime);
fprintf (f, "INTERFACE='%s'\n", iface->name);
- fprintf (f, "CLASSID='%s'\n", cleanmetas (dhcp->classid));
- fprintf (f, "CLIENTID='%s'\n", cleanmetas (dhcp->clientid));
-
+ fprintf (f, "CLASSID='%s'\n", cleanmetas (options->classid));
+ if (options->clientid[0])
+ fprintf (f, "CLIENTID='%s'\n", cleanmetas (options->clientid));
+ else
+ fprintf (f, "CLIENTID='%s'\n", ether_ntoa (&iface->ethernet_address));
+ fprintf (f, "DHCPCHADDR='%s'\n", ether_ntoa (&iface->ethernet_address));
fclose (f);
return 0;
}
char curhostname[HOSTNAME_MAX_LEN] = {0};
char *dname = NULL;
int dnamel = 0;
-
+
if (! options || ! iface || ! dhcp)
return -1;
if (new_route->destination.s_addr == route->destination.s_addr
&& new_route->netmask.s_addr == route->netmask.s_addr
&& new_route->gateway.s_addr == route->gateway.s_addr)
- {
- have = 1;
- break;
- }
+ {
+ have = 1;
+ break;
+ }
if (! have)
del_route (iface->name, route->destination, route->netmask,
route->gateway, options->metric);
/* Now delete the old address if different */
if (iface->previous_address.s_addr != dhcp->address.s_addr
&& iface->previous_address.s_addr != 0)
- del_address (iface->name, iface->previous_address);
+ del_address (iface->name, iface->previous_address);
#ifdef __linux__
/* On linux, we need to change the subnet route to have our metric. */
{
route_t *new_routes = NULL;
int remember;
-
+
for (route = dhcp->routes; route; route = route->next)
{
/* Don't set default routes if not asked to */
continue;
remember = add_route (iface->name, route->destination,
- route->netmask, route->gateway,
- options->metric);
+ route->netmask, route->gateway,
+ options->metric);
/* If we failed to add the route, we may have already added it
ourselves. If so, remember it again. */
if (remember < 0)
}
gethostname (curhostname, sizeof (curhostname));
-
+
if (options->dohostname
|| strlen (curhostname) == 0
|| strcmp (curhostname, "(none)") == 0
}
}
- write_info (iface, dhcp);
+ write_info (iface, dhcp, options);
- if (iface->previous_address.s_addr != dhcp->address.s_addr)
+ if (iface->previous_address.s_addr != dhcp->address.s_addr)
{
memcpy (&iface->previous_address,
&dhcp->address, sizeof (struct in_addr));
int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message)
{
unsigned char *p = message->options;
+ unsigned char *end = message->options; /* Add size later for gcc-3 issue */
unsigned char option;
unsigned char length;
- unsigned char *end = message->options + sizeof (message->options);
unsigned int len = 0;
int i;
int retval = -1;
route_t *route = first_route;
route_t *last_route = NULL;
route_t *csr = NULL;
- char classid[CLASS_ID_MAX_LEN];
- char clientid[CLIENT_ID_MAX_LEN];
- memset (first_route, 0, sizeof (route_t));
+ end += sizeof (message->options);
- /* The message back never has the class or client id's so we save them */
- strcpy (classid, dhcp->classid);
- strcpy (clientid, dhcp->clientid);
+ memset (first_route, 0, sizeof (route_t));
dhcp->address.s_addr = message->yiaddr;
strcpy (dhcp->servername, message->servername);
}
}
- /* The message back never has the class or client id's so we restore them */
- strcpy (dhcp->classid, classid);
- strcpy (dhcp->clientid, clientid);
-
return retval;
}
ip->ip_sum = checksum ((unsigned char *) ip, sizeof (struct ip));
}
-static int valid_dhcp_packet (unsigned char * data)
+static int valid_dhcp_packet (unsigned char *data)
{
struct udp_dhcp_packet *packet = (struct udp_dhcp_packet *) data;
uint16_t bytes = ntohs (packet->ip.ip_len);
int open_socket (interface_t *iface, bool arp)
{
int n = 0;
- int fd = 0;
+ int fd = -1;
char device[PATH_MAX];
int flags;
struct ifreq ifr;
return -1;
}
+ memset (&ifr, 0, sizeof (struct ifreq));
strncpy (ifr.ifr_name, iface->name, sizeof (ifr.ifr_name));
if (ioctl (fd, BIOCSETIF, &ifr) < 0)
{
}
iface->buffer_length = buf;
+ flags = 1;
if (ioctl (fd, BIOCIMMEDIATE, &flags) < 0)
{
logger (LOG_ERR, "ioctl BIOCIMMEDIATE: %s", strerror (errno));
/* Install the DHCP filter */
if (arp)
{
+ printf ("arp!");
p.bf_insns = arp_bpf_filter;
p.bf_len = sizeof (arp_bpf_filter) / sizeof (struct bpf_insn);
}
long bytes;
struct udp_dhcp_packet *dhcp;
- /* We don't use the given buffer, but we need to rewind the position */
+ /* We don't use the given buffer, but we need to rewind the position */
*buffer_pos = 0;
memset (buffer, 0, iface->buffer_length);