52#define UDHCP_CONFIG_PATH "/run/usb-moded/udhcpd.conf"
53#define UDHCP_CONFIG_DIR "/run/usb-moded"
54#define UDHCP_CONFIG_LINK "/etc/udhcpd.conf"
82static void ipforward_data_set_dns1 (
ipforward_data_t *self,
const char *dns);
83static void ipforward_data_set_dns2 (
ipforward_data_t *self,
const char *dns);
84static void ipforward_data_set_nat_interface(
ipforward_data_t *self,
const char *interface);
91static gchar *ofono_get_default_modem (
void);
92static gchar *ofono_get_modem_status (
const char *modem);
93static bool ofono_get_roaming_status(
void);
101static bool connman_technology_set_tethering (DBusConnection *con,
const char *technology,
bool on, DBusError *err);
102static gchar *connman_manager_get_service_path (DBusConnection *con,
const char *type);
103static bool connman_service_get_connection_data(DBusConnection *con,
const char *service,
ipforward_data_t *ipforward);
105bool connman_set_tethering (
const char *technology,
bool on);
120static bool network_interface_exists (
char *interface);
121static char *network_get_interface (
const modedata_t *data);
122static char *network_get_nat_interface (
const modedata_t *data);
123static char *network_get_ip (
const modedata_t *data);
124static char *network_get_netmask (
const modedata_t *data);
126static void network_cleanup_ip_forwarding(
void);
127static int network_check_udhcpd_symlink (
void);
139ipforward_data_create(
void)
141 LOG_REGISTER_CONTEXT;
155 LOG_REGISTER_CONTEXT;
159 ipforward_data_clear(self);
167 LOG_REGISTER_CONTEXT;
169 ipforward_data_set_dns1(self, 0);
170 ipforward_data_set_dns2(self, 0);
171 ipforward_data_set_nat_interface(self, 0);
177 LOG_REGISTER_CONTEXT;
180 self->
dns1 = dns ? g_strdup(dns) : 0;
186 LOG_REGISTER_CONTEXT;
189 self->
dns2 = dns ? g_strdup(dns) : 0;
193ipforward_data_set_nat_interface(
ipforward_data_t *self,
const char *interface)
195 LOG_REGISTER_CONTEXT;
215ofono_get_default_modem(void)
218 DBusConnection *con = 0;
219 DBusError err = DBUS_ERROR_INIT;
220 DBusMessage *rsp = 0;
222 if( !(con = umdbus_get_connection()) )
225 rsp = umdbus_blocking_call(con,
236 DBusMessageIter body;
237 if( umdbus_parser_init(&body, rsp) ) {
238 DBusMessageIter iter_array;
239 if( umdbus_parser_get_array(&body, &iter_array) ) {
240 DBusMessageIter astruct;
241 if( umdbus_parser_get_struct(&iter_array, &astruct) ) {
242 const char *
object = 0;
243 if( umdbus_parser_get_object(&astruct, &
object) ) {
244 modem = g_strdup(
object);
252 dbus_message_unref(rsp);
255 dbus_connection_unref(con);
257 dbus_error_free(&err);
259 log_warning(
"default modem = %s", modem ?:
"n/a");
273ofono_get_modem_status(
const char *modem)
276 DBusConnection *con = 0;
277 DBusError err = DBUS_ERROR_INIT;
278 DBusMessage *rsp = 0;
280 if( !(con = umdbus_get_connection()) )
283 rsp = umdbus_blocking_call(con,
286 "org.ofono.NetworkRegistration",
293 DBusMessageIter body;
294 if( umdbus_parser_init(&body, rsp) ) {
295 DBusMessageIter iter_array;
296 if( umdbus_parser_get_array(&body, &iter_array) ) {
297 DBusMessageIter entry;
298 while( umdbus_parser_get_entry(&iter_array, &entry) ) {
300 if( !umdbus_parser_get_string(&entry, &key) )
302 if( strcmp(key,
"Status") )
305 if( !umdbus_parser_get_variant(&entry, &var) )
308 if( !umdbus_parser_get_string(&var, &val) )
310 status = g_strdup(val);
318 dbus_message_unref(rsp);
321 dbus_connection_unref(con);
323 dbus_error_free(&err);
325 log_warning(
"modem status = %s", status ?:
"n/a");
335ofono_get_roaming_status(
void)
337 LOG_REGISTER_CONTEXT;
339 bool roaming =
false;
343 if( !(modem = ofono_get_default_modem()) )
346 if( !(status = ofono_get_modem_status(modem)) )
349 if( !strcmp(status,
"roaming") )
356 log_warning(
"modem roaming = %d", roaming);
367# define CONNMAN_SERVICE "net.connman"
368# define CONNMAN_TECH_INTERFACE "net.connman.Technology"
369# define CONNMAN_ERROR_ALREADY_ENABLED "net.connman.Error.AlreadyEnabled"
370# define CONNMAN_ERROR_ALREADY_DISABLED "net.connman.Error.AlreadyDisabled"
386connman_technology_set_tethering(DBusConnection *con,
const char *technology,
bool on,
389 LOG_REGISTER_CONTEXT;
392 DBusMessage *rsp = 0;
393 const char *key =
"Tethering";
394 dbus_bool_t val = on;
396 rsp = umdbus_blocking_call(con,
399 CONNMAN_TECH_INTERFACE,
402 DBUS_TYPE_STRING, &key,
404 DBUS_TYPE_BOOLEAN, &val,
409 if( !g_strcmp0(err->name, CONNMAN_ERROR_ALREADY_ENABLED) )
413 if( !g_strcmp0(err->name, CONNMAN_ERROR_ALREADY_DISABLED) )
416 log_err(
"%s.%s method call failed: %s: %s",
417 CONNMAN_TECH_INTERFACE,
"SetProperty",
418 err->name, err->message);
423 log_debug(
"%s tethering %s", technology, on ?
"on" :
"off");
424 dbus_error_free(err);
429 dbus_message_unref(rsp);
447connman_manager_get_service_path(DBusConnection *con,
const char *type)
449 LOG_REGISTER_CONTEXT;
452 DBusError err = DBUS_ERROR_INIT;
453 DBusMessage *rsp = 0;
455 rsp = umdbus_blocking_call(con,
458 "net.connman.Manager",
466 DBusMessageIter body;
467 if( umdbus_parser_init(&body, rsp) ) {
469 DBusMessageIter array_of_structs;
470 if( umdbus_parser_get_array(&body, &array_of_structs) ) {
472 DBusMessageIter astruct;
473 while( umdbus_parser_get_struct(&array_of_structs, &astruct) ) {
475 const char *
object = 0;
476 if( !umdbus_parser_get_object(&astruct, &
object) )
478 DBusMessageIter array_of_entries;
479 if( !umdbus_parser_get_array(&astruct, &array_of_entries) )
482 DBusMessageIter entry;
483 while( umdbus_parser_get_entry(&array_of_entries, &entry) ) {
486 if( !umdbus_parser_get_string(&entry, &key) )
488 if( strcmp(key,
"Type") )
491 if( !umdbus_parser_get_variant(&entry, &var) )
493 const char *value = 0;
494 if( !umdbus_parser_get_string(&var, &value) )
496 if( strcmp(value, type) )
498 service = g_strdup(
object);
507 dbus_message_unref(rsp);
509 dbus_error_free(&err);
511 log_warning(
"%s service = %s", type, service ?:
"n/a");
525connman_service_get_connection_data(DBusConnection *con,
529 LOG_REGISTER_CONTEXT;
532 DBusMessage *rsp = NULL;
533 DBusError err = DBUS_ERROR_INIT;
535 log_debug(
"Filling in dns data");
537 rsp = umdbus_blocking_call(con,
540 "net.connman.Service",
547 const char *dns1 = 0;
548 const char *dns2 = 0;
549 const char *state = 0;
550 const char *
interface = 0;
552 DBusMessageIter body;
553 if( umdbus_parser_init(&body, rsp) ) {
555 DBusMessageIter array_of_entries;
556 if( umdbus_parser_get_array(&body, &array_of_entries) ) {
558 DBusMessageIter entry;
559 while( umdbus_parser_get_entry(&array_of_entries, &entry) ) {
562 if( !umdbus_parser_get_string(&entry, &key) )
565 if( !umdbus_parser_get_variant(&entry, &var) )
568 if( !strcmp(key,
"Nameservers"))
570 DBusMessageIter array_of_strings;
571 if( umdbus_parser_get_array(&var, &array_of_strings) ) {
573 if( !umdbus_parser_at_end(&array_of_strings) )
574 umdbus_parser_get_string(&array_of_strings, &dns1);
575 if( !umdbus_parser_at_end(&array_of_strings) )
576 umdbus_parser_get_string(&array_of_strings, &dns2);
579 else if( !strcmp(key,
"State"))
581 umdbus_parser_get_string(&var, &state);
583 else if( !strcmp(key,
"Ethernet"))
585 DBusMessageIter array_of_en_entries;
586 if( umdbus_parser_get_array(&var, &array_of_en_entries) ) {
587 DBusMessageIter en_entry;
588 while( umdbus_parser_get_entry(&array_of_en_entries, &en_entry) ) {
589 const char *en_key = 0;
590 if( !umdbus_parser_get_string(&en_entry, &en_key) )
592 if( strcmp(en_key,
"Interface") )
594 DBusMessageIter en_var;
595 if( umdbus_parser_get_variant(&en_entry, &en_var) )
596 umdbus_parser_get_string(&en_var, &interface);
604 bool connected = (!g_strcmp0(state,
"ready") ||
605 !g_strcmp0(state,
"online"));
607 log_debug(
"state = %s", state ?:
"n/a");
608 log_debug(
"connected = %s", connected ?
"true" :
"false");
609 log_debug(
"interface = %s", interface ?:
"n/a");
610 log_debug(
"dns1 = %s", dns1 ?:
"n/a");
611 log_debug(
"dns2 = %s", dns2 ?:
"n/a");
613 if( !dns1 || !interface || !connected )
616 ipforward_data_set_dns1(ipforward, dns1);
617 ipforward_data_set_dns2(ipforward, dns2 ?: dns1);
618 ipforward_data_set_nat_interface(ipforward, interface);
624 dbus_message_unref(rsp);
626 dbus_error_free(&err);
644 LOG_REGISTER_CONTEXT;
647 DBusConnection *con = 0;
651 if( !(con = umdbus_get_connection()) )
655 if( !(cellular = connman_manager_get_service_path(con,
"cellular")) )
656 log_warning(
"no sellular service");
657 else if( connman_service_get_connection_data(con, cellular, ipforward) )
661 if( !(wifi = connman_manager_get_service_path(con,
"wifi")) )
662 log_warning(
"no wifi service");
663 else if( connman_service_get_connection_data(con, wifi, ipforward) )
674 log_warning(
"no connection data");
676 log_debug(
"got connection data");
682 dbus_connection_unref(con);
695connman_set_tethering(
const char *technology,
bool on)
697 LOG_REGISTER_CONTEXT;
700 DBusError err = DBUS_ERROR_INIT;
701 DBusConnection *con = 0;
703 if( !(con = umdbus_get_connection()) )
706 res = connman_technology_set_tethering(con, technology, on, &err);
709 dbus_error_free(&err);
712 dbus_connection_unref(con);
714 log_debug(
"set tethering(%s) = %s -> %s", technology,
715 on ?
"on" :
"off", res ?
"ack" :
"nak");
733 LOG_REGISTER_CONTEXT;
735 static const char path[] =
"/etc/resolv.conf";
742 if( !(file = fopen(path,
"r")) ) {
743 log_warning(
"%s: can't open for reading: %m", path);
748 while( count < 2 && getline(&buff, &size, file) >= 0 ) {
750 if( strchr(
"#\n", *buff) )
753 gchar **tokens = g_strsplit(buff,
" ", 3);
754 if( !tokens || !tokens[0] || !tokens[1] ) {
757 else if( !g_strcmp0(tokens[0],
"nameserver") ) {
759 g_strstrip(tokens[1]);
761 ipforward_data_set_dns1(ipforward, tokens[1]);
763 ipforward_data_set_dns2(ipforward, tokens[1]);
769 log_warning(
"%s: no nameserver lines found", path);
777 ipforward_data_set_dns2(ipforward, ipforward->
dns1);
800network_interface_exists(
char *interface)
802 LOG_REGISTER_CONTEXT;
809 snprintf(path,
sizeof path,
"/sys/class/net/%s", interface);
810 ack = (access(path, F_OK) == 0);
825 LOG_REGISTER_CONTEXT;
827 gchar *
interface = g_strdup(data->cached_interface);
830 log_warning(
"mode %s: network interface not specified",
833 else if( !network_interface_exists(interface) ) {
834 log_warning(
"mode %s: network interface %s does not exist",
836 g_free(interface),
interface = NULL;
849network_get_nat_interface(
const modedata_t *data)
851 LOG_REGISTER_CONTEXT;
853 gchar *
interface = g_strdup(data->cached_nat_interface);
856 log_warning(
"mode %s: network nat interface not specified",
859 else if( !network_interface_exists(interface) ) {
860 log_warning(
"mode %s: network nat interface %s does not exist",
862 g_free(interface),
interface = NULL;
877 LOG_REGISTER_CONTEXT;
881 log_warning(
"mode %s: network ip address not specified",
897 LOG_REGISTER_CONTEXT;
902 log_warning(
"mode %s: network netmask not specified",
920 LOG_REGISTER_CONTEXT;
924 char *nat_interface = 0;
928 if( !(interface = network_get_interface(data)) )
931 nat_interface = network_get_nat_interface(data);
932 if( !nat_interface ) {
934 log_debug(
"No nat interface available!");
940 write_to_file(
"/proc/sys/net/ipv4/ip_forward",
"1");
942 snprintf(command,
sizeof command,
"/sbin/iptables -t nat -A POSTROUTING -o %s -j MASQUERADE", nat_interface);
943 common_system(command);
945 snprintf(command,
sizeof command,
"/sbin/iptables -A FORWARD -i %s -o %s -m state --state RELATED,ESTABLISHED -j ACCEPT", nat_interface, interface);
946 common_system(command);
948 snprintf(command,
sizeof command,
"/sbin/iptables -A FORWARD -i %s -o %s -j ACCEPT", interface, nat_interface);
949 common_system(command);
951 log_debug(
"ipforwarding success!");
964network_cleanup_ip_forwarding(
void)
966 LOG_REGISTER_CONTEXT;
968 write_to_file(
"/proc/sys/net/ipv4/ip_forward",
"0");
970 common_system(
"/sbin/iptables -F FORWARD");
978network_check_udhcpd_symlink(
void)
980 LOG_REGISTER_CONTEXT;
983 char dest[
sizeof UDHCP_CONFIG_PATH + 1];
984 ssize_t rc = readlink(UDHCP_CONFIG_LINK, dest,
sizeof dest - 1);
987 if( errno != ENOENT )
988 log_err(
"%s: can't read symlink: %m", UDHCP_CONFIG_LINK);
990 else if( (
size_t)rc <
sizeof dest ) {
992 if( strcmp(dest, UDHCP_CONFIG_PATH) )
993 log_warning(
"%s: symlink is invalid", UDHCP_CONFIG_LINK);
1010 LOG_REGISTER_CONTEXT;
1016 char *
interface = 0;
1020 if( !(interface = network_get_interface(data)) ) {
1021 log_err(
"no network interface");
1026 if( !(ip = network_get_ip(data)) ) {
1027 log_err(
"no network address");
1032 if( sscanf(ip,
"%*d.%*d.%*d%n.%*d", &len) == EOF || ip[len] !=
'.') {
1033 log_err(
"malformed network address: %s", ip);
1037 if( !(netmask = network_get_netmask(data)) ) {
1038 log_err(
"no network address mask");
1043 if( mkdir(UDHCP_CONFIG_DIR, 0775) == -1 && errno != EEXIST ) {
1044 log_warning(
"%s: can't create directory: %m", UDHCP_CONFIG_DIR);
1048 if( !(conffile = fopen(UDHCP_CONFIG_PATH,
"w")) ) {
1049 log_err(
"%s: can't open for writing: %m", UDHCP_CONFIG_PATH);
1053 fprintf(conffile,
"start\t%.*s.1\n", len, ip);
1054 fprintf(conffile,
"end\t%.*s.15\n", len, ip);
1055 fprintf(conffile,
"interface\t%s\n", interface);
1056 fprintf(conffile,
"option\tsubnet\t%s\n", netmask);
1057 fprintf(conffile,
"option\tlease\t3600\n");
1058 fprintf(conffile,
"max_leases\t15\n");
1060 if(ipforward != NULL)
1062 if( !ipforward->
dns1 || !ipforward->
dns2 )
1063 log_debug(
"No dns info!");
1065 fprintf(conffile,
"opt\tdns\t%s %s\n", ipforward->
dns1, ipforward->
dns2);
1066 fprintf(conffile,
"opt\trouter\t%s\n", ip);
1069 fclose(conffile), conffile = 0;
1072 if( network_check_udhcpd_symlink() != 0 ) {
1073 if( unlink(UDHCP_CONFIG_LINK) == -1 && errno != ENOENT )
1074 log_warning(
"%s: can't remove invalid config: %m", UDHCP_CONFIG_LINK);
1076 if( symlink(UDHCP_CONFIG_PATH, UDHCP_CONFIG_LINK) == -1 ) {
1077 log_err(
"%s: can't create symlink to %s: %m",
1078 UDHCP_CONFIG_LINK, UDHCP_CONFIG_PATH);
1081 log_debug(
"%s: symlink to %s created",
1082 UDHCP_CONFIG_LINK, UDHCP_CONFIG_PATH);
1112 LOG_REGISTER_CONTEXT;
1122 if( ofono_get_roaming_status() ) {
1124 if(config_is_roaming_not_allowed())
1129 ipforward = ipforward_data_create();
1132 if( !connman_get_connection_data(ipforward) )
1134 log_debug(
"data connection not available from connman!");
1139 if( !legacy_get_connection_data(ipforward) ) {
1140 log_debug(
"data connection not available in resolv.conf!");
1147 ret = network_write_udhcpd_config(data, ipforward);
1149 if( ret == 0 && data->
nat )
1150 ret = network_setup_ip_forwarding(data, ipforward);
1153 ipforward_data_delete(ipforward);
1167 LOG_REGISTER_CONTEXT;
1172 gchar *
interface = 0;
1179 if( !(interface = network_get_interface(data)) ) {
1180 log_err(
"no network interface");
1184 if( !(address = network_get_ip(data)) ) {
1185 log_err(
"no network address");
1189 if( !(netmask = network_get_netmask(data)) ) {
1190 log_err(
"no network address mask");
1196 log_warning(
"no network gateway");
1199 if( !strcmp(address,
"dhcp") )
1201 snprintf(command,
sizeof command,
"dhclient -d %s", interface);
1202 if( common_system(command) != 0 ) {
1203 snprintf(command,
sizeof command,
"udhcpc -i %s", interface);
1204 if( common_system(command) != 0 )
1210 snprintf(command,
sizeof command,
"ifconfig %s %s netmask %s", interface, address, netmask);
1211 if( common_system(command) != 0 )
1218 snprintf(command,
sizeof command,
"route add default gw %s", gateway);
1219 if( common_system(command) != 0 )
1226 log_debug(
"iface=%s addr=%s mask=%s gw=%s -> %s",
1231 ret ?
"failure" :
"success");
1247 LOG_REGISTER_CONTEXT;
1249 gchar *
interface = network_get_interface(data);
1253 log_debug(
"iface=%s nat=%d", interface ?:
"n/a", data->
nat);
1256 snprintf(command,
sizeof command,
"ifconfig %s down", interface);
1257 common_system(command);
1262 network_cleanup_ip_forwarding();
1274 LOG_REGISTER_CONTEXT;
1283 modedata_cache_settings(data);
char * config_get_network_setting(const char *config)
cable_state_t control_get_cable_state(void)
void modedata_free(modedata_t *self)
struct modedata_t modedata_t
void network_update(void)
int network_up(const modedata_t *data)
struct ipforward_data_t ipforward_data_t
int network_update_udhcpd_config(const modedata_t *data)
void network_down(const modedata_t *data)
modedata_t * worker_dup_usb_mode_data(void)
void worker_set_usb_mode_data(const modedata_t *data)