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