|
@@ -0,0 +1,343 @@
|
|
|
+/*
|
|
|
+ * Module_Firewall.c
|
|
|
+ *
|
|
|
+ * Created on: 2022/12/9
|
|
|
+ * Author: folus
|
|
|
+ */
|
|
|
+#include "yuarel.h"
|
|
|
+#include "define.h"
|
|
|
+
|
|
|
+enum
|
|
|
+{
|
|
|
+ TMR_IDX_CONFIG,
|
|
|
+ TMR_IDX_CNT
|
|
|
+};
|
|
|
+
|
|
|
+#define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L)
|
|
|
+#define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
|
|
|
+#define PASS 1
|
|
|
+#define FAIL -1
|
|
|
+#define YES 1
|
|
|
+#define NO 0
|
|
|
+#define ON 1
|
|
|
+
|
|
|
+#define DEBUG_INFO(format, args...) StoreLogMsg("[%s:%d][%s][Info] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)), __LINE__, __FUNCTION__, ##args)
|
|
|
+#define DEBUG_WARN(format, args...) StoreLogMsg("[%s:%d][%s][Warn] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)), __LINE__, __FUNCTION__, ##args)
|
|
|
+#define DEBUG_ERROR(format, args...) StoreLogMsg("[%s:%d][%s][Error] "format, (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)), __LINE__, __FUNCTION__, ##args)
|
|
|
+
|
|
|
+struct SysConfigAndInfo *ShmSysConfigAndInfo;
|
|
|
+struct StatusCodeData *ShmStatusCodeData;
|
|
|
+
|
|
|
+struct timespec tmr[TMR_IDX_CNT];
|
|
|
+uint8_t natInterface = 0;
|
|
|
+
|
|
|
+struct FirewallPresentSetting
|
|
|
+{
|
|
|
+ unsigned char isEnalbleFirewall; // 0: Disable 1: Enable
|
|
|
+ unsigned char FirewallAcceptAddr[10][128]; // Max accepted server address is 10
|
|
|
+}firewallPresentInfo;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param fmt
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int StoreLogMsg(const char *fmt, ...)
|
|
|
+{
|
|
|
+ char Buf[4096+256];
|
|
|
+ char buffer[4096];
|
|
|
+ time_t CurrentTime;
|
|
|
+ struct tm *tm;
|
|
|
+ va_list args;
|
|
|
+
|
|
|
+ va_start(args, fmt);
|
|
|
+ int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
|
|
+ va_end(args);
|
|
|
+
|
|
|
+ memset(Buf,0,sizeof(Buf));
|
|
|
+ CurrentTime = time(NULL);
|
|
|
+ tm=localtime(&CurrentTime);
|
|
|
+ sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]Firewall_SystemLog",
|
|
|
+ tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
|
|
|
+ buffer,
|
|
|
+ tm->tm_year+1900,tm->tm_mon+1);
|
|
|
+#ifdef SystemLogMessage
|
|
|
+ system(Buf);
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef ConsloePrintLog
|
|
|
+ printf("[%04d.%02d.%02d %02d:%02d:%02d] - %s", tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec, buffer);
|
|
|
+#endif
|
|
|
+
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int InitShareMemory()
|
|
|
+{
|
|
|
+ int result = PASS;
|
|
|
+ int MeterSMId;
|
|
|
+
|
|
|
+ //creat ShmSysConfigAndInfo
|
|
|
+ if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
|
|
|
+ result = FAIL;
|
|
|
+ }
|
|
|
+ else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
|
|
|
+ result = FAIL;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {}
|
|
|
+
|
|
|
+ //creat ShmStatusCodeData
|
|
|
+ if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
|
|
|
+ result = FAIL;
|
|
|
+ }
|
|
|
+ else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
|
|
|
+ result = FAIL;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {}
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param cmd
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int runShellCmd(const char*cmd)
|
|
|
+{
|
|
|
+ int result = FAIL;
|
|
|
+ char buf[256];
|
|
|
+ FILE *fp;
|
|
|
+
|
|
|
+ fp = popen(cmd, "r");
|
|
|
+ if(fp != NULL)
|
|
|
+ {
|
|
|
+ while(fgets(buf, sizeof(buf), fp) != NULL)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("%s\n", buf);
|
|
|
+ }
|
|
|
+
|
|
|
+ result = PASS;
|
|
|
+ }
|
|
|
+ pclose(fp);
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param timer
|
|
|
+ */
|
|
|
+void refreshStartTimer(struct timespec *timer)
|
|
|
+{
|
|
|
+ clock_gettime(CLOCK_MONOTONIC, timer);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @param timer
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int getDiffSecNow(struct timespec timer)
|
|
|
+{
|
|
|
+ struct timespec timerNow;
|
|
|
+
|
|
|
+ clock_gettime(CLOCK_MONOTONIC, &timerNow);
|
|
|
+
|
|
|
+ return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+unsigned int isKernelSupportNAT()
|
|
|
+{
|
|
|
+ unsigned int result = NO;
|
|
|
+ unsigned int version = 0;
|
|
|
+ FILE *fp;
|
|
|
+ char cmd[256];
|
|
|
+ char buf[512];
|
|
|
+
|
|
|
+ // Get IP address & net mask
|
|
|
+ strcpy(cmd, "uname -v");
|
|
|
+ fp = popen(cmd, "r");
|
|
|
+ if(fp != NULL)
|
|
|
+ {
|
|
|
+ if(fgets(buf, sizeof(buf), fp) != NULL)
|
|
|
+ {
|
|
|
+ sscanf(buf, "#%d", &version);
|
|
|
+ //DEBUG_INFO("Kernel version: %d\n", version);
|
|
|
+
|
|
|
+ if(version >= 30)
|
|
|
+ result = YES;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pclose(fp);
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int firewallConfig()
|
|
|
+{
|
|
|
+ struct yuarel url;
|
|
|
+ char urlBuf[512] = {0};
|
|
|
+ char cmdBuf[512] = {0};
|
|
|
+
|
|
|
+ runShellCmd("/sbin/iptables -F");
|
|
|
+
|
|
|
+ if(ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall)
|
|
|
+ {
|
|
|
+ // Other address mandatory configure
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 192.168.0.0/255.255.0.0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 8.8.8.8/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 180.76.76.76/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d evsocket.phihong.com.tw/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d ocpp.phihong.com.tw/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d ftp.phihong.com.tw/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d time.windows.com/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d cn.ntp.org.cn/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d tock.stdtime.gov.tw/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 0.europe.pool.ntp.org/255.255.255.255 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d curl.haxx.se/255.255.255.255 -j ACCEPT");
|
|
|
+
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s 192.168.0.0/255.255.0.0 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s 8.8.8.8/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s 180.76.76.76/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s evsocket.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s ocpp.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s ftp.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s time.windows.com/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s cn.ntp.org.cn/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s tock.stdtime.gov.tw/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s 0.europe.pool.ntp.org/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s curl.haxx.se/255.255.255.255 -d any/0 -j ACCEPT");
|
|
|
+
|
|
|
+ // Back end server URL parse
|
|
|
+ if((ShmSysConfigAndInfo->SysConfig.OcppServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0) )
|
|
|
+ {
|
|
|
+ memcpy(urlBuf, ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL));
|
|
|
+ if(yuarel_parse(&url, urlBuf) != -1)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Add %s to allow rule.\n", url.host);
|
|
|
+ sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", url.host);
|
|
|
+ runShellCmd(cmdBuf);
|
|
|
+ sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", url.host);
|
|
|
+ runShellCmd(cmdBuf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if((ShmSysConfigAndInfo->SysConfig.MaintainServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) )
|
|
|
+ {
|
|
|
+ memcpy(urlBuf, ShmSysConfigAndInfo->SysConfig.MaintainServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.MaintainServerURL));
|
|
|
+ if(yuarel_parse(&url, urlBuf) != -1)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Add %s to allow rule.\n", url.host);
|
|
|
+ sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", url.host);
|
|
|
+ runShellCmd(cmdBuf);
|
|
|
+ sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", url.host);
|
|
|
+ runShellCmd(cmdBuf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // User custom configure address
|
|
|
+ for(uint8_t idx=0;idx<ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr);idx++)
|
|
|
+ {
|
|
|
+ if(strlen((char*)ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]) > 0)
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Add %s to allow rule.\n", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
|
|
|
+ sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
|
|
|
+ runShellCmd(cmdBuf);
|
|
|
+ sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
|
|
|
+ runShellCmd(cmdBuf);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Deny any address
|
|
|
+ runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d any/0 -j DROP");
|
|
|
+ runShellCmd("/sbin/iptables -A INPUT -p all -s any/0 -d any/0 -j DROP");
|
|
|
+
|
|
|
+ // List present rule
|
|
|
+ runShellCmd("/sbin/iptables -L -n");
|
|
|
+ }
|
|
|
+
|
|
|
+ return PASS;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int isChangeConfiguration()
|
|
|
+{
|
|
|
+ int result = NO;
|
|
|
+
|
|
|
+ if((firewallPresentInfo.isEnalbleFirewall != ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall) ||
|
|
|
+ (memcmp(firewallPresentInfo.FirewallAcceptAddr, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr, ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr)*ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr[0])) != 0))
|
|
|
+ {
|
|
|
+
|
|
|
+ firewallPresentInfo.isEnalbleFirewall = ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall;
|
|
|
+ memcpy(firewallPresentInfo.FirewallAcceptAddr, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr, ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr)*ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr[0]));
|
|
|
+
|
|
|
+ result = YES;
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+int main(void)
|
|
|
+{
|
|
|
+ //==========================================
|
|
|
+ //Initialization share memory
|
|
|
+ //==========================================
|
|
|
+ if(InitShareMemory() == FAIL)
|
|
|
+ {
|
|
|
+ DEBUG_ERROR("InitShareMemory NG\n");
|
|
|
+
|
|
|
+ if(ShmStatusCodeData!=NULL)
|
|
|
+ {
|
|
|
+ ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
|
|
|
+ }
|
|
|
+ sleep(5);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ DEBUG_INFO("Module_Firewall version: V0.01\n");
|
|
|
+ DEBUG_INFO("Module_Firewall initialized...\n");
|
|
|
+
|
|
|
+ for(;;)
|
|
|
+ {
|
|
|
+ if(isChangeConfiguration())
|
|
|
+ {
|
|
|
+ DEBUG_INFO("Firewall rule changed.\n");
|
|
|
+ sleep(3);
|
|
|
+ firewallConfig();
|
|
|
+ }
|
|
|
+
|
|
|
+ usleep(100000);
|
|
|
+ }
|
|
|
+
|
|
|
+ return -1;
|
|
|
+}
|