OSDN Git Service

resolved conflicts for merge of e36a3a2f to jb-dev-plus-aosp
[android-x86/system-netd.git] / oem_iptables_hook.cpp
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <sys/types.h>
20 #include <sys/wait.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #define LOG_TAG "OemIptablesHook"
26 #include <cutils/log.h>
27 #include "NetdConstants.h"
28
29 extern "C" int system_nosh(const char *command);
30
31
32 static int runIptablesCmd(const char *cmd) {
33     char *buffer;
34     size_t len = strnlen(cmd, 255);
35     int res;
36
37     if (len == 255) {
38         ALOGE("command too long");
39         return -1;
40     }
41
42     asprintf(&buffer, "%s %s", IPTABLES_PATH, cmd);
43     res = system_nosh(buffer);
44     free(buffer);
45     return res;
46 }
47
48 static bool oemSetupHooks() {
49     // Order is important!
50     // -N to create the chain (no-op if already exist).
51     // -D to delete any pre-existing jump rule, to prevent dupes (no-op if doesn't exist)
52     // -I to insert our jump rule into the default chain
53
54     runIptablesCmd("-N oem_out");
55     runIptablesCmd("-D OUTPUT -j oem_out");
56     if (runIptablesCmd("-I OUTPUT -j oem_out"))
57         return false;
58
59     runIptablesCmd("-N oem_fwd");
60     runIptablesCmd("-D FORWARD -j oem_fwd");
61     if (runIptablesCmd("-I FORWARD -j oem_fwd"))
62         return false;
63
64     runIptablesCmd("-t nat -N oem_nat_pre");
65     runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre");
66     if (runIptablesCmd("-t nat -I PREROUTING -j oem_nat_pre"))
67         return false;
68
69     return true;
70 }
71
72 static bool oemCleanupHooks() {
73     // Order is important!
74     // -D to remove ref to the chain
75     // -F to empty the chain
76     // -X to delete the chain
77
78     runIptablesCmd("-D OUTPUT -j oem_out");
79     runIptablesCmd("-F oem_out");
80     runIptablesCmd("-X oem_out");
81
82     runIptablesCmd("-D FORWARD -j oem_fwd");
83     runIptablesCmd("-F oem_fwd");
84     runIptablesCmd("-X oem_fwd");
85
86     runIptablesCmd("-t nat -D PREROUTING -j oem_nat_pre");
87     runIptablesCmd("-t nat -F oem_nat_pre");
88     runIptablesCmd("-t nat -X oem_nat_pre");
89
90     return true;
91 }
92
93 static bool oemInitChains() {
94     int ret = system(OEM_SCRIPT_PATH);
95     if ((-1 == ret) || (0 != WEXITSTATUS(ret))) {
96         ALOGE("%s failed: %s", OEM_SCRIPT_PATH, strerror(errno));
97         oemCleanupHooks();
98         return false;
99     }
100     return true;
101 }
102
103
104 void setupOemIptablesHook() {
105     if (0 == access(OEM_SCRIPT_PATH, R_OK | X_OK)) {
106         // The call to oemCleanupHooks() is superfluous when done on bootup,
107         // but is needed for the case where netd has crashed/stopped and is
108         // restarted.
109         if (oemCleanupHooks() && oemSetupHooks() && oemInitChains()) {
110             ALOGI("OEM iptable hook installed.");
111         }
112     }
113 }