/**************************************************
OpengateM - a MAC address authentication system
daemon header file

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 <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/un.h>
#include <sys/select.h>
#include <poll.h>
#include <strings.h>
#include <sys/ioctl.h>
#include <sys/filio.h>
#include <sys/sockio.h>
#include <pthread.h>
#include <sys/socket.h>
#include <syslog.h>
#include <ctype.h>
#include <stdarg.h>
#include <sys/signal.h>
#include <regex.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/ethernet.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <limits.h>
#include <db.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
#include <sys/utsname.h>
#include <netdb.h>

typedef	void	Sigfunc(int);	/* for signal handlers */


/***************** constants ***********************/

/* Configuration file for opengate */ 
#define CONFIGFILE "/etc/opengate/opengatemd.conf"

#define ADDRMAXLN 128      /* maximum address string length */
#define USERMAXLN 128      /* maximum userid string length */
#define BUFFMAXLN 1024      /* maximum buffer string length */
#define WORDMAXLN 64       /* maximum word length */
#define FILTERMAXLN 128   /* pcap filter max length */

#define IPV6ADDRLN 16
#define IPV4ADDRLN 4
#define MACADDRLN 6

#define TRUE 1
#define FALSE 0
#define DENY   0
#define ACCEPT 1
#define ERROR -1

#define NONAT 0
#define NAT 1
#define ROUTER 2

#define AVOID_OVERLAP 0
#define ALLOW_OVERLAP 1

extern int debug;  /* debug status read from conf file */

/**********prototypes***************************************/

/* opengatemd.c */
void ShowHelp(char* procName);
int LockDaemonLockFile(void);
void Daemonize(void);
void KillDaemon(void);
void ReloadDaemon(void);
void terminateProg(int ret);

/* ipfw.c */
int OpenClientGate(char *macAddress, char* userId, char* extraId);
int GetRuleNumber(char *macAddress);
void CloseClientGate(int ruleMumber);
int GetPacketCount(int ruleNumber);
int CountRuleNumber(int ruleNumber);
int GetRuleTableFromIpfw(DB* ruleTable);
int IsMacAddressFoundInIpfw(char* macAddress);

/* util.c */
int Lock(int fd);
int Unlock(int fd);
FILE *Popenl(int rootPriv, const char *type, const char *path, ...);
int Systeml(int roorPriv, const char *path, ...);
int Pclose(FILE *stream);
int isNull(const char *pStr);
int Open(const char *pathname, int oflag, mode_t mode);
int Close(int fd);
pid_t Fork(void);
int Pipe(int *fds);
Sigfunc * Signal(int signo, Sigfunc *func);
void * Malloc(size_t size);

/* error.c */
void err_ret(const char *fmt, ...);
void err_sys(const char *fmt, ...);
void err_dump(const char *fmt, ...);
void err_msg(const char *fmt, ...);
void err_msg_warn(const char *fmt, ...);
void err_quit(const char *fmt, ...);
void errToSyslog(int i);

/* getparam.c */
int OpenConfFile(void);
void CloseConfFile(void);
void SetupConfExtra(char *userId, char *extraId);
char *GetConfValue(char *name);
char *GetConfValueExtra(char *name);
char *GetConfAuthServer(char *name);
int SelectNextAuthServer(void);
void InitConf(void);
int RegExMatch(const char *inStr, const char *regEx);
void ResetAuthServerPointer(void);
char *GetFirstConfValue(char* name);
char *GetNextConfValue(void);

/* pcap.c */
int InitPcap(void);
int GetNextPacketFromPcap(unsigned char* macAndIpAddressRaw, int* pAddrLen, int* pTtl);
void ClosePcap(void);
int GetMyMacAddress(char* macAddress);
void ConvertIpFromRawToDisplay(unsigned char* ipAddressRaw, int ipAddrLen, char* ipAddress);
void ConvertMacFromRawToDisplay(unsigned char* macAddressRaw, char* macAddress);

/* packetcache.c */
void InitCache(void);
int IsRecentlyCheckedAddress(unsigned char* macAndIpAddressRaw, int addrLen);
void FreeCache(void);
int DelCacheItem(char* macAddress, char* ipAddress);
int DelOldestCacheItem(void);
int ReFormatMacAddr(char* macAddr);

/* managementdb.c */
int InitMngDb(void);
int QueryMacFromMngDb(char* macAddress, char* userid, char* extraid);
void CloseMngDb(void);
int PutCloseToMngDb(char* macAddress);
int PutOpenToMngDb(char* macAddress);
int PutMacIpPairToMngDb(char* macAddress, char* ipAddress);
int GetNextRecordFromWatchlistTableInMngDb(char* macAddress);
int IsAllFoundInWatchlistTable(void);

/* workdb.c */
int SetupSqliteBusyTimeoutValue(void);
int InitWorkDb(void);
int FinalizeWorkDb(void);
int InsertSessionToWorkDb(char* macAddress, char* userId, char* extraId, 
			 int ruleNumber);
int DelSessionFromWorkDb(char* macAddress);
int GetSessionFromWorkDb(char* macAddress, char* userId, char* extraId, 
			 int* openTime, int* checkTime, int* ruleNumber);
int UpdateCheckTimeInWorkDb(char* macAddress);
int DelUselessSessionsInWorkDb(int delayed);
int GetSessionTableFromWorkDb(DB* sessionTable);
int PutMacInfoToWorkDb(char* macAddress, int ttl, int isNat);
int GetMacInfoFromWorkDb(char* macAddress, char* detectTimeStr, int* pTtl);
int IsActiveRuleInWorkDb(int ruleNumber);
int IsFoundMacIpPairInWorkDb(char* macAddress, char* ipAddress);
int PutMacIpPairToWorkDb(char* macAddress, char* ipAddress);
int DelMacIpPairsInWorkDb(char* macAddress);

/* session.c */
int AddSession(char* macAddress, char* userId, char* extraId);
void DelSession(char* macAddress);
void RenewSession(char* macAddress);
void DelUselessSessions(void);
void DelAllSessions(void);
int CloseSession(void* pParam, int argc, char *argv[], char* colName[]);
int IsMatchedSessionFound(char* macAddress);
void CloseUnmatchSessions(void);
void WriteOpenToSyslog(char* userId, char* extraId, char* macAddress);
void WriteCloseToSyslog(char* userId, char* extraId, char* macAddress, int openTime);
void WriteSessionInfoToSyslog(char* userId, char* extraId, char* macAddress, int ruleNumber);
void RemoveSessionUnmatchedToIpfwRule(DB* ruleTable, DB* sessionTable);
void RemoveIpfwRuleUnmatchedToSession(DB* ruleTable, DB* sessionTable);
int IsProcessFoundForTheRule(int ruleNumber);
void SetMacIpPair(char* macAddress, char* ipAddress, char* userId, char* extraId);
void ResetMacIpPairs(char* macAddress);

/* ttlcheck.c */
int InitTtlCheck(void);
int IsSentViaNatOrRouter(char* ipAddress, char* macAddress, int ttl);
void PutLogAtNatOrRouter(int isNatOrRouter, char* ipAddress, char* macAddress, int ttl);

/* udpserv.c */
int PrepareUdpPort(void (*handler)(int));
int GetDataFromUdpPort(char* buf, int bufLen, char* clientIpAddress);
int IsUdpClientTrusted(char* clientIpAddress);
int IsMyIpAddress(char* ipAddress);
int EnableAsyncIo(int sockfd, void (*handler)(int));

/* macdbcache.c */
void InitMacCache(void);
void FreeMacCache(void);
int QueryMacFromMacCache(char* macAddress, char* userId, char* extraId);
int DelMacCacheItem(char* macAddress);
int AddMacCacheItem(char* macAddress, char* userId, char* extraId, int found);

/* watchlistcache.c */
void InitWatchlistCache(void);
int AddWatchlistCacheItem(char* macAddress);
int IsFoundInWatchlistCache(char* macAddress);
void FreeWatchlistCache(void);

/* signal.c */
Sigfunc* signalx(int signo, Sigfunc* func);
