]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
If no status message given, supply a default.
authorRoy Marples <roy@marples.name>
Wed, 29 Jan 2014 18:33:43 +0000 (18:33 +0000)
committerRoy Marples <roy@marples.name>
Wed, 29 Jan 2014 18:33:43 +0000 (18:33 +0000)
dhcp6.c
dhcp6.h

diff --git a/dhcp6.c b/dhcp6.c
index 4e696e5956c1f78c0c193088582f275ba01f737a..ec585883f96c15bc039ab3c234301a143b3d30b2 100644 (file)
--- a/dhcp6.c
+++ b/dhcp6.c
@@ -122,6 +122,15 @@ const struct dhcp_compat dhcp_compats[] = {
        { 0, 0 }
 };
 
+static const char * const dhcp6_statuses[] = {
+       "Success",
+       "Unspecified Failure",
+       "No Addresses Available",
+       "No Binding",
+       "Not On Link",
+       "Use Multicast"
+};
+
 #if DEBUG_MEMORY
 static void
 dhcp6_cleanup(void)
@@ -1191,12 +1200,13 @@ dhcp6_startrelease(struct interface *ifp)
 
 static int dhcp6_getstatus(const struct dhcp6_option *o)
 {
+       uint16_t code;
        char *nstatus;
-       const struct dhcp6_status *s;
        size_t len;
+       const uint8_t *p;
 
        len = ntohs(o->len);
-       if (len < sizeof(uint16_t)) {
+       if (len < sizeof(code)) {
                syslog(LOG_ERR, "status truncated");
                return -1;
        }
@@ -1205,8 +1215,21 @@ static int dhcp6_getstatus(const struct dhcp6_option *o)
                syslog(LOG_ERR, "not a status");
                return -1;
        }
-       s = (const struct dhcp6_status *)o;
-       len = ntohs(s->len) - sizeof(s->len);
+       p = D6_COPTION_DATA(o);
+       len = ntohs(o->len);
+       memcpy(&code, p, sizeof(code));
+       code = ntohs(code);
+       len -= sizeof(code);
+
+       if (len == 0) {
+               if (code < sizeof(dhcp6_statuses) / sizeof(char *)) {
+                       p = (const uint8_t *)dhcp6_statuses[code];
+                       len = strlen((const char *)p);
+               } else
+                       p = NULL;
+       } else {
+               p = D6_COPTION_DATA(o) + sizeof(uint16_t);
+       }
        if (status == NULL || len + 1 > status_len) {
                status_len = len;
                nstatus = realloc(status, status_len + 1);
@@ -1217,10 +1240,10 @@ static int dhcp6_getstatus(const struct dhcp6_option *o)
                status = nstatus;
        }
        if (status) {
-               memcpy(status, (const char *)s + sizeof(*s), len);
+               memcpy(status, p, len);
                status[len] = '\0';
        }
-       return ntohs(s->status);
+       return code;
 }
 
 static int
diff --git a/dhcp6.h b/dhcp6.h
index dc2b527fc6aed6bb6b98366bef1d7af340dcf7f2..4c53d427a8e5b9d816602dde0331cc5d867c0d60 100644 (file)
--- a/dhcp6.h
+++ b/dhcp6.h
@@ -1,6 +1,6 @@
 /*
  * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
+ * Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
  * All rights reserved
 
  * Redistribution and use in source and binary forms, with or without
@@ -104,13 +104,6 @@ struct dhcp6_option {
        /* followed by data */
 } __packed;
 
-struct dhcp6_status {
-       uint16_t code;
-       uint16_t len;
-       uint16_t status;
-       /* followed by message */
-} __packed;
-
 #define D6_STATUS_OK           0
 #define D6_STATUS_FAIL         1
 #define D6_STATUS_NOADDR       2