]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Move clientid generation to client.c and put it on the interface object inplace of...
authorRoy Marples <roy@marples.name>
Thu, 31 Jan 2008 11:19:17 +0000 (11:19 +0000)
committerRoy Marples <roy@marples.name>
Thu, 31 Jan 2008 11:19:17 +0000 (11:19 +0000)
client.c
dhcp.c
dhcp.h
dhcpcd.c
dhcpcd.h
duid.c
duid.h
info.c
interface.h

index 17f0d589f1baf607568e40e6b8a7d15b2cb811e9..e6bb12de9a48b3e05179d7c4c9b93facbebfcb9b 100644 (file)
--- a/client.c
+++ b/client.c
@@ -297,15 +297,6 @@ static bool client_setup (state_t *state, const options_t *options)
        state->daemonised = options->daemonised;
        state->persistent = options->persistent;
 
-#ifdef ENABLE_DUID
-       if (options->clientid_len == 0) {
-               get_duid (iface);
-               if (iface->duid_length > 0)
-                       logger (LOG_INFO, "DUID = %s",
-                               hwaddr_ntoa (iface->duid, iface->duid_length));
-       }
-#endif
-
        if (options->request_address.s_addr == 0 &&
            (options->doinform || options->dorequest || options->daemonised))
        {
@@ -364,6 +355,76 @@ static bool client_setup (state_t *state, const options_t *options)
                }
        }
 
+       if (*options->clientid) {
+               uint8_t family = 0;
+               /* Attempt to see if the ClientID is a hardware address */
+               iface->clientid_len = hwaddr_aton (NULL, options->clientid);
+
+               /* We need to at least try and guess the family */
+               switch (iface->clientid_len) {
+                       case ETHER_ADDR_LEN:
+                               family = ARPHRD_ETHER;
+                               break;
+                       case EUI64_ADDR_LEN:
+                               family = ARPHRD_IEEE1394;
+                               break;
+                       case INFINIBAND_ADDR_LEN:
+                               family = ARPHRD_INFINIBAND;
+                               break;
+               }
+
+               /* It looks and smells like one, so make it one */
+               if (family) {
+                       iface->clientid_len += 1;
+                       iface->clientid = xmalloc (iface->clientid_len);
+                       *iface->clientid =  family;
+                       hwaddr_aton (iface->clientid + 1, options->clientid);
+               } else {
+                       iface->clientid_len = strlen (options->clientid) + 1;
+                       iface->clientid = xmalloc (iface->clientid_len);
+                       *iface->clientid = '\0';
+                       memcpy (iface->clientid + 1,
+                               options->clientid, iface->clientid_len - 1);
+               }
+       } else {
+#ifdef ENABLE_DUID
+               unsigned char *duid = NULL;
+               size_t duid_len = 0;
+
+               if (options->doduid) {
+                       duid = xmalloc (DUID_LEN);
+                       duid_len = get_duid (duid, iface);
+               }
+
+               if (duid_len > 0) {
+                       logger (LOG_INFO, "DUID = %s", hwaddr_ntoa (duid, duid_len));
+               
+                       iface->clientid_len = duid_len + 5;
+                       iface->clientid = xmalloc (iface->clientid_len);
+                       *iface->clientid = 255; /* RFC 4361 */
+
+                       /* IAID is 4 bytes, so if the iface name is 4 bytes use it */
+                       if (strlen (iface->name) == 4) {
+                               memcpy (iface->clientid + 1, iface->name, 4);
+                       } else {
+                               /* Name isn't 4 bytes, so use the index */
+                               uint32_t ul = htonl (if_nametoindex (iface->name));
+                               memcpy (iface->clientid + 1, &ul, 4);
+                       }
+
+                       memcpy (iface->clientid + 5, duid, duid_len);
+                       free (duid);
+               } else {
+#else
+               {
+#endif
+                       iface->clientid_len = iface->hwlen + 1;
+                       iface->clientid = xmalloc (iface->clientid_len);
+                       *iface->clientid = iface->family;
+                       memcpy (iface->clientid + 1, iface->hwaddr, iface->hwlen);
+               }
+       }
+
        return (true);
 }
 
@@ -1034,6 +1095,7 @@ eexit:
                do_socket (state, SOCKET_CLOSED);
                drop_config (state, options);
                free_route (iface->previous_routes);
+               free (iface->clientid);
                free (iface);
        }
 
diff --git a/dhcp.c b/dhcp.c
index 838d6058dff5fdde2e9a3d9c80e537e2b0e4a208..9d81d43b528fa3edb6b203f669a30a6645d8b222 100644 (file)
--- a/dhcp.c
+++ b/dhcp.c
@@ -79,8 +79,7 @@ static const char *dhcp_message (int type)
 }
 
 ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
-                     uint32_t xid, char type,
-                     const options_t *options)
+                     uint32_t xid, char type, const options_t *options)
 {
        struct udp_dhcp_packet *packet;
        dhcpmessage_t *message;
@@ -297,74 +296,18 @@ ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
                        p += options->userclass_len;
                }
 
-               if (options->classid_len > 0) {
+               if (*options->classid > 0) {
                        *p++ = DHCP_CLASSID;
-                       *p++ = options->classid_len;
-                       memcpy (p, options->classid, options->classid_len);
-                       p += options->classid_len;
+                       *p++ = l = strlen (options->classid);
+                       memcpy (p, options->classid, l);
+                       p += l;
                }
        }
 
        *p++ = DHCP_CLIENTID;
-       if (options->clientid_len > 0) {
-               /* Attempt to see if the ClientID is a hardware address */
-               size_t hwlen = hwaddr_aton (NULL, options->clientid);
-               sa_family_t family = 0;
-
-               if (hwlen) {
-                       /* We need to at least try and guess the family */
-                       switch (hwlen) {
-                               case ETHER_ADDR_LEN:
-                                       family = ARPHRD_ETHER;
-                                       break;
-                               case EUI64_ADDR_LEN:
-                                       family = ARPHRD_IEEE1394;
-                                       break;
-                               case INFINIBAND_ADDR_LEN:
-                                       family = ARPHRD_INFINIBAND;
-                                       break;
-                       }
-               }
-
-               /* It looks and smells like one, so make it one */
-               if (hwlen && family) {
-                       unsigned char *hwaddr = xmalloc (hwlen);
-                       hwaddr_aton (hwaddr, options->clientid);
-                       *p++ = hwlen + 1;
-                       *p++ = family;
-                       memcpy (p, hwaddr, hwlen);
-                       free (hwaddr);
-                       p += hwlen;
-               } else {
-                       *p++ = options->clientid_len + 1;
-                       *p++ = 0;
-                       memcpy (p, options->clientid, options->clientid_len);
-                       p += options->clientid_len;
-               }
-#ifdef ENABLE_DUID
-       } else if (iface->duid && options->doduid) {
-               *p++ = iface->duid_length + 5;
-               *p++ = 255; /* RFC 4361 */
-
-               /* IAID is 4 bytes, so if the iface name is 4 bytes 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;
-#endif
-       } else {
-               *p++ = iface->hwlen + 1;
-               *p++ = iface->family;
-               memcpy (p, iface->hwaddr, iface->hwlen);
-               p += iface->hwlen;
-       }
+       *p++ = iface->clientid_len;
+       memcpy (p, iface->clientid, iface->clientid_len);
+       p+= iface->clientid_len;
 
        *p++ = DHCP_END;
 
diff --git a/dhcp.h b/dhcp.h
index fb3a44020ea63c50ffb77146ea23a85b44f93bf0..1d9e781d4dea27c7197968ce8b5a649a8a6df854 100644 (file)
--- a/dhcp.h
+++ b/dhcp.h
@@ -209,8 +209,7 @@ struct udp_dhcp_packet
 };
 
 ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp,
-                     uint32_t xid, char type,
-                     const options_t *options);
+                     uint32_t xid, char type, const options_t *options);
 void free_dhcp (dhcp_t *dhcp);
 int parse_dhcpmessage (dhcp_t *dhcp, const dhcpmessage_t *message);
 
index 0f8892579377dd059f6450d8e56c99164e2d13f0..fd517709b6e455746728aab7c21ce3c58795f94f 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -171,7 +171,6 @@ int main(int argc, char **argv)
        options->script = (char *) DEFAULT_SCRIPT;
        snprintf (options->classid, CLASS_ID_MAX_LEN, "%s %s",
                  PACKAGE, VERSION);
-       options->classid_len = strlen (options->classid);
 
        options->doarp = true;
        options->dodns = true;
@@ -229,8 +228,7 @@ int main(int argc, char **argv)
 #endif
                        case 'h':
                                if (! optarg)
-                                       memset (options->hostname, 0,
-                                               sizeof (options->hostname));
+                                       *options->hostname = '\0';
                                else if (strlen (optarg) > MAXHOSTNAMELEN) {
                                        logger (LOG_ERR,
                                                "`%s' too long for HostName string, max is %d",
@@ -242,17 +240,15 @@ int main(int argc, char **argv)
                                break;
                        case 'i':
                                if (! optarg) {
-                                       memset (options->classid, 0,
-                                               sizeof (options->classid));
-                                       options->classid_len = 0;
+                                       *options->classid = '\0';
                                } else if (strlen (optarg) > CLASS_ID_MAX_LEN) {
                                        logger (LOG_ERR,
                                                "`%s' too long for ClassID string, max is %d",
                                                optarg, CLASS_ID_MAX_LEN);
                                        goto abort;
                                } else
-                                       options->classid_len = strlcpy (options->classid, optarg,
-                                                                       sizeof (options->classid));
+                                       strlcpy (options->classid, optarg,
+                                                sizeof (options->classid));
                                break;
                        case 'k':
                                sig = SIGHUP;
@@ -382,10 +378,9 @@ int main(int argc, char **argv)
                                                        optarg, CLIENT_ID_MAX_LEN);
                                                goto abort;
                                        }
-                                       options->clientid_len = strlcpy (options->clientid, optarg,
-                                                                        sizeof (options->clientid));
-                                       /* empty string disabled duid */
-                                       if (options->clientid_len == 0)
+                                       if (strlcpy (options->clientid, optarg,
+                                                    sizeof (options->clientid)) == 0)
+                                               /* empty string disabled duid */
                                                options->doduid = false;
 
                                } else {
index e27c928882260914fbc9e79c08d5bdb9290cad65..f57093ff4de69a9dc0c5cbcfd8a034f2a458f33a 100644 (file)
--- a/dhcpcd.h
+++ b/dhcpcd.h
@@ -56,9 +56,7 @@ typedef struct options_t {
        char hostname[MAXHOSTNAMELEN];
        int fqdn;
        char classid[CLASS_ID_MAX_LEN];
-       size_t classid_len;
        char clientid[CLIENT_ID_MAX_LEN];
-       size_t clientid_len;
        char userclass[USERCLASS_MAX_LEN];
        size_t userclass_len;
        uint32_t leasetime;
diff --git a/duid.c b/duid.c
index f2d75468e6c7bc47e24fd838f37d21efa565fecf..9fd6f4be9a20fa81949f62598c5c23503f830faf 100644 (file)
--- a/duid.c
+++ b/duid.c
 
 #define THIRTY_YEARS_IN_SECONDS    946707779
 
-void get_duid (interface_t *iface)
+size_t get_duid (unsigned char *duid, const interface_t *iface)
 {
        FILE *f;
        uint16_t type = 0;
        uint16_t hw = 0;
        uint32_t ul;
        time_t t;
-       unsigned char *p = iface->duid;
        int x = 0;
-
+       unsigned char *p = duid;
+       size_t len = 0;
+       
        if (! iface)
-               return;
-
-       /* Remove any existing */
-       iface->duid[0] = '\0';
-       iface->duid_length = 0;
+               return (0);
 
        /* If we already have a DUID then use it as it's never supposed
         * to change once we have one even if the interfaces do */
        if ((f = fopen (DUIDFILE, "r"))) {
-               char *duid = getline (f);
-               if (duid) {
-                       iface->duid_length = hwaddr_aton (NULL, duid);
-                       if (iface->duid_length &&
-                           iface->duid_length <= DUID_LEN)
-                               hwaddr_aton (iface->duid, duid);
-                       free (duid);
+               char *line = getline (f);
+               if (line) {
+                       len = hwaddr_aton (NULL, line);
+                       if (len && len <= DUID_LEN)
+                               hwaddr_aton (duid, line);
+                       free (line);
                }
                fclose (f);
-               if (iface->duid_length)
-                       return;
+               if (len)
+                       return (len);
        } else {
                if (errno != ENOENT) {
                        logger (LOG_ERR, "fopen `%s': %s",
                                DUIDFILE, strerror (errno));
-                       return;
+                       return (0);
                }
        }
 
@@ -102,21 +98,21 @@ void get_duid (interface_t *iface)
        memcpy (p, iface->hwaddr, iface->hwlen);
        p += iface->hwlen;
 
-       iface->duid_length = p - iface->duid;
+       len = p - duid;
 
        if (! (f = fopen (DUIDFILE, "w")))
                logger (LOG_ERR, "fopen `%s': %s", DUIDFILE, strerror (errno));
        else {
-               x = fprintf (f, "%s\n",
-                            hwaddr_ntoa (iface->duid, iface->duid_length));
+               x = fprintf (f, "%s\n", hwaddr_ntoa (duid, len));
                fclose (f);
        }
 
        /* Failed to write the duid? scrub it, we cannot use it */
        if (x < 1) {
-               memset (iface->duid, 0, sizeof (iface->duid));
-               iface->duid_length = 0;
+               len = 0;
                unlink (DUIDFILE);
        }
+
+       return (len);
 }
 #endif
diff --git a/duid.h b/duid.h
index a5bf3f919ab45847b63bcde2707f4fa810a6b924..14929900674b7c20111e9c94c9e5544e036a09de 100644 (file)
--- a/duid.h
+++ b/duid.h
@@ -37,6 +37,6 @@
 
 #include "interface.h"
 
-void get_duid (interface_t *iface);
+size_t get_duid (unsigned char *duid, const interface_t *iface);
 #endif
 #endif
diff --git a/info.c b/info.c
index e24d87bcd49754dc65398fe29335f4d562db7a1d..0d1106ebabca9db3793adddb47ba9afbec112ea0 100644 (file)
--- a/info.c
+++ b/info.c
@@ -208,42 +208,10 @@ bool write_info(const interface_t *iface, const dhcp_t *dhcp,
        }
        print_clean (f, "INTERFACE", iface->name);
        print_clean (f, "CLASSID", options->classid);
-       if (options->clientid_len > 0) {
-               char *clean = cleanmetas (options->clientid);
-               fprintf (f, "CLIENTID='00:%s'\n", clean);
-               free (clean);
+       if (iface->clientid_len > 0) {
+               fprintf (f, "CLIENTID='%s'\n",
+                        hwaddr_ntoa (iface->clientid, iface->clientid_len));
        }
-#ifdef ENABLE_DUID
-       else if (iface->duid_length > 0 && options->doduid) {
-               unsigned char *duid;
-               unsigned char *p;
-               uint32_t ul;
-
-               p = duid = xmalloc (iface->duid_length + 6);
-               *p++ = 255;
-
-               /* 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,
-                                                           (size_t) (p - duid)));
-               free (duid);
-       }
-#endif
-       else
-               fprintf (f, "CLIENTID='%.2X:%s'\n", iface->family,
-                        hwaddr_ntoa (iface->hwaddr, iface->hwlen));
        fprintf (f, "DHCPCHADDR='%s'\n", hwaddr_ntoa (iface->hwaddr,
                                                      iface->hwlen));
 
index 62aaa033dbe3e6d5a5e6e01ec6e8d14a2b8b5315..6a05a6b8d2f26c48118400d6d68a9c1b2fca2732 100644 (file)
@@ -117,10 +117,8 @@ typedef struct interface_t
 
        time_t start_uptime;
 
-#ifdef ENABLE_DUID
-       unsigned char duid[DUID_LEN];
-       size_t duid_length;
-#endif
+       unsigned char *clientid;
+       size_t clientid_len;
 } interface_t;
 
 void free_address (address_t *addresses);