]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
add missing files
authorRoy Marples <roy@marples.name>
Thu, 10 May 2007 16:07:17 +0000 (16:07 +0000)
committerRoy Marples <roy@marples.name>
Thu, 10 May 2007 16:07:17 +0000 (16:07 +0000)
info.c [new file with mode: 0644]
info.h [new file with mode: 0644]

diff --git a/info.c b/info.c
new file mode 100644 (file)
index 0000000..8b1eb7a
--- /dev/null
+++ b/info.c
@@ -0,0 +1,460 @@
+/*
+ * dhcpcd - DHCP client daemon -
+ * Copyright 2006-2007 Roy Marples <uberlord@gentoo.org>
+ *
+ * dhcpcd is an RFC2131 compliant DHCP client daemon.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <sys/stat.h>
+
+#include <arpa/inet.h>
+
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "config.h"
+#include "common.h"
+#include "dhcp.h"
+#include "interface.h"
+#include "logger.h"
+#include "info.h"
+
+#ifdef ENABLE_INFO
+static char *cleanmetas (const char *cstr)
+{
+       /* 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 ' */
+       static char buffer[1024]; 
+       char *b = buffer;
+
+       memset (buffer, 0, sizeof (buffer));
+       if (cstr == NULL || strlen (cstr) == 0)
+               return b;
+
+       do
+               if (*cstr == 39) {
+                       *b++ = '\'';
+                       *b++ = '\\';
+                       *b++ = '\'';
+                       *b++ = '\'';
+               } else
+                       *b++ = *cstr;
+       while (*cstr++);
+
+       *b++ = 0;
+       b = buffer;
+
+       return b;
+}
+
+bool write_info(const interface_t *iface, const dhcp_t *dhcp,
+                               const options_t *options)
+{
+       FILE *f;
+       route_t *route;
+       address_t *address;
+
+       logger (LOG_DEBUG, "writing %s", iface->infofile);
+       if ((f = fopen (iface->infofile, "w")) == NULL) {
+               logger (LOG_ERR, "fopen `%s': %s", iface->infofile, strerror (errno));
+               return (false);
+       }
+
+       fprintf (f, "IPADDR='%s'\n", inet_ntoa (dhcp->address));
+       fprintf (f, "NETMASK='%s'\n", inet_ntoa (dhcp->netmask));
+       fprintf (f, "BROADCAST='%s'\n", inet_ntoa (dhcp->broadcast));
+       if (dhcp->mtu > 0)
+               fprintf (f, "MTU='%d'\n", dhcp->mtu);
+
+       if (dhcp->routes) {
+               bool doneone = false;
+               fprintf (f, "ROUTES='");
+               for (route = dhcp->routes; route; route = route->next) {
+                       if (route->destination.s_addr != 0) {
+                               if (doneone)
+                                       fprintf (f, " ");
+                               fprintf (f, "%s", inet_ntoa (route->destination));
+                               fprintf (f, ",%s", inet_ntoa (route->netmask));
+                               fprintf (f, ",%s", inet_ntoa (route->gateway));
+                               doneone = true;
+                       }
+               }
+               fprintf (f, "'\n");
+
+               doneone = false;
+               fprintf (f, "GATEWAYS='");
+               for (route = dhcp->routes; route; route = route->next) {
+                       if (route->destination.s_addr == 0) {
+                               if (doneone)
+                                       fprintf (f, " ");
+                               fprintf (f, "%s", inet_ntoa (route->gateway));
+                               doneone = true;
+                       }
+               }
+               fprintf (f, "'\n");
+       }
+
+       if (dhcp->hostname)
+               fprintf (f, "HOSTNAME='%s'\n", cleanmetas (dhcp->hostname));
+
+       if (dhcp->dnsdomain)
+               fprintf (f, "DNSDOMAIN='%s'\n", cleanmetas (dhcp->dnsdomain));
+
+       if (dhcp->dnssearch)
+               fprintf (f, "DNSSEARCH='%s'\n", cleanmetas (dhcp->dnssearch));
+
+       if (dhcp->dnsservers) {
+               fprintf (f, "DNSSERVERS='");
+               for (address = dhcp->dnsservers; address; address = address->next) {
+                       fprintf (f, "%s", inet_ntoa (address->address));
+                       if (address->next)
+                               fprintf (f, " ");
+               }
+               fprintf (f, "'\n");
+       }
+
+       if (dhcp->fqdn) {
+               fprintf (f, "FQDNFLAGS='%u'\n", dhcp->fqdn->flags);
+               fprintf (f, "FQDNRCODE1='%u'\n", dhcp->fqdn->r1);
+               fprintf (f, "FQDNRCODE2='%u'\n", dhcp->fqdn->r2);
+               fprintf (f, "FQDNHOSTNAME='%s'\n", dhcp->fqdn->name);
+       }
+
+       if (dhcp->ntpservers) {
+               fprintf (f, "NTPSERVERS='");
+               for (address = dhcp->ntpservers; address; address = address->next) {
+                       fprintf (f, "%s", inet_ntoa (address->address));
+                       if (address->next)
+                               fprintf (f, " ");
+               }
+               fprintf (f, "'\n");
+       }
+
+       if (dhcp->nisdomain)
+               fprintf (f, "NISDOMAIN='%s'\n", cleanmetas (dhcp->nisdomain));
+
+       if (dhcp->nisservers) {
+               fprintf (f, "NISSERVERS='");
+               for (address = dhcp->nisservers; address; address = address->next) {
+                       fprintf (f, "%s", inet_ntoa (address->address));
+                       if (address->next)
+                               fprintf (f, " ");
+               }
+               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, "DHCPSNAME='%s'\n", cleanmetas (dhcp->servername));
+       fprintf (f, "LEASEDFROM='%u'\n", dhcp->leasedfrom);
+       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 (options->classid));
+       if (options->clientid[0])
+               fprintf (f, "CLIENTID='%s'\n", cleanmetas (options->clientid));
+#ifdef ENABLE_DUID
+       else if (iface->duid_length > 0) {
+               unsigned char duid[256];
+               unsigned char *p = duid;
+               uint32_t ul;
+
+               /* IAID is 4 bytes, so if the interface name is 4 bytes then use it */
+               if (strlen (iface->name) == 4) {
+                       memcpy (p, iface->name, 4);
+               } else {
+                       /* Name isn't 4 bytes, so use the index */
+                       ul = htonl (if_nametoindex (iface->name));
+                       memcpy (p, &ul, 4);
+               }
+               p += 4;
+
+               memcpy (p, iface->duid, iface->duid_length);
+               p += iface->duid_length;
+
+               fprintf (f, "CLIENTID='%s'\n", hwaddr_ntoa (duid, p - duid));
+       }
+#endif
+       else
+               fprintf (f, "CLIENTID='%s'\n", hwaddr_ntoa (iface->hwaddr, iface->hwlen));
+       fprintf (f, "DHCPCHADDR='%s'\n", hwaddr_ntoa (iface->hwaddr, iface->hwlen));
+
+#ifdef ENABLE_INFO_COMPAT
+       /* Support the old .info settings if we need to */
+       fprintf (f, "\n# dhcpcd-1.x and 2.x compatible variables\n");
+       if (dhcp->dnsservers) {
+               fprintf (f, "DNS='");
+               for (address = dhcp->dnsservers; address; address = address->next) {
+                       fprintf (f, "%s", inet_ntoa (address->address));
+                       if (address->next)
+                               fprintf (f, ",");
+               }
+               fprintf (f, "'\n");
+       }
+
+       if (dhcp->routes) {
+               bool doneone = false;
+               fprintf (f, "GATEWAY='");
+               for (route = dhcp->routes; route; route = route->next) {
+                       if (route->destination.s_addr == 0) {
+                               if (doneone)
+                                       fprintf (f, ",");
+                               fprintf (f, "%s", inet_ntoa (route->gateway));
+                               doneone = true;
+                       }
+               }
+               fprintf (f, "'\n");
+       }
+#endif
+
+       fprintf (f, "\n");      
+       fclose (f);
+       return (true);
+}
+
+static bool parse_address (struct in_addr *addr,
+                                                  const char *value, const char *var)
+{
+       if (inet_aton (value, addr) == 0) {
+               logger (LOG_ERR, "%s `%s': %s", var, value,
+                               strerror (errno));
+               return (false);
+       }
+       return (true);
+}
+
+static bool parse_uint (unsigned int *i,
+                                               const char *value, const char *var)
+{
+       if (sscanf (value, "%u", i) != 1) {
+               logger (LOG_ERR, "%s `%s': not a valid number",
+                               var, value);
+               return (false);
+       }
+       return (true);
+}
+
+static bool parse_ushort (unsigned short *s,
+                                                 const char *value, const char *var)
+{
+       if (sscanf (value, "%hu", s) != 1) {
+               logger (LOG_ERR, "%s `%s': not a valid number",
+                               var, value);
+               return (false);
+       }
+       return (true);
+}
+
+static bool parse_addresses (address_t **address, char *value, const char *var)
+{
+       char *token;
+       char *p = value;
+       bool retval = true;
+
+       while ((token = strsep (&p, " "))) {
+               address_t *a = xmalloc (sizeof (address_t));
+               memset (a, 0, sizeof (address_t));
+
+               if (inet_aton (token, &a->address) == 0) {
+                       logger (LOG_ERR, "%s: invalid address `%s'", var, token);
+                       free (a);
+                       retval = false;
+               } else {
+                       if (*address) {
+                               address_t *aa = *address;
+                               while (aa->next)
+                                       aa = aa->next;
+                               aa->next = a;
+                       } else
+                               *address = a;
+               }
+       }
+
+       return (retval);
+}
+
+bool read_info (const interface_t *iface, dhcp_t *dhcp)
+{
+       FILE *fp;
+       char buffer[1024];
+       char *var;
+       char *value;
+       char *p;
+       struct stat sb;
+
+       if (stat (iface->infofile, &sb) != 0) {
+               syslog (LOG_ERR, "lease information file `%s' does not exist",
+                               iface->infofile);
+               return (false);
+       }
+
+       if (! (fp = fopen (iface->infofile, "r"))) {
+               syslog (LOG_ERR, "fopen `%s': %s", iface->infofile, strerror (errno));
+               return (false);
+       }
+
+       dhcp->frominfo = true;
+
+       memset (buffer, 0, sizeof (buffer));
+       while ((fgets (buffer, sizeof (buffer), fp))) {
+               var = buffer;
+
+               /* Strip leading spaces/tabs */
+               while ((*var == ' ') || (*var == '\t'))
+                       var++;
+
+               /* Trim trailing \n */
+               p = var + strlen (var) - 1;
+               if (*p == '\n')
+                       *p = 0;
+
+
+               /* Skip comments */
+               if (*var == '#')
+                       continue;
+               
+               /* If we don't have an equals sign then skip it */
+               if (! (p = strchr (var, '=')))
+                       continue;
+
+               /* Terminate the = so we have two strings */
+               *p = 0;
+
+               value = p + 1;
+               /* Strip leading and trailing quotes if present */
+               if (*value == '\'' || *value == '"')
+                       value++;
+               p = value + strlen (value) - 1;
+               if (*p == '\'' || *p == '"')
+                       *p = 0;
+
+               /* Don't process null vars or values */
+               if (! *var || ! *value)
+                       continue;
+
+               if (strcmp (var, "IPADDR") == 0)
+                       parse_address (&dhcp->address, value, "IPADDR");
+               else if (strcmp (var, "NETMASK") == 0)
+                       parse_address (&dhcp->netmask, value, "NETMASK");
+               else if (strcmp (var, "BROADCAST") == 0)
+                       parse_address (&dhcp->broadcast, value, "BROADCAST");
+               else if (strcmp (var, "MTU") == 0)
+                       parse_ushort (&dhcp->mtu, value, "MTU");
+               else if (strcmp (var, "ROUTES") == 0) {
+                       p = value;
+                       while ((value = strsep (&p, " "))) {
+                               char *pp = value;
+                               char *dest = strsep (&pp, ",");
+                               char *net = strsep (&pp, ",");
+                               char *gate = strsep (&pp, ",");
+                               route_t *route;
+
+                               if (! dest || ! net || ! gate) {
+                                       logger (LOG_ERR, "read_info ROUTES `%s,%s,%s': invalid route",
+                                                       dest, net, gate);
+                                       continue;
+                               }
+
+                               /* See if we can create a route */
+                               route = xmalloc (sizeof (route_t));
+                               memset (route, 0, sizeof (route_t));
+                               if (inet_aton (dest, &route->destination) == 0) {
+                                       logger (LOG_ERR, "read_info ROUTES `%s': not a valid destination address",
+                                                       dest);
+                                       free (route);
+                                       continue;
+                               }
+                               if (inet_aton (dest, &route->netmask) == 0) {
+                                       logger (LOG_ERR, "read_info ROUTES `%s': not a valid netmask address",
+                                                       net);
+                                       free (route);
+                                       continue;
+                               }
+                               if (inet_aton (dest, &route->gateway) == 0) {
+                                       logger (LOG_ERR, "read_info ROUTES `%s': not a valid gateway address",
+                                                       gate);
+                                       free (route);
+                                       continue;
+                               }
+
+                               /* OK, now add our route */
+                               if (dhcp->routes) {
+                                       route_t *r = dhcp->routes;
+                                       while (r->next)
+                                               r = r->next;
+                                       r->next = route;
+                               } else
+                                       dhcp->routes = route;
+                       }
+               } else if (strcmp (var, "GATEWAYS") == 0) {
+                       p = value;
+                       while ((value = strsep (&p, " "))) {
+                               route_t *route = xmalloc (sizeof (route_t));
+                               memset (route, 0, sizeof (route_t));
+                               if (parse_address (&route->gateway, value, "GATEWAYS")) {
+                                       if (dhcp->routes) {
+                                               route_t *r = dhcp->routes;
+                                               while (r->next)
+                                                       r = r->next;
+                                               r->next = route;
+                                       } else
+                                               dhcp->routes = route;
+                               } else
+                                       free (route);
+                       }
+               } else if (strcmp (var, "HOSTNAME") == 0)
+                       dhcp->hostname = xstrdup (value);
+               else if (strcmp (var, "DNSDOMAIN") == 0)
+                       dhcp->dnsdomain = xstrdup (value);
+               else if (strcmp (var, "DNSSEARCH") == 0)
+                       dhcp->dnssearch = xstrdup (value);
+               else if (strcmp (var, "DNSSERVERS") == 0)
+                       parse_addresses (&dhcp->dnsservers, value, "DNSSERVERS");
+               else if (strcmp (var, "NTPSERVERS") == 0)
+                       parse_addresses (&dhcp->ntpservers, value, "NTPSERVERS");
+               else if (strcmp (var, "NISDOMAIN") == 0)
+                       dhcp->nisdomain = xstrdup (value);
+               else if (strcmp (var, "NISSERVERS") == 0)
+                       parse_addresses (&dhcp->nisservers, value, "NISSERVERS");
+               else if (strcmp (var, "ROOTPATH") == 0)
+                       dhcp->rootpath = xstrdup (value);
+               else if (strcmp (var, "DHCPSID") == 0)
+                       parse_address (&dhcp->serveraddress, value, "DHCPSID");
+               else if (strcmp (var, "DHCPSNAME") == 0)
+                       strlcpy (dhcp->servername, value, sizeof (dhcp->servername));
+               else if (strcmp (var, "LEASEDFROM") == 0)
+                       parse_uint (&dhcp->leasedfrom, value, "LEASEDFROM");
+               else if (strcmp (var, "LEASETIME") == 0)
+                       parse_uint (&dhcp->leasetime, value, "LEASETIME");
+               else if (strcmp (var, "RENEWALTIME") == 0)
+                       parse_uint (&dhcp->renewaltime, value, "RENEWALTIME");
+               else if (strcmp (var, "REBINDTIME") == 0)
+                       parse_uint (&dhcp->rebindtime, value, "REBINDTIME");
+       }
+
+       fclose (fp);
+       return (true);
+}
+
+#endif
+
diff --git a/info.h b/info.h
new file mode 100644 (file)
index 0000000..129e740
--- /dev/null
+++ b/info.h
@@ -0,0 +1,36 @@
+/*
+ * dhcpcd - DHCP client daemon -
+ * Copyright 2006-2007 Roy Marples <uberlord@gentoo.org>
+ * 
+ * dhcpcd is an RFC2131 compliant DHCP client daemon.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef INFO_H
+#define INFO_H
+
+#include "dhcpcd.h"
+#include "interface.h"
+#include "dhcp.h"
+
+#ifdef ENABLE_INFO
+bool write_info (const interface_t *iface, const dhcp_t *dhcp,
+                                const options_t *options);
+
+bool read_info (const interface_t *iface, dhcp_t *dhcp);
+#endif
+
+#endif