From: Roy Marples Date: Fri, 25 Jan 2008 09:52:58 +0000 (+0000) Subject: If ClientID matches a hardware address formart, encode it as such. X-Git-Tag: v3.2.3~67 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d8bfb688ec1d9a86ae30eee05ecd7c6e591041f5;p=thirdparty%2Fdhcpcd.git If ClientID matches a hardware address formart, encode it as such. --- diff --git a/dhcp.c b/dhcp.c index f4b2fd82..ccc191be 100644 --- a/dhcp.c +++ b/dhcp.c @@ -308,10 +308,40 @@ ssize_t send_message (const interface_t *iface, const dhcp_t *dhcp, *p++ = DHCP_CLIENTID; if (options->clientid_len > 0) { - *p++ = options->clientid_len + 1; - *p++ = 0; /* string */ - memcpy (p, options->clientid, options->clientid_len); - p += options->clientid_len; + /* 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; diff --git a/dhcpcd.8.in b/dhcpcd.8.in index 37167ec5..0c5fdd0d 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd Jan 17, 2008 +.Dd Jan 25, 2008 .Dt DHCPCD 8 SMM .Sh NAME .Nm dhcpcd @@ -252,9 +252,12 @@ same as above, but strip the domain if it matches the dns domain. same as above, but strip the domain regardless. .El .It Fl I , -clientid Ar clientid -Send a +Send .Ar clientid -as a client identifier string. +as a client identifier string. If +.Ar clientid +matches a hardware address format, such as 00:01:02:03:04:05 then we encode +it as that, otherwise as a string. .It Fl S, -mscsr Microsoft have their own code for Classless Static Routes .Po diff --git a/interface.c b/interface.c index 158855fe..04364650 100644 --- a/interface.c +++ b/interface.c @@ -47,6 +47,7 @@ #include #endif +#include #include #include #include @@ -151,6 +152,41 @@ char *hwaddr_ntoa (const unsigned char *hwaddr, size_t hwlen) return (buffer); } +size_t hwaddr_aton (unsigned char *buffer, const char *addr) +{ + char c[3]; + const char *p = addr; + unsigned char *bp = buffer; + size_t len = 0; + + c[2] = '\0'; + while (*p) { + c[0] = *p++; + c[1] = *p++; + /* Ensure that next data is EOL or a seperator with data */ + if (! (*p == '\0' || (*p == ':' && *(p + 1) != '\0'))) { + errno = EINVAL; + return (0); + } + /* Ensure that digits are hex */ + if (isxdigit (c[0]) == 0 || isxdigit (c[1]) == 0) { + errno = EINVAL; + return (0); + } + p++; + if (bp) + *bp++ = (unsigned char) strtol (c, NULL, 16); + else + len++; + } + + printf ("vaid\n"); + + if (bp) + return (bp - buffer); + return (len); +} + static int _do_interface (const char *ifname, unsigned char *hwaddr, size_t *hwlen, struct in_addr *addr, diff --git a/interface.h b/interface.h index 58eb0b96..62aaa033 100644 --- a/interface.h +++ b/interface.h @@ -127,6 +127,7 @@ void free_address (address_t *addresses); void free_route (route_t *routes); uint32_t get_netmask (uint32_t addr); char *hwaddr_ntoa (const unsigned char *hwaddr, size_t hwlen); +size_t hwaddr_aton (unsigned char *hwaddr, const char *addr); interface_t *read_interface (const char *ifname, int metric); int get_mtu (const char *ifname);