Module_Firewall.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. /*
  2. * Module_Firewall.c
  3. *
  4. * Created on: 2022/12/9
  5. * Author: folus
  6. */
  7. #include "yuarel.h"
  8. #include "define.h"
  9. enum
  10. {
  11. TMR_IDX_CONFIG,
  12. TMR_IDX_CNT
  13. };
  14. #define is_error(ptr) ((unsigned long)ptr > (unsigned long)-4000L)
  15. #define ARRAY_SIZE(A) (sizeof(A) / sizeof(A[0]))
  16. #define PASS 1
  17. #define FAIL -1
  18. #define YES 1
  19. #define NO 0
  20. #define ON 1
  21. #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)
  22. #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)
  23. #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)
  24. struct SysConfigAndInfo *ShmSysConfigAndInfo;
  25. struct StatusCodeData *ShmStatusCodeData;
  26. struct timespec tmr[TMR_IDX_CNT];
  27. uint8_t natInterface = 0;
  28. struct FirewallPresentSetting
  29. {
  30. unsigned char isEnalbleFirewall; // 0: Disable 1: Enable
  31. unsigned char FirewallAcceptAddr[10][128]; // Max accepted server address is 10
  32. }firewallPresentInfo;
  33. /**
  34. *
  35. * @param fmt
  36. * @return
  37. */
  38. int StoreLogMsg(const char *fmt, ...)
  39. {
  40. char Buf[4096+256];
  41. char buffer[4096];
  42. time_t CurrentTime;
  43. struct tm *tm;
  44. va_list args;
  45. va_start(args, fmt);
  46. int rc = vsnprintf(buffer, sizeof(buffer), fmt, args);
  47. va_end(args);
  48. memset(Buf,0,sizeof(Buf));
  49. CurrentTime = time(NULL);
  50. tm=localtime(&CurrentTime);
  51. sprintf(Buf,"echo -n \"[%04d.%02d.%02d %02d:%02d:%02d]%s\" >> /Storage/SystemLog/[%04d.%02d]Firewall_SystemLog",
  52. tm->tm_year+1900,tm->tm_mon+1,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec,
  53. buffer,
  54. tm->tm_year+1900,tm->tm_mon+1);
  55. #ifdef SystemLogMessage
  56. system(Buf);
  57. #endif
  58. #ifdef ConsloePrintLog
  59. 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);
  60. #endif
  61. return rc;
  62. }
  63. /**
  64. *
  65. * @return
  66. */
  67. int InitShareMemory()
  68. {
  69. int result = PASS;
  70. int MeterSMId;
  71. //creat ShmSysConfigAndInfo
  72. if ((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), 0777)) < 0)
  73. {
  74. DEBUG_ERROR("shmget ShmSysConfigAndInfo NG\n");
  75. result = FAIL;
  76. }
  77. else if ((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  78. {
  79. DEBUG_ERROR("shmat ShmSysConfigAndInfo NG\n");
  80. result = FAIL;
  81. }
  82. else
  83. {}
  84. //creat ShmStatusCodeData
  85. if ((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), 0777)) < 0)
  86. {
  87. DEBUG_ERROR("shmget ShmStatusCodeData NG\n");
  88. result = FAIL;
  89. }
  90. else if ((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *) -1)
  91. {
  92. DEBUG_ERROR("shmat ShmStatusCodeData NG\n");
  93. result = FAIL;
  94. }
  95. else
  96. {}
  97. return result;
  98. }
  99. /**
  100. *
  101. * @param cmd
  102. * @return
  103. */
  104. int runShellCmd(const char*cmd)
  105. {
  106. int result = FAIL;
  107. char buf[256];
  108. FILE *fp;
  109. fp = popen(cmd, "r");
  110. if(fp != NULL)
  111. {
  112. while(fgets(buf, sizeof(buf), fp) != NULL)
  113. {
  114. DEBUG_INFO("%s\n", buf);
  115. }
  116. result = PASS;
  117. }
  118. pclose(fp);
  119. return result;
  120. }
  121. /**
  122. *
  123. * @param timer
  124. */
  125. void refreshStartTimer(struct timespec *timer)
  126. {
  127. clock_gettime(CLOCK_MONOTONIC, timer);
  128. }
  129. /**
  130. *
  131. * @param timer
  132. * @return
  133. */
  134. int getDiffSecNow(struct timespec timer)
  135. {
  136. struct timespec timerNow;
  137. clock_gettime(CLOCK_MONOTONIC, &timerNow);
  138. return (int)((((unsigned long)(timerNow.tv_sec - timer.tv_sec) * 1000) + ((unsigned long)((timerNow.tv_nsec / 1000000) - (timer.tv_nsec / 1000000))))/1000);
  139. }
  140. /**
  141. *
  142. * @return
  143. */
  144. unsigned int isKernelSupportNAT()
  145. {
  146. unsigned int result = NO;
  147. unsigned int version = 0;
  148. FILE *fp;
  149. char cmd[256];
  150. char buf[512];
  151. // Get IP address & net mask
  152. strcpy(cmd, "uname -v");
  153. fp = popen(cmd, "r");
  154. if(fp != NULL)
  155. {
  156. if(fgets(buf, sizeof(buf), fp) != NULL)
  157. {
  158. sscanf(buf, "#%d", &version);
  159. //DEBUG_INFO("Kernel version: %d\n", version);
  160. if(version >= 30)
  161. result = YES;
  162. }
  163. }
  164. pclose(fp);
  165. return result;
  166. }
  167. /**
  168. *
  169. * @return
  170. */
  171. int firewallConfig()
  172. {
  173. struct yuarel url;
  174. char urlBuf[512] = {0};
  175. char cmdBuf[512] = {0};
  176. runShellCmd("/sbin/iptables -F");
  177. if(ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall)
  178. {
  179. // Other address mandatory configure
  180. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 192.168.0.0/255.255.0.0 -j ACCEPT");
  181. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 8.8.8.8/255.255.255.255 -j ACCEPT");
  182. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 180.76.76.76/255.255.255.255 -j ACCEPT");
  183. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d evsocket.phihong.com.tw/255.255.255.255 -j ACCEPT");
  184. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d ocpp.phihong.com.tw/255.255.255.255 -j ACCEPT");
  185. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d ftp.phihong.com.tw/255.255.255.255 -j ACCEPT");
  186. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d time.windows.com/255.255.255.255 -j ACCEPT");
  187. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d cn.ntp.org.cn/255.255.255.255 -j ACCEPT");
  188. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d tock.stdtime.gov.tw/255.255.255.255 -j ACCEPT");
  189. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d 0.europe.pool.ntp.org/255.255.255.255 -j ACCEPT");
  190. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d curl.haxx.se/255.255.255.255 -j ACCEPT");
  191. runShellCmd("/sbin/iptables -A INPUT -p all -s 192.168.0.0/255.255.0.0 -d any/0 -j ACCEPT");
  192. runShellCmd("/sbin/iptables -A INPUT -p all -s 8.8.8.8/255.255.255.255 -d any/0 -j ACCEPT");
  193. runShellCmd("/sbin/iptables -A INPUT -p all -s 180.76.76.76/255.255.255.255 -d any/0 -j ACCEPT");
  194. runShellCmd("/sbin/iptables -A INPUT -p all -s evsocket.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
  195. runShellCmd("/sbin/iptables -A INPUT -p all -s ocpp.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
  196. runShellCmd("/sbin/iptables -A INPUT -p all -s ftp.phihong.com.tw/255.255.255.255 -d any/0 -j ACCEPT");
  197. runShellCmd("/sbin/iptables -A INPUT -p all -s time.windows.com/255.255.255.255 -d any/0 -j ACCEPT");
  198. runShellCmd("/sbin/iptables -A INPUT -p all -s cn.ntp.org.cn/255.255.255.255 -d any/0 -j ACCEPT");
  199. runShellCmd("/sbin/iptables -A INPUT -p all -s tock.stdtime.gov.tw/255.255.255.255 -d any/0 -j ACCEPT");
  200. runShellCmd("/sbin/iptables -A INPUT -p all -s 0.europe.pool.ntp.org/255.255.255.255 -d any/0 -j ACCEPT");
  201. runShellCmd("/sbin/iptables -A INPUT -p all -s curl.haxx.se/255.255.255.255 -d any/0 -j ACCEPT");
  202. // Back end server URL parse
  203. if((ShmSysConfigAndInfo->SysConfig.OcppServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.OcppServerURL,"") != 0) )
  204. {
  205. memcpy(urlBuf, ShmSysConfigAndInfo->SysConfig.OcppServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.OcppServerURL));
  206. if(yuarel_parse(&url, urlBuf) != -1)
  207. {
  208. DEBUG_INFO("Add %s to allow rule.\n", url.host);
  209. sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", url.host);
  210. runShellCmd(cmdBuf);
  211. sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", url.host);
  212. runShellCmd(cmdBuf);
  213. }
  214. }
  215. if((ShmSysConfigAndInfo->SysConfig.MaintainServerURL != NULL) && (strcmp((const char *)ShmSysConfigAndInfo->SysConfig.MaintainServerURL,"") != 0) )
  216. {
  217. memcpy(urlBuf, ShmSysConfigAndInfo->SysConfig.MaintainServerURL, ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.MaintainServerURL));
  218. if(yuarel_parse(&url, urlBuf) != -1)
  219. {
  220. DEBUG_INFO("Add %s to allow rule.\n", url.host);
  221. sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", url.host);
  222. runShellCmd(cmdBuf);
  223. sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", url.host);
  224. runShellCmd(cmdBuf);
  225. }
  226. }
  227. // User custom configure address
  228. for(uint8_t idx=0;idx<ARRAY_SIZE(ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr);idx++)
  229. {
  230. if(strlen((char*)ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]) > 0)
  231. {
  232. DEBUG_INFO("Add %s to allow rule.\n", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
  233. sprintf(cmdBuf, "/sbin/iptables -A OUTPUT -p all -s any/0 -d %s/255.255.255.255 -j ACCEPT", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
  234. runShellCmd(cmdBuf);
  235. sprintf(cmdBuf, "/sbin/iptables -A INPUT -p all -s %s/255.255.255.255 -d any/0 -j ACCEPT", ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr[idx]);
  236. runShellCmd(cmdBuf);
  237. }
  238. }
  239. // Deny any address
  240. runShellCmd("/sbin/iptables -A OUTPUT -p all -s any/0 -d any/0 -j DROP");
  241. runShellCmd("/sbin/iptables -A INPUT -p all -s any/0 -d any/0 -j DROP");
  242. // List present rule
  243. runShellCmd("/sbin/iptables -L -n");
  244. }
  245. return PASS;
  246. }
  247. /**
  248. *
  249. * @return
  250. */
  251. int isChangeConfiguration()
  252. {
  253. int result = NO;
  254. if((firewallPresentInfo.isEnalbleFirewall != ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall) ||
  255. (memcmp(firewallPresentInfo.FirewallAcceptAddr, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr, ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr)*ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr[0])) != 0))
  256. {
  257. firewallPresentInfo.isEnalbleFirewall = ShmSysConfigAndInfo->SysConfig.isEnalbleFirewall;
  258. memcpy(firewallPresentInfo.FirewallAcceptAddr, ShmSysConfigAndInfo->SysConfig.FirewallAcceptAddr, ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr)*ARRAY_SIZE(firewallPresentInfo.FirewallAcceptAddr[0]));
  259. result = YES;
  260. }
  261. return result;
  262. }
  263. /**
  264. *
  265. * @return
  266. */
  267. int main(void)
  268. {
  269. //==========================================
  270. //Initialization share memory
  271. //==========================================
  272. if(InitShareMemory() == FAIL)
  273. {
  274. DEBUG_ERROR("InitShareMemory NG\n");
  275. if(ShmStatusCodeData!=NULL)
  276. {
  277. ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory=1;
  278. }
  279. sleep(5);
  280. return 0;
  281. }
  282. firewallPresentInfo.isEnalbleFirewall = 0xff;
  283. DEBUG_INFO("Module_Firewall version: V0.01\n");
  284. DEBUG_INFO("Module_Firewall initialized...\n");
  285. for(;;)
  286. {
  287. if(isChangeConfiguration())
  288. {
  289. DEBUG_INFO("Firewall rule changed.\n");
  290. sleep(3);
  291. firewallConfig();
  292. }
  293. usleep(100000);
  294. }
  295. return -1;
  296. }