1 /**************************************************
3 module for Controling ipfw
5 Copyright (C) 1999 Yoshiaki Watanabe
6 Modfied 2005 Katsuhiko Eguchi
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 Email: watanaby@is.saga-u.ac.jp
23 **************************************************/
25 #include "opengatesrv.h"
27 char ruleNumber4[WORDMAXLN]; /* ipfw rule number in string form */
29 int getRuleNumber4(char *clientAddr4);
30 int GetRuleNumber4(char *clientAddr4);
32 static void sigFunc(int signo);
34 /******************************************************************/
35 /* open gate for clientAddr4 (nnn.nnn.nnn.nnn) */
36 /******************************************************************/
37 int openClientGate4(char *clientAddr4, char *userid, char *macAddr4, char *userProperty)
45 Sigfunc *defaultSigFunc;
47 /* exclusive exec of ipfw to avoid overlapped rule number */
51 fd=Open(LOCKFILE, O_RDWR|O_CREAT,
52 S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
54 defaultSigFunc=Signal(SIGALRM, sigFunc);
59 Signal(SIGALRM, defaultSigFunc);
62 /**** read rules ****/
63 if((retNum=GetRuleNumber4(clientAddr4))<0){
64 /* fail then unlock */
67 if(retNum==-3) return 1; /* ipfw returns abnormal response */
68 else return -1; /* already opened or rules are full */
71 /**** write rules ****/
73 if(GetUseFwScript()==1){
74 /********** use perl script to control firewall ************/
77 if((retFork=Fork())==0){
79 if(execl(GetFwScriptPath(),GetFwScript(),IPFWPATH,ruleNumber4,clientAddr4,
80 userid,macAddr4,userProperty,(char *)0)==-1){
81 err_quit("ERR in comm-ipfw: execl error no= %d", errno);
88 err_msg("ERR in comm-ipfw: fork error no= %d", errno);
95 if(ret) err_msg("ERR in comm-ipfw: child process returns error %d", ret);
98 err_msg("ERR in comm-ipfw: child process does not exited by exit call");
101 Unlock(fd); /* lock is not necessary in following exec */
102 Close(fd); /* because reserved number is used */
105 /********** direct control of firewall **********************/
106 /********** add outgoing ipfw rule for the client *************/
108 if((retFork=Fork())==0){
110 if(execl(IPFWPATH,"ipfw","-q","add",ruleNumber4,"allow","ip",
111 "from",clientAddr4,"to","any",(char *)0)==-1){
112 err_quit("ERR in comm-ipfw: execl error no= %d", errno);
119 err_msg("ERR in comm-ipfw: fork error no= %d", errno);
126 if(ret) err_msg("ERR in comm-ipfw: child process returns error %d", ret);
129 err_msg("ERR in comm-ipfw: child process does not exited by exit call");
132 Unlock(fd); /* lock is not necessary in following exec */
133 Close(fd); /* because reserved number is used */
135 /********** add incoming ipfw rule for the client *************/
137 if((retFork=Fork())==0){
139 if(execl(IPFWPATH,"ipfw","-q","add",ruleNumber4,"allow","ip",
140 "from","any","to",clientAddr4,(char *)0)==-1){
141 err_quit("ERR in comm-ipfw: execl error no= %d", errno);
148 err_msg("ERR in comm-ipfw: fork error no= %d", errno);
155 if(ret) err_msg("ERR in comm-ipfw: child process returns error %d", ret);
158 err_msg("ERR in comm-ipfw: child process does not exited by exit call");
166 /******************************************************************/
167 /* close gate for clientAddr (nnn.nnn.nnn.nnn) */
168 /******************************************************************/
169 void closeClientGate4(struct clientAddr *pClientAddr, char *userid, char *macAddr4)
176 /********** del ipfw rule for the client *************/
181 if(execl(IPFWPATH,"ipfw","del",pClientAddr->ruleNumber,(char *)0)==-1){
182 err_quit("ERR in comm-ipfw: execl error no= %d", errno);
189 timeOut = time(NULL);
190 time_l=difftime(timeOut,pClientAddr->timeIn);
192 min=(time_l-hour*60*60)/60;
193 sec=(time_l-hour*60*60-min*60);
194 err_msg("CLOS: user %s from %s at %s ( %02d:%02d:%02d )",
195 userid, pClientAddr->IpAddr, macAddr4, hour,min,sec);
201 /**************************************/
202 /* get unused ipfw rule number */
203 /* error if addr is already in rules */
204 /**************************************/
205 int getRuleNumber4(char *clientAddr4)
208 int piperead_fd,pipewrite_fd;
209 int stdin_fd=0,stdout_fd=1,stderr_fd=2;
212 int num,newNum,readinNum;
222 err_msg("ERR in comm-ipfw: Cannot create pipe for ipfw\n");
232 /* connect pipeout to stdout & strerr */
244 if(execl(IPFWPATH,"ipfw","list",(char *)0) == -1){
245 err_quit("ERR in comm-ipfw: execlp error no= %d", errno);
254 /* search unused rule number in the list read from pipe */
255 /* check duplication of clientAddr to existing rules */
261 /* get rule range from config */
262 ipfwmin=GetIpfwMin();
263 ipfwmax=GetIpfwMax();
264 ipfwinterval=GetIpfwInterval();
266 for(num=ipfwmin;num<=ipfwmax;num+=ipfwinterval){
268 /* skip rules smaller than num */
269 while(readinNum<num){
270 if(Readln(piperead_fd, buf, BUFFMAXLN-1)==0){
275 if( sscanf(buf, "%d", &readinNum) !=1 ){
276 err_msg("ERR in comm-ipfw: abnormal ipfw response[ %s ]", buf);
281 /* if get abnormal response, error is returned */
287 /* if no rules larger or equal to num, then search end */
289 if(newNum<0) newNum=num;
293 /* if num is already used, then check dup and go to next search */
295 /* if clientAddr is found in rule, then err exit */
296 if(((p=(char*)strstr(buf+1,clientAddr4))!=NULL)
298 && !isalnum(*(p+strlen(clientAddr4)))){
299 err_msg("ERR in comm-ipfw: overlapped request from %s", clientAddr4);
306 /* num is not used */
307 if(newNum<0)newNum=num;
308 if(readinNum>ipfwmax)break;
318 err_msg("ERR in comm-ipfw: cannot get unused ipfw number");
321 snprintf(ruleNumber4, WORDMAXLN, "%d", newNum); /* to string */
326 /****************************************/
327 /* get packet count from ipfw and ip6fw */
328 /****************************************/
329 int getPacketCount(struct clientAddr *pClientAddr)
332 struct clientAddr *pNow;
337 packets+=GetPacketCount4(pNow->ruleNumber);
338 }else if(pNow->type==6){
339 packets+=GetPacketCount6(pNow->ruleNumber);
347 /*******************************/
348 /* get packet count from ipfw */
349 /*******************************/
350 int getPacketCount4(char *ruleNumber)
353 int piperead_fd,pipewrite_fd;
354 int stdin_fd=0,stdout_fd=1;
358 int packets,packetsSum;
362 err_msg("ERR in comm-ipfw: Cannot create pipe for ipfw\n");
372 /* connect pipeout to stdout */
382 if(execl(IPFWPATH,"ipfw","-a","list",ruleNumber,(char *)0) == -1){
383 err_quit("ERR in comm-ipfw: execl error no= %d", errno);
391 /* search unused number in the list read from pipe */
395 while(Readln(piperead_fd, buf, BUFFMAXLN-1)!=0){
396 sscanf(buf, "%d %d", &rule, &packets); /* get packet count */
410 /**********************************************/
411 /* function called by signal int */
412 /**********************************************/
413 static void sigFunc(int signo)
418 /**********************************************/
419 /**********************************************/
420 int GetRuleNumber4(char *clientAddr4)
424 if(DEBUG) err_msg("DEBUG:=>getRuleNumber4(%s)",clientAddr4);
425 ret=getRuleNumber4(clientAddr4);
426 if(DEBUG) err_msg("DEBUG:(%d)<=getRuleNumber4( )",ret);
431 int OpenClientGate4(char *clientAddr4, char *userid, char *macAddr4, char *userProperty)
435 if(DEBUG) err_msg("DEBUG:=>openClientGate(%s,%s,%s,%s)",clientAddr4,userid,macAddr4,userProperty);
436 ret=openClientGate4(clientAddr4, userid, macAddr4, userProperty);
437 if(DEBUG) err_msg("DEBUG:(%d)<=openClientGate4( )",ret);
442 void CloseClientGate4(struct clientAddr *pClientAddr, char *userid, char *macAddr4)
444 if(DEBUG) err_msg("DEBUG:=>closeClientGate4(%p,%s,%s)",pClientAddr,userid,macAddr4);
445 closeClientGate4(pClientAddr,userid,macAddr4);
446 if(DEBUG) err_msg("DEBUG:<=closeClientGate4( )");
449 int GetPacketCount(struct clientAddr *pClientAddr)
453 if(DEBUG) err_msg("DEBUG:=>getPacketCount(%p)",pClientAddr);
454 ret=getPacketCount(pClientAddr);
455 if(DEBUG) err_msg("DEBUG:(%d)<=getPacketCount( )",ret);
460 int GetPacketCount4(char *ruleNumber)
464 if(DEBUG) err_msg("DEBUG:=>getPacketCount4(%s)",ruleNumber);
465 ret=getPacketCount4(ruleNumber);
466 if(DEBUG) err_msg("DEBUG:(%d)<=getPacketCount4( )",ret);