zentyal-network-2.3.13+quantal1/0000775000000000000000000000000012017102311013353 5ustar zentyal-network-2.3.13+quantal1/COPYING0000664000000000000000000004311012017102311014405 0ustar GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. zentyal-network-2.3.13+quantal1/debian/0000775000000000000000000000000012017102311014575 5ustar zentyal-network-2.3.13+quantal1/debian/compat0000664000000000000000000000000212017102311015773 0ustar 5 zentyal-network-2.3.13+quantal1/debian/copyright0000664000000000000000000000214112017102311016526 0ustar This package was debianized by Zentyal Packaging Maintainers Fri, 20 Feb 2005 15:13:22 +0100. It was downloaded from http://www.zentyal.org/ Files: * Upstream Author: eBox Technologies S.L. Copyright (C) 2004-2012 eBox Technologies S.L. License: 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. On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL-2 file. The Debian packaging is: (C) 2004-2011, Zentyal Packaging Maintainers and is licensed under the GPL, see `/usr/share/common-licenses/GPL-2'. zentyal-network-2.3.13+quantal1/debian/control0000664000000000000000000000224512017102311016203 0ustar Source: zentyal-network Section: web Priority: optional Maintainer: Zentyal Packaging Maintainers Uploaders: Jorge Salamero Sanz Build-Depends: zbuildtools Standards-Version: 3.9.2 Homepage: http://www.zentyal.org/ Vcs-Browser: http://git.zentyal.org/zentyal.git/tree/quantal:/main/network Vcs-Git: git://git.zentyal.org/zentyal.git Package: zentyal-network Architecture: all Replaces: ebox-network (<< 2.0.100) Breaks: ebox-network (<< 2.0.100) Depends: zentyal-core (>= 2.3), zentyal-core (<< 2.3.100), zentyal-objects, zentyal-services, iproute, vlan, net-tools, dnsutils, libnet-ip-perl, dhcp3-client, iptables, libnet-arp-perl, wget, traceroute, ddclient, ppp, libio-interface-perl, debconf, bridge-utils, wakeonlan, ${misc:Depends} Description: Zentyal - Network Configuration Zentyal is a Linux small business server that can act as a Gateway, Unified Threat Manager, Office Server, Infrastructure Manager, Unified Communications Server or a combination of them. One single, easy-to-use platform to manage all your network services. . This module adds network configuration featuring interfaces, routes, domain servers set up. zentyal-network-2.3.13+quantal1/debian/source/0000775000000000000000000000000012017102311016075 5ustar zentyal-network-2.3.13+quantal1/debian/source/format0000664000000000000000000000001512017102311017304 0ustar 3.0 (native) zentyal-network-2.3.13+quantal1/debian/zentyal-network.postinst0000664000000000000000000000077412017102311021567 0ustar #!/bin/bash set -e #DEBHELPER# case "$1" in configure) # inital setup /usr/share/zentyal/initial-setup --no-restart network $2 # restart module invoke-rc.d zentyal network restart || true # restart trafficshaping, ignore error if not exists # this is regenerate mangle rules after the flush in network restart invoke-rc.d zentyal trafficshaping restart >/dev/null 2>&1 || true dpkg-trigger --no-await zentyal-core ;; esac exit 0 zentyal-network-2.3.13+quantal1/debian/rules0000775000000000000000000000010612017102311015652 0ustar #!/usr/bin/make -f include /usr/share/zbuildtools/1/rules/zentyal.mk zentyal-network-2.3.13+quantal1/debian/changelog0000664000000000000000000003003312017102311016446 0ustar zentyal-network (2.3.13+quantal1) quantal; urgency=low * New upstream release for Quantal -- Jorge Salamero Sanz Tue, 28 Aug 2012 10:26:17 +0200 zentyal-network (2.3.13) precise; urgency=low * New upstream release -- José A. Calvo Thu, 23 Aug 2012 02:28:12 +0200 zentyal-network (2.3.12) precise; urgency=low * New upstream release -- José A. Calvo Wed, 18 Jul 2012 22:09:22 +0200 zentyal-network (2.3.11) precise; urgency=low * New upstream release -- José A. Calvo Thu, 12 Jul 2012 10:39:32 +0200 zentyal-network (2.3.10) precise; urgency=low * New upstream release -- José A. Calvo Fri, 06 Jul 2012 11:06:18 +0200 zentyal-network (2.3.9) precise; urgency=low * New upstream release -- José A. Calvo Wed, 20 Jun 2012 09:59:32 +0200 zentyal-network (2.3.8) precise; urgency=low * New upstream release -- José A. Calvo Sun, 17 Jun 2012 12:27:37 +0200 zentyal-network (2.3.7) precise; urgency=low * New upstream release -- José A. Calvo Mon, 04 Jun 2012 11:12:29 +0200 zentyal-network (2.3.6) precise; urgency=low * New upstream release -- José A. Calvo Mon, 02 Apr 2012 17:53:12 +0200 zentyal-network (2.3.5) precise; urgency=low * New upstream release -- José A. Calvo Mon, 26 Mar 2012 19:02:56 +0200 zentyal-network (2.3.4) precise; urgency=low * New upstream release -- José A. Calvo Thu, 22 Mar 2012 20:38:17 +0100 zentyal-network (2.3.1) precise; urgency=low * New upstream release -- José A. Calvo Tue, 06 Mar 2012 11:58:50 +0100 zentyal-network (2.3-1) precise; urgency=low * Updated Standards-Version to 3.9.2 -- José A. Calvo Wed, 08 Feb 2012 16:12:50 +0100 zentyal-network (2.3) precise; urgency=low * New upstream release -- José A. Calvo Mon, 30 Jan 2012 01:44:12 +0100 zentyal-network (2.2.3) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 26 Oct 2011 15:00:14 +0200 zentyal-network (2.2.2) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 13 Oct 2011 13:23:44 +0200 zentyal-network (2.2.1) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 21 Sep 2011 15:47:46 +0200 zentyal-network (2.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 13 Sep 2011 04:43:30 +0200 zentyal-network (2.1.16) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 12 Sep 2011 11:55:15 +0200 zentyal-network (2.1.15) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 10 Sep 2011 18:47:18 +0200 zentyal-network (2.1.14) lucid; urgency=low * New upstream release -- José A. Calvo Fri, 09 Sep 2011 17:50:22 +0200 zentyal-network (2.1.13) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 06 Sep 2011 16:57:02 +0200 zentyal-network (2.1.12) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 30 Aug 2011 17:51:04 +0200 zentyal-network (2.1.11) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 24 Aug 2011 11:50:19 +0200 zentyal-network (2.1.10) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 15 Aug 2011 23:22:48 +0200 zentyal-network (2.1.9) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 25 Jul 2011 11:55:22 +0200 zentyal-network (2.1.8) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 19 Jul 2011 14:01:04 +0200 zentyal-network (2.1.7) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 14 Jul 2011 13:35:02 +0200 zentyal-network (2.1.6) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 02 Jul 2011 16:03:23 +0200 zentyal-network (2.1.5) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 29 Jun 2011 19:34:45 +0200 zentyal-network (2.1.4) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 15 Jun 2011 11:25:06 +0200 zentyal-network (2.1.2) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 10 May 2011 22:24:39 +0200 zentyal-network (2.1.1) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 26 Feb 2011 01:43:31 +0100 zentyal-network (2.1) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 22 Feb 2011 03:14:42 +0100 ebox-network (2.0.8) lucid; urgency=low * New upstream release -- José A. Calvo Sat, 25 Dec 2010 20:53:51 +0100 ebox-network (2.0.7) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 20 Dec 2010 19:15:32 +0100 ebox-network (2.0.6) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 24 Nov 2010 14:24:44 +0100 ebox-network (2.0.5) lucid; urgency=low * New upstream release -- José A. Calvo Tue, 09 Nov 2010 11:27:11 +0100 ebox-network (2.0.4) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 18 Oct 2010 19:15:36 +0200 ebox-network (2.0.3) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 10 Oct 2010 16:31:28 +0200 ebox-network (2.0.2) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 06 Oct 2010 15:26:01 +0200 ebox-network (2.0.1) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 27 Sep 2010 22:32:45 +0200 ebox-network (2.0) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 30 Aug 2010 21:59:55 +0200 ebox-network (1.5.8-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 26 Aug 2010 16:03:46 +0200 ebox-network (1.5.7-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 23 Aug 2010 02:17:11 +0200 ebox-network (1.5.6-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 18 Aug 2010 02:30:06 +0200 ebox-network (1.5.5-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Mon, 19 Jul 2010 12:06:52 +0200 ebox-network (1.5.4-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Sun, 20 Jun 2010 20:39:32 +0200 ebox-network (1.5.3-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Wed, 16 Jun 2010 21:04:23 +0200 ebox-network (1.5.2-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 10 Jun 2010 16:33:13 +0200 ebox-network (1.5.1-0ubuntu1~ppa1~lucid1) lucid; urgency=low * New upstream release -- José A. Calvo Thu, 13 May 2010 01:32:49 +0200 ebox-network (1.5-0ubuntu1) lucid; urgency=low [Javier Uruen Val] * New upstream release (LP: #521802) * debian/control - Bump eBox dependency - Add dependency on libio-interface-perl - Update description * drop debian/patches - Drop 01_not_reconfigure_interfaces_at_booting.patch as it's already fixed in upstream * drop simple-patchsys -- Javier Uruen Val Sun, 07 Feb 2010 18:51:11 +0100 ebox-network (1.3.5-0ubuntu2) karmic; urgency=low [Javier Uruen Val] * debian/ebox-network.postinst (LP: #451499) - Redirect ebox-netcfg-import STDERR and STDOUT to /dev/null as they can be very verbose * deabian/patches - Add 02_fix_multigateway_rules_from_ebox_source.patch -- Javier Uruen Val Tue, 13 Oct 2009 19:39:44 +0200 ebox-network (1.3.5-0ubuntu1) karmic; urgency=low [Javier Uruen Val] * New upstream release [LP: #411470] * cdbs/ebox.mk - GConf schemas are not used anymore - Remove SCHEMASPATH variable - Remove schemadir variable - Use new upstart directory and file naming convention * debian/config - Add set -e * debian/control - Bump standards version - Bump eBox depenency - Add dependency on traceroute, ddclient * debian/ebox-network.postinst - Fix indentation - Do not pkill gconfd as it's not necessary anymore - Run ebox trigger - Add missing db_stop * debian/ebox-network.postrm - Run ebox trigger - Add set -e * remove debian/ebox-network.prerm - Not needed anymore as we don't use gconf schemas * debian/patches - Use simple-patchsys + Add 01_not_reconfigure_interfaces_at_booting.patch * debian/rules - Do not include debian/cdbs/gnome.mk - Include rules/simple-patchsys.mk * debian/watch - Change URL -- Javier Uruen Val Wed, 05 Aug 2009 12:29:43 +0200 ebox-network (0.12-0ubuntu1) jaunty; urgency=low [ Javier Uruen Val ] * New upstream release. Closes (LP: #318810) * debian/watch: - add watch file. -- Mathias Gug Mon, 26 Jan 2009 19:24:59 -0500 ebox-network (0.11.99-0ubuntu1) hardy; urgency=low * Added debian/patches/01_traffic_shape_path. - Fixes missing path for ebox-traffic-monitor. * Added debian/patches/02-fix-elogger-path.dpatch - Fixes missing path for ebox-traffic-monitor-logger. -- Chuck Short Tue, 04 Mar 2008 15:15:21 -0500 ebox-network (0.11.99-0ubuntu1~ppa1) hardy; urgency=low * New upstream relase. -- Chuck Short Wed, 27 Feb 2008 13:21:22 -0500 ebox-network (0.11.99-0ubuntu1~ppa1) hardy; urgency=low * New upstream release -- Javier Uruen Val Mon, 25 Feb 2008 13:32:29 +0100 ebox-network (0.11.99) unstable; urgency=low * New upstream release -- Enrique José Hernández Blasco Tue, 8 Jan 2008 16:14:39 +0100 ebox-network (0.11-0ubuntu1~ppa1) hardy; urgency=low * New upstream release -- Javier Uruen Val Wed, 28 Nov 2007 15:23:33 +0100 ebox-network (0.10.99) unstable; urgency=low * New upstream release -- Javier Uruen Val Thu, 01 Nov 2007 21:38:14 +0100 ebox-network (0.10) unstable; urgency=low * New upstream release -- Javier Uruen Val Wed, 10 Oct 2007 21:53:50 +0200 ebox-network (0.9.100) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 04 Sep 2007 14:15:27 +0200 ebox-network (0.9.99) unstable; urgency=low * New upstream release -- Javier Amor Garcia Tue, 24 Jul 2007 12:48:32 +0200 ebox-network (0.9.3) unstable; urgency=low * New upstream release -- Javier Uruen Val Sun, 24 Jun 2007 16:38:48 +0200 ebox-network (0.9.2) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 12 Jun 2007 18:59:27 +0200 ebox-network (0.9.1) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 15 May 2007 13:02:25 +0200 ebox-network (0.9) unstable; urgency=low * New upstream release -- Javier Amor Garcia Wed, 21 Mar 2007 10:02:12 +0100 ebox-network (0.7.1) unstable; urgency=low * New upstream release -- Daniel Baeyens Sicilia Wed, 22 Mar 2006 16:03:47 +0100 ebox-network (0.7.0.99-rc1+0.7.1-rc1) unstable; urgency=low * New upstream release -- Javier Uruen Val Tue, 17 Jan 2006 11:38:59 +0100 ebox-network (0.5) unstable; urgency=low * New upstream release -- Javier Uruen Mon, 16 Apr 2005 14:33:06 +0100 zentyal-network-2.3.13+quantal1/debian/zentyal-network.postrm0000664000000000000000000000033412017102311021220 0ustar #!/bin/bash set -e #DEBHELPER# case "$1" in purge) # purge configuration /usr/share/zentyal/purge-module network ;; remove) dpkg-trigger --no-await zentyal-core ;; esac exit 0 zentyal-network-2.3.13+quantal1/conf/0000775000000000000000000000000012017102311014300 5ustar zentyal-network-2.3.13+quantal1/conf/network.conf0000664000000000000000000000103712017102311016641 0ustar # network.conf - configuration file for zentyal-network. # # Everything after a '#' character is ignored # # All whitespace is ignored # # Config keys are set this way: # # key = value # # They may contain comments at the end: # # key = value # this is ignored # interfaces to ignore in the interface # (default: sit,tun,tap,lo,irda,ppp,virbr,vboxnet, vnet) ifaces_to_ignore = sit,tun,tap,lo,irda,ppp,virbr,vboxnet,vnet # If you want to define a custom mtu for any interface # you can use mtu_ = . Example: #mtu_eth0 = 1400 zentyal-network-2.3.13+quantal1/src/0000775000000000000000000000000012017102311014142 5ustar zentyal-network-2.3.13+quantal1/src/templates/0000775000000000000000000000000012017102311016140 5ustar zentyal-network-2.3.13+quantal1/src/templates/diag.mas0000664000000000000000000000477112017102311017557 0ustar <%args> $action => "" $target => "" $output => "" $objects => "" <%init> use EBox::Gettext;

<% __('Ping') %>

<% __('Host') %>:

<% __('Traceroute') %>

<% __('Host') %>:

<% __('Domain Name Resolution') %>

<% __('Domain name') %>:

<% __('Wake On LAN') %>

<% __('MAC address') %>: % my $target_found = 0; %# Do not show the select if there are no objects % if (@{$objects}) { % } % if($action ne ''){

<% __('Output') %>

<% $output %>
% }
zentyal-network-2.3.13+quantal1/src/templates/confirmVlanDel.mas0000664000000000000000000000173112017102311021547 0ustar <%args> $iface $vlanid <%init> use EBox::Gettext;
<% __('The removal of the vlan interface will affect the configuration of one or more modules that use references to this network interface.') %>

<% __('If you choose to continue, all modules that make use of this network interface will delete the relevant parts of their configuration. Choose "Cancel" if you are not sure about this.') %>

zentyal-network-2.3.13+quantal1/src/templates/confirmremove.mas0000664000000000000000000000171412017102311021520 0ustar <%args> $iface $viface <%init> use EBox::Gettext;
<% __('The change you are trying to make will affect the configuration of one or more modules that use references to this network interface.') %>

<% __('If you choose to continue, all modules that make use of this network interface will delete the relevant parts of their configuration. Choose "Cancel" if you are not sure about this.') %>

zentyal-network-2.3.13+quantal1/src/templates/ifaces.mas0000664000000000000000000003361712017102311020106 0ustar <%args> @ifaces $iface @vlans => () @bridges => () $externalWarning <%init> use EBox::Gettext; use EBox::NetWrappers qw(:all);
<% __('Remember that changing the network interfaces configuration may cause you to lose access to the administration page.') %>

<% __('Traffic being routed through interfaces marked as external will be NATed. Also, services meant for the LAN users will not be available on external interfaces.') %>
<& network/iftabs.mas, ifaces=> \@ifaces, selected => $iface->{name}&>
% if ($externalWarning) {
<% __x('You are connecting to Zentyal through this interface. If you set it as external the firewall will lock you out unless you add firewall rules to {openhref}Filtering rules from external networks to Zentyal{closehref} to allow access to the Zentyal administration port, SSH, ...', openhref => '', closehref => '') %>
% }
"/> % if (iface_exists($iface->{'name'}) or $iface->{'name'} =~ /^br/) { % } % unless ($iface->{'name'} =~ /^br/) { % }
<%__('Name')%>: '/>
<%__('Method')%>:
<%__('External (WAN)')%>:
{'external'} eq 'yes') { checked \ % } name="external" />
<% __('Check this if you are using Zentyal as a gateway and this interface is connected to your Internet router.') %>
<% __('IP address') %>:
' />
<% __('Netmask') %>:
<% __('Bridge') %>:
<% __('User name') %>:
' />
<% __('Password') %>:
' />
% if ($iface->{"method"} eq "trunk") {

<% __('VLAN List') %>

% foreach my $vlan (@vlans) { % }
<% __('VLAN Id') %> <% __('Description') %> <% __('Action') %>
"/> " title="<% __("Add") %>" value="<% __("Add") %>" >
<%$vlan->{'id'}%> <%$vlan->{'name'}%> " title="<% __("Delete") %>" value="<% __("Delete") %>" >
% }
% if ($iface->{"method"} eq "static") {

<% __('Virtual Interfaces') %>

% foreach my $viface (@{$iface->{"virtual"}}) { " action="VIface" method="post"> % }
<% __('Name') %> <% __('IP address') %> <% __('Netmask') %> <% __('Action') %>
"> " title="<% __("Add") %>" value="<% __("Add") %>" >
"> " > <% $viface->{"name"} %> <% $viface->{"address"} %> <% $viface->{"netmask"} %> " title="<% __("Delete") %>" value="<% __("Delete") %>">
% }
zentyal-network-2.3.13+quantal1/src/templates/confirm.mas0000664000000000000000000000260512017102311020302 0ustar <%args> $iface $method $address $netmask $ppp_user $ppp_pass $external $bridge <%init> use EBox::Gettext;
<% __('The change you are trying to make will affect the configuration of one or more modules that use references to this network interface.') %>

<% __('If you choose to continue, all modules that make use of the current configuration of this network interface will delete the relevant parts of their configuration. Choose "Cancel" if you are not sure about this.') %>

% if (defined($external)) { % }

zentyal-network-2.3.13+quantal1/src/templates/wizard/0000775000000000000000000000000012017102311017440 5ustar zentyal-network-2.3.13+quantal1/src/templates/wizard/network.mas0000664000000000000000000001036612017102311021641 0ustar <%args> @extifaces @intifaces <%init> use EBox::Gettext; my @ifaces = ( @extifaces, @intifaces ); my $numExt = scalar @extifaces; my $counter = 0; # Set DCHP as default value if there is only one iface my $selectedNotSet = 'selected'; my $selectedDHCP = ''; if (scalar @ifaces == 1) { $selectedNotSet = ''; $selectedDHCP = 'selected'; }

<% __('Network interfaces') %>

<% __('Configure network for external interfaces') %>

<% __('Now you can set IP addresses and networks for each interface') %>
% foreach my $iface ( @ifaces ) { % % # Limit internal ifaces options if there is any external % my $limit = ($counter >= $numExt) && ($numExt > 0);
% unless ($limit) { % }

<% $iface %>

<% __('Method') %>:
% $counter++; % }
zentyal-network-2.3.13+quantal1/src/templates/wizard/interfaces.mas0000664000000000000000000000226412017102311022271 0ustar <%args> @ifaces <%init> use EBox::Gettext;

<% __('Network interfaces') %>

<% __('Configure interface types') %>

<% __('External interfaces connect to networks that are not under your control (typically the Internet), traffic coming from external networks is not trusted by default, thus, you will not be able to connect to Zentyal administration page through them') %>
% foreach my $iface ( @ifaces ) {
<% $iface %>:
% }
zentyal-network-2.3.13+quantal1/src/templates/iftabs.mas0000664000000000000000000000051112017102311020107 0ustar <%args> @ifaces $selected
% foreach my $if (@ifaces) { % if($if->{'name'} eq $selected) { <% $if->{'alias'} %> % } else { '><% $if->{'alias'} %> % } % }
zentyal-network-2.3.13+quantal1/src/scripts/0000775000000000000000000000000012017102311015631 5ustar zentyal-network-2.3.13+quantal1/src/scripts/dhcp-nameservers.pl0000775000000000000000000000175012017102311021442 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; use Error qw(:try); EBox::init(); my $global = EBox::Global->getInstance(1); my $network = $global->modInstance("network"); my $iface = shift; $iface or exit; try { $network->setDHCPNameservers($iface, \@ARGV); } finally { exit; }; zentyal-network-2.3.13+quantal1/src/scripts/dhcp-clear-gateway.pl0000775000000000000000000000174212017102311021636 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; use Error qw(:try); EBox::init(); my $global = EBox::Global->getInstance(1); my $network = $global->modInstance("network"); my ($iface) = @ARGV; $iface or exit; try { $network->DHCPGatewayCleanUp($iface); } finally { exit; }; zentyal-network-2.3.13+quantal1/src/scripts/setup-wireless0000775000000000000000000000116312017102311020553 0ustar #!/usr/bin/perl my $iface = $ENV{'WLAN_IFACE'}; defined($iface) or exit 0; my $essid = $ENV{'WLAN_ESSID'}; defined($essid) or exit 0; my $extra_conf = $ENV{'WLAN_CONF'}; my $conf = " essid $essid\n"; if(defined($extra_conf)) { $conf .= ($extra_conf . "\n"); } my $ifile = '/etc/network/interfaces'; my $newifile = '/etc/network/interfaces.new'; open(IFACES, $ifile); open(NEW_IFACES, '>', $newifile); my $print = 1; for my $line () { print NEW_IFACES $line; if ($line =~ m/^iface $iface/) { print NEW_IFACES $conf; } } close(NEW_IFACES); close(IFACES); rename($newifile, $ifile); zentyal-network-2.3.13+quantal1/src/scripts/dhcp-gateway.pl0000775000000000000000000000254412017102311020553 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; use Error qw(:try); EBox::init(); my $network = EBox::Global->modInstance('network'); my ($iface, $router) = @ARGV; EBox::debug('Called dhcp-gateway.pl with the following values:'); $iface or exit; EBox::debug("iface: $iface"); $router or exit; EBox::debug("router: $router"); try { $network->setDHCPGateway($iface, $router); # Do not call regenGateways if we are restarting changes, they # are already going to be regenerated and also this way we # avoid nested lock problems unless (-f '/var/lib/zentyal/tmp/ifup.lock') { $network->regenGateways(); } } finally { exit; }; zentyal-network-2.3.13+quantal1/src/scripts/dhcp-clear.pl0000775000000000000000000000173312017102311020177 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; use Error qw(:try); EBox::init(); my $global = EBox::Global->getInstance(1); my $network = $global->modInstance("network"); my ($iface) = @ARGV; $iface or exit; try { $network->DHCPCleanUp($iface); } finally { exit; }; zentyal-network-2.3.13+quantal1/src/scripts/external-ip.pl0000775000000000000000000000413312017102311020422 0ustar #!/usr/bin/perl # Copyright (C) 2011-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Script: external-ip.pl # # Get the external IP address using a fixed gateway # use strict; use warnings; use EBox; use EBox::Global; use EBox::Network; use Pod::Usage; # Constants my $CHAIN = EBox::Network::CHECKIP_CHAIN(); my $DST_HOST = 'checkip.dyndns.org'; if (scalar(@ARGV) != 1 ) { pod2usage(-msg => 'Requires a gateway name', -exitval => 1); } EBox::init(); my $networkMod = EBox::Global->modInstance('network'); my $gwModel = $networkMod->model('GatewayTable'); my $gwId = $gwModel->findId(name => $ARGV[0]); unless (defined($gwId)) { pod2usage(-msg => "$ARGV[0] is not a valid gateway name", -exitval => 2); } my $marks = $networkMod->marksForRouters(); my $gwMark = $marks->{$gwId}; # Add the iptables marks my @rules = ("/sbin/iptables -t mangle -F $CHAIN || true", "/sbin/iptables -t mangle -A $CHAIN -d $DST_HOST " . "-m owner --gid-owner ebox -j MARK --set-mark $gwMark"); EBox::Sudo::root(@rules); # Perform the query as ebox my $output = EBox::Sudo::command("/usr/bin/wget http://$DST_HOST -O - -q"); my ($ip) = $output->[0] =~ m/(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/; # Flush the CHECKIP chain EBox::Sudo::silentRoot("/sbin/iptables -t mangle -F $CHAIN"); print "$ip\n"; __END__ =head1 NAME external-ip.pl - Get the external IP address using a fixed gateway =head1 SYNOPSIS external-ip.pl gateway-name gateway-name : the gateway to use for the check =cut zentyal-network-2.3.13+quantal1/src/scripts/dhcp-address.pl0000775000000000000000000000242412017102311020534 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; use Error qw(:try); EBox::init(); my $global = EBox::Global->getInstance(1); my $network = $global->modInstance("network"); my ($iface, $address, $mask) = @ARGV; EBox::debug('Called dhcp-address.pl with the following values:'); $iface or exit; EBox::debug("iface: $iface"); $address or exit; EBox::debug("address: $address"); $mask or exit; EBox::debug("mask: $mask"); try { $network->setDHCPAddress($iface, $address, $mask); } otherwise { EBox::error("Call to setDHCPAddress for $iface failed"); } finally { exit; }; zentyal-network-2.3.13+quantal1/src/scripts/flush-fwmarks0000775000000000000000000000020212017102311020342 0ustar #!/bin/bash for i in $(ip rule ls | cut -d: -f 1); do if [ $i -gt 0 -a $i -le 32765 ]; then ip rule del pref $i; fi; done zentyal-network-2.3.13+quantal1/src/scripts/ppp-set-iface.pl0000775000000000000000000000243112017102311020626 0ustar #!/usr/bin/perl # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; use EBox; use EBox::Global; use Error qw(:try); EBox::init(); my $network = EBox::Global->modInstance('network'); my ($iface, $ppp_iface, $ppp_addr) = @ARGV; EBox::debug('Called ppp-set-iface.pl with the following values:'); EBox::debug("iface: $iface") if $iface; EBox::debug("ppp_iface: $ppp_iface") if $ppp_iface; EBox::debug("ppp_addr: $ppp_addr") if $ppp_addr; try { $network->setRealPPPIface($iface, $ppp_iface, $ppp_addr); $network->regenGateways(); } otherwise { EBox::error("Call to setRealPPPIface for $iface failed"); } finally { exit; }; zentyal-network-2.3.13+quantal1/src/EBox/0000775000000000000000000000000012017102311014777 5ustar zentyal-network-2.3.13+quantal1/src/EBox/View/0000775000000000000000000000000012017102311015711 5ustar zentyal-network-2.3.13+quantal1/src/EBox/View/GatewayTableCustomizer.pm0000664000000000000000000000407212017102311022710 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # 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 # Class: EBox::Network::View::GatewayTableCustomizer # # This class is used to override the EBox::View::Customizer method # that allows modification on the fields of the GatewayTable mode. # We make the interface field non-editable for automatic rows. # package EBox::Network::View::GatewayTableCustomizer; use base 'EBox::View::Customizer'; use strict; use warnings; # Group: Public methods # Method: initHTMLStateField # # Given a field, it returns if the field has to be shown. hidden, or disabled # # Parameters: # # (Positional) # # fieldName - string containing the field name # fields - array ref of instancied types with their current values # # Returns: # # One of these strings: # # show # hide # disable # sub initHTMLStateField { my ($self, $fieldName, $fields) = @_; # We look for the auto field when we are deciding the state of # the interface field, if auto = 1, the interface select is disabled # In any other case the method from the parent class is invoked if (defined($fieldName) and ($fieldName eq 'interface')) { foreach my $field (@{$fields}) { next unless $field->fieldName() eq 'auto'; if ($field->value()) { return 'disable'; } else { last; } } } return $self->SUPER::initHTMLStateField($fieldName, $fields); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Types/0000775000000000000000000000000012017102311016103 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Types/Text/0000775000000000000000000000000012017102311017027 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Types/Text/AutoReadOnly.pm0000664000000000000000000000256712017102311021745 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Types::Text::AutoReadOnly; use strict; use warnings; use base 'EBox::Types::Text'; sub new { my $class = shift; my %opts = @_; my $self = $class->SUPER::new(%opts); bless($self, $class); return $self; } # Method: editable # # Make the field read-only when the row is auto # # Overrides: # # # sub editable { my ($self) = @_; my $row = $self->row(); unless ($row) { return 1; } my $auto = $row->valueByName('auto'); return (not $auto); } sub setMemValue { my ($self, $params) = @_; if ($self->_paramIsSet($params)) { $self->SUPER::setMemValue($params); } } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/0000775000000000000000000000000012017102311015401 5ustar zentyal-network-2.3.13+quantal1/src/EBox/CGI/Wizard/0000775000000000000000000000000012017102311016641 5ustar zentyal-network-2.3.13+quantal1/src/EBox/CGI/Wizard/Ifaces.pm0000664000000000000000000000342412017102311020374 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::Wizard::Ifaces; use strict; use warnings; use base 'EBox::CGI::WizardPage'; use EBox::Global; use EBox::Gettext; use EBox::Validate; use Error qw(:try); sub new # (cgi=?) { my $class = shift; my $self = $class->SUPER::new('template' => 'network/wizard/interfaces.mas', @_); bless($self, $class); return $self; } sub _masonParameters { my ($self) = @_; my $net = EBox::Global->modInstance('network'); my @params = (); push (@params, 'ifaces' => $net->ifaces()); return \@params; } sub _processWizard { my ($self) = @_; my $net = EBox::Global->modInstance('network'); my $interfaces = $net->get_hash('interfaces'); foreach my $iface ( @{$net->ifaces()} ) { my $scope = $self->param($iface . '_scope'); if ( $net->ifaceExists($iface) ) { my $isExternal = 0; if ($scope eq 'external') { $isExternal = 1; } $interfaces->{$iface}->{external} = $isExternal; } } $net->set('interfaces', $interfaces); } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/Wizard/Network.pm0000664000000000000000000000705212017102311020634 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::Wizard::Network; use strict; use warnings; use base 'EBox::CGI::WizardPage'; use EBox::Global; use EBox::Gettext; use EBox::Validate; use Error qw(:try); sub new # (cgi=?) { my $class = shift; my $self = $class->SUPER::new('template' => 'network/wizard/network.mas', @_); bless($self, $class); return $self; } sub _masonParameters { my ($self) = @_; my $net = EBox::Global->modInstance('network'); my @exifaces = (); my @inifaces = (); foreach my $iface ( @{$net->ifaces} ) { if ( $net->ifaceIsExternal($iface) ) { push (@exifaces, $iface); } else { push (@inifaces, $iface); } } my @params = (); push (@params, 'extifaces' => \@exifaces); push (@params, 'intifaces' => \@inifaces); return \@params; } sub _processWizard { my ($self) = @_; my $net = EBox::Global->modInstance('network'); my $gwModel = $net->model('GatewayTable'); # Remove possible gateways introduced by network-import script $gwModel->removeAll(); my $interfaces = $net->get_hash('interfaces'); foreach my $iface ( @{$net->ifaces} ) { my $method = $self->param($iface . '_method'); if ($method eq 'dhcp') { my $ext = $net->ifaceIsExternal($iface); $net->setIfaceDHCP($iface, $ext, 1); # As after the installation the method is already set # to DHCP, we need to force the change in order to # execute ifup during the first save changes $interfaces->{$iface}->{changed} = 1; } elsif ($method eq 'static') { my $ext = $net->ifaceIsExternal($iface); my $addr = $self->param($iface . '_address'); my $nmask = $self->param($iface . '_netmask'); my $gw = $self->param($iface . '_gateway'); my $dns1 = $self->param($iface . '_dns1'); my $dns2 = $self->param($iface . '_dns2'); $net->setIfaceStatic($iface, $addr, $nmask, $ext, 1); if ($gw ne '') { try { $gwModel->add(name => $gw, ip => $gw, interface => $iface, weight => 1, default => 1); } # ignore errors (probably gateway already exists) otherwise {}; } my $dnsModel = $net->model('DNSResolver'); if ($dns1 ne '') { try { $dnsModel->add(nameserver => $dns1); } otherwise {}; } if ($dns2 ne '') { try { $dnsModel->add(nameserver => $dns2); } otherwise {}; } } } $net->set('interfaces', $interfaces); } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/Vlan.pm0000664000000000000000000000453712017102311016650 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::Vlan; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Gettext; use EBox::Global; use Error qw(:try); sub new # (cgi=?) { my $class = shift; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _process { my $self = shift; my $net = EBox::Global->modInstance('network'); $self->_requireParam("ifname", __("network interface")); my $iface = $self->param("ifname"); $self->_requireParam("vlanid", __("VLAN Id")); my $vlanId = $self->param('vlanid'); $self->{redirect} = "Network/Ifaces?iface=$iface"; $self->{errorchain} = "Network/Ifaces"; my $audit = EBox::Global->modInstance('audit'); $self->keepParam('iface'); $self->cgi()->param(-name=>'iface', -value=>$iface); if ($self->param('cancel')) { return; } if (defined($self->param('del'))) { try { my $force = $self->param('force'); $net->removeVlan($vlanId, $force); $audit->logAction('network', 'Interfaces', 'removeVlan', "$iface, $vlanId", 1); } catch EBox::Exceptions::DataInUse with { $self->{template} = 'network/confirmVlanDel.mas'; $self->{redirect} = undef; my @masonParams = (); push@masonParams, ('iface' => $iface); push @masonParams, (vlanid => $vlanId); $self->{params} = \@masonParams; }; } elsif (defined($self->param('add'))) { $net->createVlan($vlanId, $self->param('vlandesc'), $iface); $audit->logAction('network', 'Interfaces', 'createVlan', "$iface, $vlanId", 1); } } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/Diag.pm0000664000000000000000000000774012017102311016613 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::Diag; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::Gettext; use Error qw(:try); sub new # (error=?, msg=?, cgi=?) { my $class = shift; my $self = $class->SUPER::new('title' => __('Network Diagnostic Tools'), 'template' => '/network/diag.mas', @_); bless($self, $class); return $self; } sub _process { my $self = shift; $self->{title} = __('Network Diagnostic Tools'); my $net = EBox::Global->modInstance('network'); my @array = (); my $action = $self->param("action"); my $objects = EBox::Global->modInstance('objects'); my @object_list; for my $object (@{$objects->objects()}) { my $there_is_mac = 0; for my $member (@{$objects->objectMembers($object->{id})}) { $there_is_mac = $there_is_mac || defined $member->{macaddr}; } if ($there_is_mac) { push(@object_list, $object); } } if(defined($action)){ if($action eq "ping"){ $self->_requireParam("ip", __("Host")); my $ip = $self->param("ip"); my $output = $net->ping($ip); push(@array, 'action' => 'ping'); push(@array, 'target' => $ip); push(@array, 'output' => $output); }elsif($action eq "traceroute"){ $self->_requireParam("ip", __("Host")); my $ip = $self->param("ip"); my $output = $net->traceroute($ip); push(@array, 'action' => 'traceroute'); push(@array, 'target' => $ip); push(@array, 'output' => $output); }elsif($action eq "dns"){ $self->_requireParam("host", __("host name")); my $host = $self->param("host"); my $output = $net->resolv($host); push(@array, 'action' => 'dns'); push(@array, 'target' => $host); push(@array, 'output' => $output); } elsif ($action eq "wakeonlan") { my $id = $self->param("object_id"); if ( $id eq 'other' || $id eq '' ) { try { $self->_requireParam("mac", __("MAC address")); } otherwise { push(@array, 'objects' => \@object_list); $self->{params} = \@array; my $ex = shift; $ex->throw(); }; my $mac = $self->param("mac"); EBox::Validate::checkMAC($mac, __("MAC address")); my $output = $net->wakeonlan($mac); push(@array, 'action' => 'wakeonlan'); push(@array, 'target' => $mac); push(@array, 'output' => $output); } else { my $objects = EBox::Global->modInstance('objects'); my @macs; for my $member (@{$objects->objectMembers($id)}) { push(@macs, $member->{macaddr}); } my $output = $net->wakeonlan(@macs); push(@array, 'action' => 'wakeonlan'); push(@array, 'target' => $id); push(@array, 'output' => $output); } } } push(@array, 'objects' => \@object_list); $self->{params} = \@array; } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/Ifaces.pm0000664000000000000000000000654312017102311017141 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::Ifaces; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::Gettext; sub new # (error=?, msg=?, cgi=?) { my $class = shift; my $self = $class->SUPER::new('title' => __('Network Interfaces'), 'template' => '/network/ifaces.mas', @_); bless($self, $class); return $self; } sub _process { my $self = shift; $self->{params} = $self->masonParameters(); } sub masonParameters { my ($self) = @_; my $net = EBox::Global->modInstance('network'); my $ifname = $self->param('iface'); ($ifname) or $ifname = ''; my $tmpifaces = $net->ifaces(); my $iface = {}; if ($ifname eq '') { $ifname = @{$tmpifaces}[0]; } my @params = (); my @bridges = (); my @ifaces = (); foreach (@{$tmpifaces}) { my $ifinfo = {}; $ifinfo->{'name'} = $_; $ifinfo->{'alias'} = $net->ifaceAlias($_); push(@ifaces,$ifinfo); ($_ eq $ifname) or next; $iface->{'name'} = $_; $iface->{'alias'} = $net->ifaceAlias($_); $iface->{'method'} = $net->ifaceMethod($_); if ($net->ifaceIsExternal($_)) { $iface->{'external'} = "yes"; } else { $iface->{'external'} = "no"; } if ($net->ifaceMethod($_) eq 'static') { $iface->{'address'} = $net->ifaceAddress($_); $iface->{'netmask'} = $net->ifaceNetmask($_); $iface->{'virtual'} = $net->vifacesConf($_); } elsif ($net->ifaceMethod($_) eq 'trunk') { push(@params, 'vlans' => $net->ifaceVlans($_)); } elsif ($net->ifaceMethod($_) eq 'bridged') { $iface->{'bridge'} = $net->ifaceBridge($_); } elsif ($net->ifaceMethod($_) eq 'ppp') { $iface->{'ppp_user'} = $net->ifacePPPUser($_); $iface->{'ppp_pass'} = $net->ifacePPPPass($_); } } my $externalWarning = 0; if ($net->ifaceIsExternal($ifname)) { $externalWarning = _externalWarning($ifname); } foreach my $bridge ( @{$net->bridges()} ) { my $brinfo = {}; $brinfo->{'id'} = $bridge; $brinfo->{'name'} = "br$bridge"; $brinfo->{'alias'} = $net->ifaceAlias("br$bridge"); push(@bridges, $brinfo); } push(@params, 'externalWarning' => $externalWarning); push(@params, 'iface' => $iface); push(@params, 'ifaces' => \@ifaces); push(@params, 'bridges', => \@bridges); return \@params; } sub _externalWarning { my ($iface) = @_; my $req = Apache2::RequestUtil->request(); return 0 unless ($req); my $remote = $req->connection->remote_ip(); my $command = "/sbin/ip route get to $remote " . ' | head -n 1 | sed -e "s/.*dev \(\w\+\).*/\1/" '; my $routeIface = `$command`; return 0 unless ( $? == 0); chop($routeIface); if (defined($routeIface) and $routeIface eq $iface) { return 1; } } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/VIface.pm0000664000000000000000000000553212017102311017101 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::VIface; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::Gettext; use EBox::Exceptions::DataInUse; use Error qw(:try); sub new # (cgi=?) { my $class = shift; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _process { my $self = shift; my $net = EBox::Global->modInstance('network'); $self->{errorchain} = "Network/Ifaces"; $self->_requireParam("ifname", __("network interface")); $self->_requireParam("ifaction", __("virtual interface action")); my $iface = $self->param("ifname"); my $ifaction = $self->param("ifaction"); my $force = undef; $self->{redirect} = "Network/Ifaces?iface=$iface"; if (defined($self->param("cancel"))) { return; } elsif (defined($self->param("force"))) { $force = 1; } my $audit = EBox::Global->modInstance('audit'); $self->keepParam('iface'); $self->cgi()->param(-name=>'iface', -value=>$iface); if ($ifaction eq 'add'){ $self->_requireParam("vif_address", __("IP address")); $self->_requireParam("vif_netmask", __("netmask")); $self->_requireParam("vif_name", __("virtual interface name")); my $name = $self->param("vif_name"); my $address = $self->param("vif_address"); my $netmask = $self->param("vif_netmask"); $net->setViface($iface, $name, $address, $netmask); $audit->logAction('network', 'Interfaces', 'setViface', "$iface:$name, $address/$netmask", 1); } elsif ($ifaction eq 'delete') { $self->_requireParam("vif_name", __("virtual interface name")); my $viface = $self->param("vif_name"); try { $net->removeViface($iface, $viface, $force); $audit->logAction('network', 'Interfaces', 'removeViface', "$iface:$viface", 1); } catch EBox::Exceptions::DataInUse with { $self->{template} = 'network/confirmremove.mas'; $self->{redirect} = undef; my @array = (); push(@array, 'iface' => $iface); push(@array, 'viface' => $viface); $self->{params} = \@array; }; } } 1; zentyal-network-2.3.13+quantal1/src/EBox/CGI/Iface.pm0000664000000000000000000001135712017102311016755 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::CGI::Network::Iface; use strict; use warnings; use base 'EBox::CGI::ClientBase'; use EBox::Global; use EBox::Gettext; use Error qw(:try); sub new # (cgi=?) { my $class = shift; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _process { my $self = shift; $self->{errorchain} = 'Network/Ifaces'; $self->_requireParam('ifname', __('network interface')); my $iface = $self->param('ifname'); $self->{redirect} = "Network/Ifaces?iface=$iface"; $self->setIface(); } sub setIface { my ($self) = @_; my $net = EBox::Global->modInstance('network'); my $force = undef; $self->_requireParam('method', __('method')); $self->_requireParam('ifname', __('network interface')); my $iface = $self->param('ifname'); my $alias = $self->param('ifalias'); my $method = $self->param('method'); my $address = ''; my $netmask = ''; my $ppp_user = ''; my $ppp_pass = ''; my $bridge = ''; my $external = undef; if (defined($self->param('external'))) { $external = 1; } my $extStr = $external ? 'external' : 'internal'; # string for audit log if (defined($self->param('cancel'))) { return; } elsif (defined($self->param('force'))) { $force = 1; } $self->keepParam('iface'); $self->cgi()->param(-name=>'iface', -value=>$iface); my $audit = EBox::Global->modInstance('audit'); try { if (defined($alias)) { $net->setIfaceAlias($iface,$alias); $audit->logAction('network', 'Interfaces', 'setIfaceAlias', "$iface, $alias", 1) if ($iface ne $alias); } if ($method eq 'static') { $self->_requireParam('if_address', __('ip address')); $self->_requireParam('if_netmask', __('netmask')); $address = $self->param('if_address'); $netmask = $self->param('if_netmask'); $net->setIfaceStatic($iface, $address, $netmask, $external, $force); $audit->logAction('network', 'Interfaces', 'setIfaceStatic', "$iface, $address, $netmask, $extStr", 1); } elsif ($method eq 'ppp') { $self->_requireParam('if_ppp_user', __('user name')); $self->_requireParam('if_ppp_pass', __('password')); $ppp_user = $self->param('if_ppp_user'); $ppp_pass = $self->param('if_ppp_pass'); $net->setIfacePPP($iface, $ppp_user, $ppp_pass, $external, $force); my $extStr = $external ? 'external' : 'internal'; $audit->logAction('network', 'Interfaces', 'setIfacePPP', "$iface, user=$ppp_user, pass=$ppp_pass, $extStr", 1); } elsif ($method eq 'dhcp') { $net->setIfaceDHCP($iface, $external, $force); $audit->logAction('network', 'Interfaces', 'setIfaceDHCP', "$iface, $extStr", 1); } elsif ($method eq 'trunk') { $net->setIfaceTrunk($iface, $force); $audit->logAction('network', 'Interfaces', 'setIfaceTrunk', $iface, 1); } elsif ($method eq 'bridged') { $self->_requireParam('bridge', __('bridge')); $bridge = $self->param('bridge'); $net->setIfaceBridged($iface, $external, $bridge, $force); $audit->logAction('network', 'Interfaces', 'setIfaceBridged', "$iface, $bridge, $extStr", 1); } elsif ($method eq 'notset') { $net->unsetIface($iface, $force); $audit->logAction('network', 'Interfaces', 'unsetIface', $iface, 1); } } catch EBox::Exceptions::DataInUse with { $self->{template} = 'network/confirm.mas'; $self->{redirect} = undef; my @array = (); push(@array, 'iface' => $iface); push(@array, 'method' => $method); push(@array, 'address' => $address); push(@array, 'netmask' => $netmask); push(@array, 'ppp_user' => $ppp_user); push(@array, 'ppp_pass' => $ppp_pass); push(@array, 'external' => $external); push(@array, 'bridge' => $bridge); $self->{params} = \@array; }; } 1; zentyal-network-2.3.13+quantal1/src/EBox/NetworkUtil.pm0000664000000000000000000000315012017102311017623 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::NetworkUtil; use strict; use warnings; use EBox::Network; BEGIN { use Exporter (); our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); @ISA = qw(Exporter); @EXPORT = qw(); %EXPORT_TAGS = (all => [qw{ gwReachable } ]); @EXPORT_OK = qw(); Exporter::export_ok_tags('all'); $VERSION = EBox::Config::version; } sub gwReachable # (network, address, exception?) { my ($network, $gw, $exception) = @_; my $cidr_gw = "$gw/32"; foreach (@{$network->allIfaces()}) { my $host = $network->ifaceAddress($_); my $mask = $network->ifaceNetmask($_); my $meth = $network->ifaceMethod($_); checkIPNetmask($gw, $mask) or next; ($meth eq 'static') or next; (defined($host) and defined($mask)) or next; if (isIPInNetwork($host,$mask,$cidr_gw)) { return 1; } } if ($exception) { throw EBox::Exceptions::External( __x("Gateway {gw} not reachable", gw => $gw)); } else { return undef; } } 1; zentyal-network-2.3.13+quantal1/src/EBox/NetworkObserver.pm0000664000000000000000000001611112017102311020476 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::NetworkObserver; use strict; use warnings; use EBox::Gettext; sub new { my $class = shift; my $self = {}; bless($self, $class); return $self; } # Method: staticIfaceAddressChanged # Invoked when the address of an static network interface is going to # be changed, this method receives the old and new addresses and masks # as arguments. Returning a true value means that this # module's configuration would become inconsistent if such a change # was made. In that case the network module will not make the change, # but warn the user instead. You should override this method if you need # to. # # Parameters: # # iface - interface name # oldaddr - old address # oldmask - old mask # newaddr - new address # newmask - new mask # # Returns: # # boolean - true if module's configuration becomes inconsistent, otherwise # false sub staticIfaceAddressChanged # (iface, oldaddr, oldmask, newaddr, newmask) { return undef; } # Method: staticIfaceAddressChangedDone # # Invoked when the change in the adddress of a static inteface has taken # place. # # Iit will be called after freeIface, ifaceMethodChanged and staticIfaceAddressChanged # when the configuration changes have already been set. # # Parameters: # # iface - interface name # oldaddr - old address # oldmask - old mask # newaddr - new address # newmask - new mask # sub staticIfaceAddressChangedDone # (iface, oldaddr, oldmask, newaddr, newmask) { # default empty implementation. Subclasses should override this as # needed. } # Method: ifaceMethodChanged # # Invoked when the configuration method for a network interface is # going to change. Both the old and new methods are passed as # arguments to this function. They are strings: static, dhcp, # trunk or notset. As with the previous function, a return value of # true will prevent the change from being made. You should override this # method if you need to. # # Parameteres: # # iface - interface name # oldmethod - old method # newmethod - newmethod # # Returns: # # boolean - true if module's configuration becomes inconsistent, otherwise # false sub ifaceMethodChanged # (iface, oldmethod, newmethod) { return undef; } # Method: ifaceMethodChangeDone # # Invoked when a method configuration change has taken place. # # Note that it will be called after freeIface and ifaceMethodChanged # when the configuration changes have already been set. # # Parameteres: # # iface - interface name # sub ifaceMethodChangeDone # (iface) { # default empty implementation. Subclasses should override this as # needed. } # Method: ifaceExternalChanged # # Invoked when a iface is going to change from external to # internal and viceversa. Its argument is the name of the real # interface. As with the previous function, a return value of # true will prevent the change from being made. You should override this # method if you need to. # # Parameteres: # # iface - interface name # # external - boolean indicating if the property is gonna set to # *external* # # Returns: # # boolean - true if module's configuration becomes inconsistent, otherwise # false sub ifaceExternalChanged # (iface) { return undef; } # Method: vifaceDelete # # Invoked when a virtual interface is going to be removed. Its # arguments are the real interface which it's going to be removed from, # the name of the interface to remove, its ip address and its netmask. It # works the same way: return true if the removal of the virtual # interface is incompatible with your module's current configuration. # # Parameteres: # # iface - interface name # viface - virtual interface to be removed # # Returns: # # boolean - true if module's configuration becomes inconsistent, otherwise # false # sub vifaceDelete # (iface, viface) { return undef; } # Method: vifaceAdded # # Invoked when a new virtual interface is going to be created. Its # arguments are the real interface to which it's going to be added, # the name of the new interface, its ip address and its netmask. It # works the same way: return true if the creation of the virtual # interface is incompatible with your module's current configuration. # # Parameteres: # # iface - interface name # viface - virtual interface to be removed # newmethod - newmethod # # Returns: # # boolean - true if module's configuration becomes inconsistent, otherwise # false sub vifaceAdded # (iface, viface, address, netmask) { return undef; } # Method: changeIfaceExternalProperty # # Invoked when an interface is going to change from external to # internal. Its argument is the name of the real interface. It # works exactly the same way as two methods above. # # Parameters: # # iface - interface name # external - boolean indicating in which way external is going to change # # Returns: # # boolean - true if module's configuration becomes inconsistent, otherwise # false # sub changeIfaceExternalProperty # (iface, external) { # default empty implementation. Subclasses should override this as # needed. } # Method: freeIface # # Invoked when an interface is going to be removed. Its argument # is the name of the real interface. It works exactly # the same way as the three methods above. # # Parameteres: # # iface - interface name # sub freeIface # (iface) { # default empty implementation. Subclasses should override this as # needed. } # Method: freeViface # # Invoked when a virtual interface is going to be removed. Its arguments # are the names of the real and virtual interfaces. It works exactly # the same way as the four methods above. # # Parameteres: # # iface - interface name # viface - virtual interface to be removed # sub freeViface # (iface, viface) { # default empty implementation. Subclasses should override this as # needed. } # Method: gatewayDelete # # Invoked when a gateway is going to be removed. # It works the same way: return true if the removal of the gateway # is incompatible with your module's current configuration. # # Parameteres: # # gwName - gateway name # # Returns: # # boolean - true if module's configuration becomes inconsistent, # false otherwise # sub gatewayDelete { my ($self, $gwName) = @_; return 0; } # Method: regenGatewaysFailover # # Invoked when the routing tables are regenerated after a failover event. # sub regenGatewaysFailover { } 1; zentyal-network-2.3.13+quantal1/src/EBox/Event/0000775000000000000000000000000012017102311016060 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Event/Watcher/0000775000000000000000000000000012017102311017455 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Event/Watcher/Gateways.pm0000664000000000000000000003251212017102311021602 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Event::Watcher::Gateways; # Class: EBox::Event::Watcher::Gateways; # # This class is a watcher which checks connection/disconnection of gateways # use base 'EBox::Event::Watcher::Base'; use EBox::Network; use EBox::Event; use EBox::Global; use EBox::Gettext; use EBox::Validate; use EBox::Exceptions::Lock; use Error qw(:try); # Group: Public methods # Constructor: new # # The constructor for # # Overrides: # # # # Parameters: # # - non parameters # # Returns: # # - the newly created object # sub new { my ($class) = @_; my $network = EBox::Global->getInstance(1)->modInstance('network'); my $options = $network->model('WANFailoverOptions')->row(); my $period = $options->valueByName('period'); my $self = $class->SUPER::new(period => $period); $self->{counter} = 0; bless ($self, $class); return $self; } # Method: ConfigurationMethod # # Overrides: # # # sub ConfigurationMethod { return 'none'; } # Method: run # # Check state of the gateways. # # Overrides: # # # # Returns: # # array ref - an info event is sent if Zentyal is up and # running and a fatal event if Zentyal is down # sub run { my ($self) = @_; EBox::debug('Entering failover event...'); $self->{eventList} = []; $self->{failed} = {}; # Getting readonly instance to test the gateways my $global = EBox::Global->getInstance(1); my $network = $global->modInstance('network'); return [] unless $network->isEnabled(); my $rules = $network->model('WANFailoverRules'); my $gateways = $network->model('GatewayTable'); $self->{gateways} = $gateways; $self->{marks} = $network->marksForRouters(); my @enabledRules = @{$rules->enabledRows()}; # If we don't have any enabled rule we finish here return [] unless @enabledRules; foreach my $id (@enabledRules) { EBox::debug("Testing rules for gateway with id $id..."); my $row = $rules->row($id); $self->_testRule($row); } # We won't do anything if there are unsaved changes my $readonly = EBox::Global->getInstance()->modIsChanged('network'); unless ($readonly) { # Getting read/write instance to apply the changes $network = EBox::Global->modInstance('network'); $gateways = $network->model('GatewayTable'); } EBox::debug('Applying changes in the gateways table...'); my $needSave = 0; foreach my $id (@{$gateways->ids()}) { my $row = $gateways->row($id); my $gwName = $row->valueByName('name'); my $enabled = $row->valueByName('enabled'); # It must be enabled if all tests are passed my $enable = $enabled; if (defined($self->{failed}->{$id})) { $enable = not($self->{failed}->{$id}) }; EBox::debug("Properties for gateway $gwName ($id): enabled=$enabled, enable=$enable"); # We don't do anything if the previous state is the same if ($enable xor $enabled) { unless ($readonly) { $row->elementByName('enabled')->setValue($enable); $row->store(); $needSave = 1; } if ($enable) { my $event = new EBox::Event(message => __x("Gateway {gw} connected again.", gw => $gwName), level => 'info', source => 'WAN Failover', additional => { 'up' => 1, gateway => $gwName }); push (@{$self->{eventList}}, $event); } } } if ($readonly) { EBox::warn('Leaving failover event without doing anything due to unsaved changes on the Zentyal interface.'); foreach my $event (@{$self->{eventList}}) { $event->{message} = __('WARNING: These changes are not applied due to unsaved changes on the administration interface.') . "\n\n" . $event->{message}; } return $self->{eventList}; } my ($setAsDefault, $unsetAsDefault); # Check if default gateway has been disabled and choose another my $default = $gateways->findValue('default' => 1); my $originalId = $network->selectedDefaultGateway(); EBox::debug("The preferred default gateway is $originalId"); unless ($default and $default->valueByName('enabled')) { # If the original default gateway is alive, restore it my $original; $original = $gateways->row($originalId) if $originalId; if ($original and $original->valueByName('enabled')) { $original = $gateways->row($originalId); $unsetAsDefault = $default; $setAsDefault = $original; EBox::debug('The original default gateway will be restored'); $needSave = 1; } else { EBox::debug('Checking if there is another enabled gateway to set as default'); # Check if we can find another enabled to set it as default my $other = $gateways->findValue('enabled' => 1); if ($other) { $unsetAsDefault = $default; $setAsDefault = $other; } } } else { # check if the gw enabled is the prefered one if ($originalId and ($default->id() ne $originalId)) { my $original = $gateways->row($originalId); if ($original and $original->valueByName('enabled')) { EBox::debug('The original default gateway will replace the current default'); $unsetAsDefault = $default; $setAsDefault = $original; } } } if ($unsetAsDefault) { $unsetAsDefault->elementByName('default')->setValue(0); $unsetAsDefault->store(); EBox::debug("The gateway " . $unsetAsDefault->valueByName('name'). " is not longer default"); $needSave = 1; } if ($setAsDefault) { $setAsDefault->elementByName('default')->setValue(1); $setAsDefault->store(); EBox::debug("The gateway " . $setAsDefault->valueByName('name'). " is now the default"); $needSave = 1; } if ($needSave) { EBox::debug('Regenerating rules for the gateways'); $network->regenGateways(); foreach my $module ($global->modInstancesOfType('EBox::NetworkObserver')) { my $timeout = 60; while ($timeout) { try { $module->regenGatewaysFailover(); last; } catch EBox::Exceptions::Lock with { sleep 5; $timeout -= 5; }; } if ($timeout <= 0) { EBox::error("WAN Failover: $module->{name} module has been locked for 60 seconds."); } } } else { EBox::debug('No need to regenerate the rules for the gateways'); } EBox::debug('Leaving failover event...'); return $self->{eventList}; } sub _testRule # (row) { my ($self, $row) = @_; my $gw = $row->valueByName('gateway'); my $network = EBox::Global->modInstance('network'); my $gwName = $self->{gateways}->row($gw)->valueByName('name'); my $iface = $self->{gateways}->row($gw)->valueByName('interface'); my $wasEnabled = $self->{gateways}->row($gw)->valueByName('enabled'); EBox::debug("Entering _testRule for gateway $gwName..."); # First test on this gateway, initialize its entry on the hash unless (exists $self->{failed}->{$gw}) { $self->{failed}->{$gw} = 0; } # If a test for this gw has already failed we don't test any other return if ($self->{failed}->{$gw}); my ($ppp_iface, $iface_up); if ($network->ifaceMethod($iface) eq 'ppp') { EBox::debug("It is a PPPoE gateway"); $ppp_iface = $network->realIface($iface); $iface_up = !($ppp_iface eq $iface); EBox::debug("Iface $ppp_iface up? = $iface_up"); if (!$iface_up) { # PPP interface down, do not make test (not needed) $self->{failed}->{$gw} = 1; return; } } my $type = $row->valueByName('type'); my $typeName = $row->printableValueByName('type'); my $host = $row->valueByName('host'); EBox::debug("Running $typeName tests for gateway $gwName..."); if ($type eq 'gw_ping') { my $gwRow = $self->{gateways}->row($gw); $host = $gwRow->valueByName('ip'); return unless $host; } my $probes = $row->valueByName('probes'); my $ratio = $row->valueByName('ratio') / 100; my $neededSuccesses = $probes * $ratio; my $maxFailRatio = 1 - $ratio; my $maxFails = $probes * $maxFailRatio; my $usedProbes = 0; my $successes = 0; my $fails = 0; # Set rule for outgoing traffic through the gateway we are testing $self->_setIptablesRule($gw, 1); for (1..$probes) { $usedProbes++; if ($self->_runTest($type, $host)) { EBox::debug("Probe number $_ succeded."); $successes++; last if ($successes >= $neededSuccesses); } else { EBox::debug("Probe number $_ failed."); $fails++; last if ($fails >= $maxFails); } } # Clean rule $self->_setIptablesRule($gw, 0); my $failRatio = $fails / $usedProbes; if ($failRatio >= $maxFailRatio) { $self->{failed}->{$gw} = 1; # Only generate event if gateway was not already disabled return unless ($wasEnabled); my $disconnectMsg = __x('Gateway {gw} disconnected', gw => $gwName); my $reason =__x("'{type}' test to host '{host}' has failed {failRatio}%, max={maxFailRatio}%.", failRatio => sprintf("%.2f", $failRatio*100), type => $typeName, host => $host, maxFailRatio => $maxFailRatio*100); my $explanation = __('This gateway will be connected again if the test are passed.'); my $event = new EBox::Event(message => "$disconnectMsg\n\n$reason\n$explanation", level => 'error', source => 'WAN Failover', additional => { down => 1, gateway => $gwName, type => $type, host => $host, fail_ratio => $failRatio, max_fail_ratio => $maxFailRatio, } ); push (@{$self->{eventList}}, $event); } } sub _runTest # (type, host) { my ($self, $type, $host) = @_; my $result; if (($type eq 'gw_ping') or ($type eq 'host_ping')) { $result = system("ping -W5 -c1 $host"); } elsif ($type eq 'dns') { $result = system("host -W 5 $host"); } elsif ($type eq 'http') { my $command = "wget $host --tries=1 -T 5 -O /dev/null"; $result = system($command); } return $result == 0; } sub _setIptablesRule # (gw, set) { my ($self, $gw, $set) = @_; my $chain = EBox::Network::FAILOVER_CHAIN(); # Flush previous rules from custom chain. It'll fail silently # if it doesn't exist EBox::Sudo::silentRoot("/sbin/iptables -t mangle -F $chain"); if ($set) { # We need to add a rule to return and do nothing # when the traffic is generated by zentyal's apache my $apachePort = EBox::Global->modInstance('apache')->port(); my $rule = "/sbin/iptables -t mangle -A $chain " . "-p tcp --source-port $apachePort -j RETURN"; EBox::Sudo::root($rule); # Add rule to mark packets generated by zentyal, i.e: failover tests my $mark = $self->{marks}->{$gw}; $rule = "/sbin/iptables -t mangle -A $chain " . "-m owner --gid-owner ebox -j MARK --set-mark $mark"; EBox::Sudo::root($rule); } } # Group: Protected methods # Method: _name # # Overrides: # # # # Returns: # # String - the event watcher name # sub _name { return __('WAN Failover'); } # Method: _description # # Overrides: # # # # Returns: # # String - the event watcher detailed description # sub _description { return __('Check if gateways are connected or disconnected.'); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/0000775000000000000000000000000012017102311016037 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Model/StaticRoute.pm0000664000000000000000000001220512017102311020643 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::Network::Model::StaticRoute # # This model configures the static route table for the server # itself. The fields are the following ones: # # - network # - gateway # - description (optional) package EBox::Network::Model::StaticRoute; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox::Gettext; use EBox::Types::IPAddr; use EBox::Types::HostIP; use EBox::Types::Text; # Dependencies # Group: Public methods # Constructor: new # # Create the static route table # # Overrides: # # # # Returns: # # # sub new { my ($class, %opts) = @_; my $self = $class->SUPER::new(%opts); bless ($self, $class); return $self; } # Method: validateTypedRow # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; # Validate the gateway is reachable if ( exists $changedFields->{gateway} ) { my $netMod = $self->parentModule(); $netMod->gatewayReachable($changedFields->{gateway}->value(), $changedFields->{gateway}->printableName()); } # As we cannot clone the oldRow, we just keep the old params here if ( $action eq 'update' ) { my $oldRow = $self->row($changedFields->{id}); unless ( ($allFields->{gateway}->cmp($oldRow->elementByName('gateway')) == 0) and ($allFields->{network}->cmp($oldRow->elementByName('network')) == 0)) { $self->{toDelete} = { network => $oldRow->printableValueByName('network'), gateway => $oldRow->printableValueByName('gateway') }; } } } # Method: updatedRowNotify # # Overrides: # # # sub updatedRowNotify { my ($self, $row, $oldRow, $force) = @_; # Check if network or gateway values have changed to delete # current route from routing table # The check is done in validateTypedRow if (exists $self->{toDelete}) { my $netMod = $self->parentModule(); $netMod->gatewayDeleted($self->{toDelete}->{gateway}); delete $self->{toDelete}; } } # Method: deletedRowNotify # # Overrides: # # # sub deletedRowNotify { my ($self, $rowDeleted, $force) = @_; my $net = $rowDeleted->elementByName('network')->printableValue(); my $gw = $rowDeleted->elementByName('gateway')->printableValue(); my $netMod = $self->parentModule(); $netMod->gatewayDeleted($gw); } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableDesc = ( new EBox::Types::IPAddr( fieldName => 'network', printableName => __('Network'), editable => 1, unique => 1, help => __('IP or network address') ), new EBox::Types::HostIP( fieldName => 'gateway', printableName => 'Gateway', editable => 1, help => __('Gateway used to reach the above network' . ' address') ), new EBox::Types::Text( fieldName => 'description', printableName => __('Description'), editable => 1, optional => 1, help => __('Optional description for this route') ), ); my $dataTable = { tableName => 'StaticRoute', printableTableName => __('Static Routes List'), pageTitle => __('Static Routes'), modelDomain => 'Network', defaultActions => [ 'add', 'del', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => __('All gateways you enter here must be reachable ' . 'through one of the network interfaces ' . 'currently configured.'), printableRowName => __('static route'), sortedBy => 'gateway', index => 'network', }; return $dataTable; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/WANFailoverRules.pm0000664000000000000000000001141212017102311021524 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::WANFailoverRules; use EBox::Global; use EBox::Gettext; use EBox::Types::Int; use EBox::Types::Select; use EBox::Types::Host; use EBox::View::Customizer; use EBox::Validate; use EBox::Exceptions::External; use Perl6::Junction qw(any); use strict; use warnings; use base 'EBox::Model::DataTable'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub gatewayModel { return EBox::Global->modInstance('network')->model('GatewayTable'); } sub types { return [ { 'value' => 'gw_ping', 'printableValue' => __('Ping to gateway') }, { 'value' => 'host_ping', 'printableValue' => __('Ping to host') }, { 'value' => 'dns', 'printableValue' => __('DNS resolve') }, { 'value' => 'http', 'printableValue' => __('HTTP Request') }, ]; } # Method: _table # # Overrides: # # # sub _table { my @tableHead = ( new EBox::Types::Select( 'fieldName' => 'gateway', 'printableName' => 'Gateway', 'foreignModel' => \&gatewayModel, 'foreignField' => 'name', 'editable' => 1, ), new EBox::Types::Select( 'fieldName' => 'type', 'printableName' => __('Test type'), 'populate' => \&types, 'editable' => 1, ), new EBox::Types::Host( 'fieldName' => 'host', 'printableName' => __('Host'), 'editable' => 1, 'optional' => 1, ), new EBox::Types::Int( 'fieldName' => 'probes', 'printableName' => __('Number of probes'), 'defaultValue' => 6, 'size' => 2, 'min' => 1, 'max' => 50, 'editable' => 1, ), new EBox::Types::Int( 'fieldName' => 'ratio', 'printableName' => __('Required success ratio'), 'trailingText' => '%', 'defaultValue' => 40, 'size' => 2, 'min' => 1, 'max' => 100, 'editable' => 1, ), ); my $dataTable = { 'tableName' => 'WANFailoverRules', 'printableTableName' => __('Test rules'), 'defaultActions' => [ 'add', 'del', 'editField', 'clone', 'changeView' ], 'modelDomain' => 'Network', 'tableDescription' => \@tableHead, 'class' => 'dataTable', 'enableProperty' => 1, 'defaultEnabledValue' => 1, 'help' => __('You can define different rules to test if a gateway is working properly. If one of the test fails the gateway will be disabled. It will be enabled again when all tests are passed.'), 'printableRowName' => __('rule'), }; return $dataTable; } # Method: viewCustomizer # # Overrides to implement # a custom behaviour to enable and disable the host field # depending on the test type # # sub viewCustomizer { my ($self) = @_; my $customizer = new EBox::View::Customizer(); my $fields = [ 'host' ]; $customizer->setModel($self); $customizer->setOnChangeActions( { type => { gw_ping => { disable => $fields }, host_ping => { enable => $fields }, dns => { enable => $fields }, http => { enable => $fields }, } }); return $customizer; } # Method: validateTypedRow # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; my $type = $allFields->{type}->value(); return if $type eq 'gw_ping'; my $host = $allFields->{host}->value(); unless (EBox::Validate::checkHost($host)) { throw EBox::Exceptions::External(__('Invalid value for Host')); } } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/DNSResolver.pm0000664000000000000000000000660112017102311020546 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Class: EBox::Network::Model::DNSResolver # # This model configures the DNS resolvers for the host. It allows to # set as many name servers as you want. The single field available is # the following one: # # - nameserver # package EBox::Network::Model::DNSResolver; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox::Gettext; use EBox::Global; use EBox::Types::HostIP; # Dependencies # Group: Public methods # Constructor: new # # Create the new DNS resolver table # # Overrides: # # # # Returns: # # - the newly created object # instance # sub new { my ($class, %opts) = @_; my $self = $class->SUPER::new(%opts); bless ( $self, $class); return $self; } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my $helpHostIP = __('IP address of the DNS server that Zentyal'. ' will use to resolve names.'); my @tableDesc = ( new EBox::Types::HostIP( fieldName => 'nameserver', printableName => __('Domain Name Server'), editable => 1, unique => 1, help => $helpHostIP ), ); my $dataTable = { tableName => 'DNSResolver', printableTableName => __('Domain Name Server Resolver List'), modelDomain => 'Network', defaultActions => [ 'add', 'del', 'move', 'editField', 'changeView' ], tableDescription => \@tableDesc, class => 'dataTable', help => _help(), printableRowName => __('name server'), order => 1, insertPosition => 'back', }; return $dataTable; } sub _help { return (__('

Here you can add the name server resolvers that Zentyal will ' . 'use.

' . '

Note that these settings may be overriden if you have any ' . 'network interface configured via DHCP

')); } sub replace { my ($self, $pos, $newIP) = @_; my @ids = @{ $self->ids() }; print "IDS @ids"; if ($pos >= scalar @ids) { throw EBox::Exceptions::Internal("Inexistent DNS resolver position $pos"); } my $id = $ids[$pos]; my $row = $self->row($id); $row->elementByName('namserver')->setValue($newIP); $row->store(); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/MultiGwRulesDataTable.pm0000664000000000000000000002752012017102311022550 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::MultiGwRulesDataTable; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use Perl6::Junction qw( any ); use EBox::Types::Int; use EBox::Types::Text; use EBox::Types::Boolean; use EBox::Types::Select; use EBox::Types::IPAddr; use EBox::Types::Union; use EBox::Types::Union::Text; use strict; use warnings; use base 'EBox::Model::DataTable'; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); $self->{'pageSize'} = 10; return $self; } sub ifacesSub { my ($self) = @_; my $network = $self->parentModule(); my @options; push (@options, { 'value' => 'any', 'printableValue' => __('any') }); foreach my $iface (@{$network->InternalIfaces()}) { push (@options, { 'value' => $iface, 'printableValue' => $iface }); } return sub { return \@options }; } # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableHead = ( new EBox::Types::Select( 'fieldName' => 'iface', 'printableName' => __('Interface'), 'editable' => 1, 'populate' => $self->ifacesSub(), 'help' => __('Incoming interface to match packets. If you '. ' want to match a whole subnet you can ' . ' select the interface of that subnet') ), new EBox::Types::Union( 'fieldName' => 'source', 'printableName' => __('Source'), 'subtypes' => [ new EBox::Types::Union::Text( 'fieldName' => 'source_any', 'printableName' => __('Any')), new EBox::Types::IPAddr( 'fieldName' => 'source_ipaddr', 'printableName' => __('Source IP'), 'editable' => 1, 'optional' => 1), new EBox::Types::Select( 'fieldName' => 'source_object', 'printableName' => __('Source object'), 'foreignModel' => $self->modelGetter('objects', 'ObjectTable'), 'foreignField' => 'name', 'foreignNextPageField' => 'members', 'editable' => 1), new EBox::Types::Union::Text( 'fieldName' => 'source_ebox', 'printableName' => 'Zentyal') ], 'size' => '16', 'unique' => 1, 'editable' => 1, ), new EBox::Types::Union( 'fieldName' => 'destination', 'printableName' => __('Destination'), 'subtypes' => [ new EBox::Types::Union::Text( 'fieldName' => 'destination_any', 'printableName' => __('Any')), new EBox::Types::IPAddr( 'fieldName' => 'destination_ipaddr', 'printableName' => __('Destination IP'), 'editable' => 1, 'optional' => 1), new EBox::Types::Select( 'fieldName' => 'destination_object', 'printableName' => __('Destination object'), 'foreignModel' => $self->modelGetter('objects', 'ObjectTable'), 'foreignField' => 'name', 'foreignNextPageField' => 'members', 'editable' => 1) ], 'size' => '16', 'unique' => 1, 'editable' => 1 ), new EBox::Types::Select( 'fieldName' => 'service', 'printableName' => __('Service'), 'foreignModel' => $self->modelGetter('services', 'ServiceTable'), 'foreignField' => 'printableName', 'foreignNextPageField' => 'configuration', 'editable' => 1, ), new EBox::Types::Select( 'fieldName' => 'gateway', 'printableName' => 'Gateway', 'foreignModel' => $self->modelGetter('network', 'GatewayTable'), 'foreignField' => 'name', 'editable' => 1, 'help' => __('Gateway to route packets matching ' . 'this rule') ) ); my $dataTable = { 'tableName' => 'MultiGwRulesDataTable', 'printableTableName' => __('Multigateway rules'), 'defaultController' => '/Network/Controller/MultiGwRulesDataTable', 'defaultActions' => [ 'add', 'del', 'clone', 'move', 'editField', 'changeView' ], 'tableDescription' => \@tableHead, 'class' => 'dataTable', 'order' => 1, 'enableProperty' => 1, 'defaultEnabledValue' => 1, 'help' => __('You can decide what kind of traffic goes out by each gateway. This way, you can force a subnet, service, destination and so forth to use the router you choose. Please, bear in mind that rules will be applied in order, from top to bottom, you can reorder them once they are added. If you do not set a port or an IP address, then the rule will match all of them'), 'rowUnique' => 0, 'printableRowName' => __('rule'), }; return $dataTable; } sub iptablesRules { my $self = shift; my @rules; for my $id (@{$self->enabledRows()}) { my $row = $self->row($id); my @rule = $self->_buildIptablesRule($row); if (@rule) { push (@rules, @rule); } } return \@rules; } sub _ifacesForRule { my ($self, $iface) = @_; unless ($iface eq 'any') { return [$iface]; } my $network = $self->parentModule(); my @ifaces; foreach my $iface (@{$network->InternalIfaces()}) { push (@ifaces, $iface) } return \@ifaces; } sub _objectMembers { my ($self, $row, $elementName) = @_; my $oid = $row->elementByName($elementName)->subtype()->value(); my $objects = $self->global()->modInstance('objects'); return $objects->objectMembers($oid); } sub _buildIptablesRule { my ($self, $row) = @_; my $network = $self->parentModule(); my $services = $self->global()->modInstance('services'); my $marks = $network->marksForRouters(); my $iface = $row->valueByName('iface'); my $srcType = $row->elementByName('source')->selectedType(); my $dstType = $row->elementByName('destination')->selectedType(); my $serviceConf = $services->serviceConfiguration($row->elementByName('service')->value()); my $gw = $row->valueByName('gateway'); # Return if the gateway for this rule is disabled my $gwRow = $self->parentModule()->model('GatewayTable')->row($gw); return unless (defined $gwRow); return unless ($gwRow->valueByName('enabled')); my @ifaces = @{$self->_ifacesForRule($iface)}; # prepare srcs into @src array my @src; if ($srcType eq 'source_any') { @src = (''); } elsif ($srcType eq 'source_ipaddr') { my $ipaddr = $row->elementByName('source')->subtype(); my $ip; if ($ipaddr->ip()) { $ip = ' --source ' . $ipaddr->ip() . '/' . $ipaddr->mask(); } else { $ip = ''; } @src = ($ip); } elsif ($srcType eq 'source_ebox') { @src = (''); } else { my $members = $self->_objectMembers($row, 'source'); @src = @{$members->iptablesSrcParams()}; } # prepare dsts into @dst array my @dst; if ($dstType eq 'destination_any') { @dst = (''); } elsif ($dstType eq 'destination_ipaddr') { my $ipaddr = $row->elementByName('destination')->subtype(); my $ip; if ($ipaddr->ip()) { $ip = ' --destination ' . $ipaddr->ip() . '/' . $ipaddr->mask(); } else { $ip = ''; } @dst = ($ip); } else { my $members = $self->_objectMembers($row, 'destination'); @dst = @{$members->iptablesDstParams()}; } my @chains; unless ($srcType eq 'source_ebox') { push(@chains, 'PREROUTING'); } if ($srcType eq 'source_ebox' or ($srcType eq 'source_any' and $iface eq 'any')) { push(@chains, 'OUTPUT'); } #rules for all prefixes my @all_rules; foreach my $chain (@chains) { my $prefix = "-t mangle -A $chain"; # prepare rules determined by the service into @prerules array my @prerules; my $port; foreach my $ser (@{$serviceConf}) { $port = ""; my $protocol = $ser->{'protocol'}; my $srcPort = $ser->{'source'}; my $dstPort = $ser->{'destination'}; if ($protocol eq any ('tcp', 'udp', 'tcp/udp')) { if ($srcPort ne 'any') { $port .= " --source-port $srcPort "; } if ($dstPort ne 'any') { $port .= " --destination-port $dstPort "; } if ($protocol eq 'tcp/udp') { push (@prerules, $prefix . " -p udp " . $port); push (@prerules, $prefix . " -p tcp " . $port); } else { push (@prerules, $prefix . " -p $protocol " . $port); } } elsif ($protocol eq any ('gre', 'icmp', 'esp')) { push (@prerules, $prefix . " -p $protocol " . $port); } elsif ($protocol eq 'any') { push (@prerules, $prefix . "" . $port); } } # generate final iptables rules from @prerules into @rules array my @rules; # src ebox (already with different prefix) we don't loop arround ifaces if ($srcType eq 'source_ebox' or $chain eq 'OUTPUT') { for my $rule (@prerules) { for my $rsrc (@src) { for my $rdst (@dst) { my $wrule = $rule . "$rsrc $rdst"; my $mrule = "$wrule -m mark --mark 0/0xff " . "-j MARK " . "--set-mark $marks->{$gw}"; push (@rules, $mrule); } } } } else { for my $rule (@prerules) { for my $riface (@ifaces) { for my $rsrc (@src) { for my $rdst (@dst) { $riface = $network->realIface($riface); my $wrule = $rule . " -i $riface"; $wrule .= " $rsrc $rdst"; my $mrule = "$wrule -m mark --mark 0/0xff " . "-j MARK " . "--set-mark $marks->{$gw}"; push (@rules, $mrule); } } } } } push(@all_rules, @rules); } return @all_rules; } sub precondition { my $network = EBox::Global->modInstance('network'); my $nGateways = @{$network->gateways()}; return $nGateways >= 2; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/GatewayTable.pm0000664000000000000000000004120012017102311020743 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::GatewayTable; use EBox::Global; use EBox::Gettext; use EBox::Validate qw(:all); use EBox::Exceptions::External; use EBox::Types::Int; use EBox::Types::Boolean; use EBox::Types::Select; use EBox::Types::IPAddr; use EBox::Types::Union; use EBox::Types::Text; use EBox::Network::Types::Text::AutoReadOnly; use EBox::Network::View::GatewayTableCustomizer; use EBox::Sudo; use Net::ARP; use strict; use warnings; use base 'EBox::Model::DataTable'; use constant MAC_FETCH_TRIES => 3; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub weights { my @options; for my $weight (1..15) { push @options, { 'value' => $weight, 'printableValue' => $weight}; } return \@options; } # Method: syncRows # # Overrides # sub syncRows { my ($self, $currentRows) = @_; my $conf = $self->{'confmodule'}; my $network = EBox::Global->modInstance('network'); my %dynamicGws; my $state = $conf->get_state(); foreach my $iface (@{$network->dhcpIfaces()}) { my $gw = $state->{dhcp}->{$iface}->{gateway}; if ($gw) { $dynamicGws{$iface} = $gw; } } foreach my $iface (@{$network->pppIfaces()}) { my $addr = $state->{interfaces}->{$iface}->{ppp_addr}; my $ppp_iface = $state->{interfaces}->{$iface}->{ppp_iface}; if ($addr and $ppp_iface) { $dynamicGws{$iface} = "$ppp_iface/$addr"; } } my %currentIfaces = map { $self->row($_)->valueByName('interface') => $_ } @{$currentRows}; my $modified = 0; my @ifacesToAdd = grep { not exists $currentIfaces{$_} } keys %dynamicGws; my @ifacesToDel = grep { not exists $dynamicGws{$_} } keys %currentIfaces; my @ifacesToModify = grep { exists $dynamicGws{$_} } keys %currentIfaces; # If we are going to add new gateways and there is no previous default # set, we will set the first added one as default if (scalar (@ifacesToAdd) > 0) { my $needDefault = 1; foreach my $id (@{$currentRows}) { my $row = $self->row($id); if ($row->valueByName('default')) { $needDefault = 0; last; } } foreach my $iface (@ifacesToAdd) { my $method = $network->ifaceMethod($iface); $self->add(name => "$method-gw-$iface", interface => $iface, ip => $dynamicGws{$iface}, default => $needDefault, auto => 1); $needDefault = 0; $modified = 1; } } foreach my $iface (@ifacesToModify) { my $row = $self->row($currentIfaces{$iface}); next unless $row->valueByName('auto'); my $ip = $row->elementByName('ip'); my $newIP = $dynamicGws{$iface}; my $oldIP = $ip->value(); unless (defined ($oldIP) and ($newIP eq $oldIP)) { $ip->setValue($newIP); $row->storeElementByName('ip'); $modified = 1; } } foreach my $iface (@ifacesToDel) { my $id = $currentIfaces{$iface}; my $row = $self->row($id); next unless $row->valueByName('auto'); $self->removeRow($id, 1); $modified = 1; } return $modified; } sub _table { my @tableHead = ( new EBox::Types::Boolean( 'fieldName' => 'auto', 'printableName' => __('Auto'), 'defaultValue' => 0, 'hidden' => 1 ), new EBox::Network::Types::Text::AutoReadOnly( 'fieldName' => 'name', 'printableName' => __('Name'), 'size' => '12', 'unique' => 1, 'editable' => 1 ), new EBox::Network::Types::Text::AutoReadOnly( 'fieldName' => 'ip', 'printableName' => __('IP address'), 'size' => '16', 'unique' => 0, # Uniqueness is checked in validateRow 'editable' => 1 ), new EBox::Types::Text( 'fieldName' => 'interface', 'printableName' => __('Interface'), 'editable' => 0, 'hiddenOnSetter' => 1, 'optional' => 1, 'help' => __('Interface connected to this gateway') ), new EBox::Types::Select( 'fieldName' => 'weight', 'printableName' => __('Weight'), 'defaultValue' => 1, 'size' => '2', 'populate' => \&weights, 'editable' => 1, 'help' => __('This field is only useful if you have ' . 'more than one router and the balance ' . 'traffic feature is enabled.') ), new EBox::Types::Boolean( 'fieldName' => 'default', 'printableName' => __('Default'), 'size' => '1', 'editable' => 1, 'HTMLViewer' => '/ajax/viewer/booleanViewer.mas', ) ); my $dataTable = { 'tableName' => 'GatewayTable', 'printableTableName' => __('Gateways List'), 'automaticRemove' => 1, 'enableProperty' => 1, 'defaultEnabledValue' => 1, 'defaultController' => '/Network/Controller/GatewayTable', 'defaultActions' => [ 'add', 'del', 'move', 'editField', 'changeView' ], 'tableDescription' => \@tableHead, 'menuNamespace' => 'Network/View/GatewayTable', 'class' => 'dataTable', 'order' => 0, 'help' => __x('You can add as many gateways as you want. This is very useful if you want to split your Internet traffic through several links. Note that if you configure interfaces as DHCP or PPPoE their gateways are added here automatically.'), 'rowUnique' => 0, 'printableRowName' => __('gateway'), }; return $dataTable; } # Method: validateRow # # Implementation note: # this is validateRow and not typedValidateRow because we dont want to execute # this when failover watcher do a $row->store() call, this could be also done # using the 'force' parameter but I want not to risk to break something in the ecent # # Override method # sub validateRow { my ($self, $action, %params) = @_; my $currentRow = $self->row($params{'id'}); my $auto = 0; my $oldIP = ''; if ($currentRow) { $auto = $currentRow->valueByName('auto'); $oldIP = $currentRow->valueByName('ip'); } if (exists $params{name}) { $self->checkGWName($params{name}); } my $network = EBox::Global->modInstance('network'); # Do not check for valid IP in case of auto-added ifaces unless ($auto) { my $printableName = __('IP address'); my $ip = $params{'ip'}; unless ($ip) { throw EBox::Exceptions::MissingArgument($printableName); } checkIP($ip, $printableName); # Check uniqueness if ($oldIP ne $ip) { if ($self->find('ip' => $ip)) { throw EBox::Exceptions::DataExists('data' => $printableName, 'value' => $ip); } } my $iface = $network->gatewayReachable($params{ip}); if ($iface) { # Only check if gateway is reachable on static interfaces unless ($network->ifaceMethod($iface) eq 'static') { if ($action eq 'add') { throw EBox::Exceptions::External(__('You can not manually add a gateway for DHCP or PPPoE interfaces')); } else { throw EBox::Exceptions::External(__x("Gateway {gw} must be reachable by a static interface. " . "Currently it is reachable by {iface} which is not static", gw => $ip, iface => $iface)); } } } else { throw EBox::Exceptions::External(__x("Gateway {gw} not reachable", gw => $ip)); } if (($action eq 'add') and ($self->size() == 0)) { if (not $params{default}) { throw EBox::Exceptions::External(__('Since you have not gateways you should add the first one as default')) } } } my $currentIsDefault = 0; if ($currentRow) { $currentIsDefault = $currentRow->valueByName('default'); } if ($params{default}) { # remove existent default mark in other row if needed if (not $currentIsDefault) { my $defaultRow = $self->find('default' => 1); if ($defaultRow) { my $default = $defaultRow->elementByName('default'); $default->setValue(undef); $defaultRow->storeElementByName('default'); } } } elsif ($currentIsDefault) { throw EBox::Exceptions::External(__('You cannot remove the default attribute, if you want to change it assign it to another gaterway')); } } sub validateRowRemoval { my ($self, $row, $force) = @_; if ( $row->valueByName('auto') and not $force) { throw EBox::Exceptions::External(__('Automatically added gateways can not be manually deleted')); } } # Method: addedRowNotify # # Overrides: # # # sub addedRowNotify { my ($self, $row) = @_; $self->_autoDetectInterface($row); if ($row->valueByName('default')) { my $network = $self->parentModule(); $network->storeSelectedDefaultGateway($row->id()); } } # Method: updatedRowNotify # # Overrides: # # # sub updatedRowNotify { my ($self, $row, $oldRow, $force) = @_; $self->_autoDetectInterface($row); return if ($force); # failover event can force changes my $network = $self->parentModule(); my $id = $row->id(); if ($row->valueByName('default')) { $network->storeSelectedDefaultGateway($id); } else { if ($id eq $network->selectedDefaultGateway()) { $network->storeSelectedDefaultGateway(''); } } } # Method: deletedRowNotify # # Overrides: # # # sub deletedRowNotify { my ($self, $row, $force) = @_; if ($row->valueByName('default')) { my $network = $self->parentModule(); my $size = $self->size(); if ($size == 0) { # no preferred gateway sicne there are not gws! $network->storeSelectedDefaultGateway(''); } else { # choose another gw my $newDefaultRow = $self->find(enabled => 1); if (not $newDefaultRow) { # no enabled, gw choosing another my ($id) = @{ $self->ids() }; $newDefaultRow = $self->row($id); } $newDefaultRow->elementByName('default')->setValue(1); $newDefaultRow->store(); # this does not upgrade preferred default gw $network->storeSelectedDefaultGateway($newDefaultRow->id()); } } } # Method: viewCustomizer # # Overrides # sub viewCustomizer { my ($self) = @_; my $customizer = new EBox::Network::View::GatewayTableCustomizer(); $customizer->setModel($self); return $customizer; } # Returns default gateway sub defaultGateway() { my ($self) = @_; my $row = $self->find('default' => 1); if ($row) { return $row->valueByName('ip'); } else { return undef; } } sub marksForRouters { my ($self) = @_; my $ids = $self->ids(); my $marks; my $i = 1; for my $id (@{$ids}) { $marks->{$id} = $i; $i++; } return $marks; } # Returns only enabled gateways sub gateways { my ($self) = @_; $self->_gateways(0); } # Returns all gateways sub allGateways { my ($self) = @_; $self->_gateways(1); } sub _gateways { my ($self, $all) = @_; my @gateways; my $balanceModel = $self->parentModule()->model('BalanceGateways'); my %balanceEnabled = map { $balanceModel->row($_)->valueByName('name') => 1 } @{$balanceModel->enabledRows()}; foreach my $id (@{$all ? $self->ids() : $self->enabledRows()}) { my $gw = $self->row($id); my $name = $gw->valueByName('name'); push (@gateways, { id => $id, auto => $gw->valueByName('auto'), name => $name, ip => $gw->valueByName('ip'), weight => $gw->valueByName('weight'), default => $gw->valueByName('default'), interface => $gw->valueByName('interface'), enabled => $gw->valueByName('enabled'), balance => $balanceEnabled{$name}, }); } return \@gateways; } sub gatewaysWithMac { my ($self) = @_; my @gateways = @{$self->allGateways()}; foreach my $gw (@gateways) { # Skip mac detection for auto-added gateways (dhcp and pppoe) if ($gw->{'auto'}) { $gw->{'mac'} = undef; } else { $gw->{'mac'} = _getRouterMac($gw->{'ip'}); } } return \@gateways; } sub _getRouterMac { my ($ip) = @_; my $macif = ''; my $mac; for (0..MAC_FETCH_TRIES) { system("ping -c 1 -W 3 $ip > /dev/null 2> /dev/null"); $mac = Net::ARP::arp_lookup($macif, $ip); return $mac if ($mac ne '00:00:00:00:00:00'); } return $mac; } # XXX fudge bz ModelManager does not delete gateway removal in tables AND we # don't have a removeRowValidate method # TODO improve this if ModelManager gets rewritten with that remove-check # feature added sub removeRow { my ($self, $id, $force) = @_; unless (defined($id)) { throw EBox::Exceptions::MissingArgument( "Missing row identifier to remove") } if (not $force) { my $row = $self->row($id); $row or throw EBox::Exceptions::Internal("Invalid row id $id"); my $gw = $row->valueByName('name'); my $global = EBox::Global->getInstance($self->{confmodule}->{ro}); my @mods = @{$global->modInstancesOfType('EBox::NetworkObserver')}; foreach my $mod (@mods) { if ($mod->gatewayDelete($gw)) { throw EBox::Exceptions::DataInUse( __x(q|The gateway '{name}' is being used by {mod}|, name => $gw, mod => $mod->name() ) ); } } } $self->SUPER::removeRow($id, $force); } sub checkGWName { my ($self, $name) = @_; if (($name =~ m/^-/) or ($name =~ m/-$/)) { throw EBox::Exceptions::InvalidData( data => __('Gateway name'), value => $name, advice => __(q{Gateways names cannot begin or end with '-'}) ); } unless ($name =~ m/^[a-z0-9\-]+$/) { throw EBox::Exceptions::InvalidData( data => __('Gateway name'), value => $name, advice => __(q{Gateways names can only be composed of lowercase ASCII english letters, digits and '-'}), ); } } sub _autoDetectInterface { my ($self, $row) = @_; return if ($row->valueByName('auto')); my $network = $self->parentModule(); my $iface = $network->gatewayReachable($row->valueByName('ip')); if ($iface) { $row->elementByName('interface')->setValue($iface); $row->store(); } } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/BalanceGateways.pm0000664000000000000000000000475012017102311021435 0ustar # Copyright (C) 2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::BalanceGateways; use base 'EBox::Model::DataTable'; use strict; use warnings; use EBox; use EBox::Gettext; use EBox::Types::Text; # Method: syncRows # # Overrides # sub syncRows { my ($self, $currentRows) = @_; my $network = $self->parentModule(); my $gwModel = $network->model('GatewayTable'); my %newGateways = map { $gwModel->row($_)->valueByName('name') => $_ } @{$gwModel->ids()}; my %currentGateways = map { $self->row($_)->valueByName('name') => $_ } @{$currentRows}; my $modified = 0; my @gwsToAdd = grep { not exists $currentGateways{$_} } keys %newGateways; my @gwsToDel = grep { not exists $newGateways{$_} } keys %currentGateways; foreach my $gw (@gwsToAdd) { $self->add(name => $gw); $modified = 1; } foreach my $gw (@gwsToDel) { $self->removeRow($currentGateways{$gw}, 1); $modified = 1; } return $modified; } # Method: _table # # sub _table { my @tableHeader = ( new EBox::Types::Text( fieldName => 'name', printableName => __('Gateway'), editable => 0, ), ); my $dataTable = { tableName => 'BalanceGateways', printableTableName => __('Gateways for Traffic Balance'), modelDomain => 'Network', defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableHeader, enableProperty => 1, defaultEnabledValue => 1, class => 'dataTable', printableRowName => __('gateway'), help => __('Here you can choose which gateways are used to balance the traffic'), }; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/Proxy.pm0000664000000000000000000000766212017102311017531 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::Proxy; use base 'EBox::Model::DataForm'; use strict; use warnings; use EBox::Gettext; use EBox::Global; use EBox::Types::Text; use EBox::Types::Password; use EBox::Types::Host; use EBox::Types::Port; use EBox::View::Customizer; # Dependencies # Group: Public methods # Constructor: new # # Create the Proxy model # # Overrides: # # # # Returns: # # # sub new { my $class = shift; my $self = $class->SUPER::new(@_); bless ( $self, $class ); return $self; } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableHeader = ( new EBox::Types::Text( 'fieldName' => 'username', 'printableName' => __('Username'), 'size' => 18, 'editable' => 1, 'optional' => 1, 'allowUnsafeChars' => 1, ), new EBox::Types::Password( 'fieldName' => 'password', 'printableName' => __('Password'), 'size' => 18, 'editable' => 1, 'optional' => 1, ), new EBox::Types::Host( 'fieldName' => 'server', 'printableName' => __('Proxy server'), 'editable' => 1, 'optional' => 1, ), new EBox::Types::Port( 'fieldName' => 'port', 'printableName' => __('Proxy port'), 'editable' => 1, 'defaultValue' => 8080, ), ); my $dataTable = { tableName => 'Proxy', disableAutocomplete => 1, printableTableName => __('Proxy'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableHeader, class => 'dataForm', help => __('This settings will be used to allow ' . 'Zentyal to access the Internet if an HTTP proxy ' . 'is needed.'), modelDomain => 'Network', }; return $dataTable; } # Method: viewCustomizer # # Overrides: # # # sub viewCustomizer { my ($self) = @_; my $customizer = new EBox::View::Customizer(); $customizer->setModel($self); if ($self->usernameValue() and $self->passwordValue()) { my $msg = __('Proxy username and password will be visible by all system users.'); $customizer->setPermanentMessage($msg); } return $customizer; } sub validateTypedRow { my ($self, $action, $newValues_r) = @_; if (exists $newValues_r->{username}) { my $username = $newValues_r->{username}->value(); if (not $username =~ m{^[\\\w /.?&+:\-\@]*$}) { throw EBox::Exceptions::External(__('The username input contains invalid ' . 'characters. All alphanumeric characters, plus these non ' . 'alphanumeric chars: \/.?&+:-@ and spaces are allowed.')); } } } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/DynDNS.pm0000664000000000000000000002016612017102311017501 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::DynDNS; use base 'EBox::Model::DataForm'; use strict; use warnings; use EBox::Exceptions::MissingArgument; use EBox::Gettext; use EBox::Global; use EBox::Types::DomainName; use EBox::Types::Password; use EBox::Types::Select; use EBox::Types::Text; use constant STORE_URL => 'http://store.zentyal.com/'; use constant BASIC_URL => STORE_URL . 'serversubscriptions/subscription-basic.html?utm_source=zentyal&utm_medium=network&utm_campaign=dynamicdns'; use constant SB_URL => STORE_URL . 'small-business-edition.html/?utm_source=zentyal&utm_medium=dyndns&utm_campaign=smallbusiness_edition'; use constant ENT_URL => STORE_URL . 'enterprise-edition.html/?utm_source=zentyal&utm_medium=dyndns&utm_campaign=enterprise_edition'; our %SERVICES = ( dyndns => { printableValue => 'DynDNS', protocol => 'dyndns2', server => 'members.dyndns.org', use => 'web', web => 'checkip.dyndns.com', web_skip => 'Current IP Address:', require_info => 1, }, zoneedit => { printableValue => 'ZoneEdit', protocol => 'zoneedit1', server => 'dynamic.zoneedit.com', use => 'web', web => 'dynamic.zoneedit.com/checkip.html', web_skip => 'Current IP Address:', require_info => 1, }, easydns => { printableValue => 'EasyDNS', protocol => 'easydns', server => 'members.easydns.com', use => 'web', web => 'checkip.dyndns.com', web_skip => 'Current IP Address:', require_info => 1, }, # disabled until ddclient bug #30 is fixed # http://sourceforge.net/apps/trac/ddclient/ticket/30 # dnspark => { # printableValue => 'dnspark.com', # protocol => 'dnspark', # server => 'www.dnspark.com', # use => 'web', # web => 'ipdetect.dnspark.com', # web_skip => 'Current Address:', # require_info => 1, # }, joker => { printableValue => 'Joker.com', protocol => 'dyndns2', server => 'svc.joker.com', use => 'web', web => 'svc.joker.com/nic/checkip', web_skip => 'Current IP Address:', require_info => 1, }, cloud => { printableValue => __('Zentyal Cloud'), protocol => 'dyndns2', use => 'web', web => 'svc.joker.com/nic/checkip', web_skip => 'Current IP Address:', require_info => 0, }, ); # Dependencies # Group: Public methods # Constructor: new # # Create the DynDNS model # # Overrides: # # # # Returns: # # # sub new { my $class = shift; my $self = $class->SUPER::new(@_); bless ( $self, $class ); return $self; } # Method: viewCustomizer # # Overrides to disable the remainder fields if service selected is # Zentyal Cloud # # Overrides: # # # sub viewCustomizer { my ($self) = @_; my $customizer = new EBox::View::Customizer(); $customizer->setModel($self); my $remainderFields = [ qw(username password hostname) ]; my $serviceAction = {}; foreach my $serviceKey (keys %SERVICES) { if ( $SERVICES{$serviceKey}->{require_info} ) { $serviceAction->{$serviceKey} = { enable => $remainderFields }; } else { $serviceAction->{$serviceKey} = { disable => $remainderFields }; } } $customizer->setOnChangeActions( { service => $serviceAction } ); unless ( $self->_isSubscribed() ) { $customizer->setPermanentMessage(_message(), 'ad'); } return $customizer; } # Method: validateTypedRow # # Check the used service requires info from form # # Overrides: # # # sub validateTypedRow { my ($self, $action, $changedFields, $allFields) = @_; if ( $allFields->{enableDDNS}->value() and $SERVICES{$allFields->{service}->value()}->{require_info} ) { # Check the username, password and domain name are set foreach my $field (qw(username password hostname)) { unless ( $allFields->{$field}->value() ) { throw EBox::Exceptions::MissingArgument( $allFields->{$field}->printableName() ); } } } } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableHeader = ( new EBox::Types::Boolean( 'fieldName' => 'enableDDNS', 'printableName' => __('Enable Dynamic DNS'), 'editable' => 1, ), new EBox::Types::Select( 'fieldName' => 'service', 'printableName' => __('Service'), 'populate' => \&services, 'editable' => 1, ), new EBox::Types::Text( 'fieldName' => 'username', 'printableName' => __('Username'), 'editable' => 1, 'optional' => 1, ), new EBox::Types::Password( 'fieldName' => 'password', 'printableName' => __('Password'), 'editable' => 1, 'optional' => 1, ), new EBox::Types::DomainName( 'fieldName' => 'hostname', 'printableName' => __('Hostname'), 'editable' => 1, 'optional' => 1, ), ); my $dataTable = { tableName => 'DynDNS', disableAutocomplete => 1, pageTitle => ('Dynamic DNS'), printableTableName => __('Configuration'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableHeader, class => 'dataForm', help => __('You should select your provider from the list ' . 'and enter your account data. ' . 'You also need to enable it in order to work.'), modelDomain => 'Network', }; return $dataTable; } # Group: Callback functions # Service populate function sub services { my @providers; foreach my $serviceKey (keys %SERVICES) { push @providers, { value => $serviceKey, printableValue => $SERVICES{$serviceKey}->{printableValue} }; if ( $serviceKey eq 'cloud' ) { $providers[-1]->{disabled} = not _isSubscribed(); } } return \@providers; } # Group: Private methods sub _isSubscribed { my $gl = EBox::Global->getInstance(1); if ( $gl->modExists('remoteservices') ) { my $rs = $gl->modInstance('remoteservices'); if ( $rs->eBoxSubscribed() ) { return 1; } } return 0; } sub _message { return __sx('You can configure your Dynamic DNS provider here. If yor server is already subscribed to Zentyal Cloud, your provider is Zentyal Cloud. Get the Free {ohb}Basic Subscription{ch}, or {ohs}Small Business{ch} or {ohe}Enterprise{ch} to obtain zentyal.me subdomain for your server.', ohb => '', ohs => '', ohe => '', ch => ''); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/MultiGwRulesOptions.pm0000664000000000000000000000475312017102311022365 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Network::Model::MultiGwRulesOptions; use base 'EBox::Model::DataForm'; use EBox::Gettext; use EBox::Types::Boolean; sub new { my $class = shift; my %parms = @_; my $self = $class->SUPER::new(@_); bless($self, $class); return $self; } sub _table { my @tableHead = ( new EBox::Types::Boolean( fieldName => 'balanceTraffic', printableName => __('Enable'), editable => 1, defaultValue => 0, ) ); my $dataTable = { 'tableName' => 'MultiGwRulesOptions', 'printableTableName' => __('Traffic balancing'), 'defaultController' => '/Network/Controller/MultiGwRulesOptions', 'defaultActions' => [ 'editField', 'changeView' ], 'tableDescription' => \@tableHead, 'class' => 'dataForm', 'order' => 1, 'enableProperty' => 0, 'defaultEnabledValue' => 1, help => __x('By enabling this feature, your traffic will be balanced amongst your gateways. That is, every new connection will be sent by a different gateway. You can choose which proportion of traffic goes through each gateway using the weight parameter of the gateway. You can change that value {openref}here{closeref}.{br}If you want to explicitily route traffic by a certain gateway, use the multigateway rules below', openref => '', closeref => '', br => '
'), 'rowUnique' => 0, 'printableRowName' => __('rule'), }; return $dataTable; } sub precondition { my $network = EBox::Global->modInstance('network'); my $nGateways = @{$network->gateways()}; return $nGateways >= 2; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/SearchDomain.pm0000664000000000000000000000440012017102311020730 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::SearchDomain; use base 'EBox::Model::DataForm'; use strict; use warnings; use EBox::Gettext; use EBox::Global; use EBox::Types::DomainName; # Dependencies # Group: Public methods # Constructor: new # # Create the DynDNS model # # Overrides: # # # # Returns: # # # sub new { my $class = shift; my $self = $class->SUPER::new(@_); bless ( $self, $class ); return $self; } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableHeader = ( new EBox::Types::DomainName( 'fieldName' => 'domain', 'printableName' => __('Domain'), 'editable' => 1, 'optional' => 1, ), ); my $dataTable = { tableName => 'SearchDomain', printableTableName => __('Search Domain'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableHeader, class => 'dataForm', help => __('This domain will be appended when trying ' . 'to resolve hosts if the first attempt ' . 'without appending it has failed.'), modelDomain => 'Network', }; return $dataTable; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Model/WANFailoverOptions.pm0000664000000000000000000000463312017102311022074 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network::Model::WANFailoverOptions; use base 'EBox::Model::DataForm'; use strict; use warnings; use EBox::Gettext; use EBox::Global; use EBox::Types::Int; # Dependencies # Group: Public methods # Constructor: new # # Create the DynDNS model # # Overrides: # # # # Returns: # # # sub new { my $class = shift; my $self = $class->SUPER::new(@_); bless ( $self, $class ); return $self; } # Group: Protected methods # Method: _table # # Overrides: # # # sub _table { my ($self) = @_; my @tableHeader = ( new EBox::Types::Int( 'fieldName' => 'period', 'printableName' => __('Time between checks'), 'trailingText' => __('seconds'), 'defaultValue' => 30, 'size' => 3, 'min' => 10, 'editable' => 1, ), ); my $dataTable = { tableName => 'WANFailoverOptions', printableTableName => __('Global options'), defaultActions => [ 'editField', 'changeView' ], tableDescription => \@tableHeader, class => 'dataForm', help => __('These options affect to all the tests.'), modelDomain => 'Network', }; return $dataTable; } # Method: formSubmitted # # Overrides # sub formSubmitted { # Notify period change to events module EBox::Global->getInstance()->modChange('events'); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Network/0000775000000000000000000000000012017102311016430 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Network/Composite/0000775000000000000000000000000012017102311020372 5ustar zentyal-network-2.3.13+quantal1/src/EBox/Network/Composite/MultiGw.pm0000664000000000000000000000336412017102311022326 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Network::Composite::MultiGw; use base 'EBox::Model::Composite'; use EBox::Gettext; use EBox::Global; # Group: Public methods # Constructor: new # # Constructor for the general byte rate composite # sub new { my ($class, @params) = @_; my $self = $class->SUPER::new(@params); return $self; } # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $description = { layout => 'top-bottom', printableName => __('Balance Traffic'), headTitle => undef, compositeDomain => 'Network', name => 'MultiGw', }; return $description; } sub precondition { my $network = EBox::Global->modInstance('network'); my $nGateways = @{$network->gateways()}; return $nGateways >= 2; } sub preconditionFailMsg { return __('To be able to use this feature you need at least two enabled gateways. You can add them here first.'); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Network/Composite/DNS.pm0000664000000000000000000000260012017102311021352 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Network::Composite::DNS; use base 'EBox::Model::Composite'; use EBox::Gettext; use EBox::Global; # Group: Public methods # Constructor: new # # Constructor for the DNS composite # # Returns: sub new { my ($class, @params) = @_; my $self = $class->SUPER::new(@params); return $self; } # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $description = { layout => 'top-bottom', pageTitle => __('Domain Name Server Resolver'), compositeDomain => 'Network', name => 'DNS', }; return $description; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Network/Composite/Gateway.pm0000664000000000000000000000263412017102311022336 0ustar # Copyright (C) 2010-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Network::Composite::Gateway; use base 'EBox::Model::Composite'; use EBox::Gettext; use EBox::Global; # Group: Public methods # Constructor: new # # Constructor for the Gateway composite. # sub new { my ($class, @params) = @_; my $self = $class->SUPER::new(@params); return $self; } # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $description = { layout => 'top-bottom', printableName => __('Gateways and Proxy'), headTitle => undef, compositeDomain => 'Network', name => 'Gateway', }; return $description; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Network/Composite/WANFailover.pm0000664000000000000000000000421412017102311023046 0ustar # Copyright (C) 2009-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Network::Composite::WANFailover; use base 'EBox::Model::Composite'; use EBox::Gettext; use EBox::Global; # Group: Public methods # Constructor: new # # Constructor for the DNS composite # # Returns: sub new { my ($class, @params) = @_; my $self = $class->SUPER::new(@params); return $self; } # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $description = { layout => 'top-bottom', printableName => __('WAN Failover'), headTitle => undef, compositeDomain => 'Network', name => 'WANFailover', }; return $description; } sub precondition { return (_isEventsEnabled() and _isWatcherEnabled()); } sub preconditionFailMsg { unless (_isEventsEnabled()) { return __('Events module is not enabled. You have to enable it and also enable the WAN Failover event in order to use this feature.'); } unless (_isWatcherEnabled()) { return __('WAN Failover event is not enabled. You have to enable it in order to use this feature'); } } sub _isEventsEnabled { my $events = EBox::Global->getInstance()->modInstance('events'); return $events->isEnabled(); } sub _isWatcherEnabled { my $events = EBox::Global->getInstance()->modInstance('events'); return $events->isEnabledWatcher('EBox::Event::Watcher::Gateways'); } 1; zentyal-network-2.3.13+quantal1/src/EBox/Network/Composite/GatewaysGeneral.pm0000664000000000000000000000347712017102311024025 0ustar # Copyright (C) 2011-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use warnings; package EBox::Network::Composite::GatewaysGeneral; use base 'EBox::Model::Composite'; use EBox::Gettext; use EBox::Global; # Group: Public methods # Constructor: new # # Constructor for the Gateway composite. # sub new { my ($class, @params) = @_; my $self = $class->SUPER::new(@params); return $self; } # Group: Protected methods # Method: _description # # Overrides: # # # sub _description { my $description = { components => [ 'Gateway', 'MultiGw', 'WANFailover', ], layout => 'tabbed', name => 'GatewaysGeneral', pageTitle => __('Gateways Configuration'), headTitle => undef, compositeDomain => 'Network', help => __('Here you can configure all the settings ' . 'related to the way Zentyal provides ' . 'Internet connection for your network'), }; return $description; } 1; zentyal-network-2.3.13+quantal1/src/EBox/Network.pm0000664000000000000000000034023112017102311016771 0ustar # Copyright (C) 2008-2012 eBox Technologies S.L. # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package EBox::Network; use strict; use warnings; use base qw(EBox::Module::Service EBox::Events::WatcherProvider); # Interfaces list which will be ignored use constant ALLIFACES => qw(sit tun tap lo irda eth wlan vlan); use constant IGNOREIFACES => qw(sit tun tap lo irda ppp virbr vboxnet vnet); use constant IFNAMSIZ => 16; #Max length name for interfaces use constant INTERFACES_FILE => '/etc/network/interfaces'; use constant DDCLIENT_FILE => '/etc/ddclient.conf'; use constant DEFAULT_DDCLIENT_FILE => '/etc/default/ddclient'; use constant RESOLV_FILE => '/etc/resolv.conf'; use constant DHCLIENTCONF_FILE => '/etc/dhcp/dhclient.conf'; use constant PPP_PROVIDER_FILE => '/etc/ppp/peers/zentyal-ppp-'; use constant CHAP_SECRETS_FILE => '/etc/ppp/chap-secrets'; use constant PAP_SECRETS_FILE => '/etc/ppp/pap-secrets'; use constant IFUP_LOCK_FILE => '/var/lib/zentyal/tmp/ifup.lock'; use constant APT_PROXY_FILE => '/etc/apt/apt.conf.d/99proxy.conf'; use constant ENV_PROXY_FILE => '/etc/profile.d/zentyal-proxy.sh'; use Net::IP; use IO::Interface::Simple; use Perl6::Junction qw(any); use EBox::NetWrappers qw(:all); use EBox::Validate qw(:all); use EBox::Config; use EBox::ServiceManager; use EBox::Exceptions::InvalidData; use EBox::Exceptions::DataExists; use EBox::Exceptions::DataInUse; use EBox::Exceptions::Internal; use EBox::Exceptions::External; use EBox::Exceptions::MissingArgument; use EBox::Exceptions::Lock; use Error qw(:try); use EBox::Dashboard::Widget; use EBox::Dashboard::Section; use EBox::Dashboard::CounterGraph; use EBox::Dashboard::GraphRow; use EBox::Dashboard::Value; use EBox::Menu::Item; use EBox::Menu::Folder; use EBox::Network::Model::DynDNS; use EBox::Sudo; use EBox::Gettext; use EBox::Common::Model::EnableForm; use EBox::Util::Lock; use EBox::DBEngineFactory; use File::Basename; use File::Slurp; use constant FAILOVER_CHAIN => 'FAILOVER-TEST'; use constant CHECKIP_CHAIN => 'CHECKIP-TEST'; sub _create { my $class = shift; my $self = $class->SUPER::_create(name => 'network', printableName => __n('Network'), @_); $self->{'actions'} = {}; bless($self, $class); return $self; } # Method: actions # # Override EBox::Module::Service::actions # sub actions { return [ { 'action' => __('Add default routers to the default table'), 'reason' => __('This is needed to work with a multigateway ' . 'configuration. Note that to list the default routes you ' . 'must execute: ') . ' ip route ls table default ', 'module' => 'network' }, { 'action' => __('Enable Zentyal DHCP hook'), 'reason' => __('It will take care of adding the default route' . ' given by a DHCP server to the default route table. '), 'module' => 'network' } ]; } # Method: usedFiles # # Override EBox::Module::Service::usedFiles # sub usedFiles { my ($self) = @_; my @files = ( { 'file' => INTERFACES_FILE, 'reason' => __('Zentyal will set your network configuration'), 'module' => 'network' }, { 'file' => RESOLV_FILE, 'reason' => __('Zentyal will set your DNS configuration'), 'module' => 'network' }, { 'file' => DHCLIENTCONF_FILE, 'reason' => __('Zentyal will set your DHCP client configuration'), 'module' => 'network' }, { 'file' => DEFAULT_DDCLIENT_FILE, 'reason' => __('Zentyal will set your ddclient configuration'), 'module' => 'network' }, { 'file' => DDCLIENT_FILE, 'reason' => __('Zentyal will set your ddclient configuration'), 'module' => 'network' }, { 'file' => CHAP_SECRETS_FILE, 'reason' => __('Zentyal will store your PPPoE passwords'), 'module' => 'network' }, { 'file' => PAP_SECRETS_FILE, 'reason' => __('Zentyal will store your PPPoE passwords'), 'module' => 'network' }, ); foreach my $iface (@{$self->pppIfaces()}) { push (@files, { 'file' => PPP_PROVIDER_FILE . $iface, 'reason' => __('Zentyal will add a DSL provider configuration for PPPoE'), 'module' => 'network' }); } my $proxy = $self->model('Proxy'); if ($proxy->serverValue() and $proxy->portValue()) { push (@files, { 'file' => ENV_PROXY_FILE, 'reason' => __('Zentyal will set HTTP proxy for all users'), 'module' => 'network' }); push (@files, { 'file' => APT_PROXY_FILE, 'reason' => __('Zentyal will set HTTP proxy for APT'), 'module' => 'network' }); } return \@files; } # Method: initialSetup # # Overrides: # EBox::Module::Base::initialSetup # sub initialSetup { my ($self, $version) = @_; # Import network configuration from system # only if installing the first time unless ($version) { try { $self->importInterfacesFile(); } otherwise { EBox::warn('Network configuration import failed'); }; } # TODO: Migration to remove zentyal-network cron tab and obsolete tables } # Method: wizardPages # # Override EBox::Module::Base::wizardPages # sub wizardPages { my ($self) = @_; return [ { page => '/Network/Wizard/Ifaces', order => 100 }, { page => '/Network/Wizard/Network', order => 101 }, ]; } # Method: eventWatchers # # Overrides: # # # sub eventWatchers { return [ 'Gateways' ]; } # Method: IPAddressExists # # Returns true if the given IP address belongs to a statically configured # network interface # # Parameters: # # ip - ip adddress to check # # Returns: # # EBox::Module instance # sub IPAddressExists { my ($self, $ip) = @_; my @ifaces = @{$self->allIfaces()}; foreach my $iface (@ifaces) { unless ($self->ifaceMethod($iface) eq 'static') { next; } if ($self->ifaceAddress($iface) eq $ip) { return 1; } } return undef; } # Method: ExternalIfaces # # Returns a list of all external interfaces # # Returns: # # array ref - holding the external interfaces # sub ExternalIfaces { my $self = shift; my @ifaces = @{$self->ifaces}; my @array = (); foreach (@ifaces) { ($self->ifaceMethod($_) eq 'notset') and next; ($self->ifaceMethod($_) eq 'trunk') and next; if ($self->ifaceIsExternal($_)) { push(@array, $_); } } return \@array; } # Method: InternalIfaces # # Returns a list of all internal interfaces # # Returns: # # array ref - holding the internal interfaces # sub InternalIfaces { my $self = shift; my @ifaces = @{$self->ifaces}; my @array = (); foreach (@ifaces) { ($self->ifaceMethod($_) eq 'notset') and next; ($self->ifaceMethod($_) eq 'trunk') and next; unless ($self->ifaceIsExternal($_)) { push(@array, $_); } } return \@array; } # Method: internalIpAddresses # # Returs a list of internal IP addresses # # Returns: # # array ref - Holding the internal IP's # sub internalIpAddresses { my ($self) = @_; my $ips = []; my $internalInterfaces = $self->InternalIfaces(); foreach my $interface (@{$internalInterfaces}) { foreach my $interfaceInfo (@{$self->ifaceAddresses($interface)}) { next unless (defined $interfaceInfo); push @{$ips}, $interfaceInfo->{address}; } } return $ips; } # Method: ifaceExists # # Checks if a given interface exists # # Parameters: # # interface - the name of a network interface # # Returns: # # boolean - true, if the interface exists, otherwise false sub ifaceExists # (interface) { my ($self, $name) = @_; defined($name) or return undef; if ($self->vifaceExists($name)) { return 1; } if (iface_exists($name)) { return 1; } my $ifaces = $self->ifaces; if (grep(/^$name$/, @{$ifaces})) { return 1; } return undef; } # Method: ifaceIsExternal # # Checks if a given iface exists and is external # # Parameters: # # interface - the name of a network interface # # Returns: # # boolean - true, if the interface is external, otherwise false sub ifaceIsExternal # (interface) { my ($self, $iface) = @_; defined($iface) or return undef; if ($self->vifaceExists($iface)) { my @aux = $self->_viface2array($iface); $iface = $aux[0]; } if ($self->ifaceIsBridge($iface)) { # Bridges are external if any of their interfaces is external my $ifaces = $self->bridgeIfaces($iface); foreach my $bridged ( @{$ifaces} ) { return 1 if ($self->ifaceIsExternal($bridged)); } return 0; } return $self->get_hash('interfaces')->{$iface}->{external} ? 1 : 0; } # Method: ifaceIsBridge # # Checks if a given iface exists and is a bridge # # Parameters: # # interface - the name of a network interface # # Returns: # # boolean - true, if the interface is external, otherwise false sub ifaceIsBridge # (interface) { my ($self, $iface) = @_; defined($iface) or return undef; if ( $self->ifaceExists($iface) and $iface =~ /^br/ ) { return 1; } else { return 0; } } # Method: ifaceOnConfig # # Checks if a given iface is configured # # Parameters: # # interface - the name of a network interface # # Returns: # # boolean - true, if the interface is configured, otherwise false # sub ifaceOnConfig { my ($self, $name) = @_; defined($name) or return undef; if ($self->vifaceExists($name)) { return 1; } return defined($self->get_hash('interfaces')->{$name}->{method}); } sub _ignoreIface { my ($self, $name) = @_; my $ignore_ifaces = EBox::Config::configkey('ifaces_to_ignore'); my @ifaces_to_ignore; if (defined($ignore_ifaces)) { @ifaces_to_ignore = split(',', $ignore_ifaces); } else { @ifaces_to_ignore = IGNOREIFACES; } foreach my $ignore (@ifaces_to_ignore) { return 1 if ($name =~ /$ignore.?/); } return undef; } # given a list of network interfaces appends to it any existing vlan interface # not already in the list and removes from it any vlan interface which has been # deleted from the configuration. sub _vlanIfaceFilter # (\array) { my ($self, $ifaces) = @_; my @array = (); foreach my $if (@{$ifaces}) { unless ($if =~ /^vlan/) { push(@array, $if); } } my $vlans = $self->vlans(); foreach my $id (@{$vlans}) { push(@array, "vlan$id"); } return \@array; } # given a list of network interfaces appends to it any existing vlan interface # not already in the list sub _vlanIfaceFilterWithRemoved # (\array) { my ($self, $ifaces) = @_; my $vlans = $self->vlans(); foreach my $id (@{$vlans}) { unless (grep(/^vlan$id$/, @{$ifaces})) { push(@{$ifaces}, "vlan$id"); } } return $ifaces; } sub _cleanupVlanIfaces { my $self = shift; my @iflist = list_ifaces(); my @cmds; foreach my $iface (@iflist) { if ($iface =~ /^vlan/) { $iface =~ s/^vlan//; my $vlans = $self->get_hash('vlans'); unless (exists $vlans->{$iface}) { push (@cmds, "/sbin/vconfig rem vlan$iface"); } } } EBox::Sudo::root(@cmds); } # given a list of network interfaces appends to it any existing bridged interface # not already in the list and removes from it any bridged interface which has been # deleted from the configuration. sub _bridgedIfaceFilter # (\array) { my ($self, $ifaces) = @_; my @array = (); foreach my $if (@{$ifaces}) { unless ($if =~ /^br/) { push(@array, $if); } } my $bridges = $self->bridges(); foreach my $id (@{$bridges}) { push(@array, "br$id"); } return \@array; } # given a list of network interfaces appends to it any existing bridge interface # not already in the list sub _bridgedIfaceFilterWithRemoved # (\array) { my ($self, $ifaces) = @_; my $bridges = $self->bridges(); foreach my $id (@{$bridges}) { unless (grep(/^br$id$/, @{$ifaces})) { push(@{$ifaces}, "br$id"); } } return $ifaces; } sub _ifaces { my $self = shift; my @iflist = list_ifaces(); my @array = (); foreach my $iface (@iflist) { next if $self->_ignoreIface($iface); push(@array, $iface); } return \@array; } # Method: ifaces # # Returns the name of all real interfaces, including vlan interfaces # # Returns: # # array ref - holding the names sub ifaces { my $self = shift; my $ifaces = $self->_ifaces(); $ifaces = $self->_vlanIfaceFilter($ifaces); $ifaces = $self->_bridgedIfaceFilter($ifaces); return $ifaces; } # Method: ifacesWithRemoved # # Returns the name of all real interfaces, including # vlan interfaces (both existing ones and those that are going to be # removed when the configuration is saved) # Returns: # # array ref - holding the names sub ifacesWithRemoved { my $self = shift; my $ifaces = $self->_ifaces(); $ifaces = $self->_vlanIfaceFilterWithRemoved($ifaces); $ifaces = $self->_bridgedIfaceFilterWithRemoved($ifaces); return $ifaces; } # Method: ifaceAddresses # # Returns an array of hashes with "address" and "netmask" fields, the # array may be empty (i.e. for a dhcp interface that did not get an # address) # # Parameters: # # iface - the name of a interface # # Returns: # # an array ref - holding hashes with keys 'address' and 'netmask' # sub ifaceAddresses { my ($self, $iface) = @_; my @array = (); if ($self->vifaceExists($iface)) { return \@array; } if ($self->ifaceMethod($iface) eq 'static') { my $addr = $self->get_hash('interfaces')->{$iface}->{address}; my $mask = $self->get_hash('interfaces')->{$iface}->{netmask}; push(@array, {address => $addr, netmask => $mask}); my $virtual = $self->get_hash('interfaces')->{$iface}->{virtual}; foreach my $name (keys %{$virtual}) { my $viface = $virtual->{$name}; push(@array, { address => $viface->{address}, netmask => $viface->{netmask}, name => $name }); } } elsif ($self->ifaceMethod($iface) eq any('dhcp', 'ppp')) { my $addr = $self->DHCPAddress($iface); my $mask = $self->DHCPNetmask($iface); if ($addr) { push(@array, {address => $addr, netmask => $mask}); } } elsif ($self->ifaceMethod($iface) eq 'bridged') { my $bridge = $self->ifaceBridge($iface); if ($self->ifaceExists("br$bridge")) { return $self->ifaceAddresses("br$bridge"); } } return \@array; } # Method: vifacesConf # # Gathers virtual interfaces from a real interface with their conf # arguments # # Parameters: # # iface - the name of a interface # # Returns: # # an array ref - holding hashes with keys 'address' and 'netmask' # 'name' # sub vifacesConf { my ($self, $iface) = @_; defined($iface) or return; my $vifaces = $self->get_hash('interfaces')->{$iface}->{virtual}; my @array = (); foreach my $name (keys %{$vifaces}) { my $viface = $vifaces->{$name}; if (defined $viface->{'address'}) { $viface->{name} = $name; push (@array, $viface); } } return \@array; } # Method: vifaceNames # # Gathers all the virtual interface names from a real interface # # Parameters: # # iface - the name of a interface # # Returns: # # an array ref - holding the name of the virtual interfaces. Each name # is a composed name like this: realinterface:virtualinterface # (i.e: eth0:foo) # sub vifaceNames { my ($self, $iface) = @_; my @array; foreach (@{$self->vifacesConf($iface)}) { push @array, "$iface:" . $_->{'name'}; } return \@array; } sub _allIfaces { my ($self, $ifaces) = @_; my @array; my @vifaces; @array = @{$ifaces}; foreach (@array) { if ($self->ifaceMethod($_) eq 'static') { push @vifaces, @{$self->vifaceNames($_)}; } } push @array, @vifaces; @array = sort @array; return \@array; } # Method: allIfaces # # Returns all the names for all the interfaces, both real and virtual. # # Returns: # # an array ref - holding the name of the interfaces. # sub allIfaces { my $self = shift; return $self->_allIfaces($self->ifaces()); } # Method: dhcpIfaces # # Returns the names for all the DHCP interfaces. # # Returns: # # an array ref - holding the name of the interfaces. # sub dhcpIfaces { my ($self) = @_; my @dhcpifaces; foreach my $iface (@{$self->ifaces()}) { if ($self->ifaceMethod($iface) eq 'dhcp') { push (@dhcpifaces, $iface); } } return \@dhcpifaces; } # Method: pppIfaces # # Returns the names for all the PPPoE interfaces. # # Returns: # # an array ref - holding the name of the interfaces. # sub pppIfaces { my ($self) = @_; my @pppifaces; foreach my $iface (@{$self->ifaces()}) { if ($self->ifaceMethod($iface) eq 'ppp') { push (@pppifaces, $iface); } } return \@pppifaces; } # Method: allIfacesWithRemoved # # Return the names of all (real and virtual) interfaces. This # method is similar to the ifacesWithRemoved method, it includes in the # results vlan interfaces which are going to be removed when the # configuration is saved. # # Returns: # # an array ref - holding the name of the interfaces. sub allIfacesWithRemoved { my $self = shift; return $self->_allIfaces($self->ifacesWithRemoved()); } # arguments # - the name of the real network interface # - the name of the virtual interface # returns # - true if exists # - false if not # throws # - Internal # - If real interface is not configured as static # sub _vifaceExists { my ($self, $iface, $viface) = @_; unless ($self->ifaceMethod($iface) eq 'static') { throw EBox::Exceptions::Internal("Could not exist a virtual " . "interface in non-static interface"); } return exists $self->get_hash('interfaces')->{$iface}->{virtual}->{$viface}; } # split a virtual iface name in real interface and virtual interface # arguments # - the composed virtual iface name # returns # - an array with the split name sub _viface2array # (interface) { my ($self, $name) = @_; my @array = $name =~ /(.*):(.*)/; return @array; } # Method: vifaceExists # # Checks if a given virtual interface exists # # Parameters: # # interface - the name of virtual interface composed by # realinterface:virtualinterface # # Returns: # # boolean - true, if the interface exists, otherwise false sub vifaceExists # (interface) { my ($self, $name) = @_; my ($iface, $viface) = $self->_viface2array($name); if (not $iface) { return undef; } if (not $viface and ($viface ne '0')) { return undef; } return $self->_vifaceExists($iface, $viface); } # Method: setViface # # Configure a virtual interface with ip and netmask # arguments # # Parameters: # # iface - the name of a real network interface # viface - the name of the virtual interface # address - the IP address for the virtual interface # netmask - the netmask # # Exceptions: # # DataExists - If interface already exists # Internal - If the real interface is not configured as static # sub setViface { my ($self, $iface, $viface, $address, $netmask) = @_; unless ($self->ifaceMethod($iface) eq 'static') { throw EBox::Exceptions::Internal("Could not add virtual " . "interface in non-static interface"); } if ($self->_vifaceExists($iface, $viface)) { throw EBox::Exceptions::DataExists( 'data' => __('Virtual interface name'), 'value' => "$viface"); } checkIPNetmask($address, $netmask, __('IP address'), __('Netmask')); checkVifaceName($iface, $viface, __('Virtual interface name')); if ($self->IPAddressExists($address)) { throw EBox::Exceptions::DataExists( 'data' => __('IP address'), 'value' => $address); } my $global = EBox::Global->getInstance(); my @mods = @{$global->modInstancesOfType('EBox::NetworkObserver')}; foreach my $mod (@mods) { try { $mod->vifaceAdded($iface, $viface, $address, $netmask); } otherwise { my $ex = shift; throw $ex; }; } my $ifaces = $self->get_hash('interfaces'); $ifaces->{$iface}->{virtual}->{$viface}->{address} = $address; $ifaces->{$iface}->{virtual}->{$viface}->{netmask} = $netmask; $ifaces->{$iface}->{changed} = 1; $self->set('interfaces', $ifaces); } # Method: removeViface # # Removes a virtual interface # # Parameters: # # iface - the name of a real network interface # viface - the name of the virtual interface # force - force deletion if in use # # Returns: # # boolean - true if exists, otherwise false # # Exceptions: # # Internal - If the real interface is not configured as static # sub removeViface { my ($self, $iface, $viface, $force) = @_; unless ($self->ifaceMethod($iface) eq 'static') { throw EBox::Exceptions::Internal("Could not remove virtual " . "interface from a non-static interface"); } unless ($self->_vifaceExists($iface, $viface)) { return undef; } $self->_routersReachableIfChange("$iface:$viface"); my $global = EBox::Global->getInstance(); my @mods = @{$global->modInstancesOfType('EBox::NetworkObserver')}; foreach my $mod (@mods) { if ($mod->vifaceDelete($iface, $viface)) { if ($force) { $mod->freeViface($iface, $viface); } else { throw EBox::Exceptions::DataInUse(); } } } my $ifaces = $self->get_hash('interfaces'); delete $ifaces->{$iface}->{virtual}->{$viface}; $ifaces->{$iface}->{changed} = 1; $self->set('interfaces', $ifaces); return 1; } # Method: vifaceAddress # # Returns the configured address for a virutal interface # # Parameters: # # interface - the composed name of a virtual interface # # Returns: # # If interface exists it returns its IP, otherwise it returns undef # # string - IP if it exists sub vifaceAddress # (interface) { my ($self, $name) = @_; my $address; unless ($self->vifaceExists($name)) { throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); } my ($iface, $viface) = $self->_viface2array($name); foreach (@{$self->vifacesConf($iface)}) { if ($_->{'name'} eq $viface) { return $_->{'address'}; } } return undef; } # Method: vifaceNetmask # # Returns the configured netmask for a virutal interface # # Parameters: # # interface - the composed name of a virtual interface # # Returns: # # If interface exists it returns its netmask, otherwise it returns undef # # string - IP if it exists sub vifaceNetmask # (interface) { my ($self, $name) = @_; my $address; unless ($self->vifaceExists($name)) { throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); } my ($iface, $viface) = $self->_viface2array($name); foreach (@{$self->vifacesConf($iface)}) { if ($_->{'name'} eq $viface) { return $_->{'netmask'}; } } return undef; } # Method: setIfaceAlias # # Sets the alias for a given interface # # Parameters: # # iface - the name of a network interface # alias - the alias for the interface # sub setIfaceAlias { my ($self, $iface, $alias) = @_; my $ifaces = $self->get_hash('interfaces'); if ($iface eq $alias) { # alias == iface name, no problems $ifaces->{$iface}->{alias} = $alias; $self->set('interfaces', $ifaces); return; } # check that the alias is not repeated or is the same that any interface # name foreach my $if (@{ $self->allIfaces() }) { if ($alias eq $if) { throw EBox::Exceptions::External( __x('There is already an interface called {al}', al => $alias) ); } if ($iface eq $if) { next; } my $ifAlias = $self->ifaceAlias($if); if ($ifAlias and ($ifAlias eq $alias)) { throw EBox::Exceptions::External( __x('There is already a interface with the alias {al}', al => $alias) ); } } $ifaces->{$iface}->{alias} = $alias; $self->set('interfaces', $ifaces); } # Method: ifaceAlias # # Returns the alias for a given interface # # Parameters: # # iface - the name of a network interface # # Returns: # # string - alias for the interface # sub ifaceAlias # (iface) { my ($self, $iface) = @_; my $viface = undef; unless ($self->ifaceExists($iface)) { throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); } if($self->vifaceExists($iface)) { my @aux = $self->_viface2array($iface); $iface = $aux[0]; $viface = $aux[1]; } my $alias = $self->get_hash('interfaces')->{$iface}->{alias}; defined($alias) or $alias = $iface; defined($viface) and $alias = $alias . ":" . $viface; return $alias; } # Method: ifaceMethod # # Returns the configured method for a given interface # # Parameters: # # interface - the name of a network interface # # Returns: # # string - dhcp|static|notset|trunk|ppp|bridged # dhcp -> the interface is configured via dhcp # static -> the interface is configured with a static ip # ppp -> the interface is configured via PPP # notset -> the interface exists but has not been # configured yet # trunk -> vlan aware interface # bridged -> bridged to other interfaces # sub ifaceMethod { my ($self, $name) = @_; unless ($self->ifaceExists($name)) { throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); } if ($self->vifaceExists($name)) { return 'static'; } $self->ifaceOnConfig($name) or return 'notset'; return $self->get_hash('interfaces')->{$name}->{method}; } # Method: setIfaceDHCP # # Configure an interface via DHCP # # Parameters: # # interface - the name of a network interface # external - boolean to indicate if it's a external interface # force - boolean to indicate if an exception should be raised when # method is changed or it should be forced # sub setIfaceDHCP { my ($self, $name, $ext, $force) = @_; defined $ext or $ext = 0; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); my $oldm = $self->ifaceMethod($name); if ($oldm eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($name); } elsif ($oldm eq 'trunk') { $self->_trunkIfaceIsUsed($name); } elsif ($oldm eq 'static') { $self->_routersReachableIfChange($name); $self->_checkStatic($name, $force); } elsif ($oldm eq 'bridged') { $self->BridgedCleanUp($name); } my $global = EBox::Global->getInstance(); my @observers = @{$global->modInstancesOfType('EBox::NetworkObserver')}; if ($ext != $self->ifaceIsExternal($name) ) { # Tell observers the interface way has changed foreach my $obs (@observers) { if ($obs->ifaceExternalChanged($name, $ext)) { if ($force) { $obs->changeIfaceExternalProperty($name, $ext); } else { throw EBox::Exceptions::DataInUse(); } } } } if ($oldm ne 'dhcp') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'dhcp', action => 'prechange', force => $force, ); } else { my $oldm = $self->ifaceIsExternal($name); if ((defined($oldm) and defined($ext)) and ($oldm == $ext)) { return; } } my $ifaces = $self->get_hash('interfaces'); $ifaces->{$name}->{external} = $ext; delete $ifaces->{$name}->{address}; delete $ifaces->{$name}->{netmask}; $ifaces->{$name}->{method} = 'dhcp'; $ifaces->{$name}->{changed} = 1; $self->set('interfaces', $ifaces); if ($oldm ne 'dhcp') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'dhcp', action => 'postchange' ); } } # Method: setIfaceStatic # # Configure with a static ip address # # Parameters: # # interface - the name of a network interface # address - IPv4 address # netmask - network mask # external - boolean to indicate if it's an external interface # force - boolean to indicate if an exception should be raised when # method is changed or it should be forced # sub setIfaceStatic { my ($self, $name, $address, $netmask, $ext, $force) = @_; defined $ext or $ext = 0; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); checkIPNetmask($address, $netmask, __('IP address'), __('Netmask')); $self->_checkStaticIP($name, $address, $netmask); my $oldm = $self->ifaceMethod($name); my $oldaddr = $self->ifaceAddress($name); my $oldmask = $self->ifaceNetmask($name); my $oldext = $self->ifaceIsExternal($name); if (($oldm eq 'static') and ($oldaddr eq $address) and ($oldmask eq $netmask) and (! ($oldext xor $ext))) { return; } if ($oldm eq 'trunk') { $self->_trunkIfaceIsUsed($name); } if ((!defined($oldaddr) or ($oldaddr ne $address)) and $self->IPAddressExists($address)) { throw EBox::Exceptions::DataExists( 'data' => __('IP address'), 'value' => $address); } if ($oldm eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($name); } elsif ($oldm eq 'static') { $self->_routersReachableIfChange($name, $address, $netmask); } elsif ($oldm eq 'bridged') { $self->BridgedCleanUp($name); } # Calling observers my $global = EBox::Global->getInstance(); my @observers = @{$global->modInstancesOfType('EBox::NetworkObserver')}; if (defined $ext and $ext != $self->ifaceIsExternal($name) ) { # Tell observers the interface way has changed foreach my $obs (@observers) { if ($obs->ifaceExternalChanged($name, $ext)) { if ($force) { $obs->changeIfaceExternalProperty($name, $ext); } else { throw EBox::Exceptions::DataInUse(); } } } } if ($oldm ne 'static') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'static', action => 'prechange', force => $force ); } else { foreach my $obs (@observers) { if ($obs->staticIfaceAddressChanged($name, $oldaddr, $oldmask, $address, $netmask)) { if ($force) { $obs->freeIface($name); } else { throw EBox::Exceptions::DataInUse(); } } } } my $ifaces = $self->get_hash('interfaces'); $ifaces->{$name}->{external} = $ext; $ifaces->{$name}->{method} = 'static'; $ifaces->{$name}->{address} = $address; $ifaces->{$name}->{netmask} = $netmask; $ifaces->{$name}->{changed} = 1; $self->set('interfaces', $ifaces); if ($oldm ne 'static') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'static', action => 'postchange' ); } else { foreach my $obs (@observers) { $obs->staticIfaceAddressChangedDone($name, $oldaddr, $oldmask, $address, $netmask); } } } sub _checkStatic # (iface, force) { my ($self, $iface, $force) = @_; my $global = EBox::Global->getInstance(); my @mods = @{$global->modInstancesOfType('EBox::NetworkObserver')}; foreach my $vif (@{$self->vifaceNames($iface)}) { foreach my $mod (@mods) { my ($tmp, $viface) = $self->_viface2array($vif); if ($mod->vifaceDelete($iface, $viface)) { if ($force) { $mod->freeViface($iface, $viface); } else { throw EBox::Exceptions::DataInUse(); } } } } } # check that no IP are in the same network # limitation: we could only check against the current # value of dynamic addresses sub _checkStaticIP { my ($self, $iface, $address, $netmask) = @_; my $network = EBox::NetWrappers::ip_network($address, $netmask); foreach my $if (@{$self->allIfaces()} ) { if ($if eq $iface) { next; } foreach my $addr_r (@{ $self->ifaceAddresses($if)} ) { my $ifNetwork = EBox::NetWrappers::ip_network($addr_r->{address}, $addr_r->{netmask}); if ($ifNetwork eq $network) { throw EBox::Exceptions::External( __x('Cannot use the address {addr} because interface {if} has already an address in the same network', addr => $address, if => $if ) ); } } } } # Method: setIfacePPP # # Configure with PPP method # # Parameters: # # interface - the name of a network interface # ppp_user - PPP user name # ppp_pass - PPP password # external - boolean to indicate if it's an external interface # force - boolean to indicate if an exception should be raised when # method is changed or it should be forced # sub setIfacePPP { my ($self, $name, $ppp_user, $ppp_pass, $ext, $force) = @_; defined $ext or $ext = 0; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); my $oldm = $self->ifaceMethod($name); my $olduser = $self->ifacePPPUser($name); my $oldpass = $self->ifacePPPPass($name); my $oldext = $self->ifaceIsExternal($name); if (($oldm eq 'ppp') and ($olduser eq $ppp_user) and ($oldpass eq $ppp_pass) and (! ($oldext xor $ext))) { return; } if ($oldm eq 'trunk') { $self->_trunkIfaceIsUsed($name); } elsif ($oldm eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($name); } elsif ($oldm eq 'static') { $self->_routersReachableIfChange($name); } elsif ($oldm eq 'bridged') { $self->BridgedCleanUp($name); } # Calling observers my $global = EBox::Global->getInstance(); my @observers = @{$global->modInstancesOfType('EBox::NetworkObserver')}; if ($ext != $self->ifaceIsExternal($name) ) { # Tell observers the interface way has changed foreach my $obs (@observers) { if ($obs->ifaceExternalChanged($name, $ext)) { if ($force) { $obs->changeIfaceExternalProperty($name, $ext); } else { throw EBox::Exceptions::DataInUse(); } } } } if ($oldm ne 'ppp') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'ppp', action => 'prechange', force => $force, ); } my $ifaces = $self->get_hash('interfaces'); $ifaces->{$name}->{external} = $ext; $ifaces->{$name}->{method} = 'ppp'; $ifaces->{$name}->{ppp_user} = $ppp_user; $ifaces->{$name}->{ppp_pass} = $ppp_pass; $ifaces->{$name}->{changed} = 1; $self->set('interfaces', $ifaces); if ($oldm ne 'ppp') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'ppp', action => 'postchange' ); } } # Method: setIfaceTrunk # # configures an interface in trunk mode, making it possible to create vlan # interfaces on it. # # Parameters: # # interface - the name of a network interface # force - boolean to indicate if an exception should be raised when # method is changed or it should be forced # sub setIfaceTrunk # (iface, force) { my ($self, $name, $force) = @_; unless ($self->ifaceExists($name)) { throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); } if ($name =~ /^vlan/) { throw EBox::Exceptions::External(__('This interface cannot '. 'be put in trunk mode, it is an vlan interface.')); } my $oldm = $self->ifaceMethod($name); ($oldm eq 'trunk') and return; if ($oldm eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($name); } elsif ($oldm eq 'static') { $self->_routersReachableIfChange($name); $self->_checkStatic($name, $force); } elsif ($oldm eq 'bridged') { $self->BridgedCleanUp($name); } if ($oldm ne 'notset') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'notset', action => 'prechange', force => $force, ); } my $ifaces = $self->get_hash('interfaces'); delete $ifaces->{$name}->{address}; delete $ifaces->{$name}->{netmask}; $ifaces->{$name}->{method} = 'trunk'; $ifaces->{$name}->{changed} = 1; $self->set('interfaces', $ifaces); if ($oldm ne 'notset') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'notset', action => 'postchange' ); } } # returns true if the given interface is in trunk mode an has at least one vlan # interface added to it which is configured as dhcp or static. sub _trunkIfaceIsUsed # (iface) { my ($self, $iface) = @_; my $vlans = $self->ifaceVlans($iface); foreach my $vlan (@{$vlans}) { defined($vlan) or next; ($iface eq $vlan->{interface}) or next; my $meth = $self->ifaceMethod("vlan$vlan->{id}"); if ($meth ne 'notset') { throw EBox::Exceptions::External( __('This interface is in trunk mode, you '. 'should unconfigure all the vlan '. 'interfaces in this trunk before changing '. 'its configuration mode.')); } } return undef; } # Method: setIfaceBridged # # configures an interface in bridged mode attached to a new or # defined bridge # # Parameters: # # interface - the name of a network interface # external - boolean to indicate if it's a external interface # bridge - bridge id number or -1 to create new one # force - boolean to indicate if an exception should be raised when # method is changed or it should be forced # sub setIfaceBridged { my ($self, $name, $ext, $bridge, $force) = @_; defined $ext or $ext = 0; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); # check if bridge exists if ( $bridge >= 0 ) { $self->ifaceExists("br$bridge") or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => "br$bridge"); } my $oldm = $self->ifaceMethod($name); if ($oldm eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($name); } elsif ($oldm eq 'trunk') { $self->_trunkIfaceIsUsed($name); } elsif ($oldm eq 'static') { $self->_routersReachableIfChange($name); $self->_checkStatic($name, $force); } elsif ($oldm eq 'bridged' and $self->ifaceBridge($name) ne $bridge) { $self->BridgedCleanUp($name); } my $global = EBox::Global->getInstance(); my @observers = @{$global->modInstancesOfType('EBox::NetworkObserver')}; if ($ext != $self->ifaceIsExternal($name) ) { # Tell observers the interface way has changed foreach my $obs (@observers) { if ($obs->ifaceExternalChanged($name, $ext)) { if ($force) { $obs->changeIfaceExternalProperty($name, $ext); } else { throw EBox::Exceptions::DataInUse(); } } } } if ($oldm ne 'bridged') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'bridged', action => 'prechange', force => $force, ); } else { my $oldm = $self->ifaceIsExternal($name); my $oldbr = $self->ifaceBridge($name); if (defined($oldm) and defined($ext) and ($oldm == $ext) and defined($oldbr) and defined($bridge) and ($oldbr eq $bridge)) { return; } } # new bridge if ($bridge < 0) { my @bridges = @{$self->bridges()}; my $last = int(pop(@bridges)); $bridge = $last+1; $self->_createBridge($bridge); } my $ifaces = $self->get_hash('interfaces'); $ifaces->{$name}->{external} = $ext; delete $ifaces->{$name}->{address}; delete $ifaces->{$name}->{netmask}; $ifaces->{$name}->{method} = 'bridged'; $ifaces->{$name}->{changed} = 1; $ifaces->{$name}->{bridge_id} = $bridge; $self->set('interfaces', $ifaces); # mark bridge as changed $self->_setChanged("br$bridge"); if ($oldm ne 'bridged') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'bridged', action => 'postchange' ); } } # Method: createVlan # # creates an vlan on a trunk interface. # # Parameters: # # id - vlan identifier # name - name # interface - the name of a network interface # sub createVlan # (id, name, iface) { my ($self, $id, $name, $iface) = @_; checkVlanID($id, __('VLAN Id')); defined($name) or $name = ''; my $vlans = $self->get_hash('vlans'); if (exists $vlans->{$id}) { throw EBox::Exceptions::DataExists('data' => 'vlan', 'value' => "$id"); } if ($self->ifaceMethod($iface) ne 'trunk') { throw EBox::Exceptions::External(__('Network interfaces need '. 'to be in trunk mode before adding vlans to them.')); } $vlans->{$id}->{id} = $id; $vlans->{$id}->{name} = $name; $vlans->{$id}->{interface} = $iface; $self->set('vlans', $vlans); } # Method: removeVlan # # Removes a vlan # # Parameters: # # id - vlan identifier # sub removeVlan # (id) { my ($self, $id, $force) = @_; checkVlanID($id, __('VLAN Id')); my $vlans = $self->get_hash('vlans'); delete $vlans->{$id}; $self->set_hash('vlans', $vlans); } # Method: vlans # # Returns a reference to an array with all existing vlan ID's # # Returns: # # an array ref - holding the vlan ID's sub vlans { my ($self) = @_; my @ids = keys %{$self->get_hash('vlans')}; return \@ids; } # # Method: vlanExists # # Checks if a given vlan id exists # # Parameters: # # id - vlan identifier # # Returns: # # boolean - true if it exits, otherwise false sub vlanExists # (vlanID) { my ($self, $vlan) = @_; return exists $self->get_hash('vlans')->{$vlan}; } # Method: ifaceVlans # # Returns information about every vlan that exists on the given trunk # interface. # # Parameters: # # iface - interface name # # Returns: # # array ref - The elements of the array are hashesh. The hashes contain # these keys: 'id' (vlan ID), 'name' (user given description for the vlan) # and 'interface' (the name of the trunk interface) # sub ifaceVlans { my ($self, $name) = @_; my @array = (); my $vlans = $self->get_hash('vlans'); foreach my $id (keys %{$vlans}) { my $vlan = $vlans->{$id}; if ($vlan->{interface} eq $name) { $vlan->{id} = $id; push(@array, $vlan); } } return \@array; } sub vlan { my ($self, $vlan) = @_; defined($vlan) or return undef; if ($vlan =~ /^vlan/) { $vlan =~ s/^vlan//; } if ($vlan =~ /:/) { $vlan =~ s/:.*$//; } my $vlans = $self->get_hash('vlans'); unless (exists $vlans->{$vlan}) { return undef; } $vlans->{$vlan}->{id} = $vlan; return $vlans->{$vlan}; } # Method: createBridge # # creates a new bridge interface. # # Parameters: # # id - bridge identifier # sub _createBridge { my ($self, $id) = @_; my $bridge = "br$id"; my $interfaces = $self->get_hash('interfaces'); if (exists $interfaces->{$bridge}) { throw EBox::Exceptions::DataExists('data' => 'bridge', 'value' => $id); } $self->setIfaceAlias($bridge, $bridge); } # Method: removeBridge # # Removes a bridge # # Parameters: # # id - bridge identifier # sub _removeBridge # (id) { my ($self, $id, $force) = @_; $self->_removeIface("br$id"); } # Method: _removeEmptyBridges # # Removes bridges which has no bridged interfaces sub _removeEmptyBridges { my ($self) = @_; my %seen; for my $if ( @{$self->ifaces()} ) { if ( $self->ifaceMethod($if) eq 'bridged' ) { $seen{$self->ifaceBridge($if)}++; } } # remove unseen bridges for my $bridge ( @{$self->bridges()} ) { next if ( $seen{$bridge} ); $self->_removeBridge($bridge); } } # Method: bridges # # Returns a reference to a sorted array with existing bridges ID's # # Returns: # # an array ref - holding the bridges ID's sub bridges { my $self = shift; my @bridges; for my $iface (keys %{$self->get_hash('interfaces')}) { if ($iface =~ /^br/) { $iface =~ s/^br//; push(@bridges, $iface); } } @bridges = sort @bridges; return \@bridges; } # Method: bridgeIfaces # # Returns a reference to an array of ifaces bridged to # the given bridge ifname # # Parameters: # # bridge - Bridge ifname # # Returns: # # an array ref - holding the iface names sub bridgeIfaces { my ($self, $bridge) = @_; # get the bridge's id $bridge =~ s/^br//; my @ifaces = (); for my $iface (@{$self->ifaces}) { if ($self->ifaceMethod($iface) eq 'bridged') { if ($self->ifaceBridge($iface) eq $bridge) { push(@ifaces, $iface); } } } return \@ifaces; } # Method: unsetIface # # Unset an interface # # Parameters: # # interface - the name of a network interface # force - boolean to indicate if an exception should be raised when # interace is changed or it should be forced sub unsetIface # (interface, force) { my ($self, $name, $force) = @_; unless ($self->ifaceExists($name)) { throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); } unless ($self->ifaceOnConfig($name)) { return; } my $oldm = $self->ifaceMethod($name); if ($oldm eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($name); } elsif ($oldm eq 'trunk') { $self->_trunkIfaceIsUsed($name); } elsif ($oldm eq 'static') { $self->_routersReachableIfChange($name); $self->_checkStatic($name, $force); } elsif ($oldm eq 'bridged') { $self->BridgedCleanUp($name); } if ($oldm ne 'notset') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'notset', action => 'prechange', force => $force, ); } my $ifaces = $self->get_hash('interfaces'); delete $ifaces->{$name}->{address}; delete $ifaces->{$name}->{netmask}; $ifaces->{$name}->{method} = 'notset'; $ifaces->{$name}->{changed} = 1; $self->set('interfaces', $ifaces); if ($oldm ne 'notset') { $self->_notifyChangedIface( name => $name, oldMethod => $oldm, newMethod => 'notset', action => 'postchange', force => $force, ); } } # Method: ifaceAddress # # Returns the configured address for a real interface # # Parameters: # # name - interface name # # Returns: # # - For static interfaces: the configured IP Address of the interface. # - For dhcp and ppp interfaces: # - the current address if the interface is up # - undef if the interface is down # - For bridged interfaces: its bridge ifaces address (static or dhcp) # - For not-yet-configured interfaces # - undef sub ifaceAddress # (name) { my ($self, $name) = @_; my $address; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); if ($self->vifaceExists($name)) { return $self->vifaceAddress($name); } if ($self->ifaceMethod($name) eq 'static') { return $self->get_hash('interfaces')->{$name}->{address}; } elsif ($self->ifaceMethod($name) eq any('dhcp', 'ppp')) { return $self->DHCPAddress($name); } elsif ($self->ifaceMethod($name) eq 'bridged') { my $bridge = $self->ifaceBridge($name); if ($self->ifaceExists("br$bridge")) { return $self->ifaceAddress("br$bridge"); } } return undef; } # Method: ifacePPPUser # # Returns the configured username for a PPP interface # # Parameters: # # name - interface name # # Returns: # # - For ppp interfaces: the configured user of the interface. # - For the rest: undef # sub ifacePPPUser # (name) { my ($self, $name) = @_; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); if ($self->ifaceMethod($name) eq 'ppp') { return $self->get_hash('interfaces')->{$name}->{ppp_user}; } else { return undef; } } # Method: ifacePPPPass # # Returns the configured password for a PPP interface # # Parameters: # # name - interface name # # Returns: # # - For ppp interfaces: the configured password of the interface. # - For the rest: undef # sub ifacePPPPass # (name) { my ($self, $name) = @_; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); if ($self->ifaceMethod($name) eq 'ppp') { return $self->get_hash('interfaces')->{$name}->{ppp_pass}; } else { return undef; } } # Method: ifaceBridge # # Returns the bridge id for an interface # # Parameters: # # name - interface name # # Returns: # # - For bridged interfaces: the bridge id # - For the rest: undef # sub ifaceBridge # (name) { my ($self, $name) = @_; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); if ($self->ifaceMethod($name) eq 'bridged') { return $self->get_hash('interfaces')->{$name}->{bridge_id}; } else { return undef; } } # Method: realIface # # Returns the associated PPP interface in case of a Ethernet # interface configured for PPPoE, or the same value in any other case. # # Parameters: # # name - interface name # # Returns: # # - For ppp interfaces: the associated interface, if it is up # - For the rest: the unaltered name # sub realIface # (name) { my ($self, $name) = @_; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); if ($self->ifaceMethod($name) eq 'ppp') { my $ppp_iface = $self->get_state()->{interfaces}->{$name}->{ppp_iface}; if ($ppp_iface) { return $ppp_iface; } } return $name; } # Method: etherIface # # Returns the associated Ethernet interface in case of a ppp # interface configured for PPPoE, or the same value in any other case. # # This is somehow the inverse function of # # Parameters: # # name - interface name # # Returns: # # - For ppp interfaces: the associated Ethernet interface, if it is up # - For the rest: the unaltered name # sub etherIface # (name) { my ($self, $name) = @_; for my $iface (@{$self->allIfaces()}) { if ($self->ifaceMethod($iface) eq 'ppp') { my $ppp_iface = $self->get_state()->{interfaces}->{$iface}->{ppp_iface}; return $iface if ($ppp_iface eq $name); } } return $name; } # Method: ifaceNetmask # # Returns the configured network mask for a real interface # # Parameters: # # interface - interface name # # Returns: # # - For static interfaces: the configured network mask of the interface. # - For dhcp interfaces: # - the current network mask the interface is up # - undef if the interface is down # - For not-yet-configured interfaces # - undef # sub ifaceNetmask { my ($self, $name) = @_; my $address; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); if ($self->vifaceExists($name)) { return $self->vifaceNetmask($name); } if ($self->ifaceMethod($name) eq 'static') { return $self->get_hash('interfaces')->{$name}->{netmask}; } elsif ($self->ifaceMethod($name) eq any('dhcp', 'ppp')) { return $self->DHCPNetmask($name); } elsif ($self->ifaceMethod($name) eq 'bridged') { my $bridge = $self->ifaceBridge($name); if ($self->ifaceExists("br$bridge")) { return $self->ifaceNetmask("br$bridge"); } } return undef; } # Method: ifaceNetwork # # Returns the configured network address for a real interface # # Parameters: # # interface - interface name # # Returns: # # - For static interfaces: the configured network address of the interface. # - For dhcp interfaces: # - the current network address the interface is up # - undef if the interface is down # - For not-yet-configured interfaces # - undef sub ifaceNetwork # (interface) { my ($self, $name) = @_; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); my $address; my $netmask; $address = $self->ifaceAddress($name); $netmask = $self->ifaceNetmask($name); if ($address) { return ip_network($address, $netmask); } return undef; } # Method: ifaceBroadcast # # Returns the configured broadcast address for a real interface # # Parameters: # # interface - interface name # # Returns: # # - For static interfaces: the configured broadcast address of the # interface. # - For dhcp interfaces: # - the current broadcast address if the interface is up # - undef if the interface is down # - For not-yet-configured interfaces sub ifaceBroadcast # (interface) { my ($self, $name) = @_; $self->ifaceExists($name) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $name); my $address; my $netmask; $address = $self->ifaceAddress($name); $netmask = $self->ifaceNetmask($name); if ($address) { return ip_broadcast($address, $netmask); } return undef; } # Method: nameservers # # Return a list of the configured name servers # # Returns: # # Array ref - each element contains a string holding the nameserver # sub nameservers { my ($self) = @_; my $resolverModel = $self->model('DNSResolver'); my $ids = $resolverModel->ids(); my @array = map { $resolverModel->row($_)->valueByName('nameserver') } @{$ids}; return \@array; } sub searchdomain { my ($self) = @_; return $self->model('SearchDomain')->domainValue(); } # Method: nameserverOne # # Return the primary nameserver's IP address # # Returns: # # String - nameserver's IP address # # empty string - if there is not primary nameserver # sub nameserverOne { my ($self) = @_; my $nss = $self->nameservers(); return $nss->[0] if (scalar(@{$nss}) >= 1); return ''; } # Method: nameserverTwo # # Return the secondary nameserver's IP address # # Returns: # # string - nameserver's IP address # # empty string - if there is not secondary nameserver # sub nameserverTwo { my ($self) = @_; my $nss = $self->nameservers(); return $nss->[1] if (scalar(@{$nss}) >= 2); return ''; } # Method: setNameservers # # Set a set of name server resolvers # # Parameters: # # array - a list of IP addresses which are the name server # resolvers # sub setNameservers # (one, two) { my ($self, @dns) = @_; my $nss = $self->nameservers(); my $resolverModel = $self->model('DNSResolver'); my $nNSS = scalar(@{$nss}); for(my $idx = 0; $idx < @dns; $idx++) { my $newNS = $dns[$idx]; my $existentRow = $resolverModel->find(nameserver => $newNS); if ($existentRow) { # remove it to insert it back in the wanted order $resolverModel->removeRow($existentRow->id(), 1); } if ($idx < $nNSS) { # There is a nameserver in the position $resolverModel->replace($idx, $newNS); } else { # Add a new one to the end of the list $resolverModel->add(nameserver => $newNS); } } } # Method: setSearchDomain # # Set the search domain # # Parameters: # # domain - string with the domain name # sub setSearchDomain { my ($self, $domain) = @_; my $model = $self->model('SearchDomain'); my $row = $model->row(); $row->elementByName('domain')->setValue($domain); $row->storeElementByName('domain'); } # Method: gateway # # Returns the default gateway's ip address # # Returns: # # If the gateway has not been set it will return undef # # string - the default gateway's ip address (undef if not set) sub gateway { my $self = shift; return $self->model('GatewayTable')->defaultGateway(); } # Method: routes # # Return the configured static routes # # Returns: # # array ref - each element contains a hash ref with keys: # # network - an IP block in CIDR format # gateway - an IP address # sub routes { my ($self) = @_; my $staticRouteModel = $self->model('StaticRoute'); my @routes; for my $id (@{$staticRouteModel->ids()}) { my $row = $staticRouteModel->row($id); push (@routes, { network => $row->printableValueByName('network'), gateway => $row->printableValueByName('gateway')}); } return \@routes; } # Method: gatewayDeleted # # Mark an interface as changed for a route delete. The selected # interface to be restarted must be the one which the gateway is # in. # # Parameters: # # gateway - String the gateway IP address # # Exceptions: # # - thrown if any compulsory # argument is missing # sub gatewayDeleted { my ($self, $gw) = @_; $gw or throw EBox::Exceptions::MissingArgument('gateway'); foreach my $iface (@{$self->allIfaces()}) { my $host = $self->ifaceAddress($iface); my $mask = $self->ifaceNetmask($iface); my $meth = $self->ifaceMethod($iface); (defined($meth) eq 'static') or next; (defined($host) and defined($mask)) or next; if (isIPInNetwork($host,$mask,$gw)) { $self->_setChanged($iface); } } } #returns true if the interface has been marked as changed sub _hasChanged { my ($self, $iface) = @_; my $real = $iface; if ($self->vifaceExists($iface)) { ($real) = $self->_viface2array($iface); } my $ifaces = $self->get_hash('interfaces'); if (exists $ifaces->{$real}) { return $ifaces->{$real}->{changed}; } else { return 1; # deleted => has changed } } #returns true if the interface is empty (ready to be removed) sub _isEmpty { my ($self, $ifc) = @_; if ($self->vifaceExists($ifc)) { my ($real, $vir) = $self->_viface2array($ifc); return (not defined($self->get_hash('interfaces')->{$real}->{virtual}->{$vir}->{address})); } else { return (not defined($self->get_hash('interfaces')->{$ifc}->{method})); } } sub _removeIface { my ($self, $iface) = @_; my $ifaces = $self->get_hash('interfaces'); if ($self->vifaceExists($iface)) { my ($real, $virtual) = $self->_viface2array($iface); delete $ifaces->{$real}->{virtual}->{$virtual}; } else { delete $ifaces->{$iface}; } $self->set('interfaces', $ifaces); } sub _unsetChanged # (interface) { my ($self, $iface) = @_; if ($self->vifaceExists($iface)) { return; } my $ifaces = $self->get_hash('interfaces'); delete $ifaces->{$iface}->{changed}; $self->set('interfaces', $ifaces); } sub _setChanged # (interface) { my ($self, $iface) = @_; my $ifaces = $self->get_hash('interfaces'); if ($self->vifaceExists($iface)) { my ($real, $vir) = $self->_viface2array($iface); $ifaces->{$real}->{changed} = 1; } else { $ifaces->{$iface}->{changed} = 1; } $self->set('interfaces', $ifaces); } # Generate the '/etc/resolv.conf' configuration file and modify # the '/etc/dhcp/dhclient.conf' to request nameservers only # if there are no manually configured ones. sub _generateDNSConfig { my ($self) = @_; # Set localhost as primary nameserver if the module is enabled. # This works because DNS module modChange network in enableService if (EBox::Global->modExists('dns')) { my $dns = EBox::Global->modInstance('dns'); my $resolver = $self->model('DNSResolver'); my $ids = $resolver->ids(); my $firstId = $ids->[0]; my $firstRow = $resolver->row($firstId); if ($dns->isEnabled()) { my $add = 1; if (defined ($firstRow)) { if ($firstRow->valueByName('nameserver') ne '127.0.0.1') { # Remove local resolver if it exists foreach my $id (@{$ids}) { if ($resolver->row($id)->valueByName('nameserver') eq '127.0.0.1') { $resolver->removeRow($id); } } } else { $add = 0; } } if ($add) { # Now add in the first place $resolver->table->{'insertPosition'} = 'front'; $resolver->addRow((nameserver => '127.0.0.1', readOnly => 1)); $resolver->table->{'insertPosition'} = 'back'; } } else { # If we have added it before remove when module is disabled. if (defined ($firstRow) and ($firstRow->valueByName('nameserver') eq '127.0.0.1') and $firstRow->readOnly()) { $resolver->removeRow($firstId); } } } my $nameservers = $self->nameservers(); my $request_nameservers = scalar (@{$nameservers}) == 0; $self->writeConfFile(RESOLV_FILE, 'network/resolv.conf.mas', [ searchDomain => $self->searchdomain(), nameservers => $nameservers ]); $self->writeConfFile(DHCLIENTCONF_FILE, 'network/dhclient.conf.mas', [ request_nameservers => $request_nameservers ]); } sub _generateProxyConfig { my ($self) = @_; my $proxy = $self->model('Proxy'); my $proxyConf; if ($proxy->serverValue() and $proxy->portValue()) { $proxyConf = "http://".$proxy->serverValue().":".$proxy->portValue()."/"; if ($proxy->usernameValue() and $proxy->passwordValue()) { $proxyConf = "http://".$proxy->usernameValue().":".$proxy->passwordValue(); $proxyConf .= "@".$proxy->serverValue().":".$proxy->portValue()."/"; } } $self->writeConfFile(ENV_PROXY_FILE, 'network/zentyal-proxy.sh.mas', [ proxyConf => $proxyConf ], { 'uid' => 0, 'gid' => 0, mode => '755' }); $self->writeConfFile(APT_PROXY_FILE, 'network/99proxy.conf.mas', [ proxyConf => $proxyConf ]); } # Method: proxySettings # # Return the proxy settings if configured # # Returns: # # Hash ref - the following keys are included # # server - the HTTP proxy's name # port - the HTTP proxy's port # username - the username to authenticate (optional) # password - the password (optional) # # undef - if there is not proxy settings # sub proxySettings { my ($self) = @_; my $proxy = $self->model('Proxy'); my $server = $proxy->serverValue(); my $port = $proxy->portValue(); if ( $server and $port ) { my $retValue = { server => $server, port => $port }; my $username = $proxy->usernameValue(); my $password = $proxy->passwordValue(); if ( $username and $password ) { $retValue->{username} = $username; $retValue->{password} = $password; } return $retValue; } else { return undef; } } # Method: isDDNSEnabled # # Check if the Dynamic DNS service is enabled or not # # Returns: # # Boolean - indicating if the service is enabled or not # sub isDDNSEnabled { my ($self) = @_; my $ddnsModel = $self->model('DynDNS'); return $ddnsModel->enableDDNSValue(); } # Method: DDNSUsingCloud # # Check if the Dynamic DNS service is using Zentyal Cloud or not # # Returns: # # Boolean - indicating if the service is enabled or not # sub DDNSUsingCloud { my ($self) = @_; my $ddnsModel = $self->model('DynDNS'); return ($ddnsModel->serviceValue() eq 'cloud'); } # Generate the '/etc/ddclient.conf' configuration file for DynDNS sub _generateDDClient { my ($self) = @_; my $enabled = $self->isDDNSEnabled(); my $ddnsModel = $self->model('DynDNS'); my $row = $ddnsModel->row(); my $serviceData = $EBox::Network::Model::DynDNS::SERVICES{$row->valueByName('service')}; my $server = $serviceData->{server}; my $hostname = $row->valueByName('hostname'); my $login = $row->valueByName('username'); my $password = $row->valueByName('password'); my $cmd = EBox::Config::share() . 'zentyal-network/external-ip.pl'; my @gws = (); if ($enabled) { if ( $row->valueByName('service') eq 'cloud' ) { my $gl = EBox::Global->getInstance(1); if ( $gl->modExists('remoteservices') ) { my $rs = $gl->modInstance('remoteservices'); if ( $rs->eBoxSubscribed() ) { # Server subscription credentials as user and pass my $cred = $rs->cloudCredentials(); # UUID for login $login = $cred->{uuid}; # Get DynDNS password $password = substr($cred->{password},0,20); $hostname = $rs->dynamicHostname(); my $cloud_domain = $rs->cloudDomain(); if ( $cloud_domain ) { $server = 'ddns.' . $cloud_domain; } else { EBox::warn('Zentyal Cloud cannot be used if we cannot ' . 'get domain name'); $enabled = 0; } # Check for multi-output gateways my $gws = $self->gateways(); if ( scalar(@{$gws}) > 1 ) { # Multigw scenario, use a domain-like name for subdomains # One per gateway @gws = map { my $name = $_->{name}; my $domain = lc $name; $domain =~ s/[^a-z0-9\-]/-/g; # Transform to domains { gw => $name , domain => $domain } } @{$gws}; } } else { EBox::warn('Zentyal Cloud cannot be used if the host is not subscribed'); $enabled = 0; } } } } $self->writeConfFile(DEFAULT_DDCLIENT_FILE, 'network/ddclient.mas', [ enabled => $enabled ]); if ( $enabled ) { $self->writeConfFile(DDCLIENT_FILE, 'network/ddclient.conf.mas', [ serviceData => $serviceData, login => $login, password => $password, hostname => $hostname, server => $server, cmd => $cmd, gws => \@gws ]); } } sub _generatePPPConfig { my ($self) = @_; my $pppSecrets = {}; my $usepeerdns = scalar (@{$self->nameservers()}) == 0; foreach my $iface (@{$self->pppIfaces()}) { my $user = $self->ifacePPPUser($iface); my $pass = $self->ifacePPPPass($iface); $pppSecrets->{$user} = $pass; $self->writeConfFile(PPP_PROVIDER_FILE . $iface, 'network/dsl-provider.mas', [ iface => $iface, ppp_user => $user, usepeerdns => $usepeerdns ]); } $self->writeConfFile(PAP_SECRETS_FILE, 'network/pap-secrets.mas', [ passwords => $pppSecrets ], { mode => '0600' } ); # Do not overwrite the entire chap-secrets file every time # to avoid conflicts with the PPTP module my $mark = '# PPPOE_CONFIG #'; my $file; try { $file = read_file(CHAP_SECRETS_FILE); } otherwise { # Write it with permissions for ebox if we can't read it my $gid = getgrnam('ebox'); $self->writeConfFile(CHAP_SECRETS_FILE, 'network/chap-secrets.mas', [], { mode => '0660', gid => $gid }); $file = read_file(CHAP_SECRETS_FILE); }; my $pppoeConf = ''; foreach my $user (keys %{$pppSecrets}) { $pppoeConf .= "$user * $pppSecrets->{$user}\n"; } $file =~ s/$mark.*$mark/$mark\n$pppoeConf$mark/sm; write_file(CHAP_SECRETS_FILE, $file); } sub generateInterfaces { my ($self) = @_; my $file = INTERFACES_FILE; my $tmpfile = EBox::Config::tmp . '/interfaces'; my $iflist = $self->allIfacesWithRemoved(); #my $manager = new EBox::ServiceManager(); #if ($manager->skipModification('network', $file)) { # EBox::info("Skipping modification of $file"); # return; #} #writing /etc/network/interfaces open(IFACES, ">", $tmpfile) or throw EBox::Exceptions::Internal("Could not write on $file"); print IFACES "auto lo"; foreach (@{$iflist}) { if (($self->ifaceMethod($_) eq 'static') or ($self->ifaceMethod($_) eq 'dhcp')) { print IFACES " " . $_; } } print IFACES "\n\niface lo inet loopback\n"; foreach my $ifname (@{$iflist}) { my $method = $self->ifaceMethod($ifname); my $bridgedVlan = $method eq 'bridged' and $ifname =~ /^vlan/; if (($method ne 'static') and ($method ne 'ppp') and ($method ne 'dhcp') and (not $bridgedVlan)) { next; } my $name = $ifname; if ($method eq 'ppp') { $name = "zentyal-ppp-$ifname"; print IFACES "auto $name\n"; } if ($bridgedVlan) { $method = 'manual'; } print IFACES "iface $name inet $method\n"; if ($ifname =~ /^vlan/) { my $vlan = $self->vlan($ifname); print IFACES "vlan-raw-device $vlan->{interface}\n"; } if ($method eq 'static') { print IFACES "\taddress ". $self->ifaceAddress($ifname). "\n"; print IFACES "\tnetmask ". $self->ifaceNetmask($ifname). "\n"; print IFACES "\tbroadcast " . $self->ifaceBroadcast($ifname) . "\n"; } elsif ($method eq 'ppp') { print IFACES "\tpre-up /sbin/ifconfig $ifname up\n"; print IFACES "\tpost-down /sbin/ifconfig $ifname down\n"; print IFACES "\tprovider $name\n"; } if ( $self->ifaceIsBridge($ifname) ) { print IFACES "\tbridge_ports"; my $ifaces = $self->bridgeIfaces($ifname); foreach my $bridged ( @{$ifaces} ) { print IFACES " $bridged"; } print IFACES "\n"; print IFACES "\tbridge_stp off\n"; print IFACES "\tbridge_waitport 5\n"; } my $mtu = EBox::Config::configkey("mtu_$ifname"); if ($mtu) { print IFACES "\tmtu $mtu\n"; } print IFACES "\n"; } close(IFACES); EBox::Sudo::root("cp $tmpfile $file"); #$manager->updateFileDigest('network', $file); } # Generate the static routes from routes() with "ip" command sub _generateRoutes { my ($self) = @_; my @routes = @{$self->routes()}; # clean up unnecesary rotues $self->_removeRoutes(\@routes); @routes or return; my @cmds; foreach my $route (@routes) { my $net = $route->{network}; $net =~ s[/32$][]; # route_is_up needs no /24 mask my $gw = $route->{gateway}; # check if route already is up if (route_is_up($net, $gw)) { next; } my $cmd = "/sbin/ip route add $net via $gw table main"; EBox::Sudo::root($cmd) } } # Remove not configured routes sub _removeRoutes { my ($self, $storedRoutes) = @_; my %toKeep = map { $_->{network} => $_ } @{ $storedRoutes }; # Delete those routes which are not defined by Zentyal my @currentRoutes = list_routes(1, 0); # routes via gateway foreach my $currentRoute (@currentRoutes) { my $network = $currentRoute->{network}; if (not $network =~ m{/}) { # add /32 mask to ips without it so we can compare same format $network .= '/32'; } my $gw = $currentRoute->{router}; if ((exists $toKeep{$network}) and ($toKeep{$network}->{gateway} eq $gw)) { next; } my $cmd = "/sbin/ip route del $network via $gw"; EBox::Sudo::root($cmd); } } # disable reverse path for gateway interfaces sub _disableReversePath { my ($self) = @_; my $routers = $self->gatewaysWithMac(); my @cmds; push (@cmds, '/sbin/sysctl -q -w net.ipv4.conf.all.rp_filter=0'); for my $router ( reverse @{$routers} ) { my $iface = $router->{'interface'}; $iface = $self->realIface($iface); push (@cmds, "/sbin/sysctl -q -w net.ipv4.conf.$iface.rp_filter=0"); } EBox::Sudo::root(@cmds); } sub _multigwRoutes { my ($self) = @_; # Flush the rules # # Add a rule to match every fwmark to pass through its # corresponding table. # # Each table only has a default # gateway, and there are as many tables as routers the user # has added. # # To route packets towards local networks, the highest # priority rule points to the main table. Note that # we do not have a default route in the main table, otherwise # we could not do the multipath stuff. Instead, we set the # default route within the default table. # # # We enclose iptables rules containing CONNMARK target # within a try/catch block because # kernels < 2.6.12 do not include such module. my $marks = $self->marksForRouters(); my $routers = $self->gatewaysWithMac(); my @cmds; # commands to run push(@cmds, EBox::Config::share() . 'zentyal-network/flush-fwmarks'); my %interfaces; for my $router ( reverse @{$routers} ) { # Skip gateways with unassigned address my $ip = $router->{'ip'}; next unless $ip; my $iface = $router->{'interface'}; $interfaces{$iface}++; } my @markRules; my @addrRules; for my $router ( reverse @{$routers} ) { # Skip gateways with unassigned address my $ip = $router->{'ip'}; next unless $ip; my $iface = $router->{'interface'}; my $method = $self->ifaceMethod($iface); $interfaces{$iface}++; my $mark = $marks->{$router->{'id'}}; my $table = 100 + $mark; $iface = $self->realIface($iface); my $net = $self->ifaceNetwork($iface); my $address = $self->ifaceAddress($iface); unless ($address) { EBox::error("Interface $iface used by gateway " . $router ->{name} . " has not address." . " Not adding multi-gateway rules for this gateway."); next; } my $route = "via $ip dev $iface src $address"; if ($method eq 'ppp') { $route = "dev $iface"; (undef, $ip) = split ('/', $ip); } # Write mark rules first to avoid local output problems push(@cmds, "/sbin/ip route flush table $table"); push(@markRules, "/sbin/ip rule add fwmark $mark/0xFF table $table"); push(@addrRules, "/sbin/ip rule add from $ip table $table"); # Add rule by source in multi interface configuration if (scalar keys %interfaces > 1) { push(@addrRules, "/sbin/ip rule add from $address table $table"); } push(@cmds, "/sbin/ip route add default $route table $table"); } push(@cmds, @addrRules, @markRules); push(@cmds,'/sbin/ip rule add table main'); # Not in @cmds array because of possible CONNMARK exception my @fcmds; push(@fcmds, '/sbin/iptables -t mangle -F'); push(@fcmds, '/sbin/iptables -t mangle -X'); push(@fcmds, '/sbin/iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark'); push(@fcmds, '/sbin/iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark'); EBox::Sudo::silentRoot(@fcmds); my $defaultRouterMark; foreach my $router (@{$routers}) { # Skip gateways with unassigned address next unless $router->{'ip'}; if ($router->{'default'} and $router->{'enabled'}) { $defaultRouterMark = $marks->{$router->{'id'}}; } my $mark = $marks->{$router->{'id'}}; # Match interface instead of mac for pppoe and dhcp my $mac = $router->{'mac'}; my $iface = $self->realIface($router->{'interface'}); my $origin; if ($mac) { # Skip unknown macs for static interfaces next if ($mac eq 'unknown'); $origin = "-m mac --mac-source $mac"; } else { $origin = "-i $iface"; } push(@cmds, '/sbin/iptables -t mangle -A PREROUTING ' . "-m mark --mark 0/0xff $origin " . "-j MARK --set-mark $mark"); } push(@cmds, @{$self->_pppoeRules()}); for my $rule (@{$self->model('MultiGwRulesDataTable')->iptablesRules()}) { push(@cmds, "/sbin/iptables $rule"); } # send unmarked packets through default router if ((not $self->balanceTraffic()) and $defaultRouterMark) { push(@cmds, "/sbin/iptables -t mangle -A PREROUTING -m mark --mark 0/0xff " . "-j MARK --set-mark $defaultRouterMark"); push(@cmds, "/sbin/iptables -t mangle -A OUTPUT -m mark --mark 0/0xff " . "-j MARK --set-mark $defaultRouterMark"); } # always before CONNMARK save commands EBox::Sudo::root(@cmds); try { my @fcmds; push(@fcmds, '/sbin/iptables -t mangle -A PREROUTING -j CONNMARK --save-mark'); push(@fcmds, '/sbin/iptables -t mangle -A OUTPUT -j CONNMARK --save-mark'); foreach my $chain (FAILOVER_CHAIN, CHECKIP_CHAIN) { push(@fcmds, "/sbin/iptables -t mangle -N $chain"); push(@fcmds, "/sbin/iptables -t mangle -A OUTPUT -j $chain"); } EBox::Sudo::root(@fcmds); } otherwise {}; } sub isRunning { my ($self) = @_; return $self->isEnabled(); } sub _supportActions { return undef; } # Method: _preSetConf # # Overrides # sub _preSetConf { my ($self, %opts) = @_; # Don't do anything during boot to avoid bringing down interfaces # which are already bringed up by the networking service return unless exists $ENV{'USER'}; my $file = INTERFACES_FILE; my $restart = delete $opts{restart}; try { EBox::Sudo::root( '/sbin/modprobe 8021q', '/sbin/vconfig set_name_type VLAN_PLUS_VID_NO_PAD' ); } catch EBox::Exceptions::Internal with { }; # Bring down changed interfaces my $iflist = $self->allIfacesWithRemoved(); foreach my $if (@{$iflist}) { if ($self->_hasChanged($if)) { try { my @cmds; if ($self->ifaceExists($if)) { my $ifname = $if; if ($self->ifaceMethod($if) eq 'ppp') { $ifname = "zentyal-ppp-$if"; } else { push (@cmds, "/sbin/ip address flush label $if"); push (@cmds, "/sbin/ip address flush label $if:*"); } push (@cmds, "/sbin/ifdown --force -i $file $ifname"); if ($self->ifaceMethod($if) eq 'bridge') { push (@cmds, "/usr/sbin/brctl delbr $if"); } } EBox::Sudo::root(@cmds); } catch EBox::Exceptions::Internal with { }; #remove if empty if ($self->_isEmpty($if)) { unless ($self->isReadOnly()) { $self->_removeIface($if); } } } # Clean up dhcp state if interface is not DHCP or # PPPoE it should be done by the dhcp, but sometimes # cruft is left if ($self->ifaceExists($if)) { unless ($self->ifaceMethod($if) eq any('dhcp', 'ppp')) { $self->DHCPCleanUp($if); } } } } sub _daemons { return [ { 'name' => 'ddclient', 'type' => 'init.d', 'pidfiles' => ['/var/run/ddclient.pid'], 'precondition' => \&isDDNSEnabled } ]; } sub _setConf { my ($self) = @_; $self->generateInterfaces(); $self->_generatePPPConfig(); $self->_generateDDClient(); $self->_generateDNSConfig(); $self->_generateProxyConfig(); } # Method: _enforceServiceState # # Overrides base method. It regenerates the network configuration. # It will set up the network interfaces, routes, dns... sub _enforceServiceState { my ($self, %opts) = @_; my $restart = delete $opts{restart}; my $file = INTERFACES_FILE; EBox::Sudo::silentRoot("ip addr add 127.0.1.1/8 dev lo"); my @ifups = (); my $iflist = $self->allIfacesWithRemoved(); foreach my $iface (@{$iflist}) { if ($self->_hasChanged($iface) or $restart) { if ($self->ifaceMethod($iface) eq 'ppp') { $iface = "zentyal-ppp-$iface"; } push(@ifups, $iface); } } # Only execute ifups if we are not running from init on boot # The interfaces are already up thanks to the networking start if (exists $ENV{'USER'}) { open(my $fd, '>', IFUP_LOCK_FILE); close($fd); foreach my $iface (@ifups) { EBox::Sudo::root(EBox::Config::scripts() . "unblock-exec /sbin/ifup --force -i $file $iface"); unless ($self->isReadOnly()) { $self->_unsetChanged($iface); } } unlink (IFUP_LOCK_FILE); } EBox::Sudo::silentRoot('/sbin/ip route del default table default', '/sbin/ip route del default'); my $cmd = $self->_multipathCommand(); if ($cmd) { try { EBox::Sudo::root($cmd); } catch EBox::Exceptions::Internal with { throw EBox::Exceptions::External("An error happened ". "trying to set the default gateway. Make sure the ". "gateway you specified is reachable."); }; } $self->_generateRoutes(); $self->_disableReversePath(); $self->_multigwRoutes(); $self->_cleanupVlanIfaces(); EBox::Sudo::root('/sbin/ip route flush cache'); $self->SUPER::_enforceServiceState(); } # Method: restoreConfig # # Restore its configuration from the backup file. # # Parameters: # dir - Directory where are located the backup files # sub restoreConfig { my ($self, $dir) = @_; # Set all configured ifaces as changed foreach my $iface (@{$self->allIfaces()}) { $self->_setChanged($iface); } $self->SUPER::restoreConfig(); } sub _stopService { my ($self) = @_; return unless ($self->configured()); my @cmds; my $file = INTERFACES_FILE; my $iflist = $self->allIfaces(); foreach my $if (@{$iflist}) { try { my $ifname = $if; if ($self->ifaceMethod($if) eq 'ppp') { $ifname = "zentyal-ppp-$if"; } else { push (@cmds, "/sbin/ip address flush label $if"); push (@cmds, "/sbin/ip address flush label $if:*"); } push (@cmds, "/sbin/ifdown --force -i $file $ifname"); } catch EBox::Exceptions::Internal with {}; } EBox::Sudo::root(@cmds); $self->SUPER::_stopService(); } sub _routersReachableIfChange # (interface, newaddress?, newmask?) { my ($self, $iface, $newaddr, $newmask) = @_; my @routes = @{$self->routes()}; my @ifaces = @{$self->allIfaces()}; my @gws = (); foreach my $route (@routes) { push(@gws, $route->{gateway}); } foreach my $gw (@{$self->model('GatewayTable')->gateways()}) { next if $gw->{'auto'}; my $ip = $gw->{'ip'}; next unless $ip; push (@gws, $ip); } foreach my $gw (@gws) { $gw .= "/32"; my $reachable = undef; foreach my $if (@ifaces) { my $host; my $mask; my $meth; if ($iface eq $if) { $host = $newaddr; $mask = $newmask; } else { $meth = $self->ifaceMethod($if); ($meth eq 'static') or next; $host = $self->ifaceAddress($if); $mask = $self->ifaceNetmask($if); } (defined($host) and defined($mask)) or next; if (isIPInNetwork($host, $mask, $gw)) { $reachable = 1; } } ($reachable) or throw EBox::Exceptions::External( __('The requested operation will cause one of the '. 'configured gateways or static routes to become unreachable. ' . 'Please remove it first if you really want to '. 'make this change.')); } return 1; } # Method: gatewayReachable # # Check if a given gateway address is reachable with the current # network configuration # # Parameters: # # gw - String the IP address for the gateway # # name - String A name to be shown if exception is launched. If # no given, then an exception is not launched. *(Optional)* # Default value: undef # # Returns: # # Boolean - name of the interface used to reach the gateway # undef if not reachable # # Exceptions: # # - thrown if any compulsory # argument is missing # # - thrown if name is supplied and # the gateway is not reachable # sub gatewayReachable { my ($self, $gw, $name) = @_; $gw or throw EBox::Exceptions::MissingArgument('gw'); my $reachableByNoStaticIface = undef; my $cidr_gw = "$gw/32"; foreach my $iface (@{$self->allIfaces()}) { my $host = $self->ifaceAddress($iface); my $mask = $self->ifaceNetmask($iface); (defined($host) and defined($mask)) or next; checkIPNetmask($gw, $mask) or next; if (isIPInNetwork($host,$mask,$cidr_gw)) { my $meth = $self->ifaceMethod($iface); if ($meth ne 'static') { $reachableByNoStaticIface = $iface; next; } return $iface; } } if ($name) { if (not $reachableByNoStaticIface) { throw EBox::Exceptions::External( __x("Gateway {gw} not reachable", gw => $gw)); } else { throw EBox::Exceptions::External( __x("Gateway {gw} must be reachable by a static interface. " . "Currently it is reachable by {iface} which is not static", gw => $gw, iface => $reachableByNoStaticIface) ); } } else { return undef; } } # Method: setDHCPAddress # # Sets the parameters for a DHCP configured interface. For instance, # this function is primaraly used from a DHCP hook. # # Parameters: # # iface - interface name # address - IPv4 address # mask - networking mask sub setDHCPAddress # (interface, ip, mask) { my ($self, $iface, $ip, $mask) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); checkIPNetmask($ip, $mask, __("IP address"), __('Netmask')); my $state = $self->get_state(); $state->{dhcp}->{$iface}->{address} = $ip; $state->{dhcp}->{$iface}->{mask} = $mask; $self->set_state($state); } # Method: setDHCPGateway # # Sets the obtained gateway via DHCP # # Parameters: # # iface - ethernet interface # gateway - gateway's IPv4 address sub setDHCPGateway # (iface, gateway) { my ($self, $iface, $gw) = @_; checkIP($gw, __("IP address")); $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); my $state = $self->get_state(); $state->{dhcp}->{$iface}->{gateway} = $gw; $self->set_state($state); } # Method: setRealPPPIface # # Sets the real PPP interface associated with the Ethernet one. # # Parameters: # # iface - ethernet interface name # ppp_iface - ppp interface name # ppp_addr - IP address of the ppp interface # sub setRealPPPIface # (iface, ppp_iface, ppp_addr) { my ($self, $iface, $ppp_iface, $ppp_addr) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); my $state = $self->get_state(); $state->{interfaces}->{$iface}->{ppp_iface} = $ppp_iface; $self->set_state($state); checkIP($ppp_addr, __("IP address")); $state->{interfaces}->{$iface}->{ppp_addr} = $ppp_addr; $self->set_state($state); } # Method: DHCPCleanUp # # Removes the dhcp configuration for a given interface # Also removes the PPPoE iface if exists # # Parameters: # # interface - interface name # sub DHCPCleanUp # (interface) { my ($self, $iface) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); my $state = $self->get_state(); delete $state->{dhcp}->{$iface}; delete $state->{interfaces}->{$iface}->{ppp_iface}; $self->set_state($state); } # Method: BridgedCleanUp # # Removes the bridge configuration for a given bridged interface # # Parameters: # # interface - interface name # sub BridgedCleanUp # (interface) { my ($self, $iface) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); my $bridge = $self->ifaceBridge($iface); # this changes the bridge if ($self->ifaceIsBridge("br$bridge")) { $self->_setChanged("br$bridge"); } $self->unset("interfaces/$iface/bridge_id"); $self->_removeEmptyBridges(); } # Method: selectedDefaultGateway # # Returns the selected default gateway # sub selectedDefaultGateway { my ($self) = @_; return $self->get('default/gateway'); } # Method: storeSelectedDefaultGateway # # Store the selected default gateway # # Parameters: # # gateway - gateway id # sub storeSelectedDefaultGateway { my ($self, $gateway) = @_; return $self->set('default/gateway', $gateway); } # Method: DHCPGateway # # Returns the gateway from a dhcp configured interface # # Parameters: # # iface - interface name (DHCP or PPPoE) # # Returns: # # string - gateway # sub DHCPGateway { my ($self, $iface) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); return $self->get_state()->{dhcp}->{$iface}->{gateway}; } # Method: DHCPAddress # # Returns the ip address from a dhcp configured interface # # Parameters: # # interface - interface name # # Returns: # # string - IPv4 address # sub DHCPAddress { my ($self, $iface) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); return $self->get_state()->{dhcp}->{$iface}->{address}; } # Method: DHCPNetmask # # Returns the network mask from a dhcp configured interface # # Parameters: # # interface - interface name # # Returns: # # string - network mask # sub DHCPNetmask { my ($self, $iface) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); return $self->get_state()->{dhcp}->{$iface}->{mask}; } # Method: DHCPNetmask # # Sets the nameserver obtained from a DHCP configured interface # # Parameters: # # interface - interface name # nameservers - array ref holding the nameservers # # Returns: # # string - network mask # sub setDHCPNameservers { my ($self, $iface, $servers) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); foreach (@{$servers}) { checkIP($_, __("IP address")); } my $state = $self->get_state(); $state->{dhcp}->{$iface}->{nameservers} = $servers; $self->set_state($state); } # Method: DHCPNameservers # # Get the nameservers obtained from a DHCP configured interface # # Parameters: # # interface - interface name # # Returns: # # array ref - holding the nameservers # sub DHCPNameservers { my ($self, $iface) = @_; $self->ifaceExists($iface) or throw EBox::Exceptions::DataNotFound(data => __('Interface'), value => $iface); return $self->get_state()->{dhcp}->{$iface}->{nameservers}; } # Method: ping # # Performs a ping test and returns the output # # Parameters: # # host - host to ping (either ip or hostname) # # Returns: # # string - output of the ping command # sub ping # (host) { my ($self, $host) = @_; (checkIP($host) or checkDomainName($host)) or throw EBox::Exceptions::InvalidData ('data' => __('Host name'), 'value' => $host); return `ping -c 3 $host 2>&1`; } # Method: traceroute # # Performs a traceroute test and returns it output # # Parameters: # # host - host to trace the route (either ip or hostname) # # Returns: # # string - output of the traceroute command # sub traceroute # (host) { my ($self, $host) = @_; (checkIP($host) or checkDomainName($host)) or throw EBox::Exceptions::InvalidData ('data' => __('Host name'), 'value' => $host); my $out = EBox::Sudo::rootWithoutException("traceroute -I -n $host 2>&1"); return join("\n", @{$out}); } # Method: resolv # # Performs a name resolution (using dig) and returns the output # # Parameters: # # host - host name to resolve # # Returns: # # string - output of the dig command # sub resolv # (host) { my ($self, $host) = @_; checkDomainName($host, __("host name")); # +time=3 sets the timeout (the default is 5), it tries three times # so in the worst case it should take 9 seconds to return from this # call # FIXME: study which options make sense in dig, remove some stuff # from the output return `dig +time=3 $host 2>&1`; } # Method: wakeonlan # # Performs a wakeonlan and returns the output # # Parameters: # # macs - Array of MAC addresses of the computers to wake # # Returns: # # string - output of the wakeonlan command # sub wakeonlan # (macs) { my ($self, @macs) = @_; my $param = join (' ' , @macs); return `wakeonlan $param 2>&1`; } sub interfacesWidget { my ($self, $widget) = @_; my @ifaces = @{$self->ifacesWithRemoved()}; my $size = scalar (@ifaces) * 1.25; $size = 0.1 unless defined ($size); $widget->{size} = $size; my $linkstatus = {}; EBox::Sudo::silentRoot('/sbin/mii-tool > ' . EBox::Config::tmp . 'linkstatus'); if (open(LINKF, EBox::Config::tmp . 'linkstatus')) { while () { if (/link ok/) { my $i = (split(" ",$_))[0]; chop($i); $linkstatus->{$i} = 1; } elsif(/no link/) { my $i = (split(" ",$_))[0]; chop($i); $linkstatus->{$i} = 0; } } } foreach my $iface (@ifaces) { iface_exists($iface) or next; my $upStr = __("down"); my $section = new EBox::Dashboard::Section($iface, $self->ifaceAlias($iface)); $widget->add($section); if (iface_is_up($iface)) { $upStr = __("up"); } my $externalStr; if ($self->ifaceIsExternal($iface)) { $externalStr = __('external'); } else { $externalStr = __('internal'); } my $linkStatusStr; if (defined($linkstatus->{$iface})) { if($linkstatus->{$iface}){ $linkStatusStr = __("link ok"); }else{ $linkStatusStr = __("no link"); } } my $status = "$upStr, $externalStr"; if ($linkStatusStr) { $status .= ", $linkStatusStr"; } $section->add(new EBox::Dashboard::Value (__("Status"), $status)); my $ether = iface_mac_address($iface); if ($ether) { $section->add(new EBox::Dashboard::Value (__("MAC address"), $ether)); } my @ips = iface_addresses($iface); foreach my $ip (@ips) { $section->add(new EBox::Dashboard::Value (__("IP address"), $ip)); } my $graphs = new EBox::Dashboard::GraphRow(); $section->add($graphs); my $cmd; my $statistics = "/sys/class/net/$iface/statistics"; my $statsFile; open ($statsFile, "$statistics/tx_bytes"); my $tx_bytes = <$statsFile>; close ($statsFile); chomp ($tx_bytes); $graphs->add(new EBox::Dashboard::CounterGraph (__("Tx bytes"), $iface . "_txbytes", $tx_bytes, 'small')); open ($statsFile, "$statistics/rx_bytes"); my $rx_bytes = <$statsFile>; close ($statsFile); chomp ($rx_bytes); $graphs->add(new EBox::Dashboard::CounterGraph (__("Rx bytes"), $iface . "_rxbytes", $rx_bytes, 'small')); } } sub widgets { return { 'interfaces' => { 'title' => __("Network Interfaces"), 'widget' => \&interfacesWidget, 'order' => 3, 'default' => 1 } }; } # Method: menu # # Overrides EBox::Module method. # # sub menu { my ($self, $root) = @_; my $folder = new EBox::Menu::Folder('name' => 'Network', 'text' => __('Network'), 'separator' => 'Core', 'order' => 40); $folder->add(new EBox::Menu::Item('url' => 'Network/Ifaces', 'text' => __('Interfaces'), 'order' => 10)); $folder->add(new EBox::Menu::Item('url' => 'Network/Composite/GatewaysGeneral', 'text' => __('Gateways'), 'order' => 20)); $folder->add(new EBox::Menu::Item('url' => 'Network/Composite/DNS', 'text' => 'DNS', 'order' => 30)); $folder->add(new EBox::Menu::Item('url' => 'Network/View/StaticRoute', 'text' => __('Static Routes'), 'order' => 60)); $folder->add(new EBox::Menu::Item('url' => 'Network/View/DynDNS', 'text' => __('Dynamic DNS'), 'order' => 70)); $folder->add(new EBox::Menu::Item('url' => 'Network/Diag', 'text' => __('Tools'), 'order' => 80)); $root->add($folder); } # Method: gateways # # Return the enabled gateways # # Returns: # # array ref of hash refs containing name, ip, # if it is the default gateway or not and the id for the gateway. # # Example: # # [ # { # name => 'gw1', ip => '192.168.1.1' , interface => 'eth0', # default => '1', id => 'foo1234' # } # ] # sub gateways { my ($self) = @_; my $gatewayModel = $self->model('GatewayTable'); return $gatewayModel->gateways(); } sub _defaultGwAndIface { my ($self) = @_; my $gw = $self->model('GatewayTable')->find('default' => 1); if ($gw and $gw->valueByName('enabled')) { return ($gw->valueByName('interface'), $gw->valueByName('ip')); } else { return (undef, undef); } } # Method: gatewaysWithMac # # Return the enabled gateways and its mac address # # Returns: # # array ref of hash refs containing name, ip, # if it is the default gateway or not and the id for the gateway. # # Example: # # [ # { # name => 'gw1', ip => '192.168.1.1' , # defalut => '1', id => 'foo1234', mac => '00:00:fa:ba:da' # } # ] # sub gatewaysWithMac { my ($self) = @_; my $gatewayModel = $self->model('GatewayTable'); return $gatewayModel->gatewaysWithMac(); } sub marksForRouters { my ($self) = @_; my $marks = $self->model('GatewayTable')->marksForRouters(); } # Method: balanceTraffic # # Return if the traffic balancing is enabled or not # # Returns: # # bool - true if enabled, otherwise false # sub balanceTraffic { my ($self) = @_; my $multiGwOptions = $self->model('MultiGwRulesOptions'); my $balanceTraffic = $multiGwOptions->balanceTrafficValue(); return ($balanceTraffic and (@{$self->gateways} > 1)); } # Method: regenGateways # # Recreate the default route table. This method is currently used # for the WAN failover and dynamic multi-gateway. # # sub regenGateways { my ($self) = @_; my $global = EBox::Global->getInstance(); my $timeout = 60; my $locked = 0; while ((not $locked) and ($timeout > 0)) { try { EBox::Util::Lock::lock('network'); $locked = 1; } catch EBox::Exceptions::Lock with { sleep 5; $timeout -= 5; }; } unless ($locked) { EBox::error('Network module has been locked for 60 seconds'); return; } $self->saveConfig(); my @commands; push (@commands, '/sbin/ip route del table default || true'); my $cmd = $self->_multipathCommand(); if ($cmd) { push (@commands, $cmd); } # Silently delete duplicated MTU rules for PPPoE interfaces and # add them to the commands array push(@commands, @{$self->_pppoeRules(1)}); try { EBox::Sudo::root(@commands); } otherwise { EBox::error('Something bad happened reseting default gateways'); }; $self->_multigwRoutes(); EBox::Sudo::root('/sbin/ip route flush cache'); $global->modRestarted('network'); EBox::Util::Lock::unlock('network'); } sub _pppoeRules { my ($self, $flush) = @_; my @add; # Warning (if flush=1): # Delete rules are immediately executed, add rules are returned # this is for performance reasons, to allow to integrate them in other # arrays, but the delete ones need to be executed with silentRoot, # so they are executed separately. my @delete; # Special rule for PPPoE interfaces to avoid problems with large packets foreach my $if (@{$self->pppIfaces()}) { $if = $self->realIface($if); my $cmd = '/sbin/iptables -t mangle'; my $params = "POSTROUTING -o $if -p tcp " . "-m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu"; if ($flush) { push (@delete, "$cmd -D $params"); } push (@add, "$cmd -A $params"); } if ($flush) { EBox::Sudo::silentRoot(@delete); } return \@add; } sub _multipathCommand { my ($self) = @_; my @gateways = @{$self->gateways()}; if (scalar(@gateways) == 0) { # If WAN failover is enabled we put the default one my $ev = $self->global()->modInstance('events'); if ($ev->isEnabledWatcher('EBox::Event::Watcher::Gateways')) { my $row = $self->model('GatewayTable')->findValue(default => 1); unless ($row) { return undef; } my $ip = $row->valueByName('ip'); my $iface = $row->valueByName('interface'); my $weight = $row->valueByName('weight'); push (@gateways, {ip => $ip, interface => $iface, weight => $weight}); } else { return undef; } } my $numGWs = 0; my $cmd = 'ip route add table default default'; for my $gw (@gateways) { # Skip gateways with unassigned address my $ip = $gw->{'ip'}; next unless $ip; # Skip gateways with traffic balance disabled # except if we just have one gateway next unless ($gw->{'balance'} or (@gateways == 1)); my $iface = $gw->{'interface'}; my $method = $self->ifaceMethod($iface); $iface = $self->realIface($iface); my $if = new IO::Interface::Simple($iface); next unless $if->address; my $route = "via $ip dev $iface"; if ($method eq 'ppp') { $route = "dev $iface"; } $cmd .= " nexthop $route weight $gw->{'weight'}"; $numGWs++; } if ($numGWs) { return $cmd; } else { return undef; } } # Method: _notifyChangedIface # # Notify network observers the change of a interface has taken place # # Parameters: # (Named) # # name - interface's name # oldMethod - old method # newMethod - new method # force - force # action - 'prechange' or 'postchange' sub _notifyChangedIface { my ($self, %args) = @_; my $name = $args{name}; my $oldMethod = $args{oldMethod}; my $newMethod = $args{newMethod}; my $force = $args{force}; my $action = $args{action}; my $global = EBox::Global->getInstance(); my @observers = @{$global->modInstancesOfType('EBox::NetworkObserver')}; foreach my $objs (@observers) { if ($action eq 'prechange') { if ($objs->ifaceMethodChanged($name, $oldMethod, $newMethod)) { if ($force) { $objs->freeIface($name); } else { throw EBox::Exceptions::DataInUse(); } } } else { $objs->ifaceMethodChangeDone($name); } } } # Method: importInterfacesFile # # Parses /etc/network/interfaces and imports values # to the Zentyal network module configuration # sub importInterfacesFile { my ($self) = @_; my $DEFAULT_IFACE = 'eth0'; my $DEFAULT_GW_NAME = 'default'; my $DEFAULT_WEIGHT = 1; my @interfaces = @{$self->_readInterfaces()}; foreach my $iface (@interfaces) { if ($iface->{name} =~ /^vlan/) { ($iface->{'vlan-raw-device'}) or die "vlan interface '$iface->{name}' needs a ". "raw-device declaration"; $self->setIfaceTrunk($iface->{'vlan-raw-device'}, 1); my $vlan = $iface->{name}; $vlan =~ s/^vlan//; $self->createVlan($vlan, undef, $iface->{'vlan-raw-device'}); } if ($iface->{'method'} eq 'static') { $self->setIfaceStatic($iface->{'name'}, $iface->{'address'}, $iface->{'netmask'}, undef, 1); if ($iface->{'gateway'}){ my $gwModel = $self->model('GatewayTable'); my $defaultGwRow = $gwModel->find(name => $DEFAULT_GW_NAME); if ($defaultGwRow) { EBox::info("Already a default gateway, keeping it"); } else { $gwModel->add(name => $DEFAULT_GW_NAME, ip => $iface->{'gateway'}, interface => $iface->{'name'}, weight => $DEFAULT_WEIGHT, default => 1); } } } elsif ($iface->{'method'} eq 'dhcp') { $self->setIfaceDHCP($iface->{'name'}, 0, 1); } } my ($searchdomain, @dns) = @{$self->_readResolv()}; $self->setNameservers(@dns); if ($searchdomain) { $self->setSearchDomain($searchdomain); } $self->saveConfig(); } sub _readInterfaces { my ($self) = @_; my $ifacesFH; unless (open($ifacesFH, INTERFACES_FILE)) { warn "couldn't open " . INTERFACES_FILE; return []; } my @interfaces; my $iface; my @fields = qw/address netmask gateway vlan-raw-device/; for my $line (<$ifacesFH>) { $line =~ s/^\s+//g; my @toks = split (/\s+/, $line); next unless @toks; if ($toks[0] eq 'iface' and $toks[2] eq 'inet') { next if ($self->_ignoreIface($toks[1])); push (@interfaces, $iface) if ($iface); $iface = { name => $toks[1], method => $toks[3] }; } if (grep((/^$toks[0]$/), @fields)) { $iface->{$toks[0]} = $toks[1]; } } close ($ifacesFH); push (@interfaces, $iface) if ($iface); return \@interfaces; } sub _readResolv { my $resolvFH; unless (open($resolvFH, RESOLV_FILE)) { EBox::warn("Couldn't open " . RESOLV_FILE); return []; } my $searchdomain = undef; my @dns; for my $line (<$resolvFH>) { $line =~ s/^\s+//g; my @toks = split (/\s+/, $line); if ($toks[0] eq 'nameserver') { push (@dns, $toks[1]); } elsif ($toks[0] eq 'search') { $searchdomain = $toks[1]; } } close ($resolvFH); return [$searchdomain, @dns]; } 1; zentyal-network-2.3.13+quantal1/stubs/0000775000000000000000000000000012017102311014513 5ustar zentyal-network-2.3.13+quantal1/stubs/pap-secrets.mas0000664000000000000000000000332112017102311017442 0ustar <%args> $passwords # # /etc/ppp/pap-secrets # # This is a pap-secrets file to be used with the AUTO_PPP function of # mgetty. mgetty-0.99 is preconfigured to startup pppd with the login option # which will cause pppd to consult /etc/passwd (and /etc/shadow in turn) # after a user has passed this file. Don't be disturbed therefore by the fact # that this file defines logins with any password for users. /etc/passwd # (again, /etc/shadow, too) will catch passwd mismatches. # # This file should block ALL users that should not be able to do AUTO_PPP. # AUTO_PPP bypasses the usual login program so it's necessary to list all # system userids with regular passwords here. # # ATTENTION: The definitions here can allow users to login without a # password if you don't use the login option of pppd! The mgetty Debian # package already provides this option; make sure you don't change that. # INBOUND connections # Every regular user can use PPP and has to use passwords from /etc/passwd * hostname "" * # UserIDs that cannot use PPP at all. Check your /etc/passwd and add any # other accounts that should not be able to use pppd! guest hostname "*" - master hostname "*" - root hostname "*" - support hostname "*" - stats hostname "*" - # OUTBOUND connections # Here you should add your userid password to connect to your providers via # PAP. The * means that the password is to be used for ANY host you connect # to. Thus you do not have to worry about the foreign machine name. Just # replace password with your password. # If you have different providers with different passwords then you better # remove the following line. # * password % foreach my $user (keys %{$passwords}) { <% $user %> * <% $passwords->{$user} %> % } zentyal-network-2.3.13+quantal1/stubs/resolv.conf.mas0000664000000000000000000000026212017102311017453 0ustar <%args> $searchDomain => '' @nameservers => () % if ($searchDomain) { search <% $searchDomain %> % } % foreach my $host (@nameservers) { nameserver <% $host %> % } zentyal-network-2.3.13+quantal1/stubs/dhclient.conf.mas0000664000000000000000000000314212017102311017733 0ustar <%args> $request_nameservers # Configuration file for /sbin/dhclient, which is included in Debian's # dhcp3-client package. # # This is a sample configuration file for dhclient. See dhclient.conf's # man page for more information about the syntax of this file # and a more comprehensive list of the parameters understood by # dhclient. # # Normally, if the DHCP server provides reasonable information and does # not leave anything out (like the domain name, for example), then # few changes must be made to this file, if any. # send host-name ""; #send dhcp-client-identifier 1:0:a0:24:ab:fb:9c; #send dhcp-lease-time 3600; #supersede domain-name "fugue.com home.vix.com"; #prepend domain-name-servers 127.0.0.1; request subnet-mask, broadcast-address, time-offset, routers, % if ($request_nameservers) { domain-name, domain-name-servers, % } host-name, netbios-name-servers, netbios-scope; #require subnet-mask, domain-name-servers; timeout 30; #retry 60; #reboot 10; #select-timeout 5; #initial-interval 2; #script "/etc/dhcp3/dhclient-script"; #media "-link0 -link1 -link2", "link0 link1"; #reject 192.33.137.209; #alias { # interface "eth0"; # fixed-address 192.5.5.213; # option subnet-mask 255.255.255.255; #} #lease { # interface "eth0"; # fixed-address 192.33.137.200; # medium "link0 link1"; # option host-name "andare.swiftmedia.com"; # option subnet-mask 255.255.255.0; # option broadcast-address 192.33.137.255; # option routers 192.33.137.250; # option domain-name-servers 127.0.0.1; # renew 2 2000/1/12 00:00:01; # rebind 2 2000/1/12 00:00:01; # expire 2 2000/1/12 00:00:01; #} zentyal-network-2.3.13+quantal1/stubs/chap-secrets.mas0000664000000000000000000000022212017102311017572 0ustar # Secrets for authentication using CHAP # client server secret IP addresses # PPPOE_CONFIG # # PPPOE_CONFIG # # PPTP_CONFIG # # PPTP_CONFIG # zentyal-network-2.3.13+quantal1/stubs/99proxy.conf.mas0000664000000000000000000000017612017102311017510 0ustar <%args> $proxyConf # Zentyal defined HTTP Proxy % if ($proxyConf) { Acquire::http::Proxy "<% $proxyConf %>"; % } zentyal-network-2.3.13+quantal1/stubs/ddclient.mas0000664000000000000000000000075312017102311017010 0ustar <%args> $enabled # /etc/default/ddclient # Set to "true" if ddclient should be run every time a new ppp connection is # established. This might be useful, if you are using dial-on-demand. run_ipup="false" # Set to "true" if ddclient should run in daemon mode. run_daemon="<% $enabled ? 'true' : 'false' %>" # Set the time interval between the updates of the dynamic DNS name in seconds. # This option only takes effect if the ddclient runs in daemon mode. daemon_interval="300" zentyal-network-2.3.13+quantal1/stubs/dsl-provider.mas0000664000000000000000000000452712017102311017637 0ustar <%args> $iface $ppp_user $usepeerdns # Configuration file for PPP, using PPP over Ethernet # to connect to a DSL provider. # # See the manual page pppd(8) for information on all the options. ## # Section 1 # # Stuff to configure... # MUST CHANGE: Uncomment the following line, replacing the user@provider.net # by the DSL user name given to your by your DSL provider. # (There should be a matching entry in /etc/ppp/pap-secrets with the password.) user <% $ppp_user %> # Use the pppoe program to send the ppp packets over the Ethernet link # This line should work fine if this computer is the only one accessing # the Internet through this DSL connection. This is the right line to use # for most people. #pty "/usr/sbin/pppoe -I eth0 -T 80 -m 1452" # An even more conservative version of the previous line, if things # don't work using -m 1452... #pty "/usr/sbin/pppoe -I eth0 -T 80 -m 1412" # If the computer connected to the Internet using pppoe is not being used # by other computers as a gateway to the Internet, you can try the following # line instead, for a small gain in speed: #pty "/usr/sbin/pppoe -I eth0 -T 80" # The following two options should work fine for most DSL users. # Assumes that your IP address is allocated dynamically # by your DSL provider... noipdefault % if ($usepeerdns) { # Try to get the name server addresses from the ISP. usepeerdns % } # Use this connection as the default route. # Comment out if you already have the correct default route installed. #defaultroute ## # Section 2 # # Uncomment if your DSL provider charges by minute connected # and you want to use demand-dialing. # # Disconnect after 300 seconds (5 minutes) of idle time. #demand #idle 300 ## # Section 3 # # You shouldn't need to change these options... hide-password lcp-echo-interval 20 lcp-echo-failure 3 # Override any connect script that may have been set in /etc/ppp/options. connect /bin/true noauth persist mtu 1492 # RFC 2516, paragraph 7 mandates that the following options MUST NOT be # requested and MUST be rejected if requested by the peer: # Address-and-Control-Field-Compression (ACFC) noaccomp # Asynchronous-Control-Character-Map (ACCM) default-asyncmap # Always retry on fail maxfail 0 # Added for eBox # Used to pass the name of the ethernet interface to the ip-up.d script ipparam <% $iface %> plugin rp-pppoe.so <% $iface %> zentyal-network-2.3.13+quantal1/stubs/rt_tables.mas0000664000000000000000000000027612017102311017201 0ustar <%args> @ids # # reserved values # 255 local 254 main 253 default 0 unspec # # local # #1 inr.ruhep % my $number = 1; % for my $id (@ids) { <% $number %> <% $id %> % $number++; % } zentyal-network-2.3.13+quantal1/stubs/ddclient.conf.mas0000664000000000000000000000200312017102311017722 0ustar <%args> $login $password $hostname $serviceData $server @gws $cmd <%init> my $protocol = $serviceData->{protocol}; my $use = $serviceData->{use}; # /etc/ddclient.conf # Default global variables pid=/var/run/ddclient.pid ssl=yes login=<% $login %> password='<% $password %>' protocol=<% $protocol %> server=<% $server %> % if ( scalar(@gws) == 0 ) { % if ($use eq 'web') { use=web, web=<% $serviceData->{web} %>, web-skip='<% $serviceData->{web_skip} %>' % } elsif ($use eq 'if') { use=if, if=<% $serviceData->{iface} %> % } elsif ($use eq 'linksys') { use=linksys, fw=<% $serviceData->{fw} %>, fw-login=<% $serviceData->{fw_login} %>, fw-password=<% $serviceData->fw_password %> % } elsif ($use eq 'fw') { use=linksys, fw=<% $serviceData->{fw} %>, fw-skip=<% $serviceData->{fw_skip} %> % } <% $hostname %> % } else { % foreach my $gw (@gws) { % my $gwName = $gw->{gw}; % my $domain = $gw->{domain}; use=cmd, cmd='<% "$cmd $gwName" %>' <% "${domain}.$hostname" %> % } % } zentyal-network-2.3.13+quantal1/stubs/zentyal-proxy.sh.mas0000664000000000000000000000020612017102311020471 0ustar <%args> $proxyConf #!/bin/sh -e # Zentyal defined HTTP Proxy % if ($proxyConf) { export http_proxy=<% $proxyConf %> % } zentyal-network-2.3.13+quantal1/extra/0000775000000000000000000000000012017102311014476 5ustar zentyal-network-2.3.13+quantal1/extra/zentyal-dhcp-enter0000664000000000000000000000053312017102311020137 0ustar set_router() { ebox_routers="$new_routers" unset new_routers } # Do nothing if network module is disbled if /etc/init.d/zentyal network status; then case $reason in BOUND) set_router ;; REBOOT|RENEW|REBIND|TIMEOUT) set_router ;; *) ;; esac fi zentyal-network-2.3.13+quantal1/extra/zentyal-dhcp-exit0000664000000000000000000000316312017102311017775 0ustar libexec=/usr/share/zentyal-network firewall_script=/usr/share/zentyal-firewall/dhcp-firewall.pl ebox_bound() { $libexec/dhcp-address.pl $interface $new_ip_address $new_subnet_mask $libexec/dhcp-nameservers.pl $interface $new_domain_name_servers $libexec/dhcp-gateway.pl $interface $ebox_routers if ( [ -x $firewall_script ] ); then $firewall_script fi; } ebox_renew() { change="no" if [ "z$new_ip_address" != "z$old_ip_address" ] ; then change="yes" fi if [ "z$new_subnet_mask" != "z$old_subnet_mask" ] ; then change="yes" fi if [ "$change" == "yes" ] ; then $libexec/dhcp-address.pl $interface $new_ip_address \ $new_subnet_mask fi if [ "z$new_domain_name_servers" != "z$old_domain_name_servers" ] ; then change="yes" $libexec/dhcp-nameservers.pl $interface $new_domain_name_servers fi if [ "z$ebox_routers" != "z$old_routers" ] ; then $libexec/dhcp-gateway.pl $interface $ebox_routers fi if [ "$change" == "yes" ] ; then if ( [ -x $firewall_script ] ); then $firewall_script fi; fi } ebox_expire() { $libexec/dhcp-clear.pl $interface if ( [ -x $firewall_script ] ); then $firewall_script $interface fi; } # Do nothing if network module is disbled if /etc/init.d/zentyal network status; then case $reason in BOUND) ebox_bound ;; REBOOT|RENEW|REBIND|TIMEOUT) ebox_renew ;; EXPIRE|FAIL|RELEASE) ebox_expire ;; *) ;; esac fi zentyal-network-2.3.13+quantal1/extra/zentyal-ppp-up0000775000000000000000000000167012017102311017335 0ustar #!/bin/bash scripts=/usr/share/zentyal-network ppp_iface=$1 eth_iface=$2 local_address=$4 remote_address=$5 LOG=/var/log/zentyal/pppoe.log #TIMESTAMP=$(date +"%Y-%m-%d %T") #echo "$TIMESTAMP> ppp-up script called with the following values:" >> $LOG #echo "ppp_iface: $ppp_iface" >> $LOG #echo "eth_iface: $eth_iface" >> $LOG #echo "local_address: $local_address" >> $LOG #echo "remote_address: $remote_address" >> $LOG #echo "full_args: $@" >> $LOG #echo "dns: $USEPEERDNS $DNS1 $DNS2" >> $LOG $scripts/ppp-set-iface.pl $eth_iface $ppp_iface $local_address $scripts/dhcp-address.pl $eth_iface $local_address 255.255.255.255 if [ $USEPEERDNS -eq 1 ] then $scripts/dhcp-nameservers.pl $eth_iface $DNS1 $DNS2 fi # Regenerate firewall rules firewall_script=/usr/share/zentyal-firewall/dhcp-firewall.pl [ -x $firewall_script ] && $firewall_script #TIMESTAMP=$(date +"%Y-%m-%d %T") #echo "$TIMESTAMP> ppp-up script for $eth_iface ended" >> $LOG zentyal-network-2.3.13+quantal1/extra/files.list0000664000000000000000000000025212017102311016474 0ustar zentyal-dhcp-enter /etc/dhcp/dhclient-enter-hooks.d zentyal-dhcp-exit /etc/dhcp/dhclient-exit-hooks.d zentyal-ppp-up /etc/ppp/ip-up.d zentyal-ppp-down /etc/ppp/ip-down.d zentyal-network-2.3.13+quantal1/extra/zentyal-ppp-down0000775000000000000000000000107412017102311017656 0ustar #!/bin/bash ppp_iface=$1 eth_iface=$2 local_address=$4 remote_address=$5 LOG=/var/log/zentyal/pppoe.log #TIMESTAMP=$(date +"%Y-%m-%d %T") #echo "$TIMESTAMP> ppp-down script called with the following values:" >> $LOG #echo "ppp_iface: $ppp_iface" >> $LOG #echo "eth_iface: $eth_iface" >> $LOG #echo "local_address: $local_address" >> $LOG #echo "remote_address: $remote_address" >> $LOG #echo "full_args: $@" >> $LOG /usr/share/zentyal-network/dhcp-clear.pl $eth_iface #TIMESTAMP=$(date +"%Y-%m-%d %T") #echo "$TIMESTAMP> ppp-down script for $eth_iface ended" >> $LOG zentyal-network-2.3.13+quantal1/ChangeLog0000664000000000000000000004106712017102311015135 0ustar HEAD + Assign ip address 127.0.1.1/8 to loopback interface in module restart and remove the post-up hook from /etc/network/interfaces file. 2.3.13 + Removed some warnings when external is undefined + Added modeldepends to yaml schema + New libossp-uuid-perl dependency + Zentyal Cloud DynDNS updates are now done outside the VPN and using the credentials obtained when the server is subscribed 2.3.12 + Interface is now auto-detected when adding gateways + New table to allow disabling of traffic balance for some gateways 2.3.11 + Fixed typo which made EBox::Network::ifaceAddress return empty addresses for virtual interfaces + Fixed validation of gateway names + Removed undefined value warning in setIfaceStatic() + Using EBox::Object::Members to generate multigw iptables rules 2.3.10 + Restricted gateway names to be sane with dyndns and fixed dyndns configuration with old incorrect gateway names + Disabled dnspark until ddclient upstream fix a bug with this provideer + Multigw rules more robust when no-static interfaces are down + Removed redis transaction workarounds in _setConf + Fixed unconfigured gateway removal, raise exception if the route addition command fails 2.3.9 + Remove all gateway based routes before adding the configured one and raise exception if the route addition command fails + Fix deadlock in preSetConf when DHCP is used + Moved bandwidth test to remoteservices 2.3.8 + internalIpAddresses() does not throw exception if there are no ifaces + ifaceExternalChanged() is now called when static or PPP interfaces changes from external to internal + Implement new EBox::Events::WatcherProvider + Remove no longer necessary ad-hoc vifacesConf cache + Adapted to new Model management framework + Reimplemented Ifaces/Vifaces/VLANs storage according to new conf backend + Added vnet to the ignored interfaces list 2.3.7 + Send additional info in Gateways watcher + Added clone action to multi gw and wan failover tables + Added EBox::Network::internalIpAddresses() + Added regenGatewaysFailover() to NetworkObserver so modules can implement actions to be done after failover regenerates routing tables + Fixed calculation of fail ratio + Assure that we have always one gateway marked as default + Restart traffic shaping on postinst to avoid rule loss on upgrades + Regenerate traffic shaping rules after failover event + EBox::Network::setNameservers does not fail if the same server is already in the list + Fixed calls to storeSelectedDefaultGateway with undef argument + EBox::Network::importInterfacesFile skips gateway adition instead of aborting if already exists one + Insert fwmark ip rules before from ones + Remove no longer necessary mark rules when having several interfaces + Pre-create failover and check-ip chains on network start to always ensure that rules are inserted in the proper position + Remove obsolete import of EBox::Order + Do not add gateways to /etc/network/interfaces to avoid conflicts 2.3.6 + Create tables with MyISAM engine by default + Fixed path of dhclient.conf 2.3.5 + Fixed path of dhclient hooks 2.3.4 + Not allowed to attach static interfaces to a network which has already another interface atached + Fixed restore of default gateway in failover event 2.3.3 + Packaging fixes for precise 2.3.2 + Updated Standards-Version to 3.9.2 2.3.1 + Adapted messages in the UI for new editions + Use printableName instead of name to select services + Fixed executable permissions in ppp hooks and external-ip.pl + Bridge interfaces are correctly removed; fixed _hasChanged method + Menu entry Diagnostic Tools in Network renamed to Tools + Added WakeOnLan to the Network Diagnostic Tools + Added proxySettings to return the proxy settings to other modules + Added new ip rules to avoid connection problems on multigateway & UDP + Virtual interfaces called '0' does not longer raise error 2.3 + Cache vifacesConf() result to improve performance + Replaced autotools with zbuildtools + Added gatewayDelete method to NetworkObserver and use it to check gateway removal in gateway table 2.2.3 + Allow to disable traffic balance with no_balance_$gwname config keys + Fixed bridged interfaces change when the bridge is not configured + Do not mark traffic to default gateway if it is disabled 2.2.2 + Fixed bug setting ip route rules with PPPoE interfaces 2.2.1 + External IP address getter now works even in an unpolite situation 2.1.16 + Does not sometimes fail in external IP address getter when multigw is enabled 2.1.15 + Fixed unique IP check on gateways table 2.1.14 + Fixed problems bringing up static interfaces during boot 2.1.13 + Proper use of ro/rw instances on failover event + Avoid duplicated gateway due to network wizard + Disable autocomplete in gateway proxy configuration + Disable autocomplete in dynamic DNS provider configuration 2.1.12 + PPPoE works again after regression by PPTP changes + Reviewed some subscription strings + Removed all the obsolete traffic monitoring stuff using jnettop and rrdtool + Added custom mtu configuration for the interfaces in /etc/zentyal/network.conf + Improved texts in configure interfaces wizard + Fixed dashboard network graphs for interfaces with strange characters 2.1.11 + Change provider for getting the public IP address in DynDNS + Better integration with core theme + Removed /zentyal prefix from URLs + Avoid errors deleting non-existent gateways 2.1.10 + Avoid duplicated restart during postinst + Added staticIfaceAddressChangedDone notification + Fixed module name in actions logging + Send only gw.hostname.dyndomain.tld to avoid ddclient go nuts 2.1.9 + Calculate interfaces widget size for a better default dashboard balance 2.1.8 + Remove pppoe debug in hooks + Allowed '/' character in proxy username + Manual log of audit actions in Iface, VIface and Vlan CGIs + Update wizard pages with new order option + Use pppoe name on chap-secrets 2.1.7 + Now chap-secrets configuration for pptp module is not overwritten + Use the new "Add new..." option in the object selectors + Set connected gateway as warn level event and minor improvements in the failover messages + Added maxfail option to PPP configuration files to retry lost connections + Added logic to manage PPP gateways in failover tests + Failover tests are now ran with a read-only instance even if there are unsaved changes on the interface and the generated events notify this + Removed unused EnableBalanceTraffic CGI + Removed use of obsolete LogAdmin 2.1.6 + Mark DHCP interfaces as changed in the Wizard to get IP on first save + Removed unnecessary call to ids() in DHCP hook 2.1.5 + Added interfaces created by libvirt and virtualbox to the ignore list + Dynamic DNS: Transform gateway names when multigw is on to send only valid domain names 2.1.4 + Group sudo commands when adding routes and cleaning VLANs + Added new Zentyal Cloud service for DynDNS + Fixed DynDNS help string 2.1.2 + Allow internal bridges + Gateways, Balance Traffic and WAN Failover are now together as tabs of the Gateways submenu + Improved order of the submenus + Setting DHCP gateway does not longer require saving changes twice + Remove unnecessary code from GatewayTable::syncRows + Do not execute ifup on interfaces during the boot to avoid multiple instances of dhclient + Fixed problem with uniqueness check in GatewayTable + Added report for bandwidth tests + Avoid warning in GatewayTable::syncRows when gateway is undef + Added debug to dhcp-gateway.pl script + New interfaces alias are checked to avoid name clashes 2.1.1 + Bugfix: PPPoE gateway is now properly set 2.1 + Removed ebox- prefix from src/scripts/* + Removed unnecesary call to isReadOnly in syncRows + Move ebox-netcfg-import to importInterfacesFile method + Remove obsolete migration + Added new initialSetup method for post-install + Replace /etc/ebox/80network.conf with /etc/zentyal/network.conf + Bug fix: Traffic monitor didn't work in non-English installations + Zoneedit service url changed + Basic support for other methods to retrieve IP + Do not try to start ddclient daemon if disabled + Make source event not i18n + Safer way to get the PPPoE 'tty' ethernet interface + Added PPPoE logging in /var/log/ebox/pppoe.log and ebox.log + Installation does not fail if the restart of EventDaemon fails + Now the ifaces_to_ignore variable is considered in ebox-netcfg-import 2.0.8 + PPPoE MTU rule is no longer flushed on module restart 2.0.7 + Show DHCP as default option in wizards if there is only one interface + Avoid problems when removing interfaces (vlan, briges) + Fixed support for bridged vlans configuration + Set all interfaces as changed on backup restore + PPPOE MTU is now changed when reconfiguring gateways + Set default order for dashboard widgets 2.0.6 + WAN Failover now supports DHCP and PPPoE interfaces + Disable reverse path to avoid failover checking problems + Better default values for failover rules + Use masks in fwmark to avoid interferences with traffic shaping + Warning in log if failover event disabled due to unsaved changes + Failover does not enable unwatched gateways + Reload events daemon after upgrade to apply failover changes 2.0.5 + Include Zentyal in multigateway rules when setting 'any' as source + Make Interfaces page title translatable 2.0.4 + Fixed failover problems in some scenarios 2.0.3 + Fixed syntax and string quote in 99proxy.conf 2.0.2 + Add support for authenticated proxy + Fixed traffic shaping problems in multigateway scenarios 2.0.1 + Fixed network confirmation page to work with bridges + Improved load balancing to avoid web sessions loss 2.0 + Fixed network wizard interface and logic 1.5.8 + Added options for internal ifaces in wizard configuration + Bug fix: disabling global proxy configuration didn't work 1.5.7 + More global proxy configuration and domain configuration improvements. + Zentyal rebrand 1.5.6 + Do not show unreplaced {link} variable in dashboard if not available + Add support to define a system wide proxy 1.5.5 + New setup wizard 1.5.4 + Bridged mode support 1.5.3 + Fixed failover problems with undefined default gateway 1.5.2 + Traceroute works again in network diagnostic tools + Using iptables statistic module instead of route for better traffic balancing 1.5.1 + Fixed nasty bug of traceroute in Diagnostic Tools with invalid host + Flush cache when regenerating routes + Bug fix: use '>=' and not '>' to check if a test exceeds $maxRatio in Failover watcher + Bug fix: do not run failover probes when all are disabled because they enable a disabled gateway. + Add and use EBox::NetworkObserver::ifaceMethodChangeDone to tell observers that a configuration method change has been carried out. So far observers were only notified right before the change takes place. + Add _notifyChangedIface() to factor code that calls observer to notify ifaceMethodChanged and ifaceMethodChangeDone + Add etherIface to fetch the ethernet interface from a ppp interface + Bug fix: do not mess with ebox's apache packets in failover test + Make failover test more robust + Added internal/external property to interfaces widget 1.4.2 + Restart squid when failover events are produced to avoid problems + Do not check host when adding a ping to gateway rule in WAN Failover 1.4.1 + Do not run ifdown for network interfaces when network is started from /etc/init.d/ebox start This seems to avoid some issues with DHCP configured gateways at boot time 1.4 + i18n help string 1.3.15 + Bug fix: warning instead of error if can't add failover rule + Bug fix: now a gateway without IP assigned can be edited 1.3.14 + Added multi-gateway support for DHCP and PPPoE + Add a warning if a user sets an interface as external and we detect the connection is made through that interface + Remove migration scrips: - 0001_import_default_gateway.pl - 0002_add_weight_to_gateway.pl - 0003_import_routes_to_mvc.pl - 0004_import_dns_to_mvc.pl 1.3.13 + Bug fix: configuration of PPPoE interfaces now works when confirmation is required because of other modules + Default field in gateways model uses '/ajax/viewer/booleanViewer.mas' instead of in-place edition 1.3.11 + Bug fix: fix issue with virtual interfaces on vlan interfaces + Add breadcrumbs 1.3.10 + Added PPPoE support 1.3.7 + Bug fix: update ebox-netcfg-import to not add upload and download as those fields do no exist any longer 1.3.6 + Remove upload/download fields from gateways. Traffic shaping has its own model for that + Bug fix: traffic generated by eBox didn't come out from the right interface as we cleared the CONNMARK with a --save-mark 1.3.4 + bugfix: add use=web to guess the public address + bugfix: make ddclient work with dhcp configured interfaces + bugfix: multi gateway rules work again 1.3.3 + Bugfix: Edition and removal routes is working again + Remove those static routes that they have been manually added 1.3.1 + bugfix: do not use Net::DNS + bugfix: used vlan interface can be removed 1.3.0 + bugfix: restart network interfaces properly 1.2 + Added support for WAN failover + ifaceNetmask method now uses DHCPNetmask to get the dhcp ifaces netmask instead NetWrapper call this adds symethrie with ifaceAdrress method and fixes a bug when changing a dhcp interface with no lease to static interface 1.1.30 + Added support for all missing netmasks between /16 and /32 + Added support for search domain in /etc/resolv.conf + Use a template to write down /etc/resolv.conf to allow easier user modifications + Use ICMP for traceroute diagnosis 1.1 + Added traceroute on network diagnosis + Use new rows() and ids() API + Bugfix: ebox-netcfg-import uses model API to import default gateway + Support for dyndns + Gateway models does not use longet custom views + Gateway rules table now use services 0.12.99 + New release 0.12 + Use new EBox::Model::Row api + Add help to model fields + Remove default option auotmatically if another router is set as default 0.11.102 + Bugfix: Static routes are deleted from ip when they are not useful + Bugfix: Fixing wrong href in multigateway rules page 0.11.101 + Static routes become a model with three methods exposed + Remove usage of a deprecated method in NetWrappers + DNS resolvers become a model with three methods exposed. Now you may add as many DNS resolvers you want + Use separator ':' in exposed method using '/' for addresses O.11.100 + Disable network traffic monitor due to a bug in perl and RRDs module + Use /etc/network/interfaces and not /var/lib/zentyal/tmp/interfaces + Run saveConfig() after importing network configuration and not save() which forced a restart of the interfaces stored in /etc/network/interfaces at package installation time + Add default gateway to /etc/network/interfaces 0.11.99 + Added traffic rate monitoring done on demand and in real-time. The monitoring may be filter by source address and service (protocol/port). 0.11 + move helper scripts to data dir (applied Soren's patch) + Bugfix: Change from static to other method works again 0.10.99 + New release 0.10 + Remove all interfaces from /etc/network/interfaces but lo after importing network configuration 0.9.100 + Fixing bug with static routes which prevented them from working if the multigateway support was enabled + Fixing bug importing gateway IP addresses from network configuration + Added /22 netmask setting iface IP address + Update models to new API + Get rid of custom controllers 0.9.99 + Restore conntrack mark in OUTPUT chain to make traffic generated in eBox go through the right router. 0.9.3 + Use value() instead of printableValue() in protocol + Add iptables rule to chain OUTPUT in table mangle to send traffic originated in eBox through the default router. 0.9.2 + Always add weighted routers when configuring routers. Instead of adding them when traffic balancing is enabled. Use iptables to send unmarked packets through the default router 0.9.1 + Add support for traffic load balancing + Try several times to fetch the mac address for each router 0.9 + Added Polish translation + Added Aragonese translation + Added German translation + Removed dependency: dhcp-hooks don't require firewall module anymore to operate correctly 0.8.99 + Support multigateway configuration + Remove old default router configuration + Add migration script from version 0 to 1 O.8.1 + New release 0.8 + Add netmask /30 (Patch from rampa at encomix.org) 0.7.99 + New release 0.7.1 + New release + Use of ebox-sudoers-friendly 0.7 + First public release 0.6 + Separate module from ebox base + move to client + API documented using naturaldocs + Update INSTALL + Update debian scripts zentyal-network-2.3.13+quantal1/AUTHORS0000664000000000000000000000024012017102311014417 0ustar Copyright (C) 2004-2012 eBox Technologies S.L. For an updated list of the current and past developers please visit: http://trac.zentyal.org/wiki/Contributors zentyal-network-2.3.13+quantal1/schemas/0000775000000000000000000000000012017102311014776 5ustar zentyal-network-2.3.13+quantal1/schemas/network.yaml0000664000000000000000000000140612017102311017354 0ustar class: 'EBox::Network' models: - GatewayTable - MultiGwRulesDataTable - MultiGwRulesOptions - StaticRoute - DNSResolver - SearchDomain - DynDNS - WANFailoverOptions - WANFailoverRules - Proxy - BalanceGateways composites: GatewaysGeneral: [Gateway, MultiGw, WANFailover] Gateway: [GatewayTable, Proxy] MultiGw: [MultiGwRulesOptions, BalanceGateways, MultiGwRulesDataTable] WANFailover: [WANFailoverOptions, WANFailoverRules] DNS: [DNSResolver, SearchDomain] modeldepends: MultiGwRulesDataTable: objects/ObjectTable: [source_object, destination_object] services/ServiceTable: [service] network/GatewayTable: [gateway] WANFailoverRules: network/GatewayTable: [gateway] zentyal-network-2.3.13+quantal1/www/0000775000000000000000000000000012017102311014177 5ustar zentyal-network-2.3.13+quantal1/www/images/0000775000000000000000000000000012017102311015444 5ustar zentyal-network-2.3.13+quantal1/www/images/interfaces.png0000664000000000000000000002206612017102311020303 0ustar PNG  IHDRdrmttEXtSoftwareAdobe ImageReadyqe<#IDATx] gu~wϹ3ݕ꾵i  & 6+&8)Hq %&Nrq:`.cc[$klI^I=\陽d*5==={fBU|Nܶᶊ6ؒD"Q90K.ީfԛP>tRHR5}b̙3Нݓڌ`|FQ:::`޼ye+ wFB9,rd@~Xq 澆qM+WqCbù_(3+Z~QOn`5⭋/Y+ }a$onGYô14tvRS)J5z{{]eݺu i؍&[+V(#k/} 08H+7_k\ے THE)s_GGG% @EPƴ|[׬Yڕj#85Z%{ M{Xc9Xy uZC0 *?vڽar@/#O| D1W/<].a VANN8qwu^RM-1կ5|+9., O ƭ {V^-34 `QB20wh %,=4nfFSX]Zc~/0ߙ@ϣy*LPU.0z ,B F-|.8EW4eslP&t$`s[.FdO R;$k&t{3pzL/݄-(KN:pjF_8MX_D齀20˜;]DQj6aVZJiiiF4O~w]1Ɖ<w^dI`c`/ջmqdY /yVa }6.7f84@yT. F!U;%<Ǹ(~|=A!^Npހ}ό CZbR]Ǐ5LG /Pƶ֋G_Rb e}n05ymk $b鷘@ (<'NXMS*rU~ oQՒ>kCwZ)9Ƽ/?_pOrM .m4B|M[|yⅆkѐ/xr|!| F//xh%phF(0ZZ]p|i y+iIvlC BG189.c g|!<=3(?X ff- Ǿxh~= áM^ MҰ$2aɓ+˖-{QwJ޽hѢ`3`!sNu\㒶yy#Lg[='&=+%r6r^ UEQ#d2`ggg8ԗg|&{QԈlns5`cqC/w,^ 'oD-y(즂yq( ޠdDA>L(Kђs|/dᚐ=ϟ?۪ jUDM?vvb6{vWt,0oZGɓ/I@ֶ0-S Ƣ|ɓ'B@5 v' g05;wB1RP|G\荅 ;ut>1*>~n/jǒh4z7%r,C%/KM J=TlT!lBEJAt|y8dwز\I=T`Oxț%m1S'Ÿŕ*lϿ=ܭn/ VT9A鱼`Wz} (<.xcnO|(r{0er %‚_x/v%0(r眄ˆF2E<'Bh\Ȼ 0FN\|7 8k|/,vFGJP,"wH.@,sJbGu!( ENE0QW*ml BI\ƭ{(?)&E2Dq9$/ܙR#: ޳%)TEP.|kVlY&& B-N#s*k-VPl.;£MmM}op-ʘKSjNOZJT/Htj32 &yCevx޴yA?@ړҜy<}piO |G FJй$sBuP 5Yf0k]|mMM@ٚK.}*.3I!o?rxbD ]E.OApqs@gid5\J|O+;;afg"9d_@wQ4jIܧh־CpxM|8ؑ[bJvM(QfX5(zg INar!*Vx,T ud HzS3ǿ@x".{ bƳ ַ]7g N XXcP)$aR if7jD떤667|d52VZ%+d"gDM5/˕"LP^rEX+*Efvۧ3|wQH4~ö,P|ඥLG_ww j2?عIq yqռ\|]fv>quŤs>:gctj :PI=Wr!QVTg5O RpY1b0 3aWz+vF^/8z&V5𶔢W\n%o0қ-{齐rk+U)H+3BKTJuYWBpxHT%mu&+Ca#'64}5ZJMt{A / J[Uˬ/ q^_G6ߟ2<$Z-Hk, .!4ݪړZV3a՜LygmkC u]cvOvV&@)س8; ߡV6\^' 6 ղ 0Zj)>('b3c?e|_,%./-Ál߾=Yt[ RoI}&tື\;ceJ,޺3o^ [-n`%P`F{/듀I) |;(_; ./~35n]Y Ub˞|ʘ bKA ==d]VppʕۜKW2a?91:5[Lے*XX'|qPh~`Y-+/P_`35]^[^T L U)BPn@q_(0K+B| EOQ>l$ёu!o[ofNYiO5 Ë}-U˜"!*}_lcV>prQ#_`/ y\[.o睑WeÜ1EׯwK+4hܥiiv⃲5+c]RTh%kߋb(@ºuE+wAj|ۮl.Y.qK`XݤvKk{=z5vTR'd^xkT .Djҍ k2O|a`T%aTqiZ>䍯#t7uj}WW7 @Ϗ#=Y)>Uw(|a{hZ=7-ʫ,X[rz5@=6&6JE/MKRp͢x {<9" ѣ)~^Vޱq&;3q/mGB)"pn<>{cǎA#&PWMB ZV">V{5X7'⻐d=9co=H/{&㶵cHoʝSBkzW2Q$7.3R/~9~8EP ] 'p{Ҍd,SsĉnWῒsIV⮩(LVXqW&}\ذ_`PT__iM؂ 0Z[[YS%kuzZhlls:rSDOD6\`؏N%/T#42X__M8]p]?YzЗ* Ѧ g]v| 45m18Y.f`6w#AC@'0 ,ps'j,6*gBΝ;p l򧦤nAMXOÒŰj8+S΄ȠOZ`Hk30c.623 U "¸K·ٮ %9oiD$Dww8 ]]5%T]V(aΜ"F%!B^P5 ,TUS~nccr3 zosJ C¹:i\U1*ba9.4c_#xkkhltlh6YصkqN5H| -h:n*BDTEC@ `(p\bm]Zތs9-Z$n0(b r[) c> =?p Ɋ60& 9, {0@S*11aFGƙ39<%O']wuOSh>1ؾ};{Z oMS@#xUS *^@zs؁*(( ȹL)D7d3 LQWyGilޡ}jx4Jgj7'g̡09_Yr8ǿ}Fm: C7 =bh̙+X8ĞRk= {Μ9*;&4aDFFT0Y"xbj%gn@)_eďPF؁$7#mpgfcBd{ }„sj=զn+3|BpmuU`BSDAaI=Wx/\X#Pn9zhhn߾M G@#Y'P F4!B7CLF8D,k#O |/ E3LMP#eA#4ok֭ \aĚA( pCJX$lj(+&*A1 yd^D`* s}bhLސZ`SJ/2a'3`\.s0!/O`ty) /~~/k2$|[`7b?y000C_d} iIHԥQ";9mۚPg&sHB_~8-h1IWDob#^H[ yad9D>OAK$\!4hm@6 wtLpE73>0~g}fL+B4B=2rgJ"T rT,Qcp.k$t doAVP4t}U.N d,ԌH$ V#?a4YO:Z4R9$H)A򡮨3UсQB(1(F–%P_f2 nّM05TgoVSKIpCWTd3vNM~b^P52U*)1E=uM4S9TjR'iD@9,flnht>1ϝ@O8D&6|E! #(:cc|$6)+]sR+kPu|IfR  P{2rr*5ð5 "Za,l"K vϋXlVur"~R<K> 75 3ΰ;OŪU)1q"x<'C7y?#gKQU#ЄRXd&'Ke3U[3qÖvQ&047˸PBU(4pG@L(ō✵2$Y`` '?kAlfbRZaRF %H A7Q[^ "9z^~Ex$ Qb}t Ġ);N6S*RsC$.Q9,ZYC}G+;ZoF*hrݻ-Y.҂tk#qIaѢ_S+]_ϝ#'e8~?4ف@tu)&֡'<,j$eS:aµP}=mFHJ`нOS#Xu)/tx,(bIENDB`