diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gprs.c | 49 |
1 files changed, 49 insertions, 0 deletions
@@ -30,6 +30,8 @@ #include <sys/ioctl.h> #include <sys/socket.h> #include <net/if.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <glib.h> #include <gdbus.h> @@ -365,6 +367,47 @@ done: close(sk); } +static void pri_setaddr(const char *interface, const char *address) +{ + struct ifreq ifr; + struct sockaddr_in addr; + int sk; + + if (!interface) + return; + + sk = socket(PF_INET, SOCK_DGRAM, 0); + if (sk < 0) + return; + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, interface, IFNAMSIZ); + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = address ? inet_addr(address) : INADDR_ANY; + memcpy(&ifr.ifr_addr, &addr, sizeof(ifr.ifr_addr)); + + if (ioctl(sk, SIOCSIFADDR, &ifr) < 0) { + ofono_error("Failed to set interface address"); + goto done; + } + + if (!address) + goto done; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr("255.255.255.255"); + memcpy(&ifr.ifr_netmask, &addr, sizeof(ifr.ifr_netmask)); + + if (ioctl(sk, SIOCSIFNETMASK, &ifr) < 0) + ofono_error("Failed to set interface netmask"); + +done: + close(sk); +} + static void pri_reset_context_settings(struct pri_context *ctx) { char *interface; @@ -380,6 +423,9 @@ static void pri_reset_context_settings(struct pri_context *ctx) pri_context_signal_settings(ctx); + if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) + pri_setaddr(interface, NULL); + pri_ifupdown(interface, FALSE); g_free(interface); @@ -412,6 +458,9 @@ static void pri_update_context_settings(struct pri_context *ctx, pri_ifupdown(interface, TRUE); + if (ctx->type == OFONO_GPRS_CONTEXT_TYPE_MMS) + pri_setaddr(interface, ip); + pri_context_signal_settings(ctx); } |