diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index fe7c26d4e6..3b51f6690b 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -562,7 +562,7 @@ make_wired_connection_setting (NMConnection *connection, nm_connection_add_setting (connection, NM_SETTING (s_wired)); } -/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, +/* add NM_SETTING_IP4_CONFIG_DHCP_HOSTNAME, * NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID in future*/ static void make_ip4_setting (NMConnection *connection, @@ -591,19 +591,19 @@ make_ip4_setting (NMConnection *connection, g_object_unref (ip4_setting); return; } - if (!strcmp (method, "dhcp")) + if (strstr (method, "dhcp")) g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); - else if (!strcmp (method, "autoip")){ + else if (strstr (method, "autoip")) { g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL, NM_SETTING_IP4_CONFIG_NEVER_DEFAULT, FALSE, NULL); nm_connection_add_setting (connection, NM_SETTING (ip4_setting)); return; - } else if (!strcmp (method, "shared")){ + } else if (strstr (method, "shared")) { g_object_set (ip4_setting, NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_SHARED, @@ -658,7 +658,7 @@ make_ip4_setting (NMConnection *connection, } /* add dhcp hostname and client id */ - if (!is_static_block && !strcmp (method, "dhcp")) { + if (!is_static_block && strstr (method, "dhcp")) { gchar *dhcp_hostname, *client_id; get_dhcp_hostname_and_client_id (&dhcp_hostname, &client_id); @@ -863,7 +863,7 @@ make_ip6_setting (NMConnection *connection, nm_ip6_route_set_dest (route, iblock->ip); nm_ip6_route_set_next_hop (route, iblock->next_hop); nm_ip6_route_set_prefix (route, iblock->prefix); - /* metric is not per routes configuration right now + /* metric is not per routes configuration right now * global metric is also supported (metric="x") */ if ((metric_str = ifnet_get_data (conn_name, "metric")) != NULL) { metric = strtol (metric_str, NULL, 10); @@ -990,7 +990,7 @@ make_wireless_connection_setting (const char *conn_name, goto error; } - /* mode=0: infrastructure + /* mode=0: infrastructure * mode=1: adhoc */ value = wpa_get_value (conn_name, "mode"); if (value) diff --git a/src/settings/plugins/ifnet/net_parser.c b/src/settings/plugins/ifnet/net_parser.c index 29a1f34cfb..417c08a996 100644 --- a/src/settings/plugins/ifnet/net_parser.c +++ b/src/settings/plugins/ifnet/net_parser.c @@ -169,12 +169,10 @@ init_block_by_line (gchar * buf) conn = add_new_connection_config ("wireless", pos); } data = g_strdup (key_value[1]); - tmp = strip_string (data, '('); - tmp = strip_string (tmp, ')'); - strip_string (tmp, '"'); + tmp = strip_string (data, '"'); strip_string (tmp, '\''); if (conn) - g_hash_table_insert (conn, g_strdup (key_value[0]), + g_hash_table_insert (conn, strip_string (g_strdup (key_value[0]), ' '), g_strdup (tmp)); g_free (data); g_strfreev (key_value); @@ -288,6 +286,20 @@ is_function (gchar * line) return FALSE; } +static void +append_line (GString *buf, gchar* line) +{ + gchar *pos = NULL; + + if ((pos = strchr (line, '#')) != NULL) + *pos = '\0'; + g_strstrip (line); + + if (line[0] != '\0') + g_string_append_printf (buf, " %s", line); + g_free (line); +} + gboolean ifnet_init (gchar * config_file) { @@ -297,6 +309,8 @@ ifnet_init (gchar * config_file) /* Handle multiple lines with brackets */ gboolean complete = TRUE; + gboolean openrc_style = TRUE; + /* line buffer */ GString *buf; @@ -324,36 +338,60 @@ ifnet_init (gchar * config_file) strip_function (channel, line); continue; } - if (line[0] != '#' && line[0] != '\0') { - gchar *pos = NULL; + // New openrc style, bash arrays are not allowed. We only care about '"' + if (openrc_style && line[0] != '#' && line[0] != '\0' + && !strchr (line, '(') && !strchr (line, ')')) { + gchar *tmp = line; + + while ((tmp = strchr (tmp, '"')) != NULL) { + complete = !complete; + ++tmp; + } + + append_line (buf, line); + // Add "(separator) for routes. It will be easier for later parsing + if (strstr (buf->str, "via")) + g_string_append_printf (buf, "\""); + + if (!complete) + continue; + + strip_string (buf->str, '"'); + + init_block_by_line (buf->str); + g_string_free (buf, TRUE); + buf = g_string_new (NULL); + } + // Old bash arrays for baselayout-1, to be deleted + else if (line[0] != '#' && line[0] != '\0') { if (!complete) { complete = g_strrstr (line, ")") == NULL ? FALSE : TRUE; - if ((pos = strchr (line, '#')) != NULL) - *pos = '\0'; - g_strstrip (line); - if (line[0] != '\0') { - g_string_append_printf (buf, - " %s", line); - } - g_free (line); - if (!complete) + + append_line (buf, line); + if (!complete) { + openrc_style = FALSE; continue; + } + else { + openrc_style = TRUE; + } } else { complete = (g_strrstr (line, "(") != NULL && g_strrstr (line, ")") != NULL) || g_strrstr (line, "(") == NULL; - if ((pos = strchr (line, '#')) != NULL) - *pos = '\0'; - g_strstrip (line); - if (line[0] != '\0') - g_string_append (buf, line); - g_free (line); + + append_line (buf, line); if (!complete) + { + openrc_style = FALSE; continue; + } else { + openrc_style = TRUE; + } } init_block_by_line (buf->str); g_string_free (buf, TRUE); @@ -396,7 +434,7 @@ ifnet_set_data (const char *conn_name, const char *key, const char *value) } /* Remove existing key value pair */ if (g_hash_table_lookup_extended (conn, key, &old_key, &old_value)) { - if (stripped && !strcmp(old_value, stripped)){ + if (stripped && !strcmp (old_value, stripped)) { g_free (stripped); return; } diff --git a/src/settings/plugins/ifnet/net_utils.c b/src/settings/plugins/ifnet/net_utils.c index b533ae3f20..fc7e283fec 100644 --- a/src/settings/plugins/ifnet/net_utils.c +++ b/src/settings/plugins/ifnet/net_utils.c @@ -352,6 +352,49 @@ is_ip6_address (const char *in_address) } +// 'c' is only used for openrc style +static gchar ** +split_addresses_by_char (const gchar *addresses, const gchar *c) +{ + gchar **ipset; + + if (addresses == NULL) + return NULL; + + if (strchr (addresses, '(') != NULL) { // old baselayout style + gchar *tmp = g_strdup (addresses); + strip_string (tmp, '('); + strip_string (tmp, ')'); + strip_string (tmp, '"'); + strip_string (tmp, '\''); + ipset = g_strsplit (tmp, "\" \"", 0); + g_free(tmp); + } else { // openrc style + if (strstr (addresses, "netmask")) + // There is only one ip address if "netmask" is specified. + // '\n' is not used in config so there will be only one split. + ipset = g_strsplit (addresses, "\n", 0); + else + ipset = g_strsplit (addresses, c, 0); + } + + return ipset; +} + +static gchar ** +split_addresses (const gchar* addresses) +{ + // " " is only used by openrc style + return split_addresses_by_char (addresses, " "); +} + +static gchar ** +split_routes (const gchar* routes) +{ + // "\"" is only used by openrc style + return split_addresses_by_char (routes, "\""); +} + gboolean has_ip6_address (const char *conn_name) { @@ -360,7 +403,7 @@ has_ip6_address (const char *conn_name) guint i; g_return_val_if_fail (conn_name != NULL, FALSE); - ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { if (!is_ip6_address (ipset[i])) @@ -512,8 +555,11 @@ get_ip4_gateway (gchar * gateway) tmp = g_strdup (tmp); strip_string (tmp, ' '); strip_string (tmp, '"'); + + // Only one gateway is selected if ((split = strstr (tmp, "\"")) != NULL) *split = '\0'; + if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr)) goto error; g_free (tmp); @@ -567,14 +613,11 @@ convert_ip4_config_block (const char *conn_name) gchar *ip; guint32 def_gateway = 0; const char *routes; - gchar *pos; ip_block *start = NULL, *current = NULL, *iblock = NULL; - const char *pattern = - "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))"; g_return_val_if_fail (conn_name != NULL, NULL); - ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); length = g_strv_length (ipset); routes = ifnet_get_data (conn_name, "routes"); @@ -584,73 +627,16 @@ convert_ip4_config_block (const char *conn_name) for (i = 0; i < length; i++) { ip = ipset[i]; ip = strip_string (ip, '"'); - //Handle ip like 192.168.4.{1..3} - if ((pos = strchr (ip, '{')) != NULL) { - gchar *ip_start, *ip_prefix; - gchar *begin_str, *end_str; - int begin, end, j; - GRegex *regex; - GMatchInfo *match_info; - - regex = g_regex_new (pattern, 0, 0, NULL); - g_regex_match (regex, ip, 0, &match_info); - g_regex_unref (regex); - - if (!g_match_info_matches (match_info)) { - g_match_info_free (match_info); - continue; - } - begin_str = g_match_info_fetch (match_info, 3); - end_str = g_match_info_fetch (match_info, 4); - begin = atoi (begin_str); - end = atoi (end_str); - ip_start = g_match_info_fetch (match_info, 2); - ip_prefix = g_match_info_fetch (match_info, 5); - if (end < begin || begin < 1 || end > 254) { - g_match_info_free (match_info); - continue; - } - - for (j = begin; j <= end; j++) { - char suf[4]; - gchar *newip; - - sprintf (suf, "%d", j); - newip = - g_strconcat (ip_start, suf, ip_prefix, - NULL); - iblock = create_ip4_block (newip); - if (iblock == NULL) { - g_free (newip); - continue; - } - if (!iblock->gateway && def_gateway != 0) - iblock->gateway = def_gateway; - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } - g_free (newip); - } - g_free (begin_str); - g_free (end_str); - g_free (ip_start); - g_free (ip_prefix); - g_match_info_free (match_info); - } else { - iblock = create_ip4_block (ip); - if (iblock == NULL) - continue; - if (!iblock->gateway && def_gateway != 0) - iblock->gateway = def_gateway; - if (start == NULL) - start = current = iblock; - else { - current->next = iblock; - current = iblock; - } + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + if (!iblock->gateway && def_gateway != 0) + iblock->gateway = def_gateway; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; } } g_strfreev (ipset); @@ -667,7 +653,7 @@ convert_ip6_config_block (const char *conn_name) ip6_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); - ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + ipset = split_addresses (ifnet_get_data (conn_name, "config")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; @@ -693,15 +679,11 @@ convert_ip4_routes_block (const char *conn_name) guint length; guint i; gchar *ip; - const char *routes; ip_block *start = NULL, *current = NULL, *iblock = NULL; g_return_val_if_fail (conn_name != NULL, NULL); - routes = ifnet_get_data (conn_name, "routes"); - if (!routes) - return NULL; - ipset = g_strsplit (routes, "\" \"", 0); + ipset = split_routes (ifnet_get_data (conn_name, "routes")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; @@ -731,15 +713,11 @@ convert_ip6_routes_block (const char *conn_name) guint length; guint i; gchar *ip, *tmp_addr; - const char *routes; ip6_block *start = NULL, *current = NULL, *iblock = NULL; struct in6_addr *tmp_ip6_addr; g_return_val_if_fail (conn_name != NULL, NULL); - routes = ifnet_get_data (conn_name, "routes"); - if (!routes) - return NULL; - ipset = g_strsplit (routes, "\" \"", 0); + ipset = split_routes (ifnet_get_data (conn_name, "routes")); length = g_strv_length (ipset); for (i = 0; i < length; i++) { ip = ipset[i]; diff --git a/src/settings/plugins/ifnet/tests/net b/src/settings/plugins/ifnet/tests/net index 0eef399a98..27d39f4480 100644 --- a/src/settings/plugins/ifnet/tests/net +++ b/src/settings/plugins/ifnet/tests/net @@ -27,10 +27,9 @@ config_eth2=( routes_eth2=("default via 4321:0:1:2:3:4:567:89ab") enable_ipv6_eth2="true" config_eth3=("nufjlsjlll") -managed_eth4=("false") +managed_eth4="false" routes_eth4=("default via 4321:0:1:2:3:4:567:89ab") config_eth5=("dhcp") -config_eth6=("192.168.4.{1..101}/24") config_eth7=( "dhcp" ) auto_eth7="true" @@ -38,6 +37,14 @@ auto_eth7="true" # missing config_eth8 auto_eth8="true" +#new openrc style +config_eth9="202.117.16.10/24 202.117.17.10/24" +routes_eth9="default via 202.117.16.1 +10.0.0.0/8 via 192.168.0.1 +" +config_eth10="202.117.16.2 netmask 255.255.255.0" +routes_eth10="10.0.0.0/8 via 192.168.0.1" + config_myxjtu2=("202.117.16.121/24 brd 202.117.16.255") routes_myxjtu2=("default via 202.117.16.1") dns_servers_myxjtu2="202.117.0.20 202.117.0.21" diff --git a/src/settings/plugins/ifnet/tests/test_all.c b/src/settings/plugins/ifnet/tests/test_all.c index 52d9ce2adf..9ca5f655f5 100644 --- a/src/settings/plugins/ifnet/tests/test_all.c +++ b/src/settings/plugins/ifnet/tests/test_all.c @@ -37,7 +37,7 @@ static void test_getdata () { ASSERT (ifnet_get_data ("eth1", "config") - && strcmp (ifnet_get_data ("eth1", "config"), "dhcp") == 0, + && strcmp (ifnet_get_data ("eth1", "config"), "( \"dhcp\" )") == 0, "get data", "config_eth1 is not correct"); ASSERT (ifnet_get_data ("ppp0", "username") && strcmp (ifnet_get_data ("ppp0", "username"), "user") == 0, @@ -84,7 +84,7 @@ test_is_static () ASSERT (is_static_ip4 ("eth0") == TRUE, "is static", "a static interface is recognized as dhcp"); ASSERT (!is_static_ip6 ("eth0") == TRUE, "is static", - "a static interface is recognized as dhcp"); + "a dhcp interface is recognized as static"); } static void @@ -182,10 +182,6 @@ test_convert_ipv4_config_block () ASSERT (iblock == NULL, "convert config_block", "convert error configuration"); destroy_ip_block (iblock); - iblock = convert_ip4_config_block ("eth6"); - ASSERT (iblock != NULL, "convert config_block", - "convert error configuration"); - destroy_ip_block (iblock); } static void @@ -200,6 +196,16 @@ test_convert_ipv4_routes_block () destroy_ip_block (tmp); ASSERT (iblock == NULL, "convert ip4 routes", "should only get one route"); + + iblock = convert_ip4_routes_block ("eth9"); + tmp = iblock; + + ASSERT (iblock != NULL, "convert ip4 routes", "should get one route"); + check_ip_block (iblock, "10.0.0.0", "255.0.0.0", "192.168.0.1"); + iblock = iblock->next; + destroy_ip_block (tmp); + ASSERT (iblock == NULL, "convert ip4 routes", + "should only get one route"); } static void @@ -272,6 +278,18 @@ test_new_connection () "new connection failed: %s", error ? error->message : "NONE"); g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("eth9", &error); + ASSERT (connection != NULL, "new connection", + "new connection(eth9) failed: %s", + error ? error->message : "NONE"); + g_object_unref (connection); + + connection = ifnet_update_connection_from_config_block ("eth10", &error); + ASSERT (connection != NULL, "new connection", + "new connection(eth10) failed: %s", + error ? error->message : "NONE"); + g_object_unref (connection); } #define NET_GEN_NAME "net.generate"