diff options
Diffstat (limited to 'system-settings/plugins/ifnet/net_utils.c')
-rw-r--r-- | system-settings/plugins/ifnet/net_utils.c | 966 |
1 files changed, 966 insertions, 0 deletions
diff --git a/system-settings/plugins/ifnet/net_utils.c b/system-settings/plugins/ifnet/net_utils.c new file mode 100644 index 000000000..2dc253c54 --- /dev/null +++ b/system-settings/plugins/ifnet/net_utils.c @@ -0,0 +1,966 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* + * Mu Qiao <qiaomuf@gmail.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 1999-2010 Gentoo Foundation, Inc. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <nm-utils.h> +#include <nm-system-config-interface.h> +#include "net_utils.h" +#include "wpa_parser.h" +#include "net_parser.h" + +/* emit heading and tailing blank space, tab, character t */ +gchar * +strip_string (gchar * str, gchar t) +{ + gchar *ret = str; + gint length = 0; + guint i = 0; + + while (ret[i] != '\0' + && (ret[i] == '\t' || ret[i] == ' ' || ret[i] == t)) { + length++; + i++; + } + i = 0; + while (ret[i + length] != '\0') { + ret[i] = ret[i + length]; + i++; + } + ret[i] = '\0'; + length = strlen (ret); + while ((length - 1) >= 0 + && (ret[length - 1] == ' ' || ret[length - 1] == '\n' + || ret[length - 1] == '\t' || ret[length - 1] == t)) + length--; + ret[length] = '\0'; + return ret; +} + +gboolean +is_hex (gchar * value) +{ + gchar *p; + + if (!value) + return FALSE; + p = value; + while (*p) { + if (!isxdigit (*p)) { + return FALSE; + } + p++; + } + return TRUE; +} + +gboolean +is_ascii (gchar * value) +{ + gchar *p; + + p = value; + while (*p) { + if (!isascii (*p)) { + return FALSE; + } + p++; + } + return TRUE; + +} + +gboolean +is_true (char *str) +{ + if (!g_ascii_strcasecmp (str, "yes") + || !g_ascii_strcasecmp (str, "true")) + return TRUE; + return FALSE; +} + +static int +hex2num (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int +hex2byte (const char *hex) +{ + int a, b; + + a = hex2num (*hex++); + if (a < 0) + return -1; + b = hex2num (*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +/* free return value by caller */ +gchar * +utils_hexstr2bin (const gchar * hex, size_t len) +{ + size_t i; + int a; + const gchar *ipos = hex; + gchar *buf = NULL; + gchar *opos; + + /* Length must be a multiple of 2 */ + if ((len % 2) != 0) + return NULL; + + opos = buf = g_malloc0 ((len / 2) + 1); + for (i = 0; i < len; i += 2) { + a = hex2byte (ipos); + if (a < 0) { + g_free (buf); + return NULL; + } + *opos++ = a; + ipos += 2; + } + return buf; +} + +/* free return value by caller */ +gchar * +utils_bin2hexstr (const gchar * bytes, int len, int final_len) +{ + static gchar hex_digits[] = "0123456789abcdef"; + gchar *result; + int i; + gsize buflen = (len * 2) + 1; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + g_return_val_if_fail (len < 4096, NULL); /* Arbitrary limit */ + if (final_len > -1) + g_return_val_if_fail (final_len < buflen, NULL); + + result = g_malloc0 (buflen); + for (i = 0; i < len; i++) { + result[2 * i] = hex_digits[(bytes[i] >> 4) & 0xf]; + result[2 * i + 1] = hex_digits[bytes[i] & 0xf]; + } + /* Cut converted key off at the correct length for this cipher type */ + if (final_len > -1) + result[final_len] = '\0'; + else + result[buflen - 1] = '\0'; + + return result; +} + +GQuark +ifnet_plugin_error_quark (void) +{ + static GQuark error_quark = 0; + + if (G_UNLIKELY (error_quark == 0)) + error_quark = + g_quark_from_static_string ("ifnet-plugin-error-quark"); + return error_quark; +} + +static char * +find_default_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "default via ")) != NULL) { + return tmp + strlen ("default via "); + } else if ((tmp = strstr (str, "default gw ")) != NULL) { + return tmp + strlen ("default gw "); + } + return NULL; +} + +static char * +find_gateway_str (char *str) +{ + char *tmp; + + if ((tmp = strstr (str, "via ")) != NULL) { + return tmp + strlen ("via "); + } else if ((tmp = strstr (str, "gw ")) != NULL) { + return tmp + strlen ("gw "); + } + return NULL; +} + +gboolean +reload_parsers () +{ + ifnet_destroy (); + wpa_parser_destroy (); + if (!ifnet_init (CONF_NET_FILE)) + return FALSE; + wpa_parser_init (WPA_SUPPLICANT_CONF); + return TRUE; +} + +gchar * +read_hostname (gchar * path) +{ + gchar *contents = NULL, *result = NULL, *tmp; + gchar **all_lines = NULL; + guint line_num, i; + + if (!g_file_get_contents (path, &contents, NULL, NULL)) + return NULL; + all_lines = g_strsplit (contents, "\n", 0); + line_num = g_strv_length (all_lines); + for (i = 0; i < line_num; i++) { + g_strstrip (all_lines[i]); + if (all_lines[i][0] == '#' || all_lines[i][0] == '\0') + continue; + if (g_str_has_prefix (all_lines[i], "hostname")) { + tmp = strstr (all_lines[i], "="); + tmp++; + tmp = strip_string (tmp, '"'); + result = g_strdup (tmp); + break; + } + + } + g_strfreev (all_lines); + g_free (contents); + return result; +} + +gboolean +write_hostname (const gchar * hostname, gchar * path) +{ + gchar *contents = g_strdup_printf ("#Generated by NetworkManager\n" + "hostname=\"%s\"\n", hostname); + gboolean result = g_file_set_contents (path, contents, -1, NULL); + + g_free (contents); + return result; +} + +gboolean +is_static_ip4 (gchar * conn_name) +{ + gchar *data = ifnet_get_data (conn_name, "config"); + gchar *dhcp6; + + if (!data) + return FALSE; + dhcp6 = strstr (data, "dhcp6"); + if (dhcp6) { + gchar *dhcp4; + + if (strstr (data, "dhcp ")) + return FALSE; + dhcp4 = strstr (data, "dhcp"); + if (!dhcp4) + return TRUE; + if (dhcp4[4] == '\0') + return FALSE; + return TRUE; + } + return strstr (data, "dhcp") == NULL ? TRUE : FALSE; +} + +gboolean +is_static_ip6 (gchar * conn_name) +{ + gchar *data = ifnet_get_data (conn_name, "config"); + + if (!data) + return TRUE; + return strstr (data, "dhcp6") == NULL ? TRUE : FALSE; +} + +gboolean +is_ip4_address (gchar * in_address) +{ + gchar *pattern = + "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.((\\{\\d{1,3}\\.\\.\\d{1,3}\\})|\\d{1,3})$"; + gchar *address = g_strdup (in_address); + gboolean result = FALSE; + gchar *tmp; + GRegex *regex = g_regex_new (pattern, 0, 0, NULL); + GMatchInfo *match_info; + + if (!address) + goto done; + g_strstrip (address); + if ((tmp = strstr (address, "/")) != NULL) + *tmp = '\0'; + if ((tmp = strstr (address, " ")) != NULL) + *tmp = '\0'; + g_regex_match (regex, address, 0, &match_info); + result = g_match_info_matches (match_info); + done: + if (match_info) + g_match_info_free (match_info); + g_regex_unref (regex); + g_free (address); + return result; +} + +gboolean +is_ip6_address (gchar * in_address) +{ + struct in6_addr tmp_ip6_addr; + gchar *tmp; + gchar *address = g_strdup (in_address); + gboolean result = FALSE; + + if (!address) { + g_free (address); + return FALSE; + } + g_strstrip (address); + if ((tmp = strchr (address, '/')) != NULL) + *tmp = '\0'; + if (inet_pton (AF_INET6, address, &tmp_ip6_addr)) + result = TRUE; + g_free (address); + return result; + +} + +gboolean +has_ip6_address (gchar * conn_name) +{ + gchar **ipset; + guint length; + guint i; + + g_return_val_if_fail (conn_name != NULL, FALSE); + ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + if (!is_ip6_address (ipset[i])) + continue; + else { + g_strfreev (ipset); + return TRUE; + } + + } + g_strfreev (ipset); + return FALSE; +} + +gboolean +has_default_route (gchar * conn_name, gboolean (*check_fn) (gchar *)) +{ + gchar *routes = NULL, *tmp, *end; + + g_return_val_if_fail (conn_name != NULL, FALSE); + tmp = ifnet_get_data (conn_name, "routes"); + if (!tmp) + return FALSE; + routes = g_strdup (tmp); + tmp = find_default_gateway_str (routes); + if (!tmp) { + goto error; + } + g_strstrip (tmp); + if ((end = strstr (tmp, "\"")) != NULL) + *end = '\0'; + if (check_fn (tmp)) { + g_free (routes); + return TRUE; + } + error: + g_free (routes); + return FALSE; +} + +static ip_block * +create_ip4_block (gchar * ip) +{ + ip_block *iblock = g_slice_new0 (ip_block); + struct in_addr tmp_ip4_addr; + int i; + guint length; + gchar **ip_mask; + + /* prefix format */ + if (strstr (ip, "/")) { + gchar *prefix; + + ip_mask = g_strsplit (ip, "/", 0); + length = g_strv_length (ip_mask); + if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) + goto error; + iblock->ip = tmp_ip4_addr.s_addr; + prefix = ip_mask[1]; + i = 0; + while (i < length && isdigit (prefix[i])) + i++; + prefix[i] = '\0'; + iblock->netmask = nm_utils_ip4_prefix_to_netmask ((guint32) + atoi (ip_mask + [1])); + } else if (strstr (ip, "netmask")) { + ip_mask = g_strsplit (ip, " ", 0); + length = g_strv_length (ip_mask); + if (!inet_pton (AF_INET, ip_mask[0], &tmp_ip4_addr)) + goto error; + iblock->ip = tmp_ip4_addr.s_addr; + i = 0; + while (i < length && !strstr (ip_mask[++i], "netmask")) ; + while (i < length && ip_mask[++i][0] == '\0') ; + if (i >= length) + goto error; + if (!inet_pton (AF_INET, ip_mask[i], &tmp_ip4_addr)) + goto error; + iblock->netmask = tmp_ip4_addr.s_addr; + } else { + g_slice_free (ip_block, iblock); + if (!is_ip6_address (ip) && !strstr (ip, "dhcp")) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't handle ipv4 address: %s, missing netmask or prefix", + ip); + return NULL; + } + g_strfreev (ip_mask); + return iblock; + error: + if (!is_ip6_address (ip)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 address: %s", + ip); + g_strfreev (ip_mask); + g_slice_free (ip_block, iblock); + return NULL; +} + +static ip6_block * +create_ip6_block (gchar * ip) +{ + ip6_block *iblock = g_slice_new0 (ip6_block); + gchar *dup_ip = g_strdup (ip); + struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); + gchar *prefix = NULL; + + if ((prefix = strstr (dup_ip, "/")) != NULL) { + *prefix = '\0'; + prefix++; + } + if (!inet_pton (AF_INET6, dup_ip, tmp_ip6_addr)) { + goto error; + } + iblock->ip = tmp_ip6_addr; + if (prefix) { + errno = 0; + iblock->prefix = strtol (prefix, NULL, 10); + if (errno || iblock->prefix <= 0 || iblock->prefix > 128) { + goto error; + } + } else + iblock->prefix = 64; + g_free (dup_ip); + return iblock; + error: + if (!is_ip4_address (ip)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv6 address: %s", + ip); + g_slice_free (ip6_block, iblock); + g_slice_free (struct in6_addr, tmp_ip6_addr); + + g_free (dup_ip); + return NULL; +} + +static guint32 +get_ip4_gateway (gchar * gateway) +{ + gchar *tmp, *split; + struct in_addr tmp_ip4_addr; + + if (!gateway) + return 0; + tmp = find_gateway_str (gateway); + if (!tmp) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Couldn't obtain gateway in \"%s\"", gateway); + return 0; + } + tmp = g_strdup (tmp); + strip_string (tmp, ' '); + strip_string (tmp, '"'); + if ((split = strstr (tmp, "\"")) != NULL) + *split = '\0'; + if (!inet_pton (AF_INET, tmp, &tmp_ip4_addr)) + goto error; + g_free (tmp); + return tmp_ip4_addr.s_addr; + error: + if (!is_ip6_address (tmp)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, "Can't handle IPv4 gateway: %s", + tmp); + g_free (tmp); + return 0; +} + +static struct in6_addr * +get_ip6_next_hop (gchar * next_hop) +{ + gchar *tmp; + struct in6_addr *tmp_ip6_addr = g_slice_new0 (struct in6_addr); + + if (!next_hop) + return 0; + tmp = find_gateway_str (next_hop); + if (!tmp) { + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Couldn't obtain next_hop in \"%s\"", next_hop); + return 0; + } + tmp = g_strdup (tmp); + strip_string (tmp, ' '); + strip_string (tmp, '"'); + g_strstrip (tmp); + if (!inet_pton (AF_INET6, tmp, tmp_ip6_addr)) + goto error; + g_free (tmp); + return tmp_ip6_addr; + error: + if (!is_ip4_address (tmp)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "Can't handle IPv6 next_hop: %s", tmp); + g_free (tmp); + g_slice_free (struct in6_addr, tmp_ip6_addr); + + return NULL; +} + +ip_block * +convert_ip4_config_block (gchar * conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + guint32 def_gateway; + gchar *routes; + gchar *pos; + ip_block *start = NULL, *current = NULL, *iblock = NULL; + gchar *pattern = + "((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.)\\{(\\d{1,3})\\.\\.(\\d{1,3})\\}(/\\d{1,2}))"; + GRegex *regex = g_regex_new (pattern, 0, 0, NULL); + + g_return_val_if_fail (conn_name != NULL, NULL); + ipset = g_strsplit (ifnet_get_data (conn_name, "config"), "\" \"", 0); + length = g_strv_length (ipset); + routes = ifnet_get_data (conn_name, "routes"); + if (routes) + def_gateway = get_ip4_gateway (strstr (routes, "default")); + else + def_gateway = 0; + 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; + GMatchInfo *match_info; + + g_regex_match (regex, ip, 0, &match_info); + 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; + } + } + } + g_strfreev (ipset); + g_regex_unref (regex); + return start; +} + +ip6_block * +convert_ip6_config_block (gchar * conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + 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); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + iblock = create_ip6_block (ip); + if (iblock == NULL) + continue; + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +ip_block * +convert_ip4_routes_block (gchar * conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip; + gchar *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); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + ip = ipset[i]; + if (find_default_gateway_str (ip) || strstr (ip, "::") + || !find_gateway_str (ip)) + continue; + ip = strip_string (ip, '"'); + iblock = create_ip4_block (ip); + if (iblock == NULL) + continue; + iblock->gateway = get_ip4_gateway (ip); + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +ip6_block * +convert_ip6_routes_block (gchar * conn_name) +{ + gchar **ipset; + guint length; + guint i; + gchar *ip, *tmp_addr; + gchar *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); + length = g_strv_length (ipset); + for (i = 0; i < length; i++) { + ip = ipset[i]; + ip = strip_string (ip, '"'); + if (ip[0] == '\0') + continue; + if ((tmp_addr = find_default_gateway_str (ip)) != NULL) { + if (!is_ip6_address (tmp_addr)) + continue; + else { + tmp_ip6_addr = g_slice_new0 (struct in6_addr); + + if (inet_pton (AF_INET6, "::", tmp_ip6_addr)) { + iblock = g_slice_new0 (ip6_block); + iblock->ip = tmp_ip6_addr; + iblock->prefix = 128; + } else { + g_slice_free (struct in6_addr, + tmp_ip6_addr); + continue; + } + } + } else + iblock = create_ip6_block (ip); + if (iblock == NULL) + continue; + iblock->next_hop = get_ip6_next_hop (ip); + if (iblock->next_hop == NULL) { + destroy_ip6_block (iblock); + continue; + } + if (start == NULL) + start = current = iblock; + else { + current->next = iblock; + current = iblock; + } + } + g_strfreev (ipset); + return start; +} + +void +destroy_ip_block (ip_block * iblock) +{ + g_slice_free (ip_block, iblock); +} + +void +destroy_ip6_block (ip6_block * iblock) +{ + g_slice_free (struct in6_addr, iblock->ip); + g_slice_free (struct in6_addr, iblock->next_hop); + + g_slice_free (ip6_block, iblock); +} + +void +set_ip4_dns_servers (NMSettingIP4Config * s_ip4, gchar * conn_name) +{ + gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers"); + gchar **server_list; + guint length, i; + struct in_addr tmp_ip4_addr; + guint32 new_dns; + + if (!dns_servers) + return; + strip_string (dns_servers, '"'); + server_list = g_strsplit (dns_servers, " ", 0); + length = g_strv_length (server_list); + if (length) + g_object_set (s_ip4, NM_SETTING_IP4_CONFIG_IGNORE_AUTO_DNS, + TRUE, NULL); + for (i = 0; i < length; i++) { + g_strstrip (server_list[i]); + if (server_list[i][0] == '\0') + continue; + if (!inet_pton (AF_INET, server_list[i], &tmp_ip4_addr)) { + if (!is_ip6_address (server_list[i])) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "ignored dns: %s\n", + server_list[i]); + continue; + } + new_dns = tmp_ip4_addr.s_addr; + if (new_dns && !nm_setting_ip4_config_add_dns (s_ip4, new_dns)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "warning: duplicate DNS server %s", + server_list[i]); + } + g_strfreev (server_list); +} + +void +set_ip6_dns_servers (NMSettingIP6Config * s_ip6, gchar * conn_name) +{ + gchar *dns_servers = ifnet_get_data (conn_name, "dns_servers"); + gchar **server_list; + guint length, i; + struct in6_addr tmp_ip6_addr; + + if (!dns_servers) + return; + strip_string (dns_servers, '"'); + server_list = g_strsplit (dns_servers, " ", 0); + length = g_strv_length (server_list); + if (length) + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_IGNORE_AUTO_DNS, + TRUE, NULL); + for (i = 0; i < length; i++) { + g_strstrip (server_list[i]); + if (server_list[i][0] == '\0') + continue; + if (!inet_pton (AF_INET6, server_list[i], &tmp_ip6_addr)) { + if (is_ip6_address (server_list[i])) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "ignored dns: %s\n", + server_list[i]); + continue; + } + if (!IN6_IS_ADDR_UNSPECIFIED (&tmp_ip6_addr) + && !nm_setting_ip6_config_add_dns (s_ip6, &tmp_ip6_addr)) + PLUGIN_WARN (IFNET_PLUGIN_NAME, + "warning: duplicate DNS server %s", + server_list[i]); + } + g_strfreev (server_list); +} + +gboolean +is_managed (gchar * conn_name) +{ + gchar *config; + + g_return_val_if_fail (conn_name != NULL, FALSE); + config = (gchar *) ifnet_get_data (conn_name, "managed"); + if (!config) + return TRUE; + if (strcmp (config, "false") == 0) + return FALSE; + return TRUE; +} + +void +get_dhcp_hostname_and_client_id (char **hostname, char **client_id) +{ + gchar *dhcp_client = NULL; + const gchar *dhcpcd_conf = "/etc/dhcpcd.conf"; + const gchar *dhclient_conf = "/etc/dhcp/dhclient.conf"; + gchar *line = NULL, *tmp = NULL, *contents = NULL; + gchar **all_lines; + guint line_num, i; + + *hostname = NULL; + *client_id = NULL; + dhcp_client = ifnet_get_global_setting ("main", "dhcp"); + if (dhcp_client) { + if (!strcmp (dhcp_client, "dhclient")) + g_file_get_contents (dhclient_conf, &contents, NULL, + NULL); + else if (!strcmp (dhcp_client, "dhcpcd")) + g_file_get_contents (dhcpcd_conf, &contents, NULL, + NULL); + g_free (dhcp_client); + } else { + if (g_file_test (dhclient_conf, G_FILE_TEST_IS_REGULAR)) + g_file_get_contents (dhclient_conf, &contents, NULL, + NULL); + else if (g_file_test (dhcpcd_conf, G_FILE_TEST_IS_REGULAR)) + g_file_get_contents (dhcpcd_conf, &contents, NULL, + NULL); + } + if (!contents) + return; + all_lines = g_strsplit (contents, "\n", 0); + line_num = g_strv_length (all_lines); + for (i = 0; i < line_num; i++) { + line = all_lines[i]; + // dhcpcd.conf + g_strstrip (line); + if (g_str_has_prefix (line, "hostname")) { + tmp = line + strlen ("hostname"); + g_strstrip (tmp); + if (tmp[0] != '\0') + *hostname = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhcpcd hostname not defined, ignoring"); + } else if (g_str_has_prefix (line, "clientid")) { + tmp = line + strlen ("clientid"); + g_strstrip (tmp); + if (tmp[0] != '\0') + *client_id = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhcpcd clientid not defined, ignoring"); + } + // dhclient.conf + else if ((tmp = strstr (line, "send host-name")) != NULL) { + tmp += strlen ("send host-name"); + g_strstrip (tmp); + strip_string (tmp, '"'); + strip_string (tmp, ';'); + if (tmp[0] != '\0') + *hostname = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhclient hostname not defined, ignoring"); + } else if ((tmp = strstr (line, "send dhcp-client-identifier")) + != NULL) { + tmp += strlen ("send dhcp-client-identifier"); + g_strstrip (tmp); + strip_string (tmp, ';'); + if (tmp[0] != '\0') + *client_id = g_strdup (tmp); + else + PLUGIN_PRINT (IFNET_PLUGIN_NAME, + "dhclient clientid not defined, ignoring"); + } + } + g_strfreev (all_lines); + g_free (contents); +} |