*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;
.\" 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
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
#include <netinet/in.h>
#endif
+#include <ctype.h>
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
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,
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);