8990f811684e61e9b59e62257603d010e03f8caf
[rahunas] / src / rh-task-iptables.c
1 /**
2  * RahuNAS task bandwidth implementation 
3  * Author: Neutron Soutmun <neo.neutron@gmail.com>
4  * Date:   2008-11-20
5  */
6
7 #include <stdlib.h>
8 #include <syslog.h>
9 #include <sys/types.h>
10 #include <unistd.h>
11 #include <sys/wait.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14
15 #include "rahunasd.h"
16 #include "rh-task.h"
17 #include "rh-utils.h"
18
19 int iptables_exec(struct vserver *vs, char *const args[])
20 {
21   pid_t ws;
22   pid_t pid;
23   int status;
24   int exec_pipe[2];
25   char buffer[150];
26   char *endline = NULL;
27   int ret = 0;
28   int fd = 0;
29   int i = 0;
30   char *env[22];
31   int env_size = (sizeof (env) / sizeof (char *));
32
33   env[0]  = g_strdup("ENV_OVERRIDE=yes");
34   env[1]  = g_strdup_printf("SETNAME=%s", vs->vserver_config->vserver_name);
35   env[2]  = g_strdup_printf("VSERVER_ID=%d", vs->vserver_config->vserver_id);
36   env[3]  = g_strdup_printf("DEV_EXTERNAL=%s",vs->vserver_config->dev_external);
37   env[4]  = g_strdup_printf("DEV_INTERNAL=%s",vs->vserver_config->dev_internal);
38   env[5]  = g_strdup_printf("BRIDGE=%s", vs->vserver_config->bridge);
39   env[6]  = g_strdup_printf("MASQUERADE=%s", vs->vserver_config->masquerade);
40   env[7]  = g_strdup_printf("IGNORE_MAC=%s", vs->vserver_config->ignore_mac);
41   env[8]  = g_strdup_printf("VSERVER_IP=%s", vs->vserver_config->vserver_ip);
42   env[9]  = g_strdup_printf("CLIENTS=%s", vs->vserver_config->clients);
43   env[10] = g_strdup_printf("EXCLUDED=%s", vs->vserver_config->excluded);
44   env[11] = g_strdup_printf("DNS=%s", vs->vserver_config->dns);
45   env[12] = g_strdup_printf("SSH=%s", vs->vserver_config->ssh);
46   env[13] = g_strdup_printf("PROXY=%s", vs->vserver_config->proxy);
47   env[14] = g_strdup_printf("PROXY_HOST=%s", vs->vserver_config->proxy_host);
48   env[15] = g_strdup_printf("PROXY_PORT=%s", vs->vserver_config->proxy_port);
49   env[16] = g_strdup_printf("BITTORRENT=%s", vs->vserver_config->bittorrent);
50   env[17] = g_strdup_printf("BITTORRENT_ALLOW=%s", 
51                             vs->vserver_config->bittorrent_allow);
52   env[18] = g_strdup_printf("VSERVER_PORTS_ALLOW=%s", 
53                             vs->vserver_config->vserver_ports_allow);
54   env[19] = g_strdup_printf("VSERVER_PORTS_INTERCEPT=%s", 
55                             vs->vserver_config->vserver_ports_intercept);
56   env[20] = g_strdup_printf("KEEP_SET=%s",
57                             vs->vserver_config->init_flag == VS_RELOAD ?
58                             "yes" : "no");
59   env[21] = (char *) 0;
60
61   for (i = 0; i < env_size; i++) {
62     if (env[i] != NULL) 
63       DP("%s", env[i]);
64   }
65   
66   memset(buffer, '\0', sizeof(buffer));
67
68   if (pipe(exec_pipe) == -1) {
69     logmsg(RH_LOG_ERROR, "Error: pipe()");
70     return -1;
71   }
72   DP("pipe0=%d,pipe1=%d", exec_pipe[0], exec_pipe[1]);
73
74   pid = vfork();
75   dup2(exec_pipe[1], STDOUT_FILENO);
76
77   if (pid == 0) {
78     // Child
79     execve(RAHUNAS_FIREWALL_WRAPPER, args, env);
80   } else if (pid < 0) {
81     // Fork error
82     logmsg(RH_LOG_ERROR, "Error: vfork()"); 
83     ret = -1;
84   } else {
85     // Parent
86     ws = waitpid(pid, &status, 0);
87
88     DP("IPTables: Return (%d)", WEXITSTATUS(status));
89
90     if (WIFEXITED(status)) {
91       ret = WEXITSTATUS(status);
92     } else {
93       ret = -1;
94     } 
95   }
96
97   close(exec_pipe[0]);
98   close(exec_pipe[1]);
99
100  
101   for (i = 0; i < env_size; i++) {
102     g_free(env[i]);
103   } 
104   
105   return ret;
106 }
107
108 int iptables_start(struct vserver *vs)
109 {
110   char *args[3];
111
112   DP("IPTables: start");
113
114   args[0] = RAHUNAS_FIREWALL_WRAPPER;
115   args[1] = "start-config";
116   args[2] = (char *) 0;
117
118   return iptables_exec(vs, args);
119 }
120
121 int iptables_stop(struct vserver *vs)
122 {
123   char *args[3];
124
125   DP("IPTables: stop");
126
127   args[0] = RAHUNAS_FIREWALL_WRAPPER;
128   args[1] = "stop-config";
129   args[2] = (char *) 0;
130
131   return iptables_exec(vs, args);
132 }
133
134 /* Start service task */
135 static int startservice ()
136 {
137   return 0;
138 }
139
140 /* Stop service task */
141 static int stopservice  ()
142 {
143   return 0;
144 }
145
146 /* Initialize */
147 static void init (struct vserver *vs)
148 {
149   logmsg(RH_LOG_NORMAL, "[%s] Task IPTABLES initialize..", 
150          vs->vserver_config->vserver_name);  
151
152   iptables_start(vs);
153 }
154
155 /* Cleanup */
156 static int cleanup (struct vserver *vs)
157 {
158   logmsg(RH_LOG_NORMAL, "[%s] Task IPTABLES cleanup..",
159          vs->vserver_config->vserver_name);  
160
161   iptables_stop(vs);
162 }
163
164 /* Start session task */
165 static int startsess (struct vserver *vs, struct task_req *req)
166 {
167   /* Do nothing */
168   return 0;
169 }
170
171 /* Stop session task */
172 static int stopsess  (struct vserver *vs, struct task_req *req)
173 {
174   /* Do nothing */
175   return 0; 
176 }
177
178 /* Commit start session task */
179 static int commitstartsess (struct vserver *vs, struct task_req *req)
180 {
181   /* Do nothing or need to implement */
182 }
183
184 /* Commit stop session task */
185 static int commitstopsess  (struct vserver *vs, struct task_req *req)
186 {
187   /* Do nothing or need to implement */
188 }
189
190 /* Rollback start session task */
191 static int rollbackstartsess (struct vserver *vs, struct task_req *req)
192 {
193   /* Do nothing or need to implement */
194 }
195
196 /* Rollback stop session task */
197 static int rollbackstopsess  (struct vserver *vs, struct task_req *req)
198 {
199   /* Do nothing or need to implement */
200 }
201
202 static struct task taskiptables = {
203   .taskname = "IPTABLES",
204   .taskprio = 50,
205   .init = &init,
206   .cleanup = &cleanup,
207   .startservice = &startservice,
208   .stopservice = &stopservice,
209   .startsess = &startsess,
210   .stopsess = &stopsess,
211   .commitstartsess = &commitstartsess,
212   .commitstopsess = &commitstopsess,
213   .rollbackstartsess = &rollbackstartsess,
214   .rollbackstopsess = &rollbackstopsess,
215 };
216
217 void rh_task_iptables_reg(struct main_server *ms) {
218   task_register(ms, &taskiptables);
219 }