dhcp: add generic DUID infrastructure
Add infrastructure for generating DUID-LLT from a given device MAC and passing it around to the DHCP client implementations. Thanks to Mathieu Trudel-Lapierre for bug fixes in the unescaping code, which were merged into this commit.
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "nm-dhcp-dhclient-utils.h"
|
||||
|
||||
@@ -255,3 +256,75 @@ nm_dhcp_dhclient_create_config (const char *interface,
|
||||
return g_string_free (new_contents, FALSE);
|
||||
}
|
||||
|
||||
/* Roughly follow what dhclient's quotify_buf() and pretty_escape() functions do */
|
||||
char *
|
||||
nm_dhcp_dhclient_escape_duid (const GByteArray *duid)
|
||||
{
|
||||
char *escaped;
|
||||
const guint8 *s = duid->data;
|
||||
char *d;
|
||||
|
||||
d = escaped = g_malloc0 ((duid->len * 4) + 1);
|
||||
while (s < (duid->data + duid->len)) {
|
||||
if (!g_ascii_isprint (*s)) {
|
||||
*d++ = '\\';
|
||||
*d++ = '0' + ((*s >> 6) & 0x7);
|
||||
*d++ = '0' + ((*s >> 3) & 0x7);
|
||||
*d++ = '0' + (*s++ & 0x7);
|
||||
} else if (*s == '"' || *s == '\'' || *s == '$' ||
|
||||
*s == '`' || *s == '\\' || *s == '|' ||
|
||||
*s == '&') {
|
||||
*d++ = '\\';
|
||||
*d++ = *s++;
|
||||
} else
|
||||
*d++ = *s++;
|
||||
}
|
||||
return escaped;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
isoctal (const guint8 *p)
|
||||
{
|
||||
return ( p[0] >= '0' && p[0] <= '3'
|
||||
&& p[1] >= '0' && p[1] <= '7'
|
||||
&& p[2] >= '0' && p[2] <= '7');
|
||||
}
|
||||
|
||||
GByteArray *
|
||||
nm_dhcp_dhclient_unescape_duid (const char *duid)
|
||||
{
|
||||
GByteArray *unescaped;
|
||||
const guint8 *p = (const guint8 *) duid;
|
||||
guint i, len;
|
||||
guint8 octal;
|
||||
|
||||
len = strlen (duid);
|
||||
unescaped = g_byte_array_sized_new (len);
|
||||
for (i = 0; i < len; i++) {
|
||||
if (p[i] == '\\') {
|
||||
i++;
|
||||
if (isdigit (p[i])) {
|
||||
/* Octal escape sequence */
|
||||
if (i + 2 >= len || !isoctal (p + i))
|
||||
goto error;
|
||||
octal = ((p[i] - '0') << 6) + ((p[i + 1] - '0') << 3) + (p[i + 2] - '0');
|
||||
g_byte_array_append (unescaped, &octal, 1);
|
||||
i += 2;
|
||||
} else {
|
||||
/* One of ", ', $, `, \, |, or & */
|
||||
g_warn_if_fail (p[i] == '"' || p[i] == '\'' || p[i] == '$' ||
|
||||
p[i] == '`' || p[i] == '\\' || p[i] == '|' ||
|
||||
p[i] == '&');
|
||||
g_byte_array_append (unescaped, &p[i], 1);
|
||||
}
|
||||
} else
|
||||
g_byte_array_append (unescaped, &p[i], 1);
|
||||
}
|
||||
|
||||
return unescaped;
|
||||
|
||||
error:
|
||||
g_byte_array_free (unescaped, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user