From: Roy Marples Date: Thu, 31 Jan 2008 11:19:17 +0000 (+0000) Subject: Move clientid generation to client.c and put it on the interface object inplace of... X-Git-Tag: v3.2.3~44 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=61a22947abd96a1dba9b11d7e383477500453b87;p=thirdparty%2Fdhcpcd.git Move clientid generation to client.c and put it on the interface object inplace of duid. Always save the ClientID as a hex string. This reduces our binary size. --- diff --git a/client.c b/client.c index 17f0d589..e6bb12de 100644 --- 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 838d6058..9d81d43b 100644 --- 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 fb3a4402..1d9e781d 100644 --- 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); diff --git a/dhcpcd.c b/dhcpcd.c index 0f889257..fd517709 100644 --- 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 { diff --git a/dhcpcd.h b/dhcpcd.h index e27c9288..f57093ff 100644 --- 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 f2d75468..9fd6f4be 100644 --- a/duid.c +++ b/duid.c @@ -43,42 +43,38 @@ #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 a5bf3f91..14929900 100644 --- 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 e24d87bc..0d1106eb 100644 --- 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)); diff --git a/interface.h b/interface.h index 62aaa033..6a05a6b8 100644 --- a/interface.h +++ b/interface.h @@ -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);