From: Jaehyun Kim Date: Thu, 7 Dec 2017 05:59:55 +0000 (+0900) Subject: Initialize smart traffic control iptables package X-Git-Tag: submit/tizen/20171211.072253~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F79%2F163079%2F1;p=platform%2Fcore%2Fconnectivity%2Fstc-iptables.git Initialize smart traffic control iptables package Change-Id: I675ed04338b2d59000dbb71b432cc1a02a2f6386 Signed-off-by: Jaehyun Kim --- diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..bc5fb9a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,15 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(stc-iptables C) + +SET(PACKAGE ${PROJECT_NAME}) +SET(INTERFACES "${CMAKE_SOURCE_DIR}/interfaces") +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(LIBDIR ${PREFIX}/${LIB_PATH}) + +SET(COMMON_DEPS "glib-2.0 gio-2.0 gio-unix-2.0") + +SET(TARGET_STC_IPTABLES "stc-iptables") +SET(TARGET_STC_IPT_TEST "stc_ipt_test") + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(test) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/COPYING @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6d45519 --- /dev/null +++ b/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..dd954da --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# stc-iptables +STC means Smart Traffic Control. +It provides iptables control services using libiptc. +Stc-iptables is a GNU project. + +The stc-iptables binary is licensed under the GNU General +Public License version 2 or later. See the file LICENSE. + +The command line tool (stc_ipt_test) is licensed under +the Apache Lisence version 2.0 or later. See the file COPYING. + +Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. diff --git a/include/linux/netfilter/xt_cgroup.h b/include/linux/netfilter/xt_cgroup.h new file mode 100755 index 0000000..7fe61ed --- /dev/null +++ b/include/linux/netfilter/xt_cgroup.h @@ -0,0 +1,24 @@ +#ifndef _XT_CGROUP_H +#define _XT_CGROUP_H + +#include +#include + +struct xt_cgroup_info_v0 { + __u32 id; + __u32 invert; +}; + +struct xt_cgroup_info_v1 { + __u8 has_path; + __u8 has_classid; + __u8 invert_path; + __u8 invert_classid; + char path[PATH_MAX]; + __u32 classid; + + /* kernel internal data */ + void *priv __attribute__((aligned(8))); +}; + +#endif /* _XT_CGROUP_H */ diff --git a/include/linux/netfilter/xt_nfacct.h b/include/linux/netfilter/xt_nfacct.h new file mode 100755 index 0000000..3e19c8a --- /dev/null +++ b/include/linux/netfilter/xt_nfacct.h @@ -0,0 +1,13 @@ +#ifndef _XT_NFACCT_MATCH_H +#define _XT_NFACCT_MATCH_H + +#include + +struct nf_acct; + +struct xt_nfacct_match_info { + char name[NFACCT_NAME_MAX]; + struct nf_acct *nfacct; +}; + +#endif /* _XT_NFACCT_MATCH_H */ diff --git a/include/stc-iptables-gdbus.h b/include/stc-iptables-gdbus.h new file mode 100755 index 0000000..234e002 --- /dev/null +++ b/include/stc-iptables-gdbus.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __STC_IPTABLES_GDBUS_H__ +#define __STC_IPTABLES_GDBUS_H__ + +#include + +#include "stc-iptables-util.h" +#include "generated-code.h" + +#define STC_IPTABLES_DBUS_SERVICE "net.stc.iptables" +#define STC_IPTABLES_DBUS_RULE_INTERFACE STC_IPTABLES_DBUS_SERVICE ".rule" +#define STC_IPTABLES_DBUS_CHAIN_INTERFACE STC_IPTABLES_DBUS_SERVICE ".chain" +#define STC_IPTABLES_DBUS_SERVICE_RULE_PATH "/net/stc/iptables/rule" +#define STC_IPTABLES_DBUS_SERVICE_CHAIN_PATH "/net/stc/iptables/chain" + +typedef void(*dbus_dict_cb)(const char *key, GVariant *value, + void *user_data); + +void stc_iptables_gdbus_init(gpointer stc_data); +void stc_iptables_gdbus_deinit(gpointer stc_data); + +void stc_iptables_gdbus_dict_foreach(GVariantIter *iter, + dbus_dict_cb cb, void *user_data); + +#endif /* __STC_IPTABLES_GDBUS_H__ */ diff --git a/include/stc-iptables-log.h b/include/stc-iptables-log.h new file mode 100755 index 0000000..1919190 --- /dev/null +++ b/include/stc-iptables-log.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __STC_IPTABLES_LOG_H__ +#define __STC_IPTABLES_LOG_H__ + +void stc_iptables_log(const char *format, ...); +gboolean stc_iptables_log_sync(gpointer data); +void stc_iptables_log_cleanup(void); + +#define __LOG(level, format, arg...) \ + do { \ + stc_iptables_log("[%s] %s(%d) "format"\n", level, \ + __FUNCTION__, __LINE__, ##arg); \ + } while(0) + +#define LOG_SYNC_TIME 1500 + +#define LOG_INFO "I" +#define LOG_WARN "W" +#define LOG_ERROR "E" +#define LOG_DEBUG "D" + +#define STC_LOGD(format, args...) __LOG(LOG_DEBUG, format, ##args) +#define STC_LOGI(format, args...) __LOG(LOG_INFO, format, ##args) +#define STC_LOGW(format, args...) __LOG(LOG_WARN, format, ##args) +#define STC_LOGE(format, args...) __LOG(LOG_ERROR, format, ##args) + +#define __STC_LOG_FUNC_ENTER__ __LOG(LOG_DEBUG, "Enter") +#define __STC_LOG_FUNC_EXIT__ __LOG(LOG_DEBUG, "Quit") + +#endif /* __STC_IPTABLES_LOG_H__ */ diff --git a/include/stc-iptables-util.h b/include/stc-iptables-util.h new file mode 100755 index 0000000..55de31d --- /dev/null +++ b/include/stc-iptables-util.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __STC_IPTABLES_UTIL_H__ +#define __STC_IPTABLES_UTIL_H__ + +#include +#include + +#include "stc-iptables-log.h" +#include "stc-iptables-gdbus.h" + +#define MALLOC0(t, n) ((t*) g_try_malloc0((n) * sizeof(t))) +#define FREE(p) do { \ + if (p) { \ + g_free(p); \ + p = NULL; \ + } \ +} while (0) + +#define STC_DEBUG_GDBUS_VARIANT(str, parameters) do { \ + gchar *params_str = NULL; \ + if (parameters) { \ + params_str = g_variant_print(parameters, \ + TRUE); \ + } \ + STC_LOGD("%s[%s]", str, \ + params_str ? params_str : "NULL"); \ + g_free(params_str); \ + } while (0) + +#define STC_DEBUG_GDBUS_KEY_VALUE(key, value) do { \ + if (key) { \ + STC_LOGD("Key : [%s]", key); \ + } \ + if (value) { \ + STC_DEBUG_GDBUS_VARIANT("Value: ", value); \ + } \ + } while (0) + +typedef enum { + STC_ERROR_OPERATION_FAILED = -6, /**< Operation failed */ + STC_ERROR_INVALID_PARAMETER = -5, /**< Invalid function parameter */ + STC_ERROR_INVALID_OPERATION = -4, /**< Invalid operation */ + STC_ERROR_PERMISSION_DENIED = -3, /**< Permission denied */ + STC_ERROR_OUT_OF_MEMORY = -2, /**< Out of memory */ + STC_ERROR_NOT_PERMITTED = -1, /**< Operation not permitted */ + STC_ERROR_NONE = 0 /**< Successful */ +} stc_error_e; + +/* iptables */ +gboolean handle_iptables_add_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule, + void *user_data); + +gboolean handle_iptables_remove_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule, + void *user_data); + +gboolean handle_iptables_add_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data); + +gboolean handle_iptables_remove_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data); + +/* ip6tables */ +gboolean handle_ip6tables_add_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule, + void *user_data); + +gboolean handle_ip6tables_remove_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rule, + void *user_data); + +gboolean handle_ip6tables_add_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data); + +gboolean handle_ip6tables_remove_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data); + +#endif /* __STC_IPTABLES_UTIL_H__ */ diff --git a/include/stc-iptables.h b/include/stc-iptables.h new file mode 100755 index 0000000..ec8f850 --- /dev/null +++ b/include/stc-iptables.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef __STC_IPTABLES_H__ +#define __STC_IPTABLES_H__ + +#include +#include + +#include "stc-iptables-log.h" +#include "stc-iptables-util.h" + +typedef struct { + GMainLoop *main_loop; + + gpointer rule_obj; + gpointer chain_obj; + + GDBusObjectManagerServer *obj_mgr; + GDBusConnection *connection; + guint gdbus_owner_id; +} stc_iptables_s; + +stc_iptables_s *stc_get_iptables(void); + +#endif /* __STC_IPTABLES_H__ */ diff --git a/interfaces/stc-iptables-iface.xml b/interfaces/stc-iptables-iface.xml new file mode 100755 index 0000000..2a1c379 --- /dev/null +++ b/interfaces/stc-iptables-iface.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/stc-iptables.spec b/packaging/stc-iptables.spec new file mode 100644 index 0000000..6b78a3b --- /dev/null +++ b/packaging/stc-iptables.spec @@ -0,0 +1,78 @@ +Name: stc-iptables +Summary: STC(Smart Traffic Control) iptables +Version: 0.0.1 +Release: 0 +Group: Network & Connectivity/Other +License: GPL-2.0+ +Source0: %{name}-%{version}.tar.gz + +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(gio-unix-2.0) +BuildRequires: pkgconfig(libiptc) +BuildRequires: pkgconfig(libip6tc) + +%description +A smart traffic control iptables to manage iptables rules using libiptc + +%package test +Summary: STC iptables test binaries + +%description test +Test Application for STC Iptables + +%prep +%setup -q +chmod 644 %{SOURCE0} + +%build + +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE -D_GNU_SOURCE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" + +%cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -DBIN_DIR=%{_bindir} \ + -DLIB_PATH=%{_lib} \ + +make %{?_smp_mflags} + +%install +rm -rf %{buildroot} + +%make_install + +#Systemd iptables service file +mkdir -p %{buildroot}%{_libdir}/systemd/system/ +cp resources/systemd/stc-iptables.service %{buildroot}%{_libdir}/systemd/system/stc-iptables.service + +mkdir -p %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/ +ln -s ../stc-iptables.service %{buildroot}%{_libdir}/systemd/system/multi-user.target.wants/stc-iptables.service + +#DBus DAC (stc-iptables.manifest enables DBus SMACK) +mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d +cp resources/dbus/stc-iptables.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/stc-iptables.conf + +%post +#Logs +mkdir -p /opt/usr/data/network +chmod 755 /opt/usr/data/network +chown network_fw:network_fw /opt/usr/data/network + +%files +%manifest %{name}.manifest +%license LICENSE +%license COPYING +%defattr(-,root,root,-) +%attr(500,root,root) %{_bindir}/stc-iptables + +%attr(644,root,root) %{_libdir}/systemd/system/stc-iptables.service +%attr(644,root,root) %{_libdir}/systemd/system/multi-user.target.wants/stc-iptables.service + +#DBus DAC +%attr(644,root,root) %{_sysconfdir}/dbus-1/system.d/stc-iptables.conf + +#Test +%{_bindir}/stc_ipt_test +%attr(755,root,root) %{_bindir}/stc_ipt_test diff --git a/resources/dbus/stc-iptables.conf b/resources/dbus/stc-iptables.conf new file mode 100755 index 0000000..4beab7a --- /dev/null +++ b/resources/dbus/stc-iptables.conf @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/resources/systemd/stc-iptables.service b/resources/systemd/stc-iptables.service new file mode 100755 index 0000000..413520b --- /dev/null +++ b/resources/systemd/stc-iptables.service @@ -0,0 +1,14 @@ +[Unit] +Description=Smart Traffic Control Iptables +Requires=dbus.socket +Before=stc-manager.service +After=dbus.socket + +[Service] +Type=forking +SmackProcessLabel=System +ExecStart=/usr/bin/stc-iptables +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100755 index 0000000..eed8daa --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,49 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +SET(REQUIRES_LIST ${REQUIRES_LIST} + ${COMMON_DEPS} + libiptc + libip6tc + ) + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(iptables_pkgs REQUIRED "${REQUIRES_LIST}") + +FOREACH(flag ${iptables_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(INTERFACES_DIR ${CMAKE_SOURCE_DIR}/interfaces) +SET(SOURCE_DIR ${CMAKE_SOURCE_DIR}/src) +SET(HELPER_SOURCE_DIR ${SOURCE_DIR}/helper) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${SOURCE_DIR}) +INCLUDE_DIRECTORIES(${HELPER_SOURCE_DIR}) + +FILE(GLOB SOURCE_SRCS ${SOURCE_DIR}/*.c) +FILE(GLOB HELPER_SRCS ${HELPER_SOURCE_DIR}/*.c) + +SET(SRCS ${SRCS} ${SOURCE_SRCS} ${HELPER_SRCS}) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fpic -Wall -Werror-implicit-function-declaration -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") + +ADD_CUSTOM_COMMAND( + WORKING_DIRECTORY + OUTPUT ${SOURCE_DIR}/generated-code.c + COMMAND gdbus-codegen --interface-prefix net.stc.iptables. + --generate-c-code generated-code + --c-namespace Stc + --c-generate-object-manager + --generate-docbook generated-code-docs + ${INTERFACES_DIR}/stc-iptables-iface.xml + COMMENT "Generating GDBus .c/.h") + +SET(SRCS ${SRCS} ${SOURCE_DIR}/generated-code.c) +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${iptables_pkgs_LDFLAGS} -ldl) + +INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${BIN_DIR}) diff --git a/src/helper/helper-ip6tables.c b/src/helper/helper-ip6tables.c new file mode 100755 index 0000000..128787f --- /dev/null +++ b/src/helper/helper-ip6tables.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include + +#include "helper-ip6tables.h" +#include "stc-iptables-util.h" + +#define IP6T_ALIGN XT_ALIGN +#define IP6TC_TABLE "filter" +#define IP6TC_CGROUP "cgroup" +#define IP6TC_NFACCT "nfacct" + +/* handle */ +typedef struct xtc_handle ip6t_handle_t; + +/* entry */ +typedef struct ip6t_entry ip6t_entry_t; +typedef struct ip6t_entry_match ip6t_entry_match_t; +typedef struct ip6t_entry_target ip6t_entry_target_t; + +/* matches */ +typedef struct xt_cgroup_info_v0 ip6t_cgroup_info_t; +typedef struct xt_nfacct_match_info ip6t_nfacct_info_t; + +#define SIZE_ENTRY IP6T_ALIGN(sizeof(ip6t_entry_t)) +#define SIZE_CGROUP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_cgroup_info_t)) +#define SIZE_NFACCT_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_nfacct_info_t)) +#define SIZE_TARGET IP6T_ALIGN(sizeof(ip6t_entry_target_t)) + IP6T_ALIGN(sizeof(int)) +#define SIZE_TOTAL SIZE_ENTRY + SIZE_CGROUP_MATCH + SIZE_NFACCT_MATCH + SIZE_TARGET + +static unsigned int __add_match(const char *name, ip6t_entry_match_t *start, size_t size, void *data) +{ + ip6t_entry_match_t *match = start; + + match->u.match_size = IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(size); + + strncpy(match->u.user.name, name, sizeof(match->u.user.name)); + memcpy(match->data, data, size); + + return match->u.match_size; +} + +static unsigned int __add_cgroup_match(unsigned int classid, ip6t_entry_match_t *start) +{ + /* cgroup => "--cgroup 0" */ + ip6t_cgroup_info_t cgroup; + memset(&cgroup, 0, sizeof(ip6t_cgroup_info_t)); + cgroup.id = classid; + /* match_cgroup => "-m cgroup" */ + return __add_match(IP6TC_CGROUP, start, sizeof(ip6t_cgroup_info_t), &cgroup); +} + +static unsigned int __add_nfacct_match(const char *nfacct_name, ip6t_entry_match_t *start) +{ + /* nfacct => "--nfacct_name " */ + ip6t_nfacct_info_t nfacct; + memset(&nfacct, 0, sizeof(ip6t_nfacct_info_t)); + strncpy(nfacct.name, nfacct_name, sizeof(nfacct.name)); + /* match_nfacct => "-m nfacct" */ + return __add_match(IP6TC_NFACCT, start, sizeof(ip6t_nfacct_info_t), &nfacct); +} + +static int __create_entry_data(unsigned char *entry, unsigned char *mask, + ip6tables_rule_s *rule) +{ + ip6t_entry_t *e = NULL; + ip6t_entry_target_t *target = NULL; + unsigned int size_match = 0; + + if (!rule->chain || !rule->ifname || + (rule->classid < 0) || !rule->nfacct_name) { + STC_LOGE("Invalid parameters"); + return STC_ERROR_INVALID_PARAMETER; + } + + e = (ip6t_entry_t *)(entry); + + /* entry size */ + e->target_offset = SIZE_ENTRY + SIZE_CGROUP_MATCH + SIZE_NFACCT_MATCH; + e->next_offset = SIZE_TOTAL; + + switch (rule->type) { + case IP6TABLES_RULE_IN: + /* entry => "-i wlan0" */ + strncpy(e->ipv6.iniface, rule->ifname, IFNAMSIZ); + memset(&(e->ipv6.iniface_mask), 0xFF, IFNAMSIZ); + break; + case IP6TABLES_RULE_OUT: + /* entry => "-o wlan0" */ + strncpy(e->ipv6.outiface, rule->ifname, IFNAMSIZ); + memset(&(e->ipv6.outiface_mask), 0xFF, IFNAMSIZ); + break; + default: + STC_LOGE("Invalid parameter"); + return STC_ERROR_INVALID_PARAMETER; + } + + size_match = __add_cgroup_match(rule->classid, (ip6t_entry_match_t *) e->elems); + size_match += __add_nfacct_match(rule->nfacct_name, (ip6t_entry_match_t *) (e->elems + size_match)); + + /* target => "-j ACCEPT" */ + target = (ip6t_entry_target_t *) (e->elems + size_match); + target->u.target_size = SIZE_TARGET; + if (rule->target) + strncpy(target->u.user.name, rule->target, sizeof(target->u.user.name)); + + memset(mask, 0xFF, sizeof(ip6t_entry_t) + + sizeof(ip6t_entry_match_t) + sizeof(ip6t_entry_match_t)); + + return STC_ERROR_NONE; +} + +int ip6tables_add_rule(ip6tables_rule_s *rule) +{ + ip6t_handle_t *handle; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + const char *chain = rule->chain; + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + return STC_ERROR_OPERATION_FAILED; + } + + handle = ip6tc_init(IP6TC_TABLE); + if (handle == NULL) { + STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_is_chain(chain, handle)) { + STC_LOGW("chain not present [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (ip6tc_check_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) { + STC_LOGW("Entry already present"); + ip6tc_free(handle); + return STC_ERROR_NONE; + } + + if (!ip6tc_append_entry(chain, (const ip6t_entry_t *)entry, handle)) { + STC_LOGW("ip6tc_append_entry failed [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_commit(handle)) { + STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + ip6tc_free(handle); + + STC_LOGI("Success adding rule"); + return STC_ERROR_NONE; +} + +int ip6tables_remove_rule(ip6tables_rule_s *rule) +{ + ip6t_handle_t *handle; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + const char *chain = rule->chain; + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + return STC_ERROR_OPERATION_FAILED; + } + + handle = ip6tc_init(IP6TC_TABLE); + if (handle == NULL) { + STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_is_chain(chain, handle)) { + STC_LOGW("chain not present [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_delete_entry(chain, (const ip6t_entry_t *)entry, mask, handle)) { + STC_LOGW("ip6tc_delete_entry failed [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_commit(handle)) { + STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + ip6tc_free(handle); + + STC_LOGI("Success removing rule"); + return STC_ERROR_NONE; +} + +int ip6tables_add_chain(const char *chain) +{ + ip6t_handle_t *handle; + + handle = ip6tc_init(IP6TC_TABLE); + if (handle == NULL) { + STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (ip6tc_is_chain(chain, handle)) { + STC_LOGW("chain already exists"); + ip6tc_free(handle); + return STC_ERROR_NONE; + } + + if (!ip6tc_create_chain(chain, handle)) { + STC_LOGE("Failed to create chaing [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_commit(handle)) { + STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + ip6tc_free(handle); + + STC_LOGI("Success adding chain"); + return 0; +} + +int ip6tables_remove_chain(const char *chain) +{ + ip6t_handle_t *handle; + + handle = ip6tc_init(IP6TC_TABLE); + if (handle == NULL) { + STC_LOGE("ip6tc_init failed [%s]", ip6tc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_is_chain(chain, handle)) { + STC_LOGW("chain not present"); + ip6tc_free(handle); + return STC_ERROR_NONE; + } + + ip6tc_flush_entries(chain, handle); + + if (!ip6tc_delete_chain(chain, handle)) { + STC_LOGE("Failed to delete chain [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!ip6tc_commit(handle)) { + STC_LOGE("Failed to ip6tc_commit [%s]", ip6tc_strerror(errno)); + ip6tc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + ip6tc_free(handle); + + STC_LOGI("Success removing chain"); + return STC_ERROR_NONE; +} diff --git a/src/helper/helper-ip6tables.h b/src/helper/helper-ip6tables.h new file mode 100755 index 0000000..4ca0438 --- /dev/null +++ b/src/helper/helper-ip6tables.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Manage ip6tables rule using libip6tc + */ +#ifndef __STC_HELPER_IP6TABLES_H__ +#define __STC_HELPER_IP6TABLES_H__ + +#include + +#define RULE_SIZE 64 + +typedef enum { + IP6TABLES_CHAIN_INPUT, + IP6TABLES_CHAIN_OUTPUT +} ip6tables_chain_e; + +typedef enum { + IP6TABLES_RULE_IN, + IP6TABLES_RULE_OUT +} ip6tables_rule_type_e; + +typedef enum { + IP6TABLES_ACTION_ACCEPT, + IP6TABLES_ACTION_DROP +} ip6tables_target_action_e; + +typedef struct { + char *chain; + ip6tables_rule_type_e type; + char *ifname; + int classid; + char *nfacct_name; + char *target; +} ip6tables_rule_s; + +/** + * @desc This function adds a new iptables rule. + * @return 0 on success and negative value if error. + */ +int ip6tables_add_rule(ip6tables_rule_s *rule); + +/** + * @desc This function removes already set iptables rule. + * @return 0 on success and negative value if error. + */ +int ip6tables_remove_rule(ip6tables_rule_s *rule); + +/** + * @desc This function adds a new iptables chain. + * @return 0 on success and negative value if error. + */ +int ip6tables_add_chain(const char *chain); + +/** + * @desc This function removes already set iptables chain. + * @return 0 on success and negative value if error. + */ +int ip6tables_remove_chain(const char *chain); + +#endif /*__STC_HELPER_IP6TABLES_H__*/ diff --git a/src/helper/helper-iptables.c b/src/helper/helper-iptables.c new file mode 100755 index 0000000..1c3cc00 --- /dev/null +++ b/src/helper/helper-iptables.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include + +#include "helper-iptables.h" +#include "stc-iptables-util.h" + +#define IPT_ALIGN XT_ALIGN +#define IPTC_TABLE "filter" +#define IPTC_CGROUP "cgroup" +#define IPTC_NFACCT "nfacct" + +/* handle */ +typedef struct xtc_handle ipt_handle_t; + +/* entry */ +typedef struct ipt_entry ipt_entry_t; +typedef struct ipt_entry_match ipt_entry_match_t; +typedef struct ipt_entry_target ipt_entry_target_t; + +/* matches */ +typedef struct xt_cgroup_info_v0 ipt_cgroup_info_t; +typedef struct xt_nfacct_match_info ipt_nfacct_info_t; + +#define SIZE_ENTRY IPT_ALIGN(sizeof(ipt_entry_t)) +#define SIZE_CGROUP_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_cgroup_info_t)) +#define SIZE_NFACCT_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_nfacct_info_t)) +#define SIZE_TARGET IPT_ALIGN(sizeof(ipt_entry_target_t)) + IPT_ALIGN(sizeof(int)) +#define SIZE_TOTAL SIZE_ENTRY + SIZE_CGROUP_MATCH + SIZE_NFACCT_MATCH + SIZE_TARGET + +static unsigned int __add_match(const char *name, ipt_entry_match_t *start, size_t size, void *data) +{ + ipt_entry_match_t *match = start; + + match->u.match_size = IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(size); + + strncpy(match->u.user.name, name, sizeof(match->u.user.name)); + memcpy(match->data, data, size); + + return match->u.match_size; +} + +static unsigned int __add_cgroup_match(unsigned int classid, ipt_entry_match_t *start) +{ + /* cgroup => "--cgroup 0" */ + ipt_cgroup_info_t cgroup; + memset(&cgroup, 0, sizeof(ipt_cgroup_info_t)); + cgroup.id = classid; + /* match_cgroup => "-m cgroup" */ + return __add_match(IPTC_CGROUP, start, sizeof(ipt_cgroup_info_t), &cgroup); +} + +static unsigned int __add_nfacct_match(const char *nfacct_name, ipt_entry_match_t *start) +{ + /* nfacct => "--nfacct_name " */ + ipt_nfacct_info_t nfacct; + memset(&nfacct, 0, sizeof(ipt_nfacct_info_t)); + strncpy(nfacct.name, nfacct_name, sizeof(nfacct.name)); + /* match_nfacct => "-m nfacct" */ + return __add_match(IPTC_NFACCT, start, sizeof(ipt_nfacct_info_t), &nfacct); +} + +static int __create_entry_data(unsigned char *entry, unsigned char *mask, + iptables_rule_s *rule) +{ + ipt_entry_t *e = NULL; + ipt_entry_target_t *target = NULL; + unsigned int size_match = 0; + + if (!rule->chain || !rule->ifname || + (rule->classid < 0) || !rule->nfacct_name) { + STC_LOGE("Invalid parameters"); + return STC_ERROR_INVALID_PARAMETER; + } + + e = (ipt_entry_t *)(entry); + + /* entry size */ + e->target_offset = SIZE_ENTRY + SIZE_CGROUP_MATCH + SIZE_NFACCT_MATCH; + e->next_offset = SIZE_TOTAL; + + switch (rule->type) { + case IPTABLES_RULE_IN: + /* entry => "-i wlan0 */ + strncpy(e->ip.iniface, rule->ifname, IFNAMSIZ); + memset(&(e->ip.iniface_mask), 0xFF, IFNAMSIZ); + break; + case IPTABLES_RULE_OUT: + /* entry => "-o wlan0 */ + strncpy(e->ip.outiface, rule->ifname, IFNAMSIZ); + memset(&(e->ip.outiface_mask), 0xFF, IFNAMSIZ); + break; + default: + STC_LOGE("Invalid parameter"); + return STC_ERROR_INVALID_PARAMETER; + } + + size_match = __add_cgroup_match(rule->classid, (ipt_entry_match_t *) e->elems); + size_match += __add_nfacct_match(rule->nfacct_name, (ipt_entry_match_t *) (e->elems + size_match)); + + /* target => "-j ACCEPT" */ + target = (ipt_entry_target_t *) (e->elems + size_match); + target->u.target_size = SIZE_TARGET; + if (rule->target) + strncpy(target->u.user.name, rule->target, sizeof(target->u.user.name)); + + memset(mask, 0xFF, sizeof(ipt_entry_t) + + sizeof(ipt_entry_match_t) + sizeof(ipt_entry_match_t)); + + return STC_ERROR_NONE; +} + +int iptables_add_rule(iptables_rule_s *rule) +{ + ipt_handle_t *handle; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + const char *chain = rule->chain; + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + return STC_ERROR_OPERATION_FAILED; + } + + handle = iptc_init(IPTC_TABLE); + if (handle == NULL) { + STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_is_chain(chain, handle)) { + STC_LOGW("chain not present [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (iptc_check_entry(chain, (const ipt_entry_t *)entry, mask, handle)) { + STC_LOGW("Entry already present"); + iptc_free(handle); + return STC_ERROR_NONE; + } + + if (!iptc_append_entry(chain, (const ipt_entry_t *)entry, handle)) { + STC_LOGW("iptc_append_entry failed [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_commit(handle)) { + STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + iptc_free(handle); + + STC_LOGI("Success adding rule"); + return STC_ERROR_NONE; +} + +int iptables_remove_rule(iptables_rule_s *rule) +{ + ipt_handle_t *handle; + unsigned char entry[SIZE_TOTAL] = {0, }; + unsigned char mask[SIZE_TOTAL] = {0, }; + + const char *chain = rule->chain; + + if (__create_entry_data(entry, mask, rule) != 0) { + STC_LOGE("Failed to create entry"); + return STC_ERROR_OPERATION_FAILED; + } + + handle = iptc_init(IPTC_TABLE); + if (handle == NULL) { + STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_is_chain(chain, handle)) { + STC_LOGW("chain not present [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_delete_entry(chain, (const ipt_entry_t *)entry, mask, handle)) { + STC_LOGW("iptc_delete_entry failed [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_commit(handle)) { + STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + iptc_free(handle); + + STC_LOGI("Success removing rule"); + return STC_ERROR_NONE; +} + +int iptables_add_chain(const char *chain) +{ + ipt_handle_t *handle; + + handle = iptc_init(IPTC_TABLE); + if (handle == NULL) { + STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (iptc_is_chain(chain, handle)) { + STC_LOGW("chain already exists"); + iptc_free(handle); + return STC_ERROR_NONE; + } + + if (!iptc_create_chain(chain, handle)) { + STC_LOGE("Failed to create chaing [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_commit(handle)) { + STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + iptc_free(handle); + + STC_LOGI("Success adding chain"); + return 0; +} + +int iptables_remove_chain(const char *chain) +{ + ipt_handle_t *handle; + + handle = iptc_init(IPTC_TABLE); + if (handle == NULL) { + STC_LOGE("iptc_init failed [%s]", iptc_strerror(errno)); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_is_chain(chain, handle)) { + STC_LOGW("chain not present"); + iptc_free(handle); + return STC_ERROR_NONE; + } + + iptc_flush_entries(chain, handle); + + if (!iptc_delete_chain(chain, handle)) { + STC_LOGE("Failed to delete chain [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + if (!iptc_commit(handle)) { + STC_LOGE("Failed to iptc_commit [%s]", iptc_strerror(errno)); + iptc_free(handle); + return STC_ERROR_OPERATION_FAILED; + } + + iptc_free(handle); + + STC_LOGI("Success removing chain"); + return STC_ERROR_NONE; +} diff --git a/src/helper/helper-iptables.h b/src/helper/helper-iptables.h new file mode 100755 index 0000000..a306b9f --- /dev/null +++ b/src/helper/helper-iptables.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * Manage iptables rule using libiptc + */ +#ifndef __STC_HELPER_IPTABLES_H__ +#define __STC_HELPER_IPTABLES_H__ + +#include + +#define RULE_SIZE 64 + +typedef enum { + IPTABLES_CHAIN_INPUT, + IPTABLES_CHAIN_OUTPUT +} iptables_chain_e; + +typedef enum { + IPTABLES_RULE_IN, + IPTABLES_RULE_OUT +} iptables_rule_type_e; + +typedef enum { + IPTABLES_ACTION_ACCEPT, + IPTABLES_ACTION_DROP +} iptables_target_action_e; + +typedef struct { + char *chain; + iptables_rule_type_e type; + char *ifname; + int classid; + char *nfacct_name; + char *target; +} iptables_rule_s; + +/** + * @desc This function adds a new iptables rule. + * @return 0 on success and negative value if error. + */ +int iptables_add_rule(iptables_rule_s *rule); + +/** + * @desc This function removes already set iptables rule. + * @return 0 on success and negative value if error. + */ +int iptables_remove_rule(iptables_rule_s *rule); + +/** + * @desc This function adds a new iptables chain. + * @return 0 on success and negative value if error. + */ +int iptables_add_chain(const char *chain); + +/** + * @desc This function removes already set iptables chain. + * @return 0 on success and negative value if error. + */ +int iptables_remove_chain(const char *chain); + +#endif /*__STC_HELPER_IPTABLES_H__*/ diff --git a/src/stc-iptables-gdbus.c b/src/stc-iptables-gdbus.c new file mode 100755 index 0000000..4f610a1 --- /dev/null +++ b/src/stc-iptables-gdbus.c @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "stc-iptables.h" +#include "stc-iptables-gdbus.h" + +static gboolean __stc_iptables_gdbus_chain_init(stc_iptables_s *stc_iptables) +{ + __STC_LOG_FUNC_ENTER__; + gboolean ret = TRUE; + gchar *s = NULL; + + StcObjectSkeleton *object = NULL; + StcChain *chain = NULL; + s = g_strdup_printf(STC_IPTABLES_DBUS_SERVICE_CHAIN_PATH); + + /* Add interface to default object path */ + object = stc_object_skeleton_new(s); + g_free(s); + + chain = stc_chain_skeleton_new(); + stc_object_skeleton_set_chain(object, chain); + g_object_unref(chain); + + g_signal_connect(chain, "handle-ipt-add-chain", + G_CALLBACK(handle_iptables_add_chain), + stc_iptables); + + g_signal_connect(chain, "handle-ipt-remove-chain", + G_CALLBACK(handle_iptables_remove_chain), + stc_iptables); + + g_signal_connect(chain, "handle-ip6t-add-chain", + G_CALLBACK(handle_ip6tables_add_chain), + stc_iptables); + + g_signal_connect(chain, "handle-ipt6-remove-chain", + G_CALLBACK(handle_ip6tables_remove_chain), + stc_iptables); + + g_dbus_object_manager_server_export(stc_iptables->obj_mgr, + G_DBUS_OBJECT_SKELETON(object)); + g_object_unref(object); + + stc_iptables->chain_obj = (gpointer)chain; + + __STC_LOG_FUNC_EXIT__; + return ret; +} + +static gboolean __stc_iptables_gdbus_rule_init(stc_iptables_s *stc_iptables) +{ + __STC_LOG_FUNC_ENTER__; + gboolean ret = TRUE; + gchar *s = NULL; + + StcObjectSkeleton *object = NULL; + StcRule *rule = NULL; + s = g_strdup_printf(STC_IPTABLES_DBUS_SERVICE_RULE_PATH); + + /* Add interface to default object path */ + object = stc_object_skeleton_new(s); + g_free(s); + + rule = stc_rule_skeleton_new(); + stc_object_skeleton_set_rule(object, rule); + g_object_unref(rule); + + g_signal_connect(rule, "handle-ipt-add-rule", + G_CALLBACK(handle_iptables_add_rule), + stc_iptables); + + g_signal_connect(rule, "handle-ipt-remove-rule", + G_CALLBACK(handle_iptables_remove_rule), + stc_iptables); + + g_signal_connect(rule, "handle-ip6t-add-rule", + G_CALLBACK(handle_ip6tables_add_rule), + stc_iptables); + + g_signal_connect(rule, "handle-ip6t-remove-rule", + G_CALLBACK(handle_ip6tables_remove_rule), + stc_iptables); + + g_dbus_object_manager_server_export(stc_iptables->obj_mgr, + G_DBUS_OBJECT_SKELETON(object)); + g_object_unref(object); + + stc_iptables->rule_obj = (gpointer)rule; + + __STC_LOG_FUNC_EXIT__; + return ret; +} + +static void __stc_iptables_gdbus_on_bus_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_iptables_s* stc_iptables = (stc_iptables_s*)user_data; + + stc_iptables->obj_mgr = g_dbus_object_manager_server_new("/net/stc"); + + STC_LOGD("path : %s", name); + + stc_iptables->connection = connection; + + if (__stc_iptables_gdbus_chain_init(stc_iptables) == FALSE) { + STC_LOGE("Can not signal connect to chain"); + /* Deinitialize and quit iptables */ + } + + if (__stc_iptables_gdbus_rule_init(stc_iptables) == FALSE) { + STC_LOGE("Can not signal connect to rule"); + /* Deinitialize and quit iptables */ + } + + g_dbus_object_manager_server_set_connection(stc_iptables->obj_mgr, + stc_iptables->connection); + + __STC_LOG_FUNC_EXIT__; +} + +static void __stc_iptables_gdbus_on_name_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + STC_LOGD("name : %s", name); +} + +static void __stc_iptables_gdbus_on_name_lost(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + STC_LOGD("name : %s", name); +} + +void stc_iptables_gdbus_init(gpointer stc_data) +{ + __STC_LOG_FUNC_ENTER__; + + stc_iptables_s *stc_iptables = (stc_iptables_s *)stc_data; + + stc_iptables->gdbus_owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, + STC_IPTABLES_DBUS_SERVICE, + G_BUS_NAME_OWNER_FLAGS_NONE, + __stc_iptables_gdbus_on_bus_acquired, + __stc_iptables_gdbus_on_name_acquired, + __stc_iptables_gdbus_on_name_lost, + stc_iptables, + NULL); + + __STC_LOG_FUNC_EXIT__; +} + +void stc_iptables_gdbus_deinit(gpointer stc_data) +{ + __STC_LOG_FUNC_ENTER__; + + stc_iptables_s *stc_iptables = (stc_iptables_s *)stc_data; + + g_bus_unown_name(stc_iptables->gdbus_owner_id); + + stc_iptables->rule_obj = NULL; + stc_iptables->chain_obj = NULL; + + __STC_LOG_FUNC_EXIT__; +} + +void stc_iptables_gdbus_dict_foreach(GVariantIter *iter, + dbus_dict_cb cb, void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + + gchar *key = NULL; + GVariant *value = NULL; + + if (!cb) { + __STC_LOG_FUNC_EXIT__; + return; + } + + while (g_variant_iter_loop(iter, "{sv}", &key, &value)) { + /* STC_DEBUG_GDBUS_KEY_VALUE(key, value); */ + if (key && cb) + cb(key, value, user_data); + } + + __STC_LOG_FUNC_EXIT__; +} diff --git a/src/stc-iptables-log.c b/src/stc-iptables-log.c new file mode 100755 index 0000000..05725a5 --- /dev/null +++ b/src/stc-iptables-log.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include "stc-iptables-log.h" + +#define LOG_FILE_PATH "/opt/usr/data/network/stc-iptables.log" +#define MAX_LOG_SIZE 1 * 1024 * 1024 +#define MAX_LOG_COUNT 1 + +static FILE *log_file = NULL; + +static void __stc_iptables_log_update_file_revision(int rev) +{ + int next_log_rev = 0; + char *log_file = NULL; + char *next_log_file = NULL; + + next_log_rev = rev + 1; + + log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev); + next_log_file = g_strdup_printf("%s.%d", LOG_FILE_PATH, next_log_rev); + + if (next_log_rev >= MAX_LOG_COUNT) + remove(next_log_file); + + if (access(next_log_file, F_OK) == 0) + __stc_iptables_log_update_file_revision(next_log_rev); + + if (rename(log_file, next_log_file) != 0) + remove(log_file); + + g_free(log_file); + g_free(next_log_file); +} + +static void __stc_iptables_log_make_backup(void) +{ + const int rev = 0; + char *backup = NULL; + + backup = g_strdup_printf("%s.%d", LOG_FILE_PATH, rev); + + if (access(backup, F_OK) == 0) + __stc_iptables_log_update_file_revision(rev); + + if (rename(LOG_FILE_PATH, backup) != 0) + remove(LOG_FILE_PATH); + + g_free(backup); +} + +static void __stc_iptables_log_get_local_time(char *strtime, const int size) +{ + time_t buf; + struct tm *local_ptm; + struct tm result = {0, }; + + time(&buf); + buf = time(NULL); + local_ptm = localtime_r(&buf, &result); + + if (local_ptm) + strftime(strtime, size, "%m/%d %H:%M:%S", local_ptm); +} + +void stc_iptables_log(const char *format, ...) +{ + va_list ap; + int log_size = 0; + struct stat buf; + char str[256]; + char strtime[40]; + + if (log_file == NULL) + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + + if (log_file == NULL) + return; + + va_start(ap, format); + + if (fstat(fileno(log_file), &buf) == 0) + log_size = buf.st_size; + + if (log_size >= MAX_LOG_SIZE) { + fclose(log_file); + log_file = NULL; + + __stc_iptables_log_make_backup(); + + log_file = (FILE *)fopen(LOG_FILE_PATH, "a+"); + + if (log_file == NULL) { + va_end(ap); + return; + } + } + + __stc_iptables_log_get_local_time(strtime, sizeof(strtime)); + + if (vsnprintf(str, sizeof(str), format, ap) > 0) + fprintf(log_file, "%s %s", strtime, str); + + va_end(ap); +} + +gboolean stc_iptables_log_sync(gpointer data) +{ + if (log_file) { + fflush(log_file); + fsync(log_file->_fileno); + } + + return TRUE; +} + +void stc_iptables_log_cleanup(void) +{ + if (log_file == NULL) + return; + + fclose(log_file); + log_file = NULL; +} diff --git a/src/stc-iptables-util.c b/src/stc-iptables-util.c new file mode 100755 index 0000000..6ca1094 --- /dev/null +++ b/src/stc-iptables-util.c @@ -0,0 +1,445 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "stc-iptables-util.h" +#include "helper-iptables.h" +#include "helper-ip6tables.h" + +#define STC_IPTABLES_DBUS_ERROR_NAME "net.stc.iptables.Error.Failed" + +#define STC_IPTABLES_DBUS_REPLY(invocation, parameters) \ + g_dbus_method_invocation_return_value((invocation), parameters); + +#define STC_IPTABLES_DBUS_REPLY_ERROR(invocation, err_num) \ + g_dbus_method_invocation_return_dbus_error((invocation), \ + STC_IPTABLES_DBUS_ERROR_NAME, \ + stc_iptables_err_strs[-(err_num)]) + +static const gchar *stc_iptables_err_strs[] = { + "ERROR_NONE", + "FAIL", + "DB_FAILED", + "OUT_OF_MEMORY", + "INVALID_PARAMETER", + "NO_DATA", + "UNINITIALIZED", + "NOTIMPL" + }; + +void __stc_extract_rule(const char *key, GVariant *value, + void *user_data) +{ + iptables_rule_s *rule = (iptables_rule_s *)user_data; + if (rule == NULL) + return; + + if (!g_strcmp0(key, "chain")) { + gsize len = 0; + rule->chain = g_variant_dup_string(value, &len); + STC_LOGD("chain: [%s]", rule->chain); + + } else if (!g_strcmp0(key, "type")) { + rule->type = g_variant_get_uint32(value); + STC_LOGD("type: [%d]", rule->type); + + } else if (!g_strcmp0(key, "ifname")) { + gsize len = 0; + rule->ifname = g_variant_dup_string(value, &len); + STC_LOGD("ifname: [%s]", rule->ifname); + + } else if (!g_strcmp0(key, "cgroup")) { + rule->classid = g_variant_get_uint32(value); + STC_LOGD("classid: [%d]", rule->classid); + + } else if (!g_strcmp0(key, "nfacct")) { + gsize len = 0; + rule->nfacct_name = g_variant_dup_string(value, &len); + STC_LOGD("nfacct_name: [%s]", rule->nfacct_name); + + } else if (!g_strcmp0(key, "target")) { + gsize len = 0; + rule->target = g_variant_dup_string(value, &len); + STC_LOGD("target: [%s]", rule->target); + + } else { + STC_LOGD("Unknown rule"); + } +} + +void __stc_extract_6_rule(const char *key, GVariant *value, + void *user_data) +{ + ip6tables_rule_s *rule = (ip6tables_rule_s *)user_data; + if (rule == NULL) + return; + + if (!g_strcmp0(key, "chain")) { + gsize len = 0; + rule->chain = g_variant_dup_string(value, &len); + STC_LOGD("chain: [%s]", rule->chain); + + } else if (!g_strcmp0(key, "type")) { + rule->type = g_variant_get_uint32(value); + STC_LOGD("type: [%d]", rule->type); + + } else if (!g_strcmp0(key, "ifname")) { + gsize len = 0; + rule->ifname = g_variant_dup_string(value, &len); + STC_LOGD("ifname: [%s]", rule->ifname); + + } else if (!g_strcmp0(key, "cgroup")) { + rule->classid = g_variant_get_uint32(value); + STC_LOGD("classid: [%d]", rule->classid); + + } else if (!g_strcmp0(key, "nfacct")) { + gsize len = 0; + rule->nfacct_name = g_variant_dup_string(value, &len); + STC_LOGD("nfacct_name: [%s]", rule->nfacct_name); + + } else if (!g_strcmp0(key, "target")) { + gsize len = 0; + rule->target = g_variant_dup_string(value, &len); + STC_LOGD("target: [%s]", rule->target); + + } else { + STC_LOGD("Unknown rule"); + } +} + +gboolean handle_iptables_add_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rules, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + if (rules != NULL) { + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + + g_variant_get(rules, "aa{sv}", &iter); + + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1); + if (rule != NULL) { + memset(rule, 0, sizeof(iptables_rule_s)); + + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_rule, + rule); + + ret = iptables_add_rule(rule); + if (ret != STC_ERROR_NONE) { + STC_LOGE("Failed add rule [%s:%d:%s:%d:%s:%s]", rule->chain, + rule->type, rule->ifname, rule->classid, + rule->nfacct_name, rule->target); + } + + FREE(rule->chain); + FREE(rule->ifname); + FREE(rule->nfacct_name); + FREE(rule->target); + } + + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + } else { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, + STC_ERROR_INVALID_PARAMETER); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_iptables_remove_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rules, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + if (rules != NULL) { + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + g_variant_get(rules, "aa{sv}", &iter); + + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + iptables_rule_s *rule = MALLOC0(iptables_rule_s, 1); + if (rule != NULL) { + memset(rule, 0, sizeof(iptables_rule_s)); + + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_rule, + rule); + + ret = iptables_remove_rule(rule); + if (ret != STC_ERROR_NONE) { + STC_LOGE("Failed remove rule [%s:%d:%s:%d:%s:%s]", rule->chain, + rule->type, rule->ifname, rule->classid, + rule->nfacct_name, rule->target); + } + + FREE(rule->chain); + FREE(rule->ifname); + FREE(rule->nfacct_name); + FREE(rule->target); + } + + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + } else { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, + STC_ERROR_INVALID_PARAMETER); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_iptables_add_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + ret = iptables_add_chain(chain); + if (ret < STC_ERROR_NONE) { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_iptables_remove_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + ret = iptables_remove_chain(chain); + if (ret < STC_ERROR_NONE) { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_ip6tables_add_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rules, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + if (rules != NULL) { + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + + g_variant_get(rules, "aa{sv}", &iter); + + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1); + if (rule != NULL) { + memset(rule, 0, sizeof(ip6tables_rule_s)); + + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_6_rule, + rule); + + ret = ip6tables_add_rule(rule); + if (ret != STC_ERROR_NONE) { + STC_LOGE("Failed add rule [%s:%d:%s:%d:%s:%s]", rule->chain, + rule->type, rule->ifname, rule->classid, + rule->nfacct_name, rule->target); + } + + FREE(rule->chain); + FREE(rule->ifname); + FREE(rule->nfacct_name); + FREE(rule->target); + } + + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + } else { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, + STC_ERROR_INVALID_PARAMETER); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_ip6tables_remove_rule(StcRule *object, + GDBusMethodInvocation *invocation, + GVariant *rules, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + if (rules != NULL) { + GVariantIter *iter = NULL; + GVariantIter *iter_row = NULL; + g_variant_get(rules, "aa{sv}", &iter); + + while (g_variant_iter_next(iter, "a{sv}", &iter_row)) { + ip6tables_rule_s *rule = MALLOC0(ip6tables_rule_s, 1); + if (rule != NULL) { + memset(rule, 0, sizeof(ip6tables_rule_s)); + + stc_iptables_gdbus_dict_foreach(iter_row, + __stc_extract_6_rule, + rule); + + ret = ip6tables_remove_rule(rule); + if (ret != STC_ERROR_NONE) { + STC_LOGE("Failed remove rule [%s:%d:%s:%d:%s:%s]", rule->chain, + rule->type, rule->ifname, rule->classid, + rule->nfacct_name, rule->target); + } + + FREE(rule->chain); + FREE(rule->ifname); + FREE(rule->nfacct_name); + FREE(rule->target); + } + + g_variant_iter_free(iter_row); + } + g_variant_iter_free(iter); + } else { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, + STC_ERROR_INVALID_PARAMETER); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_ip6tables_add_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + ret = ip6tables_add_chain(chain); + if (ret < STC_ERROR_NONE) { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} + +gboolean handle_ip6tables_remove_chain(StcChain *object, + GDBusMethodInvocation *invocation, + const gchar *chain, + void *user_data) +{ + __STC_LOG_FUNC_ENTER__; + stc_error_e ret = STC_ERROR_NONE; + GVariant *return_parameters = NULL; + + ret = ip6tables_remove_chain(chain); + if (ret < STC_ERROR_NONE) { + STC_IPTABLES_DBUS_REPLY_ERROR(invocation, ret); + __STC_LOG_FUNC_EXIT__; + return TRUE; + } + + return_parameters = g_variant_new("(i)", STC_ERROR_NONE); + + STC_DEBUG_GDBUS_VARIANT("Return parameters: ", return_parameters); + STC_IPTABLES_DBUS_REPLY(invocation, return_parameters); + + __STC_LOG_FUNC_EXIT__; + return TRUE; +} diff --git a/src/stc-iptables.c b/src/stc-iptables.c new file mode 100755 index 0000000..e9843aa --- /dev/null +++ b/src/stc-iptables.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "stc-iptables.h" +#include "stc-iptables-util.h" +#include "stc-iptables-gdbus.h" +#include "helper-iptables.h" + +static stc_iptables_s *g_stc_iptables = NULL; + +static void __stc_iptables_deinit(void) +{ + __STC_LOG_FUNC_ENTER__; + + if (!g_stc_iptables) { + STC_LOGE("Memory for iptables structure is not allocated"); + return; + } + + stc_iptables_gdbus_deinit((gpointer)g_stc_iptables); + + STC_LOGI("stc iptables deinitialized"); + FREE(g_stc_iptables); + __STC_LOG_FUNC_EXIT__; +} + +static stc_iptables_s *__stc_iptables_init(void) +{ + __STC_LOG_FUNC_ENTER__; + stc_iptables_s *stc_iptables; + + stc_iptables = MALLOC0(stc_iptables_s, 1); + if (!stc_iptables) { + STC_LOGE("Failed to allocate memory for iptables structure"); + return NULL; + } + g_stc_iptables = stc_iptables; + + stc_iptables_gdbus_init((gpointer)g_stc_iptables); + + STC_LOGI("stc iptables initialized"); + __STC_LOG_FUNC_EXIT__; + return g_stc_iptables; +} + +gint32 main(gint32 argc, gchar *argv[]) +{ + GMainLoop *main_loop = NULL; + gint32 ret = -1; + int sync_timer = 0; + + STC_LOGI("Smart Traffic Control Iptables"); + + if (daemon(0, 0) != 0) + STC_LOGE("Can't start daemon"); + + /* Initialize required subsystems */ +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + + sync_timer = g_timeout_add(LOG_SYNC_TIME, + stc_iptables_log_sync, NULL); + + /* Crate the GLIB main loop */ + main_loop = g_main_loop_new(NULL, FALSE); + + g_stc_iptables = __stc_iptables_init(); + if (!g_stc_iptables) + goto fail; + g_stc_iptables->main_loop = main_loop; + + /* Run the main loop */ + g_main_loop_run(main_loop); + + ret = 0; + +fail: + + if (sync_timer > 0) + g_source_remove(sync_timer); + + stc_iptables_log_cleanup(); + __stc_iptables_deinit(); + + if (main_loop) + g_main_loop_unref(main_loop); + + return ret; +} + +stc_iptables_s *stc_get_iptables(void) +{ + return g_stc_iptables; +} diff --git a/stc-iptables.manifest b/stc-iptables.manifest new file mode 100644 index 0000000..81ace0c --- /dev/null +++ b/stc-iptables.manifest @@ -0,0 +1,6 @@ + + + + + + diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100755 index 0000000..80299b3 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,32 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(stc_ipt_test C) + +SET(TARGET_STC_IPT_TEST "stc_ipt_test") + +SET(STC_IPT_TEST_INCLUDE_DIR ${STC_IPT_TEST_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../include) +INCLUDE_DIRECTORIES(${STC_IPT_TEST_INCLUDE_DIR}) + +INCLUDE(FindPkgConfig) +pkg_check_modules(TARGET_STC_IPT_TEST REQUIRED ${COMMON_DEPS}) +FOREACH(flag ${TARGET_STC_IPT_TEST_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") + MESSAGE(${flag}) +ENDFOREACH() + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -fPIE") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie") + +SET(stc_ipt_test + stc_ipt_menu.c + stc_ipt_chain.c + stc_ipt_rule.c + stc_ipt_gdbus.c + stc_ipt_sys.c + stc_ipt_test.c +) + +ADD_EXECUTABLE(${PROJECT_NAME} ${stc_ipt_test}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${TARGET_STC} ${TARGET_STC_IPT_TEST_LDFLAGS}) + + +INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION ${BIN_DIR}) diff --git a/test/stc_ipt_chain.c b/test/stc_ipt_chain.c new file mode 100755 index 0000000..ec0ed41 --- /dev/null +++ b/test/stc_ipt_chain.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "stc_ipt_test.h" +#include "stc_ipt_gdbus.h" +#include "stc_ipt_sys.h" +#include "stc_ipt_menu.h" + +static char g_chain_name[MENU_DATA_SIZE] = "STC_CHAIN"; + +static int __stc_ipt_add_chain(void) +{ + GVariant *message = NULL; + GVariant *params = NULL; + int err = STC_ERROR_NONE; + int result = 0; + + params = g_variant_new("(s)", g_chain_name); + + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_CHAIN_PATH, + STC_IPT_DBUS_CHAIN_INTERFACE, + STC_IPT_DBUS_METHOD_IPT_ADD_CHAIN, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully add chain [%d]" LOG_END, result); + g_variant_unref(message); + + stc_ipt_exe_cmd(CHECK_IPTABLES); + + return err; +} + +static int __stc_ip6t_add_chain(void) +{ + GVariant *message = NULL; + GVariant *params = NULL; + int err = STC_ERROR_NONE; + int result = 0; + + params = g_variant_new("(s)", g_chain_name); + + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_CHAIN_PATH, + STC_IPT_DBUS_CHAIN_INTERFACE, + STC_IPT_DBUS_METHOD_IP6T_ADD_CHAIN, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully add 6 chain [%d]" LOG_END, result); + g_variant_unref(message); + + stc_ipt_exe_cmd(CHECK_IP6TABLES); + + return err; +} + +static int __stc_ipt_remove_chain(void) +{ + GVariant *message = NULL; + GVariant *params = NULL; + int err = STC_ERROR_NONE; + int result = 0; + + params = g_variant_new("(s)", g_chain_name); + + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_CHAIN_PATH, + STC_IPT_DBUS_CHAIN_INTERFACE, + STC_IPT_DBUS_METHOD_IPT_REMOVE_CHAIN, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + stc_ipt_exe_cmd(CHECK_IPTABLES); + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully remove chain [%d]" LOG_END, result); + g_variant_unref(message); + + return err; +} + +static int __stc_ip6t_remove_chain(void) +{ + GVariant *message = NULL; + GVariant *params = NULL; + int err = STC_ERROR_NONE; + int result = 0; + + params = g_variant_new("(s)", g_chain_name); + + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_CHAIN_PATH, + STC_IPT_DBUS_CHAIN_INTERFACE, + STC_IPT_DBUS_METHOD_IP6T_REMOVE_CHAIN, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + stc_ipt_exe_cmd(CHECK_IP6TABLES); + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully remove 6 chain [%d]" LOG_END, result); + g_variant_unref(message); + + return err; +} + +static int test_stc_ipt_add_chain(MManager *mm, struct menu_data *menu) +{ + int err = STC_ERROR_NONE; + + err = __stc_ipt_add_chain(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to add chain" LOG_END); + + err = __stc_ip6t_add_chain(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to add 6 chain" LOG_END); + + return err; +} + +static int test_stc_ipt_remove_chain(MManager *mm, struct menu_data *menu) +{ + int err = STC_ERROR_NONE; + + err = __stc_ipt_remove_chain(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to remove chain" LOG_END); + + err = __stc_ip6t_remove_chain(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to remove 6 chain" LOG_END); + + return err; +} + +struct menu_data menu_chain[] = { + { "1", LOG_LIGHTMAGENTA "[Set]" LOG_END " Chain Name", NULL, NULL, g_chain_name}, + { "a", LOG_LIGHTBLUE "[Add]" LOG_END " Chain", NULL, test_stc_ipt_add_chain, NULL}, + { "r", LOG_LIGHTMAGENTA "[Remove]" LOG_END " Chain", NULL, test_stc_ipt_remove_chain, NULL}, + { NULL, NULL, }, +}; diff --git a/test/stc_ipt_chain.h b/test/stc_ipt_chain.h new file mode 100755 index 0000000..79ebe5d --- /dev/null +++ b/test/stc_ipt_chain.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TEST_STC_IPT_CHAIN_H__ +#define __TEST_STC_IPT_CHAIN_H__ + +#endif /** __TEST_STC_IPT_CHAIN_H__ */ diff --git a/test/stc_ipt_gdbus.c b/test/stc_ipt_gdbus.c new file mode 100755 index 0000000..c168743 --- /dev/null +++ b/test/stc_ipt_gdbus.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include "stc_ipt_test.h" +#include "stc_ipt_gdbus.h" +#include "stc_ipt_menu.h" + +static __thread stc_ipt_dbus_conn_data_s g_stc_ipt_dbus_conn = { NULL, NULL }; + +static int __stc_ipt_convert_error_string_to_enum(const char *error) +{ + msg("Passed error value [%s]", error); + + if (NULL != strstr(error, "NoReply")) + return STC_ERROR_INVALID_OPERATION; + else if (NULL != strstr(error, "Failed")) + return STC_ERROR_OPERATION_FAILED; + else if (NULL != strstr(error, "UnknownMethod")) + return STC_ERROR_INVALID_OPERATION; + else if (NULL != strstr(error, "InvalidArguments")) + return STC_ERROR_INVALID_PARAMETER; + else if (NULL != strstr(error, "AccessDenied")) + return STC_ERROR_PERMISSION_DENIED; + else if (NULL != strstr(error, "PermissionDenied")) + return STC_ERROR_PERMISSION_DENIED; + + return STC_ERROR_OPERATION_FAILED; +} + +int stc_ipt_dbus_create(void) +{ + GError *err = NULL; + +#if !GLIB_CHECK_VERSION(2, 36, 0) + g_type_init(); +#endif + + g_stc_ipt_dbus_conn.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err); + if (g_stc_ipt_dbus_conn.connection == NULL) { + if (err != NULL) { + msg("Failed to connect to the D-BUS daemon [%s]", err->message); + g_error_free(err); + } + return STC_ERROR_OPERATION_FAILED; + } + + g_stc_ipt_dbus_conn.cancellable = g_cancellable_new(); + + return STC_ERROR_NONE; +} + +int stc_ipt_dbus_destroy(void) +{ + g_cancellable_cancel(g_stc_ipt_dbus_conn.cancellable); + g_object_unref(g_stc_ipt_dbus_conn.cancellable); + g_stc_ipt_dbus_conn.cancellable = NULL; + + g_object_unref(g_stc_ipt_dbus_conn.connection); + g_stc_ipt_dbus_conn.connection = NULL; + + return STC_ERROR_NONE; +} + +GDBusConnection *stc_ipt_dbus_get_connection(void) +{ + return g_stc_ipt_dbus_conn.connection; +} + +GCancellable *stc_ipt_dbus_get_cancellable(void) +{ + return g_stc_ipt_dbus_conn.cancellable; +} + +GVariant *stc_ipt_dbus_invoke_method(const char *dest, + const char *path, const char *interface_name, const char *method, + GVariant *params, int *dbus_error) +{ + GError *error = NULL; + GVariant *reply = NULL; + *dbus_error = STC_ERROR_NONE; + GDBusConnection *connection; + + connection = stc_ipt_dbus_get_connection(); + if (connection == NULL) { + msg(LOG_RED "GDBusconnection is NULL" LOG_END); + *dbus_error = STC_ERROR_INVALID_OPERATION; + return reply; + } + + reply = g_dbus_connection_call_sync(connection, + dest, + path, + interface_name, + method, + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + STC_IPT_DBUS_REPLY_TIMEOUT, + stc_ipt_dbus_get_cancellable(), + &error); + + if (reply == NULL) { + if (error != NULL) { + msg("g_dbus_connection_call_sync() failed " + "error " LOG_RED "[%d: %s]" LOG_END, error->code, error->message); + *dbus_error = __stc_ipt_convert_error_string_to_enum(error->message); + g_error_free(error); + } else { + msg(LOG_RED "g_dbus_connection_call_sync() failed" LOG_END); + *dbus_error = STC_ERROR_OPERATION_FAILED; + } + + return NULL; + } + + return reply; +} + +int stc_ipt_dbus_invoke_method_nonblock(const char *dest, + const char *path, const char *interface_name, const char *method, + GVariant *params, int timeout, + GAsyncReadyCallback notify_func, void *user_data) +{ + GDBusConnection *connection; + + connection = stc_ipt_dbus_get_connection(); + if (connection == NULL) { + msg("GDBusconnection is NULL"); + return STC_ERROR_INVALID_OPERATION; + } + + g_dbus_connection_call(connection, + dest, + path, + interface_name, + method, + params, + NULL, + G_DBUS_CALL_FLAGS_NONE, + timeout, + stc_ipt_dbus_get_cancellable(), + (GAsyncReadyCallback) notify_func, + (gpointer)user_data); + + return STC_ERROR_NONE; +} diff --git a/test/stc_ipt_gdbus.h b/test/stc_ipt_gdbus.h new file mode 100755 index 0000000..c485750 --- /dev/null +++ b/test/stc_ipt_gdbus.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TEST_STC_IPT_GDBUS_H_ +#define __TEST_STC_IPT_GDBUS_H_ + +#include + +#define STC_IPT_DBUS_REPLY_TIMEOUT (120 * 1000) + +#define STC_IPT_DBUS_SERVICE "net.stc.iptables" +#define STC_IPT_DBUS_RULE_INTERFACE STC_IPT_DBUS_SERVICE ".rule" +#define STC_IPT_DBUS_CHAIN_INTERFACE STC_IPT_DBUS_SERVICE ".chain" +#define STC_IPT_DBUS_RULE_PATH "/net/stc/iptables/rule" +#define STC_IPT_DBUS_CHAIN_PATH "/net/stc/iptables/chain" +#define STC_IPT_DBUS_METHOD_IPT_ADD_CHAIN "IptAddChain" +#define STC_IPT_DBUS_METHOD_IPT_REMOVE_CHAIN "IptRemoveChain" +#define STC_IPT_DBUS_METHOD_IP6T_ADD_CHAIN "Ip6tAddChain" +#define STC_IPT_DBUS_METHOD_IP6T_REMOVE_CHAIN "Ip6tRemoveChain" +#define STC_IPT_DBUS_METHOD_IPT_ADD_RULE "IptAddRule" +#define STC_IPT_DBUS_METHOD_IPT_REMOVE_RULE "IptRemoveRule" +#define STC_IPT_DBUS_METHOD_IP6T_ADD_RULE "Ip6tAddRule" +#define STC_IPT_DBUS_METHOD_IP6T_REMOVE_RULE "Ip6tRemoveRule" + +typedef struct { + GDBusConnection *connection; + GCancellable *cancellable; +} stc_ipt_dbus_conn_data_s; + +int stc_ipt_dbus_create(void); +int stc_ipt_dbus_destroy(void); + +GDBusConnection *stc_ipt_dbus_get_connection(void); +GCancellable *stc_ipt_dbus_get_cancellable(void); + +GVariant *stc_ipt_dbus_invoke_method(const char *dest, + const char *path, const char *interface_name, const char *method, + GVariant *params, int *dbus_error); +int stc_ipt_dbus_invoke_method_nonblock(const char *dest, + const char *path, const char *interface_name, const char *method, + GVariant *params, int timeout, + GAsyncReadyCallback notify_func, void *user_data); + +#endif /** __TEST_STC_IPT_GDBUS_H_ */ diff --git a/test/stc_ipt_menu.c b/test/stc_ipt_menu.c new file mode 100755 index 0000000..a96c50e --- /dev/null +++ b/test/stc_ipt_menu.c @@ -0,0 +1,374 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stc_ipt_menu.h" + +#define DEFAULT_MENU_MENU "m" +#define DEFAULT_MENU_PREV "p" +#define DEFAULT_MENU_QUIT "q" +#define DEFAULT_MENU_NONE "-" +#define TAB_SPACE " " + +struct menu_manager { + GQueue *stack; + GQueue *title_stack; + + struct menu_data *menu; + + char *buf; + + void *user_data; + GMainLoop *mainloop; +}; + + +char key_buffer[MENU_DATA_SIZE]; +int flag_pid_display = 1; + + +static void _show_prompt(void) +{ + msgn("(%5d) >> ", get_tid()); +} + +static void _show_reserved_menu(void) +{ + msg(LOG_DARKGRAY HR_SINGLE2 LOG_END); + msg(LOG_DARKGRAY " [ " LOG_END "%s" LOG_DARKGRAY + " ] " LOG_END "Previous Menu " , DEFAULT_MENU_PREV); + msg(LOG_DARKGRAY " [ " LOG_END "%s" LOG_DARKGRAY + " ] " LOG_END "Show Menu " , DEFAULT_MENU_MENU); + msg(LOG_DARKGRAY " [ " LOG_END "%s" LOG_DARKGRAY + " ] " LOG_END "Quit " , DEFAULT_MENU_QUIT); +} + +static void _show_input_ok(void) +{ + msg("OK."); +} + +static void _show_menu(MManager *m, struct menu_data menu[]) +{ + int i = 0; + int len = 0; + struct menu_data *item; + char title_buf[256] = { 0, }; + + if (!menu) + return; + + msg(""); + msg(HR_DOUBLE); + + len = g_queue_get_length(m->title_stack); + msgn(LOG_YELLOW " Main"); + if (len > 0) { + for (i = 0; i < len; i++) { + msgn(LOG_END " >> " LOG_YELLOW "%s", + (char *)g_queue_peek_nth(m->title_stack, i)); + } + } + msg(LOG_END); + msg(HR_SINGLE); + + hide_pid(); + i = 0; + + while (1) { + item = menu + i; + if (item->key == NULL) + break; + + if (!g_strcmp0(item->key, "-")) { + msgn(" "); + } else if (!g_strcmp0(item->key, "_")) { + msg(LOG_DARKGRAY HR_SINGLE2 LOG_END); + + if (item->callback) + item->callback(m, item); + + i++; + + continue; + } else if (!g_strcmp0(item->key, "*")) { + msg(" %s", item->title); + if (item->callback) + item->callback(m, item); + } else { + msgn(LOG_DARKGRAY " [" LOG_END "%3s" + LOG_DARKGRAY "] " LOG_END, item->key); + } + + memset(title_buf, 0, 256); + if (item->title) { + snprintf(title_buf, MAX_TITLE, "%s", item->title); + + if (strlen(item->title) >= MAX_TITLE) { + title_buf[MAX_TITLE - 2] = '.'; + title_buf[MAX_TITLE - 1] = '.'; + } + } + + if (item->data) { + msg("%s " LOG_LIGHTBLUE "(%s)" LOG_END, + title_buf, item->data); + } else if (!g_strcmp0(item->key, "*")) { + /* none */ + } else { + msg("%s", title_buf); + } + + if (item->sub_menu) + msg("\e[1A\e[%dC >", (int)POS_MORE); + + i++; + } + + show_pid(); + + _show_reserved_menu(); + + msg(HR_DOUBLE); + + _show_prompt(); +} + +static void _show_item_data_input_msg(struct menu_data *item) +{ + msg(""); + msg(HR_DOUBLE); + msg(" Input [%s] data ", item->title); + msg(HR_SINGLE); + msg(" current = [%s]", item->data); + msgn(" new >> "); +} + +static void _move_menu(MManager *mm, struct menu_data menu[], char *key) +{ + struct menu_data *item; + int i = 0; + + if (!mm->menu) + return; + + if (!g_strcmp0(DEFAULT_MENU_PREV, key)) { + if (g_queue_get_length(mm->stack) > 0) { + mm->menu = g_queue_pop_tail(mm->stack); + g_queue_pop_tail(mm->title_stack); + } + + _show_menu(mm, mm->menu); + mm->buf = key_buffer; + + return; + } else if (!g_strcmp0(DEFAULT_MENU_MENU, key)) { + _show_menu(mm, mm->menu); + return; + } else if (!g_strcmp0(DEFAULT_MENU_QUIT, key)) { + g_main_loop_quit(mm->mainloop); + return; + } else if (!g_strcmp0(DEFAULT_MENU_NONE, key)) { + _show_prompt(); + return; + } + + while (1) { + int ret = RET_SUCCESS; + item = menu + i; + if (item->key == NULL) + break; + + if (!g_strcmp0(item->key, key)) { + if (item->callback) { + ret = item->callback(mm, item); + _show_prompt(); + } + + if (RET_SUCCESS == ret) { + if (item->sub_menu) { + g_queue_push_tail(mm->stack, mm->menu); + g_queue_push_tail(mm->title_stack, (gpointer *)item->title); + + mm->menu = item->sub_menu; + _show_menu(mm, mm->menu); + mm->buf = key_buffer; + } + + if (item->data) { + _show_item_data_input_msg(item); + mm->buf = item->data; + } + } + + return; + } + + i++; + } + + _show_prompt(); +} + +MManager *menu_manager_new(struct menu_data items[], GMainLoop *mainloop) +{ + MManager *mm; + + mm = calloc(sizeof(struct menu_manager), 1); + if (!mm) + return NULL; + + mm->stack = g_queue_new(); + mm->title_stack = g_queue_new(); + mm->menu = items; + mm->mainloop = mainloop; + + return mm; +} + +int menu_manager_run(MManager *mm) +{ + _show_menu(mm, mm->menu); + + mm->buf = key_buffer; + + return 0; +} + +int menu_manager_set_user_data(MManager *mm, void *user_data) +{ + if (!mm) + return -1; + + mm->user_data = user_data; + + return 0; +} + +void *menu_manager_ref_user_data(MManager *mm) +{ + if (!mm) + return NULL; + + return mm->user_data; +} + +gboolean on_menu_manager_keyboard(GIOChannel *src, GIOCondition con, + gpointer data) +{ + MManager *mm = data; + char local_buf[MENU_DATA_SIZE + 1] = { 0, }; + + if (fgets(local_buf, MENU_DATA_SIZE, stdin) == NULL) + return TRUE; + + if (strlen(local_buf) > 0) { + if (local_buf[strlen(local_buf) - 1] == '\n') + local_buf[strlen(local_buf) - 1] = '\0'; + } + + if (mm->buf == key_buffer) { + if (strlen(local_buf) < 1) { + _show_prompt(); + return TRUE; + } + + _move_menu(mm, mm->menu, local_buf); + } else { + if (mm->buf) { + memset(mm->buf, 0, MENU_DATA_SIZE); + memcpy(mm->buf, local_buf, MENU_DATA_SIZE); + _show_input_ok(); + } + mm->buf = key_buffer; + _move_menu(mm, mm->menu, (char *)DEFAULT_MENU_MENU); + } + + return TRUE; +} + +pid_t get_tid() +{ + return syscall(__NR_gettid); +} + +void hide_pid() +{ + flag_pid_display = 0; +} + +void show_pid() +{ + flag_pid_display = 1; +} + +int is_pid_show() +{ + return flag_pid_display; +} + +static void _hex_dump(const char *pad, int size, const void *data) +{ + char buf[255] = {0, }; + char hex[4] = {0, }; + int i; + unsigned char *p; + + if (size <= 0) { + msg("%sno data", pad); + return; + } + p = (unsigned char *)data; + + snprintf(buf, 255, "%s%04X: ", pad, 0); + for (i = 0; i < size; i++) { + snprintf(hex, 4, "%02X ", p[i]); + strncat(buf, hex, 255 - strlen(buf) - 1); + + if ((i + 1) % 8 == 0) { + if ((i + 1) % 16 == 0) { + msg("%s", buf); + memset(buf, 0, 255); + snprintf(buf, 255, "%s%04X: ", pad, i + 1); + } else { + strncat(buf, TAB_SPACE, 255 - strlen(buf) - 1); + } + } + } + + msg("%s", buf); +} + +void menu_print_dump(int data_len, void *data) +{ + if (!data) + return; + + msg(""); + msg(" \tlen=%d", data_len); + _hex_dump(" ", data_len, data); + + msg(""); +} + diff --git a/test/stc_ipt_menu.h b/test/stc_ipt_menu.h new file mode 100755 index 0000000..74a112a --- /dev/null +++ b/test/stc_ipt_menu.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __STC_IPT_MENU_H__ +#define __STC_IPT_MENU_H__ + +__BEGIN_DECLS + +#define LOG_END "\e[0m" + +#define LOG_BLACK "\e[0;30m" +#define LOG_RED "\e[0;31m" +#define LOG_GREEN "\e[0;32m" +#define LOG_BROWN "\e[0;33m" +#define LOG_BLUE "\e[0;34m" +#define LOG_MAGENTA "\e[0;35m" +#define LOG_CYAN "\e[0;36m" +#define LOG_LIGHTGRAY "\e[0;37m" + +#define LOG_DARKGRAY "\e[1;30m" +#define LOG_LIGHTRED "\e[1;31m" +#define LOG_LIGHTGREEN "\e[1;32m" +#define LOG_YELLOW "\e[1;33m" +#define LOG_LIGHTBLUE "\e[1;34m" +#define LOG_LIGHTMAGENTA "\e[1;35m" +#define LOG_LIGHTCYAN "\e[1;36m" +#define LOG_WHITE "\e[1;37m" + + +#define msg(fmt,args...) do { fprintf(stdout, fmt "\n", ##args); \ + fflush(stdout); } while (0) +#define msgn(fmt,args...) do { fprintf(stdout, fmt, ##args); \ + fflush(stdout); } while (0) + +/* Bold (green) */ +#define msgb(fmt,args...) do { fprintf(stdout, LOG_LIGHTGREEN fmt \ + LOG_END "\n", ##args); fflush(stdout); } while (0) + +/* Property message */ +#define msgp(fmt,args...) do { fprintf(stdout, LOG_LIGHTMAGENTA fmt \ + LOG_END "\n", ##args); fflush(stdout); } while (0) + +#define msgt(n,fmt,args...) do { fprintf(stdout, "\e[%dC" fmt "\n", \ + 3 + ((n) * 2), ##args); fflush(stdout); } while (0) + +#define pmsg(fmt,args...) do { \ + if (is_pid_show()) { fprintf(stdout, "(%5d) ", get_tid()); } \ + fprintf(stdout, fmt "\n", ##args); fflush(stdout); } while (0) + +#define pmsgb(fmt,args...) do { \ + if (is_pid_show()) { fprintf(stdout, "(%5d) ", get_tid()); } \ + fprintf(stdout, LOG_LIGHTGREEN fmt \ + LOG_END "\n", ##args); fflush(stdout); } while (0) + +#define pmsgt(n,fmt,args...) do { \ + if (is_pid_show()) { fprintf(stdout, "(%5d) ", get_tid()); } \ + fprintf(stdout, "\e[%dC" fmt "\n", \ + 3 + ((n) * 2), ##args); fflush(stdout); } while (0) + +#define MENU_DATA_SIZE 255 + + + +/* + * Horizontal Line - width: 65 + * .12345678901234567890123456789012345678901234567890. + */ +#define HR_SINGLE "----------------------------------------" \ + "-------------------------" +#define HR_DOUBLE "========================================" \ + "=========================" +#define HR_SINGLE2 " ---------------------------------------" \ + "------------------------ " + +#define MAX_WIDTH strlen (HR_SINGLE) +#define MAX_TITLE ((MAX_WIDTH) - 10) +#define POS_MORE ((MAX_WIDTH) - 3) +#define RET_SUCCESS 0 +#define RET_FAILURE -1 + +typedef struct menu_manager MManager; + +struct menu_data { + const char *key; + const char *title; + struct menu_data *sub_menu; + int (*callback)(MManager *mm, struct menu_data *menu); + char *data; +}; + +MManager* menu_manager_new(struct menu_data items[], GMainLoop *mainloop); +int menu_manager_run(MManager *mm); +int menu_manager_set_user_data(MManager *mm, void *user_data); +void* menu_manager_ref_user_data(MManager *mm); + +gboolean on_menu_manager_keyboard(GIOChannel *src, GIOCondition con, + gpointer data); + +pid_t get_tid (); +void hide_pid (); +void show_pid (); +int is_pid_show (); +void menu_print_dump(int data_len, void *data); + +__END_DECLS + +#endif /* __STC_IPT_MENU_H__ */ diff --git a/test/stc_ipt_rule.c b/test/stc_ipt_rule.c new file mode 100755 index 0000000..28e6c22 --- /dev/null +++ b/test/stc_ipt_rule.c @@ -0,0 +1,517 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "stc_ipt_test.h" +#include "stc_ipt_gdbus.h" +#include "stc_ipt_sys.h" +#include "stc_ipt_menu.h" + +#define RULE_SIZE 64 + +#define TARGET_ACCEPT "ACCEPT" +#define TARGET_DROP "DROP" + +#define RULE_CHAIN "chain" +#define RULE_TYPE "type" +#define RULE_IFNAME "ifname" +#define RULE_CGROUP "cgroup" +#define RULE_NFACCT "nfacct" +#define RULE_TARGET "target" + +typedef enum { + IPTABLES_CHAIN_INPUT, + IPTABLES_CHAIN_OUTPUT +} ipt_chain_e; + +typedef enum { + IPTABLES_RULE_IN, + IPTABLES_RULE_OUT +} ipt_rule_type_e; + +typedef enum { + IPTABLES_ACTION_NONE, + IPTABLES_ACTION_ACCEPT, + IPTABLES_ACTION_DROP +} ipt_target_action_e; + +typedef struct { + char *chain; + ipt_rule_type_e type; + char *ifname; + int classid; + char *nfacct_name; + char *target; +} ipt_rule_s; + +static char g_rule_chain[MENU_DATA_SIZE] = "STC_CHAIN"; +static char g_rule_type[MENU_DATA_SIZE] = "0"; +static char g_rule_ifname[MENU_DATA_SIZE] = "seth_w0"; +static char g_rule_cgroup[MENU_DATA_SIZE] = "0"; +static char g_rule_nfacct[MENU_DATA_SIZE] = ""; +static char g_rule_target[MENU_DATA_SIZE] = "0"; + +static __thread GSList *g_rule_list = NULL; + +static void __test_print_rule(ipt_rule_s *rule) +{ + msg(HR_SINGLE); + + msg("Chain : [%s]", rule->chain); + if (rule->type == IPTABLES_RULE_IN) + msg("Type : [IN]"); + else if (rule->type == IPTABLES_RULE_OUT) + msg("Type : [OUT]"); + msg("Ifname : [%s]", rule->ifname); + msg("Cgroup : [%d]", rule->classid); + msg("Nfacct : [%s]", rule->nfacct_name); + msg("Target : [%s]", rule->target); + + msg(HR_SINGLE); +} + +static int __test_append_rule_to_list(void) +{ + ipt_rule_s *rule; + + int type = (int)strtol(g_rule_type, NULL, 10); + int classid = (int)strtol(g_rule_cgroup, NULL, 10); + int target = (int)strtol(g_rule_target, NULL, 10); + + if (g_rule_chain[0] == '\0' || + g_rule_ifname[0] == '\0' || + g_rule_nfacct[0] == '\0' || + type < IPTABLES_RULE_IN || + type > IPTABLES_RULE_OUT || + classid < 0 || + target < IPTABLES_ACTION_NONE || + target > IPTABLES_ACTION_DROP) { + msg(LOG_RED "Invalid parameter" LOG_END); + return STC_ERROR_INVALID_PARAMETER; + } + + rule = g_try_new0(ipt_rule_s, 1); + if (rule == NULL) { + msg(LOG_RED "Out of memory" LOG_END); + return STC_ERROR_OUT_OF_MEMORY; + } + + memset(rule, 0, sizeof(ipt_rule_s)); + rule->chain = g_strdup(g_rule_chain); + rule->type = type; + rule->ifname = g_strdup(g_rule_ifname); + rule->classid = classid; + rule->nfacct_name = g_strdup(g_rule_nfacct); + + switch (target) { + case IPTABLES_ACTION_ACCEPT: + rule->target = g_strdup(TARGET_ACCEPT); + break; + case IPTABLES_ACTION_DROP: + rule->target = g_strdup(TARGET_DROP); + break; + default: + rule->target = NULL; + break; + } + + g_rule_list = g_slist_append(g_rule_list, rule); + __test_print_rule(rule); + + return STC_ERROR_NONE; +} + +static void __test_get_rule_list(void) +{ + GSList *list; + + for (list = g_rule_list; list; list = list->next) { + ipt_rule_s *rule = (ipt_rule_s *)list->data; + __test_print_rule(rule); + } +} + +static void __test_list_free_func(gpointer data) +{ + ipt_rule_s *rule = (ipt_rule_s *)data; + + FREE(rule->chain); + FREE(rule->ifname); + FREE(rule->nfacct_name); + FREE(rule->target); + FREE(rule); +} + +static void __test_remove_rule_list(void) +{ + if (g_rule_list != NULL) + g_slist_free_full(g_rule_list, __test_list_free_func); + + g_rule_list = NULL; +} + +static int test_stc_ipt_add_rule(MManager *mm, struct menu_data *menu) +{ + int ret = STC_ERROR_NONE; + + ret = __test_append_rule_to_list(); + if (ret != STC_ERROR_NONE) { + msg(LOG_RED "Failed to add rule to list" LOG_END); + return ret; + } + + msg(LOG_GREEN "Successfully add rule" LOG_END); + + return ret; +} + +static int test_stc_ipt_get_rules(MManager *mm, struct menu_data *menu) +{ + int ret = STC_ERROR_NONE; + + __test_get_rule_list(); + msg(LOG_GREEN "Successfully get rule" LOG_END); + + return ret; +} + +static int test_stc_ipt_reset_rules(MManager *mm, struct menu_data *menu) +{ + int ret = STC_ERROR_NONE; + + __test_remove_rule_list(); + msg(LOG_GREEN "Successfully reset rule" LOG_END); + + return ret; +} + +static void __test_add_rule_info_to_builder(GVariantBuilder *builder, + ipt_rule_s *rule) +{ + g_variant_builder_add(builder, "{sv}", RULE_CHAIN, + g_variant_new_string(rule->chain)); + + g_variant_builder_add(builder, "{sv}", RULE_TYPE, + g_variant_new_uint32(rule->type)); + + g_variant_builder_add(builder, "{sv}", RULE_IFNAME, + g_variant_new_string(rule->ifname)); + + g_variant_builder_add(builder, "{sv}", RULE_CGROUP, + g_variant_new_uint32(rule->classid)); + + g_variant_builder_add(builder, "{sv}", RULE_NFACCT, + g_variant_new_string(rule->nfacct_name)); + + if (rule->target) + g_variant_builder_add(builder, "{sv}", RULE_TARGET, + g_variant_new_string(rule->target)); + +} + +static int __test_make_rule_params(GVariantBuilder *builder, + ipt_rule_s *rule) +{ + GVariantBuilder sub_builder; + + if (builder == NULL || rule == NULL) + return STC_ERROR_INVALID_PARAMETER; + + g_variant_builder_init(&sub_builder, G_VARIANT_TYPE("a{sv}")); + __test_add_rule_info_to_builder(&sub_builder, rule); + __test_print_rule(rule); + g_variant_builder_add_value(builder, g_variant_builder_end(&sub_builder)); + + return STC_ERROR_NONE; +} + +static int __stc_ipt_add_rules(void) +{ + int err = STC_ERROR_NONE; + int len = 0; + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + GSList *list; + + len = g_slist_length(g_rule_list); + if (len == 0) { + msg(LOG_RED "There are no rules" LOG_END); + return STC_ERROR_INVALID_OPERATION; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}")); + + for (list = g_rule_list; list; list = list->next) { + ipt_rule_s *rule = (ipt_rule_s *)list->data; + err = __test_make_rule_params(builder, rule); + if (err != STC_ERROR_NONE) { + g_variant_builder_unref(builder); + return err; + } + } + + params = g_variant_new("(aa{sv})", builder); + g_variant_builder_unref(builder); + + err = STC_ERROR_NONE; + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_RULE_PATH, + STC_IPT_DBUS_RULE_INTERFACE, + STC_IPT_DBUS_METHOD_IPT_ADD_RULE, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + stc_ipt_exe_cmd(CHECK_IPTABLES); + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully add rules [%d]" LOG_END, result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __stc_ip6t_add_rules(void) +{ + int err = STC_ERROR_NONE; + int len = 0; + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + GSList *list; + + len = g_slist_length(g_rule_list); + if (len == 0) { + msg(LOG_RED "There are no rules" LOG_END); + return STC_ERROR_INVALID_OPERATION; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}")); + + for (list = g_rule_list; list; list = list->next) { + ipt_rule_s *rule = (ipt_rule_s *)list->data; + err = __test_make_rule_params(builder, rule); + if (err != STC_ERROR_NONE) { + g_variant_builder_unref(builder); + return err; + } + } + + params = g_variant_new("(aa{sv})", builder); + g_variant_builder_unref(builder); + + err = STC_ERROR_NONE; + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_RULE_PATH, + STC_IPT_DBUS_RULE_INTERFACE, + STC_IPT_DBUS_METHOD_IP6T_ADD_RULE, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + stc_ipt_exe_cmd(CHECK_IP6TABLES); + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully add 6 rules [%d]" LOG_END, result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + + +static int __stc_ipt_remove_rules(void) +{ + int err = STC_ERROR_NONE; + int len = 0; + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + GSList *list; + + len = g_slist_length(g_rule_list); + if (len == 0) { + msg(LOG_RED "There are no rules" LOG_END); + return STC_ERROR_INVALID_OPERATION; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}")); + + for (list = g_rule_list; list; list = list->next) { + ipt_rule_s *rule = (ipt_rule_s *)list->data; + err = __test_make_rule_params(builder, rule); + if (err != STC_ERROR_NONE) { + g_variant_builder_unref(builder); + return err; + } + } + + params = g_variant_new("(aa{sv})", builder); + g_variant_builder_unref(builder); + + err = STC_ERROR_NONE; + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_RULE_PATH, + STC_IPT_DBUS_RULE_INTERFACE, + STC_IPT_DBUS_METHOD_IPT_REMOVE_RULE, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + stc_ipt_exe_cmd(CHECK_IPTABLES); + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully remove rules [%d]" LOG_END, result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int __stc_ip6t_remove_rules(void) +{ + int err = STC_ERROR_NONE; + int len = 0; + int result = 0; + GVariantBuilder *builder = NULL; + GVariant *params = NULL; + GVariant *message = NULL; + GSList *list; + + len = g_slist_length(g_rule_list); + if (len == 0) { + msg(LOG_RED "There are no rules" LOG_END); + return STC_ERROR_INVALID_OPERATION; + } + + builder = g_variant_builder_new(G_VARIANT_TYPE("aa{sv}")); + + for (list = g_rule_list; list; list = list->next) { + ipt_rule_s *rule = (ipt_rule_s *)list->data; + err = __test_make_rule_params(builder, rule); + if (err != STC_ERROR_NONE) { + g_variant_builder_unref(builder); + return err; + } + } + + params = g_variant_new("(aa{sv})", builder); + g_variant_builder_unref(builder); + + err = STC_ERROR_NONE; + message = stc_ipt_dbus_invoke_method( + STC_IPT_DBUS_SERVICE, + STC_IPT_DBUS_RULE_PATH, + STC_IPT_DBUS_RULE_INTERFACE, + STC_IPT_DBUS_METHOD_IP6T_REMOVE_RULE, + params, + &err); + + if (message == NULL) { + msg(LOG_RED "Failed to invoke dbus method" LOG_END); + return err; + } + + stc_ipt_exe_cmd(CHECK_IP6TABLES); + + g_variant_get(message, "(i)", &result); + msg(LOG_GREEN "Successfully remove 6 rules [%d]" LOG_END, result); + g_variant_unref(message); + + return STC_ERROR_NONE; +} + +static int test_stc_ipt_add_rules(MManager *mm, struct menu_data *menu) +{ + int err = STC_ERROR_NONE; + + err = __stc_ipt_add_rules(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to add rules" LOG_END); + + err = __stc_ip6t_add_rules(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to add 6 rules" LOG_END); + + return err; +} + +static int test_stc_ipt_remove_rules(MManager *mm, struct menu_data *menu) +{ + int err = STC_ERROR_NONE; + + err = __stc_ipt_remove_rules(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to remove rules" LOG_END); + + err = __stc_ip6t_remove_rules(); + if (err != STC_ERROR_NONE) + msg(LOG_RED "Failed to remove 6 rules" LOG_END); + + return err; +} + +int test_stc_ipt_clear_rule_list(void) +{ + __test_remove_rule_list(); +} + +static struct menu_data menu_set[] = { + { "1", "chain name", NULL, NULL, g_rule_chain}, + { "2", "type (0.IN/1.OUT)", NULL, NULL, g_rule_type}, + { "3", "interface name", NULL, NULL, g_rule_ifname}, + { "4", "cgroup classid", NULL, NULL, g_rule_cgroup}, + { "5", "nfacct name", NULL, NULL, g_rule_nfacct}, + { "6", "target (0.NONE/1.ACCEPT/2.DROP)", NULL, NULL, g_rule_target}, + { "a", LOG_LIGHTBLUE "[Add]" LOG_END " rule to list", NULL, test_stc_ipt_add_rule, NULL}, + { NULL, NULL, }, +}; + +struct menu_data menu_rule[] = { + { "1", LOG_LIGHTBLUE "[Set]" LOG_END " rule list", menu_set, NULL, NULL}, + { "2", LOG_LIGHTBLUE "[Get]" LOG_END " rule list", NULL, test_stc_ipt_get_rules, NULL}, + { "3", LOG_LIGHTBLUE "[Reset]" LOG_END " rule list", NULL, test_stc_ipt_reset_rules, NULL}, + { "a", LOG_LIGHTMAGENTA "[Add]" LOG_END " rules", NULL, test_stc_ipt_add_rules, NULL}, + { "r", LOG_LIGHTMAGENTA "[Remove]" LOG_END " rules", NULL, test_stc_ipt_remove_rules, NULL}, + { NULL, NULL, }, +}; diff --git a/test/stc_ipt_rule.h b/test/stc_ipt_rule.h new file mode 100755 index 0000000..51ef0e3 --- /dev/null +++ b/test/stc_ipt_rule.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TEST_STC_IPT_RULE_H__ +#define __TEST_STC_IPT_RULE_H__ + +int test_stc_ipt_clear_rule_list(void); + +#endif /** __TEST_STC_IPT_RULE_H__ */ diff --git a/test/stc_ipt_sys.c b/test/stc_ipt_sys.c new file mode 100755 index 0000000..64738ae --- /dev/null +++ b/test/stc_ipt_sys.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "stc_ipt_test.h" +#include "stc_ipt_sys.h" +#include "stc_ipt_menu.h" + +#define MAX_ERR_BUFFER 256 + +int stc_ipt_exe_cmd(const char *cmd) +{ + int pid = 0; + int status = 0; + int ret = 0; + char err_buf[MAX_ERR_BUFFER] = { 0, }; + gchar **args = NULL; + + if (cmd == NULL) + return STC_ERROR_INVALID_PARAMETER; + + errno = 0; + args = g_strsplit_set(cmd, " ", -1); + pid = fork(); + + if (pid == 0) { + errno = 0; + ret = execv(args[0], args); + if (ret) { + strerror_r(errno, err_buf, MAX_ERR_BUFFER); + msg("Failed to exe cmd " LOG_RED "[%s]" LOG_END, err_buf); + g_strfreev(args); + } + exit(ret); + } else if (pid > 0) { + if (waitpid(pid, &status, 0) < 0) { + strerror_r(errno, err_buf, MAX_ERR_BUFFER); + msg("Can't wait for a pid " LOG_RED "[%d %d %s]" LOG_END, + pid, status, err_buf); + g_strfreev(args); + return STC_ERROR_INVALID_OPERATION; + } + g_strfreev(args); + return STC_ERROR_NONE; + } + + strerror_r(errno, err_buf, MAX_ERR_BUFFER); + msg("Failed to fork " LOG_RED "[%s]" LOG_END, err_buf); + g_strfreev(args); + + return STC_ERROR_OPERATION_FAILED; +} diff --git a/test/stc_ipt_sys.h b/test/stc_ipt_sys.h new file mode 100755 index 0000000..ce71613 --- /dev/null +++ b/test/stc_ipt_sys.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __TEST_STC_IPT_SYS_H_ +#define __TEST_STC_IPT_SYS_H_ + +#define CHECK_IPTABLES "/usr/sbin/iptables -S" +#define CHECK_IP6TABLES "/usr/sbin/ip6tables -S" + +int stc_ipt_exe_cmd(const char *cmd); + +#endif /** __TEST_STC_IPT_SYS_H_ */ diff --git a/test/stc_ipt_test.c b/test/stc_ipt_test.c new file mode 100755 index 0000000..2bf2ae0 --- /dev/null +++ b/test/stc_ipt_test.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "stc_ipt_test.h" +#include "stc_ipt_gdbus.h" +#include "stc_ipt_rule.h" +#include "stc_ipt_menu.h" + +extern struct menu_data menu_chain[]; +extern struct menu_data menu_rule[]; + +const char *test_stc_ipt_convert_error_type_to_string(stc_error_e err) +{ + switch (err) { + case STC_ERROR_NONE: + return "Successful"; + case STC_ERROR_NOT_PERMITTED: + return "Operation not permitted"; + case STC_ERROR_OUT_OF_MEMORY: + return "Out of memory"; + case STC_ERROR_PERMISSION_DENIED: + return "Permission denied"; + case STC_ERROR_INVALID_OPERATION: + return "Invalid operation"; + case STC_ERROR_INVALID_PARAMETER: + return "Invalid parameter"; + case STC_ERROR_OPERATION_FAILED: + return "Operation failed"; + default: + return "Unknown"; + } +} + +static struct menu_data menu_main[] = { + { "1", LOG_LIGHTBLUE "[Chain]" LOG_END, menu_chain, NULL, NULL}, + { "2", LOG_LIGHTMAGENTA "[Rule]" LOG_END, menu_rule, NULL, NULL}, + { NULL, NULL, }, +}; + +static int __test_stc_ipt_initialize(MManager *mm, struct menu_data *menu) +{ + int ret = STC_ERROR_NONE; + + ret = stc_ipt_dbus_create(); + if (ret != STC_ERROR_NONE) { + msg("Failed to create DBus " LOG_RED "[%s]" LOG_END, + test_stc_ipt_convert_error_type_to_string(ret)); + return ret; + } + + return ret; +} + +static int __test_stc_ipt_deinitialize(void) +{ + GDBusConnection *conn; + int ret = STC_ERROR_NONE; + + test_stc_ipt_clear_rule_list(); + + conn = stc_ipt_dbus_get_connection(); + if (conn == NULL) { + msg("Already de-registered"); + return STC_ERROR_NONE; + } + + ret = stc_ipt_dbus_destroy(); + if (ret != STC_ERROR_NONE) + msg("Failed to destroy DBus " LOG_RED "[%s]" LOG_END, + test_stc_ipt_convert_error_type_to_string(ret)); + + return ret; +} + +static gboolean __test_stc_ipt_create_init_menu(struct menu_data init_menu[1]) +{ + init_menu[0].key = "1"; + init_menu[0].title = LOG_YELLOW "STC Iptables" LOG_END; + init_menu[0].sub_menu = menu_main; + init_menu[0].callback = __test_stc_ipt_initialize; + init_menu[0].data = NULL; + + return TRUE; +} + +int main(int arg, char **argv) +{ + GMainLoop *mainloop = NULL; + GIOChannel *channel = g_io_channel_unix_new(STDIN_FILENO); + MManager *manager; + struct menu_data init_menu[1+1] = { {NULL, NULL, } }; + +#if !GLIB_CHECK_VERSION(2, 35, 0) + g_type_init(); +#endif + mainloop = g_main_loop_new(NULL, FALSE); + + msg(""); + msg(LOG_GREEN "* STC Iptables Test application " LOG_END); + msg("* Build On: %s %s", __DATE__, __TIME__); + + if (__test_stc_ipt_create_init_menu(init_menu) == FALSE) + goto OUT; + + manager = menu_manager_new(init_menu, mainloop); + if (!manager) + goto OUT; + + menu_manager_run(manager); + + g_io_add_watch(channel, (G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), + on_menu_manager_keyboard, manager); + g_main_loop_run(mainloop); + +OUT: + __test_stc_ipt_deinitialize(); + g_main_loop_unref(mainloop); + msg("******* Bye bye *******"); + + return 0; +} diff --git a/test/stc_ipt_test.h b/test/stc_ipt_test.h new file mode 100755 index 0000000..7d1f00c --- /dev/null +++ b/test/stc_ipt_test.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __STC_IPT_TEST_H__ +#define __STC_IPT_TEST_H__ + +#define MALLOC0(t, n) ((t*) g_try_malloc0((n) * sizeof(t))) +#define FREE(p) do { \ + if (p) { \ + g_free(p); \ + p = NULL; \ + } \ +} while (0) + +typedef enum { + STC_ERROR_OPERATION_FAILED = -6, /**< Operation failed */ + STC_ERROR_INVALID_PARAMETER = -5, /**< Invalid function parameter */ + STC_ERROR_INVALID_OPERATION = -4, /**< Invalid operation */ + STC_ERROR_PERMISSION_DENIED = -3, /**< Permission denied */ + STC_ERROR_OUT_OF_MEMORY = -2, /**< Out of memory */ + STC_ERROR_NOT_PERMITTED = -1, /**< Operation not permitted */ + STC_ERROR_NONE = 0 /**< Successful */ +} stc_error_e; + +#endif /* __STC_IPT_TEST_H__ */