mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-11 11:00:17 +01:00
dhcp: add support for Fedora dhclient RFC3442 routes (rh #639935)
Add support for Fedora's dhclient's built-in RFC3442 classless static routes format. Since the Fedora format uses the same name as the dhcpcd format, we need to refactor a bunch of the code to ensure we can distinguish between the types. Do this at runtime now by consolidating the classless static routes parsing code into the DHCP Client base class and rework the unit tests so that we can test all variations of the classless static route parsing code at the same time. This also fixes a bug with the dhcpcd classless static route gateway handling that would return the wrong gateway address. Many thanks to Jiri Popelka from Red Hat for the initial patch and explanations.
This commit is contained in:
parent
80b9047e1c
commit
8b006f331d
5 changed files with 551 additions and 429 deletions
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <ctype.h>
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
|
@ -647,6 +648,243 @@ nm_dhcp_client_foreach_option (NMDHCPClient *self,
|
|||
|
||||
/********************************************/
|
||||
|
||||
static gboolean
|
||||
ip4_process_dhcpcd_rfc3442_routes (const char *str,
|
||||
NMIP4Config *ip4_config,
|
||||
guint32 *gwaddr)
|
||||
{
|
||||
char **routes, **r;
|
||||
gboolean have_routes = FALSE;
|
||||
|
||||
routes = g_strsplit (str, " ", 0);
|
||||
if (g_strv_length (routes) == 0)
|
||||
goto out;
|
||||
|
||||
if ((g_strv_length (routes) % 2) != 0) {
|
||||
nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (r = routes; *r; r += 2) {
|
||||
char *slash;
|
||||
NMIP4Route *route;
|
||||
int rt_cidr = 32;
|
||||
struct in_addr rt_addr;
|
||||
struct in_addr rt_route;
|
||||
|
||||
slash = strchr(*r, '/');
|
||||
if (slash) {
|
||||
*slash = '\0';
|
||||
errno = 0;
|
||||
rt_cidr = strtol (slash + 1, NULL, 10);
|
||||
if ((errno == EINVAL) || (errno == ERANGE)) {
|
||||
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (inet_pton (AF_INET, *r, &rt_addr) <= 0) {
|
||||
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r);
|
||||
continue;
|
||||
}
|
||||
if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) {
|
||||
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
have_routes = TRUE;
|
||||
if (rt_cidr == 0 && rt_addr.s_addr == 0) {
|
||||
/* FIXME: how to handle multiple routers? */
|
||||
*gwaddr = rt_route.s_addr;
|
||||
} else {
|
||||
route = nm_ip4_route_new ();
|
||||
nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
|
||||
nm_ip4_route_set_prefix (route, rt_cidr);
|
||||
nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);
|
||||
|
||||
nm_ip4_config_take_route (ip4_config, route);
|
||||
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
g_strfreev (routes);
|
||||
return have_routes;
|
||||
}
|
||||
|
||||
static const char **
|
||||
process_dhclient_rfc3442_route (const char **octets, NMIP4Route **out_route)
|
||||
{
|
||||
const char **o = octets;
|
||||
int addr_len = 0, i = 0;
|
||||
long int tmp;
|
||||
NMIP4Route *route;
|
||||
char *next_hop;
|
||||
struct in_addr tmp_addr;
|
||||
|
||||
if (!*o)
|
||||
return o; /* no prefix */
|
||||
|
||||
tmp = strtol (*o, NULL, 10);
|
||||
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
|
||||
return o;
|
||||
|
||||
route = nm_ip4_route_new ();
|
||||
nm_ip4_route_set_prefix (route, (guint32) tmp);
|
||||
o++;
|
||||
|
||||
if (tmp > 0)
|
||||
addr_len = ((tmp - 1) / 8) + 1;
|
||||
|
||||
/* ensure there's at least the address + next hop left */
|
||||
if (g_strv_length ((char **) o) < addr_len + 4)
|
||||
goto error;
|
||||
|
||||
if (tmp) {
|
||||
const char *addr[4] = { "0", "0", "0", "0" };
|
||||
char *str_addr;
|
||||
|
||||
for (i = 0; i < addr_len; i++)
|
||||
addr[i] = *o++;
|
||||
|
||||
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
|
||||
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) {
|
||||
g_free (str_addr);
|
||||
goto error;
|
||||
}
|
||||
tmp_addr.s_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp);
|
||||
nm_ip4_route_set_dest (route, tmp_addr.s_addr);
|
||||
}
|
||||
|
||||
/* Handle next hop */
|
||||
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
|
||||
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) {
|
||||
g_free (next_hop);
|
||||
goto error;
|
||||
}
|
||||
nm_ip4_route_set_next_hop (route, tmp_addr.s_addr);
|
||||
g_free (next_hop);
|
||||
|
||||
*out_route = route;
|
||||
return o + 4; /* advance to past the next hop */
|
||||
|
||||
error:
|
||||
nm_ip4_route_unref (route);
|
||||
return o;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip4_process_dhclient_rfc3442_routes (const char *str,
|
||||
NMIP4Config *ip4_config,
|
||||
guint32 *gwaddr)
|
||||
{
|
||||
char **octets, **o;
|
||||
gboolean have_routes = FALSE;
|
||||
NMIP4Route *route = NULL;
|
||||
|
||||
o = octets = g_strsplit_set (str, " .", 0);
|
||||
if (g_strv_length (octets) < 5) {
|
||||
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (*o) {
|
||||
route = NULL;
|
||||
o = (char **) process_dhclient_rfc3442_route ((const char **) o, &route);
|
||||
if (!route) {
|
||||
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes");
|
||||
break;
|
||||
}
|
||||
|
||||
have_routes = TRUE;
|
||||
if (nm_ip4_route_get_prefix (route) == 0) {
|
||||
/* gateway passed as classless static route */
|
||||
*gwaddr = nm_ip4_route_get_next_hop (route);
|
||||
nm_ip4_route_unref (route);
|
||||
} else {
|
||||
char addr[INET_ADDRSTRLEN + 1];
|
||||
char nh[INET_ADDRSTRLEN + 1];
|
||||
struct in_addr tmp;
|
||||
|
||||
/* normal route */
|
||||
nm_ip4_config_take_route (ip4_config, route);
|
||||
|
||||
tmp.s_addr = nm_ip4_route_get_dest (route);
|
||||
inet_ntop (AF_INET, &tmp, addr, sizeof (addr));
|
||||
tmp.s_addr = nm_ip4_route_get_next_hop (route);
|
||||
inet_ntop (AF_INET, &tmp, nh, sizeof (nh));
|
||||
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
|
||||
addr, nm_ip4_route_get_prefix (route), nh);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
g_strfreev (octets);
|
||||
return have_routes;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
ip4_process_classless_routes (GHashTable *options,
|
||||
NMIP4Config *ip4_config,
|
||||
guint32 *gwaddr)
|
||||
{
|
||||
const char *str, *p;
|
||||
|
||||
g_return_val_if_fail (options != NULL, FALSE);
|
||||
g_return_val_if_fail (ip4_config != NULL, FALSE);
|
||||
|
||||
*gwaddr = 0;
|
||||
|
||||
/* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a
|
||||
* slightly different format:
|
||||
*
|
||||
* option classless-static-routes = array of (destination-descriptor ip-address);
|
||||
*
|
||||
* which results in:
|
||||
*
|
||||
* 0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6
|
||||
*
|
||||
* dhcpcd supports classless static routes natively and uses this same
|
||||
* option identifier with the following format:
|
||||
*
|
||||
* 192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41
|
||||
*/
|
||||
str = g_hash_table_lookup (options, "new_classless_static_routes");
|
||||
|
||||
/* dhclient doesn't have actual support for rfc3442 classless static routes
|
||||
* upstream. Thus, people resort to defining the option in dhclient.conf
|
||||
* and using arbitrary formats like so:
|
||||
*
|
||||
* option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
|
||||
*
|
||||
* See https://lists.isc.org/pipermail/dhcp-users/2008-December/007629.html
|
||||
*/
|
||||
if (!str)
|
||||
str = g_hash_table_lookup (options, "new_rfc3442_classless_static_routes");
|
||||
|
||||
/* Microsoft version; same as rfc3442 but with a different option # (249) */
|
||||
if (!str)
|
||||
str = g_hash_table_lookup (options, "new_ms_classless_static_routes");
|
||||
|
||||
if (!str || !strlen (str))
|
||||
return FALSE;
|
||||
|
||||
p = str;
|
||||
while (*p) {
|
||||
if (!isdigit (*p) && (*p != ' ') && (*p != '.') && (*p != '/')) {
|
||||
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str);
|
||||
return FALSE;
|
||||
}
|
||||
p++;
|
||||
};
|
||||
|
||||
if (strchr (str, '/')) {
|
||||
/* dhcpcd format */
|
||||
return ip4_process_dhcpcd_rfc3442_routes (str, ip4_config, gwaddr);
|
||||
}
|
||||
|
||||
return ip4_process_dhclient_rfc3442_routes (str, ip4_config, gwaddr);
|
||||
}
|
||||
|
||||
static void
|
||||
process_classful_routes (GHashTable *options, NMIP4Config *ip4_config)
|
||||
{
|
||||
|
|
@ -747,7 +985,6 @@ ip4_options_to_config (NMDHCPClient *self)
|
|||
NMIP4Address *addr = NULL;
|
||||
char *str = NULL;
|
||||
guint32 gwaddr = 0, prefix = 0;
|
||||
gboolean have_classless = FALSE;
|
||||
|
||||
g_return_val_if_fail (self != NULL, NULL);
|
||||
g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL);
|
||||
|
|
@ -788,17 +1025,8 @@ ip4_options_to_config (NMDHCPClient *self)
|
|||
/* Routes: if the server returns classless static routes, we MUST ignore
|
||||
* the 'static_routes' option.
|
||||
*/
|
||||
if (NM_DHCP_CLIENT_GET_CLASS (self)->ip4_process_classless_routes) {
|
||||
have_classless = NM_DHCP_CLIENT_GET_CLASS (self)->ip4_process_classless_routes (self,
|
||||
priv->options,
|
||||
ip4_config,
|
||||
&gwaddr);
|
||||
}
|
||||
|
||||
if (!have_classless) {
|
||||
gwaddr = 0; /* Ensure client code doesn't lie */
|
||||
if (!ip4_process_classless_routes (priv->options, ip4_config, &gwaddr))
|
||||
process_classful_routes (priv->options, ip4_config);
|
||||
}
|
||||
|
||||
if (gwaddr) {
|
||||
char buf[INET_ADDRSTRLEN + 1];
|
||||
|
|
|
|||
|
|
@ -76,15 +76,6 @@ typedef struct {
|
|||
|
||||
/* Methods */
|
||||
|
||||
/* Given the options table, extract any classless routes, add them to
|
||||
* the IP4 config and return TRUE if any existed. If a gateway was sent
|
||||
* as a classless route return that in out_gwaddr.
|
||||
*/
|
||||
gboolean (*ip4_process_classless_routes) (NMDHCPClient *self,
|
||||
GHashTable *options,
|
||||
NMIP4Config *ip4_config,
|
||||
guint32 *out_gwaddr);
|
||||
|
||||
GPid (*ip4_start) (NMDHCPClient *self,
|
||||
NMSettingIP4Config *s_ip4,
|
||||
guint8 *anycast_addr,
|
||||
|
|
|
|||
|
|
@ -635,136 +635,6 @@ real_stop (NMDHCPClient *client)
|
|||
remove (priv->pid_file);
|
||||
}
|
||||
|
||||
static const char **
|
||||
process_rfc3442_route (const char **octets, NMIP4Route **out_route)
|
||||
{
|
||||
const char **o = octets;
|
||||
int addr_len = 0, i = 0;
|
||||
long int tmp;
|
||||
NMIP4Route *route;
|
||||
char *next_hop;
|
||||
struct in_addr tmp_addr;
|
||||
|
||||
if (!*o)
|
||||
return o; /* no prefix */
|
||||
|
||||
tmp = strtol (*o, NULL, 10);
|
||||
if (tmp < 0 || tmp > 32) /* 32 == max IP4 prefix length */
|
||||
return o;
|
||||
|
||||
route = nm_ip4_route_new ();
|
||||
nm_ip4_route_set_prefix (route, (guint32) tmp);
|
||||
o++;
|
||||
|
||||
if (tmp > 0)
|
||||
addr_len = ((tmp - 1) / 8) + 1;
|
||||
|
||||
/* ensure there's at least the address + next hop left */
|
||||
if (g_strv_length ((char **) o) < addr_len + 4)
|
||||
goto error;
|
||||
|
||||
if (tmp) {
|
||||
const char *addr[4] = { "0", "0", "0", "0" };
|
||||
char *str_addr;
|
||||
|
||||
for (i = 0; i < addr_len; i++)
|
||||
addr[i] = *o++;
|
||||
|
||||
str_addr = g_strjoin (".", addr[0], addr[1], addr[2], addr[3], NULL);
|
||||
if (inet_pton (AF_INET, str_addr, &tmp_addr) <= 0) {
|
||||
g_free (str_addr);
|
||||
goto error;
|
||||
}
|
||||
tmp_addr.s_addr &= nm_utils_ip4_prefix_to_netmask ((guint32) tmp);
|
||||
nm_ip4_route_set_dest (route, tmp_addr.s_addr);
|
||||
}
|
||||
|
||||
/* Handle next hop */
|
||||
next_hop = g_strjoin (".", o[0], o[1], o[2], o[3], NULL);
|
||||
if (inet_pton (AF_INET, next_hop, &tmp_addr) <= 0) {
|
||||
g_free (next_hop);
|
||||
goto error;
|
||||
}
|
||||
nm_ip4_route_set_next_hop (route, tmp_addr.s_addr);
|
||||
g_free (next_hop);
|
||||
|
||||
*out_route = route;
|
||||
return o + 4; /* advance to past the next hop */
|
||||
|
||||
error:
|
||||
nm_ip4_route_unref (route);
|
||||
return o;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_ip4_process_classless_routes (NMDHCPClient *client,
|
||||
GHashTable *options,
|
||||
NMIP4Config *ip4_config,
|
||||
guint32 *gwaddr)
|
||||
{
|
||||
const char *str;
|
||||
char **octets, **o;
|
||||
gboolean have_routes = FALSE;
|
||||
NMIP4Route *route = NULL;
|
||||
|
||||
/* dhclient doesn't have actual support for rfc3442 classless static routes
|
||||
* upstream. Thus, people resort to defining the option in dhclient.conf
|
||||
* and using arbitrary formats like so:
|
||||
*
|
||||
* option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;
|
||||
*
|
||||
* See https://lists.isc.org/pipermail/dhcp-users/2008-December/007629.html
|
||||
*/
|
||||
|
||||
str = g_hash_table_lookup (options, "new_rfc3442_classless_static_routes");
|
||||
/* Microsoft version; same as rfc3442 but with a different option # (249) */
|
||||
if (!str)
|
||||
str = g_hash_table_lookup (options, "new_ms_classless_static_routes");
|
||||
|
||||
if (!str || !strlen (str))
|
||||
return FALSE;
|
||||
|
||||
o = octets = g_strsplit (str, " ", 0);
|
||||
if (g_strv_length (octets) < 5) {
|
||||
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes '%s'", str);
|
||||
goto out;
|
||||
}
|
||||
|
||||
while (*o) {
|
||||
route = NULL;
|
||||
o = (char **) process_rfc3442_route ((const char **) o, &route);
|
||||
if (!route) {
|
||||
nm_log_warn (LOGD_DHCP4, "ignoring invalid classless static routes");
|
||||
break;
|
||||
}
|
||||
|
||||
have_routes = TRUE;
|
||||
if (nm_ip4_route_get_prefix (route) == 0) {
|
||||
/* gateway passed as classless static route */
|
||||
*gwaddr = nm_ip4_route_get_next_hop (route);
|
||||
nm_ip4_route_unref (route);
|
||||
} else {
|
||||
char addr[INET_ADDRSTRLEN + 1];
|
||||
char nh[INET_ADDRSTRLEN + 1];
|
||||
struct in_addr tmp;
|
||||
|
||||
/* normal route */
|
||||
nm_ip4_config_take_route (ip4_config, route);
|
||||
|
||||
tmp.s_addr = nm_ip4_route_get_dest (route);
|
||||
inet_ntop (AF_INET, &tmp, addr, sizeof (addr));
|
||||
tmp.s_addr = nm_ip4_route_get_next_hop (route);
|
||||
inet_ntop (AF_INET, &tmp, nh, sizeof (nh));
|
||||
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s",
|
||||
addr, nm_ip4_route_get_prefix (route), nh);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
g_strfreev (octets);
|
||||
return have_routes;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -801,6 +671,5 @@ nm_dhcp_dhclient_class_init (NMDHCPDhclientClass *dhclient_class)
|
|||
client_class->ip4_start = real_ip4_start;
|
||||
client_class->ip6_start = real_ip6_start;
|
||||
client_class->stop = real_stop;
|
||||
client_class->ip4_process_classless_routes = real_ip4_process_classless_routes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -179,83 +179,6 @@ real_stop (NMDHCPClient *client)
|
|||
remove (priv->pid_file);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
real_ip4_process_classless_routes (NMDHCPClient *client,
|
||||
GHashTable *options,
|
||||
NMIP4Config *ip4_config,
|
||||
guint32 *gwaddr)
|
||||
{
|
||||
const char *str;
|
||||
char **routes, **r;
|
||||
gboolean have_routes = FALSE;
|
||||
|
||||
/* Classless static routes over-ride any static routes and routers
|
||||
* provided. We should also check for MS classless static routes as
|
||||
* they implemented the draft RFC using their own code.
|
||||
*/
|
||||
str = g_hash_table_lookup (options, "new_classless_static_routes");
|
||||
if (!str)
|
||||
str = g_hash_table_lookup (options, "new_ms_classless_static_routes");
|
||||
|
||||
if (!str || !strlen (str))
|
||||
return FALSE;
|
||||
|
||||
routes = g_strsplit (str, " ", 0);
|
||||
if (g_strv_length (routes) == 0)
|
||||
goto out;
|
||||
|
||||
if ((g_strv_length (routes) % 2) != 0) {
|
||||
nm_log_warn (LOGD_DHCP4, " classless static routes provided, but invalid");
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (r = routes; *r; r += 2) {
|
||||
char *slash;
|
||||
NMIP4Route *route;
|
||||
int rt_cidr = 32;
|
||||
struct in_addr rt_addr;
|
||||
struct in_addr rt_route;
|
||||
|
||||
slash = strchr(*r, '/');
|
||||
if (slash) {
|
||||
*slash = '\0';
|
||||
errno = 0;
|
||||
rt_cidr = strtol (slash + 1, NULL, 10);
|
||||
if ((errno == EINVAL) || (errno == ERANGE)) {
|
||||
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route cidr: '%s'", slash + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (inet_pton (AF_INET, *r, &rt_addr) <= 0) {
|
||||
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route address: '%s'", *r);
|
||||
continue;
|
||||
}
|
||||
if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) {
|
||||
nm_log_warn (LOGD_DHCP4, "DHCP provided invalid classless static route gateway: '%s'", *(r + 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
have_routes = TRUE;
|
||||
if (rt_cidr == 0 && rt_addr.s_addr == 0) {
|
||||
/* FIXME: how to handle multiple routers? */
|
||||
*gwaddr = rt_addr.s_addr;
|
||||
} else {
|
||||
route = nm_ip4_route_new ();
|
||||
nm_ip4_route_set_dest (route, (guint32) rt_addr.s_addr);
|
||||
nm_ip4_route_set_prefix (route, rt_cidr);
|
||||
nm_ip4_route_set_next_hop (route, (guint32) rt_route.s_addr);
|
||||
|
||||
|
||||
nm_ip4_config_take_route (ip4_config, route);
|
||||
nm_log_info (LOGD_DHCP4, " classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
g_strfreev (routes);
|
||||
return have_routes;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -290,6 +213,5 @@ nm_dhcp_dhcpcd_class_init (NMDHCPDhcpcdClass *dhcpcd_class)
|
|||
client_class->ip4_start = real_ip4_start;
|
||||
client_class->ip6_start = real_ip6_start;
|
||||
client_class->stop = real_stop;
|
||||
client_class->ip4_process_classless_routes = real_ip4_process_classless_routes;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,149 +250,274 @@ test_wins_options (const char *client)
|
|||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static Option classless_routes_options[] = {
|
||||
/* For dhclient */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" },
|
||||
/* For dhcpcd */
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
static void
|
||||
ip4_test_route (const char *test,
|
||||
NMIP4Config *ip4_config,
|
||||
guint route_num,
|
||||
const char *expected_dest,
|
||||
const char *expected_gw,
|
||||
guint expected_prefix)
|
||||
{
|
||||
NMIP4Route *route;
|
||||
struct in_addr tmp;
|
||||
|
||||
route = nm_ip4_config_get_route (ip4_config, route_num);
|
||||
ASSERT (inet_pton (AF_INET, expected_dest, &tmp) > 0,
|
||||
test, "couldn't convert expected route destination #1");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
test, "unexpected route %d destination", route_num + 1);
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0,
|
||||
test, "couldn't convert expected route next hop %d",
|
||||
route_num + 1);
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
test, "unexpected route %d next hop", route_num + 1);
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == expected_prefix,
|
||||
test, "unexpected route %d prefix", route_num + 1);
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
test, "unexpected route %d metric", route_num + 1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_classless_static_routes (const char *client)
|
||||
ip4_test_gateway (const char *test,
|
||||
NMIP4Config *ip4_config,
|
||||
const char *expected_gw)
|
||||
{
|
||||
NMIP4Address *addr;
|
||||
struct in_addr tmp;
|
||||
|
||||
ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1,
|
||||
test, "unexpected number of IP addresses");
|
||||
addr = nm_ip4_config_get_address (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_gw, &tmp) > 0,
|
||||
test, "couldn't convert expected IP gateway");
|
||||
ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr,
|
||||
test, "unexpected IP gateway");
|
||||
}
|
||||
|
||||
static void
|
||||
test_classless_static_routes_1 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
NMIP4Route *route;
|
||||
struct in_addr tmp;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
const char *expected_route2_dest = "10.0.0.0";
|
||||
const char *expected_route2_gw = "10.17.66.41";
|
||||
static Option data[] = {
|
||||
/* dhclient custom format */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 8 10 10 17 66 41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (classless_routes_options, options);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-rfc3442", "failed to parse DHCP4 options");
|
||||
"dhcp-classless-1", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
|
||||
"dhcp-rfc3442", "unexpected number of IP routes");
|
||||
|
||||
/* Route #1 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442", "couldn't convert expected route destination #1");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442", "unexpected route #1 destination");
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442", "couldn't convert expected route next hop #1");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442", "unexpected route #1 next hop");
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 24,
|
||||
"dhcp-rfc3442", "unexpected route #1 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442", "unexpected route #1 metric");
|
||||
|
||||
/* Route #2 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 1);
|
||||
ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442", "couldn't convert expected route destination #2");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442", "unexpected route #2 destination");
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442", "couldn't convert expected route next hop #2");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442", "unexpected route #2 next hop");
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 8,
|
||||
"dhcp-rfc3442", "unexpected route #2 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442", "unexpected route #2 metric");
|
||||
"dhcp-classless-1", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-classless-1", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route ("dhcp-classless-1", ip4_config, 1,
|
||||
expected_route2_dest, expected_route2_gw, 8);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static Option invalid_classless_routes1[] = {
|
||||
/* For dhclient */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" },
|
||||
/* For dhcpcd */
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
test_invalid_classless_routes1 (const char *client)
|
||||
test_classless_static_routes_2 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
NMIP4Route *route;
|
||||
struct in_addr tmp;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
const char *expected_route2_dest = "10.0.0.0";
|
||||
const char *expected_route2_gw = "10.17.66.41";
|
||||
static Option data[] = {
|
||||
/* dhcpcd format */
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.0.0/8 10.17.66.41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (invalid_classless_routes1, options);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-rfc3442-invalid-1", "failed to parse DHCP4 options");
|
||||
"dhcp-classless-2", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"dhcp-rfc3442-invalid-1", "unexpected number of IP routes");
|
||||
|
||||
/* Route #1 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-1", "couldn't convert expected route destination #1");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-1", "unexpected route #1 destination");
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-1", "couldn't convert expected route next hop #1");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-1", "unexpected route #1 next hop");
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 24,
|
||||
"dhcp-rfc3442-invalid-1", "unexpected route #1 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442-invalid-1", "unexpected route #1 metric");
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
|
||||
"dhcp-classless-2", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-classless-2", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
ip4_test_route ("dhcp-classless-2", ip4_config, 1,
|
||||
expected_route2_dest, expected_route2_gw, 8);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static Option invalid_classless_routes2[] = {
|
||||
/* For dhclient */
|
||||
{ "new_rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" },
|
||||
/* For dhcpcd */
|
||||
{ "new_classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
test_invalid_classless_routes2 (const char *client)
|
||||
test_fedora_dhclient_classless_static_routes (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
const char *expected_route1_dest = "129.210.177.128";
|
||||
const char *expected_route1_gw = "192.168.0.113";
|
||||
const char *expected_route2_dest = "2.0.0.0";
|
||||
const char *expected_route2_gw = "10.34.255.6";
|
||||
const char *expected_gateway = "192.168.0.113";
|
||||
static Option data[] = {
|
||||
/* Fedora dhclient format */
|
||||
{ "new_classless_static_routes", "0 192.168.0.113 25.129.210.177.132 192.168.0.113 7.2 10.34.255.6" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-fedora-dhclient-classless", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
|
||||
"dhcp-fedora-dhclient-classless", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-fedora-dhclient-classless", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 25);
|
||||
ip4_test_route ("dhcp-fedora-dhclient-classless", ip4_config, 1,
|
||||
expected_route2_dest, expected_route2_gw, 7);
|
||||
|
||||
/* Gateway */
|
||||
ip4_test_gateway ("dhcp-fedora-dhclient-classless", ip4_config, expected_gateway);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dhclient_invalid_classless_routes_1 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
static Option data[] = {
|
||||
/* dhclient format */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 45 10 17 66 41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-dhclient-classless-invalid-1", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"dhcp-dhclient-classless-invalid-1", "unexpected number of IP routes");
|
||||
|
||||
ip4_test_route ("dhcp-dhclient-classless-invalid-1", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dhcpcd_invalid_classless_routes_1 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
NMIP4Route *route;
|
||||
struct in_addr tmp;
|
||||
const char *expected_route1_dest = "10.1.1.5";
|
||||
const char *expected_route1_gw = "10.1.1.1";
|
||||
const char *expected_route2_dest = "100.99.88.56";
|
||||
const char *expected_route2_gw = "10.1.1.1";
|
||||
static Option data[] = {
|
||||
/* dhcpcd format */
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 10.0.adfadf/44 10.17.66.41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (invalid_classless_routes2, options);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-rfc3442-invalid-2", "failed to parse DHCP4 options");
|
||||
"dhcp-dhcpcd-classless-invalid-1", "failed to parse DHCP4 options");
|
||||
|
||||
/* Test falling back to old-style static routes if the classless static
|
||||
* routes are invalid.
|
||||
*/
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
|
||||
"dhcp-dhcpcdp-classless-invalid-1", "unexpected number of routes");
|
||||
ip4_test_route ("dhcp-dhcpcdp-classless-invalid-1", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 32);
|
||||
ip4_test_route ("dhcp-dhcpcdp-classless-invalid-1", ip4_config, 1,
|
||||
expected_route2_dest, expected_route2_gw, 32);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dhclient_invalid_classless_routes_2 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
const char *expected_route1_dest = "10.1.1.5";
|
||||
const char *expected_route1_gw = "10.1.1.1";
|
||||
const char *expected_route2_dest = "100.99.88.56";
|
||||
const char *expected_route2_gw = "10.1.1.1";
|
||||
static Option data[] = {
|
||||
{ "new_rfc3442_classless_static_routes", "45 10 17 66 41 24 192 168 10 192 168 1 1" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-dhclient-classless-invalid-2", "failed to parse DHCP4 options");
|
||||
|
||||
/* Test falling back to old-style static routes if the classless static
|
||||
* routes are invalid.
|
||||
*/
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
|
||||
"dhcp-dhclient-classless-invalid-2", "unexpected number of routes");
|
||||
ip4_test_route ("dhcp-dhclient-classless-invalid-2", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 32);
|
||||
ip4_test_route ("dhcp-dhclient-classless-invalid-2", ip4_config, 1,
|
||||
expected_route2_dest, expected_route2_gw, 32);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dhcpcd_invalid_classless_routes_2 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
const char *expected_route1_dest = "10.1.1.5";
|
||||
const char *expected_route1_gw = "10.1.1.1";
|
||||
const char *expected_route2_dest = "100.99.88.56";
|
||||
const char *expected_route2_gw = "10.1.1.1";
|
||||
static Option data[] = {
|
||||
{ "new_classless_static_routes", "10.0.adfadf/44 10.17.66.41 192.168.10.0/24 192.168.1.1" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-dhcpcd-classless-invalid-2", "failed to parse DHCP4 options");
|
||||
|
||||
/* Test falling back to old-style static routes if the classless static
|
||||
* routes are invalid.
|
||||
|
|
@ -400,150 +525,131 @@ test_invalid_classless_routes2 (const char *client)
|
|||
|
||||
/* Routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 2,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected number of routes");
|
||||
|
||||
/* Route #1 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-2", "couldn't convert expected route destination #1");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #1 destination");
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-2", "couldn't convert expected route next hop #1");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #1 next hop");
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 32,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #1 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #1 metric");
|
||||
|
||||
/* Route #2 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 1);
|
||||
ASSERT (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-2", "couldn't convert expected route destination #2");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #2 destination");
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-2", "couldn't convert expected route next hop #2");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #2 next hop");
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 32,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #2 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442-invalid-2", "unexpected route #2 metric");
|
||||
"dhcp-dhcpcd-classless-invalid-2", "unexpected number of routes");
|
||||
ip4_test_route ("dhcp-dhcpcd-classless-invalid-2", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 32);
|
||||
ip4_test_route ("dhcp-dhcpcd-classless-invalid-2", ip4_config, 1,
|
||||
expected_route2_dest, expected_route2_gw, 32);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static Option invalid_classless_routes3[] = {
|
||||
/* For dhclient */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" },
|
||||
/* For dhcpcd */
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
test_invalid_classless_routes3 (const char *client)
|
||||
test_dhclient_invalid_classless_routes_3 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
NMIP4Route *route;
|
||||
struct in_addr tmp;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
static Option data[] = {
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 32 128 10 17 66 41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (invalid_classless_routes3, options);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-rfc3442-invalid-3", "failed to parse DHCP4 options");
|
||||
"dhcp-dhclient-classless-invalid-3", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"dhcp-rfc3442-invalid-3", "unexpected number of IP routes");
|
||||
|
||||
/* Route #1 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-3", "couldn't convert expected route destination #1");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-3", "unexpected route #1 destination");
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442-invalid-3", "couldn't convert expected route next hop #1");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-invalid-3", "unexpected route #1 next hop");
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 24,
|
||||
"dhcp-rfc3442-invalid-3", "unexpected route #1 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442-invalid-3", "unexpected route #1 metric");
|
||||
"dhcp-dhclient-classless-invalid-3", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-dhclient-classless-invalid-3", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static Option gw_in_classless_routes[] = {
|
||||
/* For dhclient */
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" },
|
||||
/* For dhcpcd */
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static void
|
||||
test_gateway_in_classless_routes (const char *client)
|
||||
test_dhcpcd_invalid_classless_routes_3 (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
static Option data[] = {
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 128/32 10.17.66.41" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-dhcpcd-classless-invalid-3", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"dhcp-dhcpcd-classless-invalid-3", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-dhcpcd-classless-invalid-3", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
static void
|
||||
test_dhclient_gw_in_classless_routes (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
NMIP4Address *addr;
|
||||
NMIP4Route *route;
|
||||
struct in_addr tmp;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
const char *expected_gateway = "192.2.3.4";
|
||||
static Option data[] = {
|
||||
{ "new_rfc3442_classless_static_routes", "24 192 168 10 192 168 1 1 0 192 2 3 4" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (gw_in_classless_routes, options);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-rfc3442-gateway", "failed to parse DHCP4 options");
|
||||
"dhcp-dhclient-classless-gateway", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"dhcp-rfc3442-gateway", "unexpected number of IP routes");
|
||||
"dhcp-dhclient-classless-gateway", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-dhclient-classless-gateway", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
|
||||
/* Route #1 */
|
||||
route = nm_ip4_config_get_route (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0,
|
||||
"dhcp-rfc3442-gateway", "couldn't convert expected route destination #1");
|
||||
ASSERT (nm_ip4_route_get_dest (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-gateway", "unexpected route #1 destination");
|
||||
/* Gateway */
|
||||
ip4_test_gateway ("dhcp-dhclient-classless-gateway", ip4_config, expected_gateway);
|
||||
|
||||
ASSERT (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0,
|
||||
"dhcp-rfc3442-gateway", "couldn't convert expected route next hop #1");
|
||||
ASSERT (nm_ip4_route_get_next_hop (route) == tmp.s_addr,
|
||||
"dhcp-rfc3442-gateway", "unexpected route #1 next hop");
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
||||
ASSERT (nm_ip4_route_get_prefix (route) == 24,
|
||||
"dhcp-rfc3442-gateway", "unexpected route #1 prefix");
|
||||
ASSERT (nm_ip4_route_get_metric (route) == 0,
|
||||
"dhcp-rfc3442-gateway", "unexpected route #1 metric");
|
||||
static void
|
||||
test_dhcpcd_gw_in_classless_routes (const char *client)
|
||||
{
|
||||
GHashTable *options;
|
||||
NMIP4Config *ip4_config;
|
||||
const char *expected_route1_dest = "192.168.10.0";
|
||||
const char *expected_route1_gw = "192.168.1.1";
|
||||
const char *expected_gateway = "192.2.3.4";
|
||||
static Option data[] = {
|
||||
{ "new_classless_static_routes", "192.168.10.0/24 192.168.1.1 0.0.0.0/0 192.2.3.4" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Address */
|
||||
ASSERT (nm_ip4_config_get_num_addresses (ip4_config) == 1,
|
||||
"dhcp-rfc3442-gateway", "unexpected number of IP addresses");
|
||||
addr = nm_ip4_config_get_address (ip4_config, 0);
|
||||
ASSERT (inet_pton (AF_INET, expected_gateway, &tmp) > 0,
|
||||
"dhcp-rfc3442-gateway", "couldn't convert expected IP gateway");
|
||||
ASSERT (nm_ip4_address_get_gateway (addr) == tmp.s_addr,
|
||||
"dhcp-rfc3442-gateway", "unexpected IP gateway");
|
||||
options = fill_table (generic_options, NULL);
|
||||
options = fill_table (data, options);
|
||||
|
||||
ip4_config = nm_dhcp_manager_test_ip4_options_to_config (client, "eth0", options, "rebind");
|
||||
ASSERT (ip4_config != NULL,
|
||||
"dhcp-dhcpcd-classless-gateway", "failed to parse DHCP4 options");
|
||||
|
||||
/* IP4 routes */
|
||||
ASSERT (nm_ip4_config_get_num_routes (ip4_config) == 1,
|
||||
"dhcp-dhcpcd-classless-gateway", "unexpected number of IP routes");
|
||||
ip4_test_route ("dhcp-dhcpcd-classless-gateway", ip4_config, 0,
|
||||
expected_route1_dest, expected_route1_gw, 24);
|
||||
|
||||
/* Gateway */
|
||||
ip4_test_gateway ("dhcp-dhcpcd-classless-gateway", ip4_config, expected_gateway);
|
||||
|
||||
g_hash_table_destroy (options);
|
||||
}
|
||||
|
|
@ -694,11 +800,17 @@ int main (int argc, char **argv)
|
|||
|
||||
test_generic_options (client);
|
||||
test_wins_options (client);
|
||||
test_classless_static_routes (client);
|
||||
test_invalid_classless_routes1 (client);
|
||||
test_invalid_classless_routes2 (client);
|
||||
test_invalid_classless_routes3 (client);
|
||||
test_gateway_in_classless_routes (client);
|
||||
test_classless_static_routes_1 (client);
|
||||
test_classless_static_routes_2 (client);
|
||||
test_fedora_dhclient_classless_static_routes (client);
|
||||
test_dhclient_invalid_classless_routes_1 (client);
|
||||
test_dhcpcd_invalid_classless_routes_1 (client);
|
||||
test_dhclient_invalid_classless_routes_2 (client);
|
||||
test_dhcpcd_invalid_classless_routes_2 (client);
|
||||
test_dhclient_invalid_classless_routes_3 (client);
|
||||
test_dhcpcd_invalid_classless_routes_3 (client);
|
||||
test_dhclient_gw_in_classless_routes (client);
|
||||
test_dhcpcd_gw_in_classless_routes (client);
|
||||
test_escaped_domain_searches (client);
|
||||
test_invalid_escaped_domain_searches (client);
|
||||
test_ip4_missing_prefix (client, "192.168.1.10", 24);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue