Bug 960865 - Part 3: modify nat command to support setting rules for secondary routing table. r=vchang
authorJessica Jong <jjong@mozilla.com>
Fri, 28 Feb 2014 18:05:02 +0800
changeset 171637 df6bbad379aa4f8efcb5c4c4efc5db098be29a42
parent 171636 4307f548abf1d075938ccfe3c59f41fd1059c622
child 171638 56e53b005ea7aea246ecded4af2fbe033594ed35
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersvchang
bugs960865
milestone30.0a1
Bug 960865 - Part 3: modify nat command to support setting rules for secondary routing table. r=vchang
dom/system/gonk/NetworkUtils.cpp
--- a/dom/system/gonk/NetworkUtils.cpp
+++ b/dom/system/gonk/NetworkUtils.cpp
@@ -218,16 +218,34 @@ static uint32_t makeMask(const uint32_t 
   uint32_t mask = 0;
   for (uint32_t i = 0; i < prefixLength; ++i) {
     mask |= (0x80000000 >> i);
   }
   return ntohl(mask);
 }
 
 /**
+ * Helper function to get the network part of an ip from prefix.
+ * param ip must be in network byte order.
+ */
+static char* getNetworkAddr(const uint32_t ip, const uint32_t prefix)
+{
+  uint32_t mask = 0, subnet = 0;
+
+  mask = ~mask << (32 - prefix);
+  mask = htonl(mask);
+  subnet = ip & mask;
+
+  struct in_addr addr;
+  addr.s_addr = subnet;
+
+  return inet_ntoa(addr);
+}
+
+/**
  * Helper function to split string by seperator, store split result as an nsTArray.
  */
 static void split(char* str, const char* sep, nsTArray<nsCString>& result)
 {
   char *s = strtok(str, sep);
   while (s != nullptr) {
     result.AppendElement(s);
     s = strtok(nullptr, sep);
@@ -736,27 +754,52 @@ void NetworkUtils::setDnsForwarders(Comm
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::enableNat(CommandChain* aChain,
                              CommandCallback aCallback,
                              NetworkResultOptions& aResult)
 {
   char command[MAX_COMMAND_SIZE];
-  snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0", GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
+
+  if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) {
+    uint32_t prefix = atoi(GET_CHAR(mPrefix));
+    uint32_t ip = inet_addr(GET_CHAR(mIp));
+    char* networkAddr = getNetworkAddr(ip, prefix);
+
+    // address/prefix will only take effect when secondary routing table exists.
+    snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 1 %s/%s",
+      GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr,
+      GET_CHAR(mPrefix));
+  } else {
+    snprintf(command, MAX_COMMAND_SIZE - 1, "nat enable %s %s 0",
+      GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
+  }
 
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::disableNat(CommandChain* aChain,
                               CommandCallback aCallback,
                               NetworkResultOptions& aResult)
 {
   char command[MAX_COMMAND_SIZE];
-  snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0", GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
+
+  if (!GET_FIELD(mIp).IsEmpty() && !GET_FIELD(mPrefix).IsEmpty()) {
+    uint32_t prefix = atoi(GET_CHAR(mPrefix));
+    uint32_t ip = inet_addr(GET_CHAR(mIp));
+    char* networkAddr = getNetworkAddr(ip, prefix);
+
+    snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 1 %s/%s",
+      GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname), networkAddr,
+      GET_CHAR(mPrefix));
+  } else {
+    snprintf(command, MAX_COMMAND_SIZE - 1, "nat disable %s %s 0",
+      GET_CHAR(mInternalIfname), GET_CHAR(mExternalIfname));
+  }
 
   doCommand(command, aChain, aCallback);
 }
 
 void NetworkUtils::setDefaultInterface(CommandChain* aChain,
                                        CommandCallback aCallback,
                                        NetworkResultOptions& aResult)
 {