]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
If ClientID matches a hardware address formart, encode it as such.
authorRoy Marples <roy@marples.name>
Fri, 25 Jan 2008 09:52:58 +0000 (09:52 +0000)
committerRoy Marples <roy@marples.name>
Fri, 25 Jan 2008 09:52:58 +0000 (09:52 +0000)
dhcp.c
dhcpcd.8.in
interface.c
interface.h

diff --git a/dhcp.c b/dhcp.c
index f4b2fd82a339a69432c7296c9d0f8f7a1e0e6966..ccc191be1a4184976de54fdd2b858081890841e3 100644 (file)
--- 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;
index 37167ec5ddbc723628d34851b0d2ba6f653b23a8..0c5fdd0d7142d44ff1210b1414420489a8c3ce00 100644 (file)
@@ -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
index 158855fe14166dc2cd4175479cd133d736ee62b5..043646505beced416aefa9f1bdc46c3ee139284d 100644 (file)
@@ -47,6 +47,7 @@
 #include <netinet/in.h>
 #endif
 
+#include <ctype.h>
 #include <errno.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -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,
index 58eb0b968e5a9546967137685fccf429bf0ea428..62aaa033dbe3e6d5a5e6e01ec6e8d14a2b8b5315 100644 (file)
@@ -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);