/**************************************************
OpengateM - MAC address authentication system 
 module for child process control 

 this module opens the network for the candidate of the user device.
 (this is used in opengatemchk).
 a child process opens net, sleeps while, and closes net automatically.
 independent process is employed to perform a series of processing surely.

Copyright (C) 2011 Opengate Project Team
Written by Yoshiaki Watanabe

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Email: watanaby@is.saga-u.ac.jp
**************************************************/

#include	"opengatemmng.h"

int rule4=0;
int rule6=0;
char loadPath[BUFFMAXLN];

/**********************************************************/
/* start child process that open-net, sleep and close-net */
/**********************************************************/
int startChildProc(char* macAddress){

  int dummyfd[2];
  char ipv4[ADDRMAXLN];
  char ipv6[ADDRMAXLN];
  int pid;

  /* fork child process */
  if((pid=fork())==-1){
    err_msg("ERR at %s#%d: fork error",__FILE__,__LINE__);
    return -1;
  }

  /* parent process */
  else if(pid!=0){
    return pid;
  }

  /* child process */
  else{

    /* detach from server */
    Close(0);Close(1);Close(2);
    Pipe(dummyfd);      /* connect dummy pipe for stdin and out */

    /* get ipv4/ipv6 corresponding to the mac from db */
    GetIpFromMacCheckTable(macAddress, ipv4, ipv6);

    /* open firewall */
    if(!isNull(ipv4)) rule4=OpenClientGate(ipv4,FALSE,"temp","","");
    if(!isNull(ipv6)) rule6=OpenClientGate(ipv6,FALSE,"temp","","");
    
    /* save pid/ruleNumber to db */
    SavePidToMacCheckTable(macAddress, getpid(), rule4, rule6);

    /* at TERM signal is received, call closeExit */
    signalx(SIGTERM, closeExit);

    /* sleep a while */
    sleep(atoi(GetConfValue("OpenTimeout")));

    /* close firewall */
    if(rule4!=0) CloseClientGate(rule4);
    if(rule6!=0) CloseClientGate(rule6);    

    return 0;
  }
}

/***************************/
/* signal function         */
/***************************/
void closeExit(int signo){

    /* close firewall */
    if(rule4!=0) CloseClientGate(rule4);
    if(rule6!=0) CloseClientGate(rule6);    
    exit(0);
}

/*********************************/
/* stop child process            */
/*********************************/
int stopChildProc(char* macAddress){
  
  int pid;

  /* get pid/ruleNumber from db */
  GetPidFromMacCheckTable(macAddress, &pid, &rule4, &rule6);

  /* close firewall */
  if(rule4!=0) CloseClientGate(rule4);
  if(rule6!=0) CloseClientGate(rule6);    

  /* kill child process */
  kill(pid, SIGKILL);

  return TRUE;
}

/******************************/
/* save the program load path */
/******************************/
void saveLoadPath(char* argv0){
  strlcpy(loadPath, argv0, BUFFMAXLN);
}

/***********************************************/
/* get the program name extracted from argv[0] */
/***********************************************/
char* getProgramName(void){
  char* pCh;
  pCh = strrchr(loadPath, '/');
  if(isNull(pCh)) return loadPath;
  else return pCh+1;
}

/*********************************************
**********************************************/
int StartChildProc(char* macAddress){
  int ret;
  if(debug>1) err_msg("DEBUG:=>startChildProc(%s)",macAddress);
  ret=startChildProc(macAddress);
  if(debug>1) err_msg("DEBUG:(%d)<=startChildProc( )",ret);
  return ret;
}

int StopChildProc(char* macAddress){
  int ret;
  if(debug>1) err_msg("DEBUG:=>stopChildProc(%s)",macAddress);
  ret=stopChildProc(macAddress);
  if(debug>1) err_msg("DEBUG:(%d)<=stopChildProc( )",ret);
  return ret;
}

